Multiple vulnerabilities in S.T.A.L.K.E.R. 1.0006
#######################################################################
Luigi Auriemma
Application: S.T.A.L.K.E.R.: Shadow of Chernobyl
http://www.stalker-game.com
Versions: <= 1.0006
Platforms: Windows
Bugs: A] IPureServer::_Recieve buffer-overflow
B] NET_Compressor::Decompress integer overflow
C] MultipacketReciever::RecievePacket INT3
Exploitation: remote, versus server (probably clients too)
Date: 28 Jun 2008
Author: Luigi Auriemma
e-mail: aluigi@xxxxxxxxxxxxx
web: aluigi.org
#######################################################################
1) Introduction
2) Bugs
3) The Code
4) Fix
#######################################################################
===============
1) Introduction
===============
S.T.A.L.K.E.R. is a FPS game developed by GSC Game World
(http://www.gsc-game.com) and released at the beginning of the 2007
(the Clear Sky sequel is planned for the next months).
#######################################################################
=======
2) Bugs
=======
----------------------------------------
A] IPureServer::_Recieve buffer-overflow
----------------------------------------
MultipacketReciever::RecievePacket is a function used in the game when
a packet beginning with the byte 0x39 is received.
The main actions performed by this function are:
- checking if a specific value in the packet is equal to 0xe0 or 0xe1
- calling NET_Compressor::Decompress for checking the availability of
compressed data and decompress it through the lzo1x algorithm and a
specific dictionary (mp\lzo-dict.bin)
- calling _Recieve for handling the content of this data
The _Recieve function gets the 16 bit number specified in the incoming
packet and uses memcpy with a 8 kilobytes stack buffer as destination,
the data from the packet as source and that 16 bit value as amount of
bytes to copy.
Each UDP packet in S.T.A.L.K.E.R. has a maximum size of 1472 bytes but
through the LZO compression implemented in the game is possible to
place up to 32 kilobytes of data in the packet resulting in a stack
based buffer-overflow fully controllable by the attacker.
----------------------------------------------
B] NET_Compressor::Decompress integer overflow
----------------------------------------------
This function checks if a specific byte in the packet is equal to 0xc1
in which case is performed a CRC check and the decompression of the
data using the rtc9_decompress function (lzo1x_decompress_dict_safe).
If the data is not compressed the function gets the current size of the
data in the packet and performs a memcpy(dst, data, data_size - 1), so
the sending of a packet without data causes a crash of the server due
to the copying of 0xffffffff (0 - 1) bytes.
------------------------------------------
C] MultipacketReciever::RecievePacket INT3
------------------------------------------
One of the first operations made by this interesting function is
checking if a certain byte in the packet is equal to 0xe0 or 0xe1
otherwise an INT3 instruction is executed leading to the immediate
termination of the server:
01906F33 8A45 00 MOV AL,BYTE PTR SS:[EBP]
01906F36 3C E1 CMP AL,0E1
01906F38 56 PUSH ESI
01906F39 57 PUSH EDI
01906F3A 894C24 18 MOV DWORD PTR SS:[ESP+18],ECX
01906F3E 74 05 JE SHORT xrNetSer.01906F45 ; jump if 0xe1
01906F40 3C E0 CMP AL,0E0
01906F42 74 01 JE SHORT xrNetSer.01906F45 ; jump if 0xe0
01906F44 CC INT3 ; boom
The attacker needs to join the server for exploiting the above
vulnerabilities, but although it supports the banning of the IP
addresses is possible to spoof the packets and bypassing this
limitation due to the lack of handshakes in the protocol of the game.
#######################################################################
===========
3) The Code
===========
http://aluigi.org/poc/stalker39x.zip
#######################################################################
======
4) Fix
======
No fix
#######################################################################
---
Luigi Auriemma
http://aluigi.org