Advertisement
opexxx

DeXRAY.pl

Sep 5th, 2014
299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6.93 KB | None | 0 0
  1. #!/usr/bin/perl
  2. #
  3. # dexray v0.2, written by Adam Blaszczyk @ Hexacorn.com, 2012-01/09
  4. #
  5. # This is a simple script that attempts to decrypt Portable Executable files
  6. # embedded in an encrypted form within other files (using encryption
  7. # relying on a one-byte xor key).
  8. #
  9. # Note: it scans directories recursively
  10. #
  11. # It attempts to handle:
  12. #     * Any binary file (using X-RAY scanning)
  13. #     * Symantec Quarantine files (VBN/QBD)
  14. #     * McAfee Quarantine files (BUP)
  15. #
  16. # Usage:
  17. #      perl DeXRAY.pl <filename or directory>
  18. #
  19. #  History
  20. #     2012-09-22 - added support fore new VBN files (xor A5 + F6 xx xx FF FF chunks)
  21. #     2012-01-23 - fixed minor bug in X-RAY loop
  22. #     2012-01-05 - first release
  23. #
  24.  
  25. use strict;
  26. use warnings;
  27.  
  28. $| = 1;
  29.  
  30. print STDERR "
  31. =================================================================
  32. dexray v0.2, written by Adam Blaszczyk @ Hexacorn.com, 2012-01/09
  33. =================================================================
  34. ";
  35.  
  36.     my $target = shift or die "\n\nError: Gimme a filename or dir (use '.' for a current directory)!\n";
  37.  
  38.        if (-d $target)
  39.        {
  40.           scan ($target);
  41.        }
  42.     elsif (-f $target)
  43.        {
  44.           processonefile ($target);
  45.        }
  46.     else
  47.        {
  48.           print "\n\nError: Don't know what to do with '$target'!\n";
  49.        }
  50.  
  51.     exit(0);
  52.  
  53. ######################
  54. sub scan
  55.     {
  56.         my $subdir = shift;
  57.  
  58.         $subdir =~ s/^\.\///;
  59.  
  60.         print   STDERR "Processing  directory: '$subdir'\n";
  61.  
  62.         opendir(DIR, $subdir);
  63.         my @sorted_subdir = sort readdir DIR;
  64.         closedir DIR;
  65.  
  66.         foreach my $filename (@sorted_subdir)
  67.            {
  68.                 next if $filename =~ /^\.{1,2}$/;
  69.  
  70.                 my $fullpath = $subdir.'/'.$filename;
  71.  
  72.                 if (-d $fullpath)
  73.                    {
  74.                        scan ($fullpath);
  75.                        next;
  76.                    }
  77.  
  78.                 processonefile ($fullpath);
  79.            }
  80.     }
  81.  
  82. ######################
  83. sub processonefile
  84.     {
  85.         my $file = shift;
  86.  
  87.         print   STDERR "Processing file: '$file'!\n";
  88.  
  89.         if (! -f $file)
  90.             {
  91.                 print STDERR " -> Can't be found! (check attributes/access rights)\n";
  92.                 return;
  93.             }
  94.  
  95.         my $filesize = -s $file;
  96.  
  97.         if ($filesize == 0)
  98.             {
  99.                 print STDERR " -> Skipping cuz it's empty !\n";
  100.                 return;
  101.             }
  102.  
  103.         my $data = readfile ($file, 0, $filesize);
  104.  
  105.         my $datalen = length($data);
  106.         if ($filesize != $datalen)
  107.             {
  108.                 print STDERR " -> Skipping cuz something funny happened during data reading (investigate)!\n";
  109.                 return;
  110.             }
  111.  
  112.         my $newdata = '';
  113.  
  114.         if ($file =~ /\.vbn$/i)
  115.             {
  116.                 my $ofs = unpack ("L", $data);
  117.                 if ($ofs < ($filesize-4))
  118.                 {
  119.                    extractdata ($file, $data, $ofs, $filesize-$ofs, 0x5A, 1);
  120.                    extractdata ($file, $data, $ofs, $filesize-$ofs, 0xA5, 1);
  121.                 }
  122.                 else
  123.                 {
  124.                    extractdata ($file, $data, 0x00000000,$filesize, 0x5A, 1);
  125.                    extractdata ($file, $data, 0x00000000,$filesize, 0xA5, 1);
  126.                 }
  127.             }
  128.  
  129.         if ($file =~ /\.qbd$/i)
  130.             {
  131.                 extractdata ($file, $data, 0x00000000, $filesize, 0xB3, 1);
  132.             }
  133.  
  134.         if ($file =~ /\.bup$/i)
  135.             {
  136.                 extractdata ($file, $data, 0x00000000, $filesize, 0x6A, 1);
  137.             }
  138.  
  139.         my $progress_delta = 100/$datalen; # $datalen is never 0
  140.         my $progress = 0;
  141.         my $lastprogress = 0;
  142.  
  143. #       my @dataa = split(//,$data);
  144.         my $cnt = 0;
  145.         print   STDERR "    Attempting x-ray scan ($datalen bytes)\n";
  146.         print   STDERR "    (may take quite some time !!!)\n" if $datalen>2000000;
  147.         for (my $ofs=1; $ofs<$datalen; $ofs++)
  148.             {
  149.                print STDERR int($progress)."%\r" if $progress != $lastprogress;
  150.  
  151.                 if ( (ord(substr($data, $ofs, 1)) ^ ord(substr($data, $ofs+1, 1))) == 0x17)
  152.                 #if ( (ord($dataa[$ofs]) ^ ord($dataa[$ofs+1]) ) == 0x17)
  153.                 {
  154.                   my $key = ord(substr($data, $ofs, 1)) ^ 0x4D;
  155.                   next if ( ord(substr($data, $ofs+1, 1)) ^ $key ) != 0x5A;
  156.  
  157.                   my $MZPE = dexor(substr($data,$ofs,16384),$key);
  158.                   if ($MZPE =~ /^MZ.+PE\x00\x00/s)
  159.                      {
  160.                         $cnt+=extractdata ($file, $data, $ofs,$filesize-$ofs, $key, 0);
  161.                      }
  162.                 }
  163.                 $lastprogress = $progress;
  164.                 $progress+=$progress_delta;
  165.             }
  166.  
  167.         print   STDERR " -> Nothing found via X-RAY!\n" if $cnt == 0;
  168.         print   STDERR " -> $cnt potential file(s) found via X-RAY!\n" if $cnt > 0;
  169.     }
  170.  
  171. sub extractdata
  172.     {
  173.         my $file = shift;
  174.         my $data = shift;
  175.         my $ofs  = shift;
  176.         my $size = shift;
  177.         my $key  = shift;
  178.         my $flag = shift;
  179.  
  180.         my $newfilename = sprintf($file.'.%08d.%02X.out',$ofs,$key);
  181.  
  182.         my $newdata = dexor(substr($data,$ofs,$size),$key);
  183.         if ($newdata =~ /^MZ.+PE\x00\x00/s)
  184.            {
  185.                print   STDERR " -> '$newfilename' - Possible PE\n -> ofs='$ofs' (".sprintf("%08lX",$ofs)."), key = 0x".sprintf("%02X",$key)." ($key)!\n";
  186.                if ($file =~/\.vbn$/i && $key==0xA5)
  187.                {
  188.                  print   STDERR "     removing chunk dividers for newer VBN files ... \n";
  189.                  $newdata =~ s/(.{3864})\xF6..\xFF\xFF/$1/sig;
  190.                }
  191.                writefile ($newfilename, $newdata);
  192.                return 1;
  193.            }
  194.         elsif ($flag == 1)
  195.            {
  196.                print   STDERR " -> '$newfilename' - Decrypted data\n -> ofs='$ofs' (".sprintf("%08lX",$ofs)."), key = 0x".sprintf("%02X",$key)." ($key)!\n";
  197.                writefile ($newfilename, $newdata);
  198.                return 1;
  199.            }
  200.  
  201.       return 0;
  202.     }
  203.  
  204. sub writefile
  205.     {
  206.         my $file = shift;
  207.         my $data = shift;
  208.  
  209.         open    (FILE, '>'.$file);
  210.         binmode (FILE);
  211.         print    FILE $data;
  212.         close   (FILE);
  213.     }
  214.  
  215. sub readfile
  216.     {
  217.         my $file = shift;
  218.         my $ofs  = shift;
  219.         my $siz  = shift;
  220.  
  221.         return  '' if !-f $file;
  222.  
  223.         open    (FILE, '<'.$file);
  224.         binmode (FILE);
  225.         seek    (FILE, $ofs, 0);
  226.         read    (FILE, my $data, $siz);
  227.         close   (FILE);
  228.  
  229.         return $data;
  230.     }
  231.  
  232. sub dexor
  233.     {
  234.         my $data = shift;
  235.         my $xorv = shift;
  236.  
  237.         my $newdata = '';
  238.  
  239.         for (my $i=0; $i<length($data); $i++)
  240.             {
  241.                 $newdata .= chr(ord(substr($data, $i, 1)) ^ $xorv);
  242.             }
  243.  
  244.         return $newdata;
  245.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement