STACK OVERFLOW / 8 - Exploiting CrossFire online multiplayer RPG game
- This exercise has been executed within a Kali Linux instance, where CrossFire has been installed and run, referring to the loopback interface 127.0.0.1:
0 - Introduction
- CrossFire is an online multiplayer RPG game application available for Microsoft Windows.
- The application is prone to a remote buffer-overflow vulnerability because it fails to perform adequate boundary checks on user supplied input. Successfully exploiting this issue may allow remote attackers to execute arbitrary code in the context of the vulnerable application.
- A buffer overflow vulnerability for CrossFire was registered and documented on 2006 at Exploit Database:
https://www.exploit-db.com/exploits/1582/
1 - Installing and running CrossFire
- CrossFire can be downloaded from Exploit Database, as seen in previous image. This version of the gam does not use stack smashing protection like ASLR or DEP.
- Once downloaded, tar is used to extract the files:
- The program can be directly launched using the script ./crossfire:
- The program is running on the port 13327:
- Because this is a Linux environment, the Evans Debugger (edb) will be used to debug and analyze the application:
- Running the program, clicking twice on this icon, the application is loaded into Evans Debugger:
- Output from Evans Debugger:
2 - Overwriting the stack
- Writing a basic Python script to overwrite the stack of the victim with a set of 4379 'A' characters:
- Giving execution permissions to the exploit:
- Launching the exploit:
- The consequence of the exploit is a segmentation fault when EIP is overwritten with a set of 'A's:
- Following in dump the EAX:
- Following the content on EAX on the stack:
- Checking the content the EIP:
3 - Controlling the EIP
- With the purpose of detecting where the EIP is overwritten, an easily recognizable pattern or string of 4379 bytes is created with a Ruby script, and sent to the victim.
- The string is introduced into the exploit:
- Once CrossFire restarted with Evans Debugger, the exploit CFexploit.py is launched:
- Now EIP is overwritten with 46367046:
- Checking the content of the EIP, as expected, it is 46367046:
- Using another Ruby script, 4637046 is located into the pattern with an offset of 4368:
- Now, the Python script is modified according to the previous results:
i) the set of 'A's will reach up to the EIP location.
ii) EIP will be overwritten with four 'B's.
iii) the rest of the stack will be overwritten with 'C's.
- Restarting CrossFire and launching CFexploit.py.
- As expected, the program crashes and EIP is overwritten with four 'B's:
- Following in dump the ESP, it is very clear the set of 'A's, four 'B's and the rest of 'C's:
- Following in dump the EAX, it is also clear the beginning of the buffer loaded into the stack, starting with the 'setup sound' string:
- Going to the beginning of the buffer, just where the letter 's' is located at b74990ae address:
- In order to align the EAX, so that it points exactly to the beginning of the series of A's, a number of 12 is added ('setup sound ' is composed of 12 carachters). Then, the expected JMP EAX instruction is added. To determine the opcode of both instructions the Ruby nasm_shell.rb script is used:
- The script is modified accordingly to previous opcodes (83C00C+FFE0)
- CrossFire is restarted and the exploit CFexploit.py launched:
4 - Redirecting the flow execution
- The goal of this part of the attack is to find an stable way of redirecting the execution flow to the memory section where the buffer pointed by ESP is located.
- Evans Debugger offers the plugin Opcode Searcher for locating instructions:
- Looking for JMP ESP instructions, one instruction is found at 0x08134597:
- The script is modified accordingly with this last result. The set of four 'B's on the Python exploit is replaced by the memory address 08134597 introduced under the name 'return_adress' in reverse order '\x97\x45\x13\x08', due to the fact that x86 processor architecture follows the Little Endian format (least significant byte occupying the lowest memory position):
- Restarting CrossFire and launching the exploit CFexploit.py:
- Now, EAX is also loaded with the set of 'A's from the beginning, perfectly aligned:
- Regarding the ESP, it is overwritten with the return address found by the Evans Debugger plugin:
- Following in dump:
- Checking that the content of 0x08134597 corresponds to the instruction JMP ESP:
- As expected:
5 - Hunting bad characters
- Bad characters are those ones interpreted literally by the program, so that the program is truncated in the middle of the execution.
- With the purpose of identifying bad characters, a string with all the possible hexadecimal characters is created. The Python script is modified, introducing the 256 bytes AllChars string:
- Step by step, like performed at other exercises of this blog, we can deduce that x00, x0A and x0D are bad characters, because the buffer is interrupted every time it reaches each one of these characters. In that way, we can remove those 3 characters from the script:
- Restarting CrossFire and launching the exploit CFexploit.py.
- However, in this case, there is also a new bad character, because the buffer is stopped just after 0x1F, so we can deduce that 0x20 is also a bad character:
- According to this last result, the 0x20 character is removed from the buffer:
- Once those 4 bad characters are removed, the program CrosFire is restarted and the exploit CFexploit.py is launched.
- Now he program crashes as usual, but the execution of AllChars is completed, from x01 to xFF, meaning that there are no more bad characters.
- Following in dump EAX, it is clear that all characters, from \0x01 to \xFF, have been executed:
- To sum it up, there are 4 bad characters, that being interpreted literally by the compiler, its immediate effect consists of truncating the normal execution of the program. Once removed, the buffer is executed correctly.
0x00 = Null Byte = terminates a string copy operation.
0x0A = Line Feed = advances by the space of one line.
0x0D = Carriage Return = resets to the beginning of a line of text.
0x20 = Space = introduces an space character
0x0D = Carriage Return = resets to the beginning of a line of text.
0x20 = Space = introduces an space character
6 - Generating a shellcode
- msfvenom helps generating a shellcode, with these options:
a) payload: -p linux/x86/shell_bind_tcp
b) local port: LPORT=4444
c) format = -f c, language C
- msfvenom helps generating a shellcode, with these options:
a) payload: -p linux/x86/shell_bind_tcp
b) local port: LPORT=4444
c) format = -f c, language C
d) bad characters = -b '\x00\x0A\x0D\x20'
- The Python script is redefined to include the shellcode. Finally:
- The Python script is redefined to include the shellcode. Finally:
7 - Exploiting the victim
- Running CrossFire directly, now without Evans Debugger:
- Launching the exploit CFexploit.py:
- The attack is successfull, because a connection to the loopback 127.0.0.1 on port 4444 opens a shell :