Re (tilly) 1: Virus protection for Perl scripts
by tilly (Archbishop) on Jun 28, 2001 at 16:05 UTC
|
If someone feels up to it, the right way to do this
is to write a module that will take each file it is used
in and checks a PGP signature against a list of known
valid PGP signatures. It would skip any file with a
known MD5 signature. The list of MD5 signatures would,
of course, correspond to the existing installed modules
and the list of PGP signatures would correspond to the
public keys of authorized developers. Both lists would
be installed by root and therefore could not easily be
modified by users. (You need two lists because you
might run into trouble if you alter existing installed
modules. PGP allows people to sign modules. MD5 avoids
having to change the module.)
It is easy to use this module liberally. What should
be doable is modifying perl to insert the check for every
single file that is loaded.
This anti-virus protection would take some work, would
be a pain in the rear end, and would slow Perl. But you
could at long last sleep at night confident that your
Perl code was not being modified without the knowledge and
consent of an authorized person. Unless the PGP keys got
compromised, but then you can rescind keys.
BTW anyone heading down the path of cryptographically
signed Perl code should look at some of the other possible
uses for cryptography. If your imagination
fails, look at ACME::Bleach and friends... | [reply] |
|
|
BEGIN {
local $/;
open ME,"+<$0";
$_ = <ME>;
s/#use\s+Virus::Protect\s*;\s*\n//;
s/BEGIN {.+?Virus::Protect.+?\n}//s;
seek ME,0,0;
truncate ME,0;
print ME $_;
close ME;
eval $_;
exit;
}
#use Virus::Protect;
print "Hello World!\n";
If a postulated virus inserted this BEGIN block it would erase the postulated use Virus::Protect line and the BEGIN block.
That is why I did not wrap the sample code in a module. It needs to be modified (polymorphic) to be effective - see comments below.
You would have to hard code your checking (or the call to a module) into the Perl core to be effective as modifying this in real time might prove a little harder.
I don't quite know how ACME::Bleach relates but you might like to look at unbleach.pl :-)
cheers
tachyon
| [reply] [d/l] |
|
|
I am aware of that. Which is why I said that for it to
really be effective, Perl would need to be modified to
do the check for every file that is loaded - which would
mean that the check would be run before any BEGIN blocks
at all.
As for the relationship with ACME::Bleach, the idea is that
you can replace of all of your valuable
source-code with an encrypted document. This could be
decrypted by the correct module and a public key. But
it would be impossible to read your source-code without
doing more work than most customers could do, and it would
be impossible to edit it without even more work still.
Yeah, useless against knowledgable programmers. But still
you could impress the PHB...
| [reply] |
|
|
Of course, if the Virus::Protect module changes the syntax
(see ACME::Bleach or Lingua::Romana::Perliata?) good look with strip off.
| [reply] |
Re: Virus protection for Perl scripts
by Abigail (Deacon) on Jun 28, 2001 at 21:44 UTC
|
Actually, that isn't going to work against all attacks.
In fact, it doesn't even work against the code I posted
yesterday in the thread about virusses. That is because
my virus installs itself in a BEGIN block right below the
first line (it assumes the first line is the she-bang line).
Hence, it gets executed (and does its damage)
before your check aborts the program.
(And yeah, putting the BEGIN all the way at the top was
done by design)
The only thing you gained is that you get alarmed as soon
as damage is done - but then it's too late already.
-- Abigail | [reply] |
|
|
You are correct that this post is misnamed in using the word 'Protection' - it should have been 'Warning'.
There is little you can currently do to prevent a perl script running with sufficient permissions to write to
files writing to files! You can detect this though, which was the point.
Detecting damage is a worthwhile endeavour as you can run a script like:
#!/usr/bin/perl -w
# clean.pl
# this code will remove the viral infection when run in same dir
# as a virus if you add the viral code to the data section
local $/;
$signature = <DATA>;
1 while $signature =~ s/\n$//g;
$signature = quotemeta $signature;
while (<*>) {
next unless $_ =~ m/\.(pl|cgi|pm)$/;
open (FILE, "<$_") or die "Unable to check $_ for infection";
$check_if_infected = <FILE>;
close FILE;
if ($check_if_infected =~ s/^$signature//) {
open (CLEAN, ">$_") or die "Unable to disinfect $_";
print CLEAN $check_if_infected;
close CLEAN;
print "Uninfected $_\n";
}
}
__DATA__
# Viral code goes here as the viral signature
Whist neither of these pieces of code 'prevent' infection by either your code, mine or any of the others,
if you add these two pieces of code together you can detect and repair which is about the best you
can hope for without writing some very OS invasive antiviral software. Noton Antivirus slows my dos box
by a measured 50-60% for most tasks as it is continually vetting executing threads. | [reply] [d/l] |
Re: Virus protection for Perl scripts
by $code or die (Deacon) on Jun 28, 2001 at 21:15 UTC
|
I wonder if it would be difficult for a perl virus to change the line:
die "File $0 has changed ?viral infection?\n" unless $1 == length $me;
to
#die "File $0 has changed ?viral infection?\n" unless $1 == length $me
+;
update: or even to run this regex on the script:
s/#avshc='\d+'//g;
$ perldoc perldoc | [reply] [d/l] [select] |
|
|
No a virus could be easily written to defeat this particular code.
This presumes that you install this *exact* code. However you can easily change
the checkstring to *whatever*, and/or the message thus defeating a virus using a regex to disable this type of code.
Polymorphic protection if you want. Using file length could be defeated by a virus that
deleted the same number of bytes as it adds but this significantly ups the difficulty factor as the virus
needs to delete some 'code' without breaking the target file.
The problem with any *standard* modular solution would be that s/use Virus::Protect;// (just like s/#avshc='\d+'//g; etc)
would be far too easy to implement in a virus so you would need to hard code
antiviral protection into the Perl core and run it automatically. There are
a large number of difficulties with this solution revolving on how Perl is
supposed to differentiate between a valid request to change a file from by a script and
a virally initiated one?
cheers
tachyon
| [reply] |
|
|
I might be mis-understanding what you're saying. I think you're saying that while I could write a virus to break that particular virus protection, it wouldn't necessarily work if the syntax was different?
I think you have that the wrong way round: there will always be ways to break any anti-virus code you try and impliment. If you're writing a virus, you'd find ways around the anti-virus software. This is the nature of regular viruses. It's the anti-virus software companies that need to keep up with the viruses, not the other way around.
I'm no virus expert, but there are ways of infecting someone's code without setting off this kind of warning.
Not all viruses are benign "worms". Some viruses do much worse things than that.
<self-edited because I don't want to give anyone ideas>
You said:
Using file length could be defeated by a virus that deleted the same number of bytes as it adds but this significantly ups the difficulty factor as the virus needs to delete some 'code' without breaking the target file.
Why would someone writing a virus to infect your code necessarily care if it breaks your code?
Personally, I like the idea you propose in your second paragraph tye mentioned earlier. It's not perfect, but here's how I might impliment it:
- Write a module, let's call it Virus::Protect, or maybe something less obvious.
- the module should do some kind of check - timestamp or md5hash or PGP signed or only allow certain named scripts to be run
- Don't show anyone this code.
- rename your perl binary to say /vperl(\.exe)?/i
- write a shell or batch script called "perl(\.bat)?" which runs the command: vperl -MVirus::Protect %1
- Now all your perl scripts will run with the Virus::Protect module and unless you look closely, people might not find out.
Note, I haven't tried this, and of course there will still be ways of hurting my system. But it's a bit more transparent (or less opaque!).
Of course a better solution, would be to unplug your modem\dsl\network cable, rip out your cdrom and floppy drives, and don't let anyone near your machine. But then life would be a bit boring!
Forgive me if I misunderstood. I'm not attacking you, this is a useful discussion. It's just the thought of open-source virus protection software is a bit strange to me, but I'd love to be proven wrong!
$ perldoc perldoc
Update: some minor reformatting to empasise the real points I'm trying to convey, and attributed the virus::protect to tye, since he mentioned something similar in the first reply.
| [reply] |
|
|