'Protecting' Perl Code?
An anonymous reader asks: "Ok, so here is the scenario: my company has some software that is used internally and it is written in Perl. We now need to put this code on a server that has 'public' access (it's a university machine). We provide root access to the system for the purpose of learning, but we need to keep the code from being viewed or edited. Is there anything to do besides the 'perl2exe' and the ActiveState compiler? How effective are those really at protecting code?"
CHMOD?
You could scambling the code un-readable uncompiled.
One of my professors told me a story about how he once worked with a guy that mantained a project. To help keep his job he would always submit the code scrambled with all names of variables and functions seemingly meaningless. He showed him this one day and asked, "How can you read this?" He said, "I can't. I write the code, put the source through a filter program and then submit the result. If they need someone to fix it or read it or improve it, they will have to go through me." This was back in the early 80's.
..and it's called "Perl". You don't need to do anything at all for your code to be unreadable.
uh......put the os on a cd....
Nobody can read it anyway!
But seriously, if you provide root access to the system, what good is a Perl obfuscator/encryptor/compiler going to do? Nothing can really stop someone with a will and enough free time from decrypting the code.
If it's for learning and people have root, why put it on this server if you don't want people to learn from it?? Still want to do it? Move this perl code to another box and call it via RPC.
My second though was permissions. Why do the students need root access? Couldn't you make some new account that had permissions to do anything but access that one directory?
My last thought is a sandbox (or I think the BSD concept of a Jail is the same idea). If you were to run Linux on Linux (Xen, or just some other sandbox, maybe even chroot) then you could give them root, while keeping them out of the true root.
It's a tough situation. Does it really have to be on that server? You can't stick it on a new server your company buys for the purpose and donates (what is more important, My last idea (a bit extreme, I would think) would be to modify the Perl interpreter to run the perl code through a decryption algorithm first (so the source on disk would be encrypted so it couldn't be read). With open source software, there is no reason this isn't possible (would hurt performance though).
Does Perl support some kind of tolkenizing? When you run a Python script you get the .pyo (I think) file that is basically the cached compiled Python byte code. Can you do that with Perl? It isn't perfect (can be disassembled back into Perl, but without variable names, etc) but it is better than plain text.
Comment forecast: Bits of genius surrounded by a sea of mediocrity.
"We leave our doors open, but how can we stop people from stealing things?"
I'd re-consider allowing such open access to root.
It occurs to me that asking a bunch of pro-open-source geeks how to best maintain control over closed-source code in an sub-ideal environment is perhaps not the best idea ever. In fact, I would suggest that you double-check any answers you get here, as, for all you know, they're purposefully sub-par solutions designed to lull you into a false sense of security so the code can be more easily nabbed.
Those dudes had a fairly nasty pack/unpack decryption sequence in their pay webmail system that I never got around to cracking. If those tards figured it out surely someone else can.
Beyond that, make the perl script on the box be a wraper that lwp's a request to your box and spits out the output as a cgi.
09f911029d74e35bd84156c5635688c0
This is such a frequently asked question that there's even a faq in the documentation that is distributed in almost every single perl distribution.
perldoc -q 'hide the source'
If that's not simple enough, then see the thread on perlmonks.org about it.
If you still think that obfuscating the source code is going to gain your company anything, then I doubt anyone really wants to see your code at all. (You don't happen to work for Blackboard, do you?)
http://www.donarmstrong.com
That's nonsense, don't listen to this guy.
Look, just to show how nice we are, why don't you upload it to my FTP server, give me the root password and IP of this machine, and I'll take care of the rest.
<xml><I><am><so><damn>Web 2.0</damn></so></am></I></xml>
Re Viewing - me thinks this fool is trying to implement security by obscurity. Why else this silly request?
Re Editing - of course if you have root access you can edit *anything*. Of course if you turn it into a binary, they won't be able to directly edit it, but they could reverse engineer it, re-create it, and edit that. Why stop them? Me thinks this fool wants security by obscurity.
The method for protecting your code from being copied is called "copyright". Really, that's the whole reason for the existence of copyright.
Software sucks. Open Source sucks less.
If you are giving root access to the machine to students, you do not need to put your preciousss perl application on the same machine. In fact, you need to NOT put it there, because even if you obfuscate it, encrypt it, or compile it, it's possible to reverse the process. Obfuscated code can be analyzed and understood, plus it's going to take some real talent and time if you want to do it right, so it's expensive. Encrypted code needs to be decrypted before it can be executed. Compiled code can be decompiled.
You might use something like a BSD Jail or some other kind of server virtualization, so it merely looks like your software is on another machine. If it is really important that this program remains your dirty little secret, don't put it on a machine which you don't control. Really.
But if you really want to put it on the same machine, try compiling it into a binary, and not draw any attention to it, to avoid people getting curious about it. Still, if someone finds it and takes enough of an interest in it, all bets are off.
I suffer from attention surplus disorder.
Comment removed based on user account deletion
Is like giving teenager boys whiskey and car keys. I think P.J. O'Rourke said it first about politicians and money...
"Eve of Destruction", it's not just for old hippies anymore...
...no one will understand it anyway.
How much safer can it get?
Gregor
if you want to give them root and prevent them definitively from reading it, you're going to need to come up with a better plan.
with a debugger (which i presume they'll have and understand, since these are obviously CS students of some flavor) they'll be able to attach to the process with an all-seeing-eye, so running it on the system where they've got root is just not what you want.
depending on what sort of script this is, could you store it on a different, restricted box, and only let them interact with it over the network? if they have no need to alter it or read it, then what need is there to even store it on the same machine? if the script needs access to the filesystem, you could export it through your favorite network FS to the restricted machine running the script.
encryption and obfuscation are rarely going to be as effective -- and will usually be more of a headache -- compared simply moving it to a more controlled box.
Just a quick question... what are these students supposedly learning from this script anyway?
If it was a systems program, well it probably wouldn't have been written in perl, lets be honest.
AI? If the students can't learn about the algorithm, it's not much use.
Theory? What will you prove about a black box perl script?
It sounds like you're a bit confused, if the people are supposed to have access to learn, then why are you denying them access to learn from this script. It sounds like you really just shouldn't have this script on there, as was said before, you should move it elsewhere and call it remotely.
But MOST IMPORTANTLY, I wouldn't put anything of value or importance onto a machine where uni students have root access. If you remote call, whose to say they won't break the call, if you obfuscate, whose to say that they won't just break the script or delete or replace it. It just seems silly...
Perhaps you should give them access to a root-like group, then not put this file in that group. I think you problem is that you want more complex permissions then you've relegated yourself to having.
http://monkeyserver.com --- weeeeee
Why don't you install yourself a nice Kernel with grsecurity.
Using it's permissions system, you can allow root to login and do whatever you'd like, you but can set grsec so that only certain other groups/systems are able to view/run etc your perl code.
The permissions system is very configurable and it's a steep learning curve with not a real lot of documentation. But playing with it for a few days should get you all figured out.
Using grsec it's possible to allow root to login and really do zero damage, it's a great system. I don't think any Linux box should be allowed on the 'net without this patch! There are other systems (SeLinux) that offer the same sort of thing, so if GrSec isn't quite what you need be sure to look at the others.
Using a system like this means all those "they have root forget about it" isn't true anymore, you can configure it so root can do very little damage to the working system, but still have access to edit all those files the normal pleb user accounts can't.
Tim
The problem with Perl is that it's an interpreted language. That is, you need an interpreter to read the code and then run it. And if the perl binary can read the code, then so can you.
An obfuscator could work, but then someone could easily nuke the program, or just generally mess with it.
Honestly, I think it's a retarded idea to begin with. First, drop ALL the root access, no excuses. Add stuff back in with Sudo as needed, giving each command careful review. Then, rewrite your app to work with suidperl, and run that with setuid root, or with sudo.
That's the technical answer. But honestly, why are you afraid of them looking at your code?
Don't thank God, thank a doctor!
Comment removed based on user account deletion
If you have embeded passwords or hostnames in the app then there is nothing you can realistically do to protect that info. If you are trying to keep thieving students from stealing your code and calling their own then copyright is probably a better answer. We don't even know what the code does, is it possible to host it on a protected machine and run it via cgi or any other rmi?
[Set Cain on fire and steal his lute.]
Root can do anything. If you don't want people to have write access to your perl script, then don't give them root access! Think about it. Even if you used something like perl2exe, root could simply delete your script, and replace it with something that did something nasty. Do you really want that? No.
LOL!!!! FUNNY!!!! PERL IS MESSY!!! ONE OF A KIND JOKE.
Oh wait, on second thought, the joke was already used here, here, here, etc...
EOM
70e808a22cb027cde4a6abddf6435d55
You provide access to it for learning purposes, but don't want anybody to view it? Just put it inside a password protected archive or something.
I'll subscribe to Slashdot when I see a month without a dupe, a typo, or an article the "editors" didn't read.
I think you want Perl Packager with the --filter option...there are a few filters that can be used with that (specifically PAR::Filter::Bleach), but if one of these won't work, then I'm afraid you are asking for something that simply doesn't exist...no security through obscurity and all of that...
Does the script have to run fully on the unsecured box? If not, then you may be able to break it into two pieces. Run the user interface locally have it call a second script on a secure machine. This may be a simple as ssh or as complex as a full blow client server app depending on your needs. The principle is to perform all "interesting" processing on a remote machine that is secure.
a) download perl source
:)
b) in perl source, modify all control symbols to other control symbols. e.g. "-" treated as "+", "+" treated as "@", etc.
c) make a script to modify your code's control symbols with the same mapping and obfuscate all variable names to randomly generated ones
d) run the obfuscated script on obfuscated perl
by the time they'll decode everything that version of your code will be outdated
Did you know that "FTW" ("for the win") is a direct translation of "Sieg Heil"?
This sounds like such a BAD setup: security through obscurity (in Perl?!), basic inability to understand root. After all, if hackers can reverse-engineer DVD software to decrypt all movies, your Perl script doesn't stand a chance. And I bet you're putting a password in it!!
:) Modify the script to load once, delete the file, and respond to requests. See perldoc -q 'hide the source'.
But assuming you know what you're talking about, it's an interesting puzzle.
Read-only as root? Mount a write-protected media. CD, floppy, USB dongle. Some hard drives let you set a write-protect jumper. Or you could go with that modified kernal that someone else mentioned here.
Obfuscating Perl? Install a Sony rootkit!
Everyone is entitled to his own opinions, but not his own facts.
Perl is already Tolkienized -- just look at the start of every source file!
More seriously, you can save the internal representation, but it's easy for someone skilled to turn that back in to mostly-readable source code. You don't even lose the variable names; Perl keeps them around. (For globals, you have to -- you always have to do a symbol lookup. Lexicals don't have symbolic access; the compiler turns these into indexes into pads attached to the internal representations of code objects. However, these lexical pads do keep the variable names around as they're important for error messages, among other things.)
(Guess who just wrote about lexical pads in a Perl book not more than ten minutes ago?)
how to invest, a novice's guide
If you must provide root, how about using a system like SELinux that provides "mandatory access control" that root can't override? Then you can lock the kiddies out of messing with anything that could wreck the machine, while leaving them free rein in everything else.
1) implement soap interface to your program,
2) put it on secure machine (without "public" accounts)
3) write client to use your "web service" and put it on university server.
4) done
you are not your sig
A lot of people have recommended not giving the students root access. How about just limiting their admin priviliges using sudo? If you're using Linux then you could use SELinux or systrace on OpenBSD to limit what root can do.
A memory dump of a running process that is using Perl Dev Kit produced DLLs will also show the embedded Perl code. This happened with the PDK I used a year back. Memory dump was created by Visual Studio 2003 after attaching to the process.
Try using Module::Crypt, it just entered CPAN few weeks ago! I've tested it, it works well.
,
#!/usr/bin/perl -w
use strict;
use lib '/home/vservers/modules';
use Module::Crypt;
CryptModule(
name => 'NCM::Crypttest',
file => '/home/vservers/crypttest/maedls.at/Crypttest.pm'
);
The best protection for any kind of application you hand over to a customer is a clear license agreement stating what is allowed and what not, together with a good lawyer. It is probably the best way to make the lawyer write the license agreement together with you.
Just as a good hint for you and your customer(s), you may digitally sign your code with a private key (using PGP or similar). Refuse any kind of support when the signature validation fails, i.e. the code is modified. Think of it as a "warranty void if seal broken" in code. Don't check the signature in the code, this is just stupid. The first step of modifying your code would be to remove the signature checker. The signature checker is a separate application on your computer(s) that you do not give away. It may be just a simple shell script using PGP and your public key.
Don't even think about encrypting your code, this is plain stupid. Your application needs to know how to decrypt the code, and the decryption engine must be unencrypted to run. So with a minimal modification of the decryption engine, your customer can read your code anyway. A binary decryption engine (XS in Perl) is not directly readable, but it makes the job just a little bit harder. There are decompilers out there.
Tux2000 <- gave away 100.000 lines of code to paying customers, multiple times
Denken hilft.
[boggle]
Yet another Ask Slashdot submission with not enough information about your circumstances or reasoning to offer any kind of truly insightful response... except perhaps this one.
- What does the code do? Why is it important it is protected?
- Do these students actually need root access, or is it just management laziness on your/your companies/the universities part?
- Would these students actually care enough to bother doing anything with this code?
- Have you considered a jail/sandbox/some kind of secure system emulator?
- What is wrong with perl2exe (Windows only?) or the ActiveState compiler?
- Why can you not get the students to sign a user (non-disclosure?) agreement in good faith (agree not use the box for malicious purposes, intentionally damage the system, or steal your code etc)? Is this not covered already by the unniversity network's user agreement?
I personally can't invision a program that could be SO mission critical that you are considering puting on an open box AT ALL. Presumeably it isn't that critical, so why not persaude your company to make an exception in licensing in this case and let it go.
Who knows one of the students might find some obscure bug and make a suggestion on how you can fix it, or help you make some other such improvement.
If this is a windows machine, you could install a certain DRM program and start the file name of your perl script with $sys$.
You're as bad as all the damn proprietary software vendors who try to prevent people from examining their compiled code in a hex editor or decompiling it.
Why do you want to do this? Is the code proprietary? Does the code contain security sensitive information?
If the latter, then jeez, that's just plain piss poor design. In the case of the former, just put a license warning in the code. It's impossible to "protect" overall design and algorithms anyway.
You can obfuscate the code of course, but really, that's just an exercise in futility.
Sticking feathers up your butt does not make you a chicken - Tyler Durden
We use the ActiveState compiler at my work for pretty much only this purpose ( well, it also gives you the benefit of not having to depend on all the modules since they are compiled into the binary).
The code is pretty much unreadable, it is just a ton of binary garbage. I am sure someone with enough ninja-like skills could step-trace it through and get the original Perl instructions, since there is probably a perl VM compiled in with it. But this is not the kind of protection you are looking for, all you want to do is stop 05% of the people. The other 5% can reverse engineer *anything* anyways, even a compiled C++ app.
The only non-stupid reason this MUST be on the machine is that it is required that these users be permitted to run it, on this machine.
If it is on the machine, root shall be able to read it. If it is possible to execute it, the method of easily decrypting it is present on the machine.
Place it on another machine, executeable only through a network interface, thus making your program itself purely a "black box".
Example 1: Your program is an encryptor, and it takes a key and a data file.
The interface code could be as simple as a shell script that reads the key and filename, and uses a restricted ssh key (on application hosting server, the key is tied to a specific commandline) to transfer the file to a staging location on the application server through scp, run the command, and retrieve the resulting file.
Example 2: Your program passes down a directory tree and creates new files related to existing files.
Simplest solution is like example 1 - script tars up the directory tree and feeds it through ssh to an untar and calls your program on the new remote tree - it could even be a pipe then - you feed your tar directly to a script on the other end that picks a staging location, untars the stream, runs your program on the tree, and sends back the result as a new tar stream. Obviously, it wouldn't be a true stream since the output wouldn't even start until sometime after the completion of input.
If the tree is too big, you put a modified version of your command on the remote that does only the secret part, and a modified version that's publically available to do the obvious part, and outsource the secret work, again through restricted ssh keys.
Example 3: Your program really is a pipe.
You provide a script on your end that just execs an over to that other box with a restricted ssh key limited to running only your command, and runs it.
In my solutions, ssh is a theme - because I don't know the environment, and go with the most secure and flexible solution using service that's likely already approved. For many tasks, you could wrap your stuff up as a cgi script and call it through wget. Maybe write it to listen on a socket and be a plain old service on the box that you control.
If the customer insists that the program itself be present on a box to which he has privileged access and rejects all solutions that don't include that condition, he wants the code. Both of you drop the charade and start negotiating based on that fact.
<p>Yeah, this is called a source filter. There are a large number of them on the CPAN. They're all done for fun-related purposes, mostly humor. Some examples include ACME::Bleach (the program is encoded entirely in whitespace), or ACME::Buffy (for vampire fans), and ACME::Eyedrops (my personal favorite, and different from the others in that the module doesn't have to be installed on the system where the code is to be executed; it produces code that abuses (severely) the regular expression engine to accomplish what the original code accomplished).
</p>
<p>However, none of these will prevent someone with full access to the system, who understands Perl, from being able to reverse the process and demangle the code to obtain it in the form the interpreter sees. And yes, there's a performance hit, although with most of them (notably excepting Eyedrops) it's upfront (when the program is first launched), not continuous (thoughout the execution of the program), so it's not as bad as you might think.
</p>
Cut that out, or I will ship you to Norilsk in a box.
Alternatively you can try LIDS. One of the many features of LIDS is ACLs that are applicable to root as well. Configuring LIDS section of their FAQ gives a number of interesting examples of putting a heavy "lid" on access to the system, while keeping it useable.
Perl is already Tolkienized -- just look at the start of every source file!
What, do you have to run it on a Tolkien Ring network instead of Ethernet?
"One Ring to rule them all,
One Ring to find them,
One Ring to bring them all
And in the darkness bind them."
You may try perlcc
If they have root on that system, they can read anything on that system, and that's the end of it. You can hide it/obfuscate it N different ways, but they're all fixable -- in order to run it on that box, the perl text (or some equivalent transformation) has to be obtainable on that box for perl to execute it. And if it can be obtained to run it, it can be obtained to read it.
You might have enough limits with a BSD jail, or a virtual machine layer, to keep them in a subtree somewhere, but you're still going to have to call out of the jail/virtual machine to let them run the script, so it's the same archetecture, just a different network.
- "History shows again and again how nature points out the folly of men" -- Blue Oyster Cult, 'Godzilla'
Aren't there true compilers for Perl?
You could use this module to convert your code to Morse code.
:wq
-- Phase 1: Collect under pants Phase 2: ? Phase 3: Profit
You give a bunch of college kids root access to a public access server?
how many porn sites do you host?
'perlcc -B' may do (it's quite broken, but it works fine with many scripts).
And no, one cannot run Deparse on it.
It can't really be done. You can make it harder, but never bulletproof.
You can use Filter::decrypt or similar to encrypt the source, but if someone's really determined, they can you the B:: modules to look at the opcodes and convert it back to Perl.
-William Shatner can be neither created nor destroyed.
PERLCC(1) Perl Programmers Reference Guide PERLCC(1)
NAME
perlcc - generate executables from Perl programs
DESCRIPTION
perlcc creates standalone executables from Perl programs, using the
code generators provided by the B module. At present, you may either
create executable Perl bytecode, using the "-B" option, or generate and
compile C files using the standard and 'optimised' C backends.
The code generated in this way is not guaranteed to work. The whole
codegen suite ("perlcc" included) should be considered very experimen-
tal. Use for production purposes is strongly discouraged.
Root for learning is a great idea but these days give people their own virtual machines. Bochs, User-Mode Linux, and a variety of other solutions are out there.
Besides, most students have PCs and they can install Linux on their boxes if they want to. Maybe you can negotiate a university license for VMWare or MS's VirtualPC so they can have both MS-Windows and Linux up concurrently in their own dorms.
Knowledge is how to play a game, intelligence is how to win, wisdom is knowing what game to play.
I just posted on comp.lang.python asking about available protection schemes for python code
Python obfuscation thread at comp.lang.python
petantik.blogsome.com - A Lucid Look at Reality
Give them root on a XEN machine, not the primary box. Allow them to access you perl code in whatever fashion it was intended.
But Acme::Bleach and Acme::Eyedrops can at least make it a pain in the ass to work out what it's doing.
However it could be copied verbatim and it would still work.
As with all other things perl, see CPAN and perlmonks for more information.
- Paul
Whatever. Please switch to python, please..they need more companies like yours ,and the perl community needs many less.
muhahahahahahahaahah
man perlcc
.pl not for .pm (as far as I can see). .pl file..
This however only applies for
But no one can stop you from including all your pm's into one
Ugly but usable.
I've never gotten the perlcc to binary (only to bytecode) to work with modules.
You want to *protect* something on a machine you're giving root access to?
You work for Microsoft, don't you?
Acme::DonMartin is the way to go.
"The first time you run a program under Acme::DonMartin, your source code is magically transformed into Don Martin cartoon sound effects. [...] This can also be construed as a security feature. It is expected that a hacker will be laughing too hard to be able to recover the source code."
1. perlcc to compiled code doesn't work for compiling to C for most of code (and generates 5-10Mb of C code that compiles for 10 minutes by gcc) and result doesn't work almost all of the time. Output of 'perlcc -B' can be reversed using B::Deparse..
2. ActiveState PerlApp just extracts all your project's files to a temporary directory during execution of your "compiled" code. Just copy them from there, with all comments and documentation. Simply LOL. Why nobody is sueing ActiveState for this?
3. Using PAR even with --filter option produces rather readable code, that doesn't work most of the time for real projects.
4. Using perl2exe is questionable due to existnance of exe2perl (search on google for it). If it won't work for current version of perl2exe, memory dump of running process should do the trick and one will get cleartext of your scripts with comments and everything.
The only reliable and unreversable solution is the use of obfuscator - like Stunnix Perl-Obfus. Obfuscators replace names of variables and functions (and other names like names of file handles) with some random-generated identifiers (this is one-way function, it can't be reversed), also removing comments, white spaces and replacing strings and integers with expressions or their uglified versions.
I know two complete applications written in Perl. Solarwinds TFTP (http://www.solarwinds.net/ and Whitehorn TFTP (http://www.pegsol.com./ Use TFTPD32! Loosers.
I'm trying to use that pile of shit to mark some assignments right now. Here's a hint. DON'T EVER USE BLACKBOARD VOLUNTARILY. It is an impediment to productivity.