STACK OVERFLOW / 7 - Exploiting MicroP multimedia player
- Layout for this exercise:
0 - Introduction
- MicroP is a multimedia player 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. Specifically, this issue occurs when the application opens specially crafted .mppl files.
- Successfully exploiting this issue may allow remote attackers to execute arbitrary code in the context of the vulnerable application.
- A buffer overflow vulnerability for MicroP player was registered and documented on 2014 at Exploit Database:
https://www.exploit-db.com/exploits/32261/
https://www.rapid7.com/db/modules/exploit/windows/fileformat/microp_mppl
- The author of the exploit quotes a shellcode for triggering a message box on any Windows version:
1 - Installing and running MicroP
- MicroP can be downloaded from Exploit Database, as seen in previous image:
- The program can be started either directly or by using Immunity Debugger.
- For the purpose of making easier the process of creating and reading an exploit, a shared folder is enabled between the attacker and the victim:
2 - Overwriting the stack
- Writing a basic Python script to overwrite the stack of the victim with a set of 2000 'A' characters:
- Giving execution permissions to the exploit:
- Launching the exploit:
- The consequence of the exploit is the creation of a file called MPexploit.mppl, what will be read by the vulnerable program MicroP on the victim machine.
- Due to the fact of having enabled shared folders, every time the MPexploit.py and MPexploit.mppl are changed at the attacker's side, the modified files are available immediately at the victim's machine, so that MPexploit.mppl can be read by MicroP.
- MicroP reads MicroP.mppl and the exploite is executed on Windows 7:
- The program crashes because it is forced to be executed in a non accessible memory area like 41414141 (AAAA in ASCII). It is very important to notice that in this case EAX points to the beginning of the 'A's section:
3 - Controlling the EIP
- With the purpose of detecting where the EIP is overwritten, an easily recognizable pattern or string of 2000 bytes is created with a Ruby script, and sent to the victim.
- The string is introduced into the exploit:
- Once MicroP restarted with Immunity Debugger, the exploit is launched:
- MicroP opens MPexploit.mppl and the program crashes, but now EIP is overwritten with 71423571 and EAX points to 0048DD1C:
- Following EAX in dump, it is clear that the pattern starts to be executed just at 0048DD1C:
- Using another Ruby script, 71423571 address is located into the memory dump, with an offset of 1276:
- 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.
- Executing MPexploit.py, restarting MicroP player, and opening MPexploit.mppl.
- As expected, the program crashes. EIP is overwritten with four 'B's.
- To find the set of 'BBBB' in dump, a number of 1276 (0x4FC) is added to the starting point 0048DD1C:
- Going to 00488DD1C + 4FC = 00488E128
- In this way, the set of 'A's, four 'B's and the rest of 'C's is clearly noticed in dump:
4 - 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 after 'BBBB:
- Executing MPexploit.py, restarting MicroP player, and opening MPexploit.mppl.
- The program crashes as usual, because EIP points to a non executable area of 'B's:
'
- However, a close inspection of the memory details that the buffer execution has been interrupted just after the four 'B's, just where the AllChars string should begin to be executed. This means that the character '0x00' truncates the execution of the rest of the buffer:
- So, '\x00' is clearly a bad character, and it should be removed from the DBexploit.py:
- Let's go on searching for more bad characters. Again, executing MPexploit.py, restarting MicroP player, and opening MPexploit.mppl.
- Now, the buffer execution has been interrupted just after '0x09'. This means that the character '0x0A' truncates the execution of the rest of the buffer. Following in dump:
- So, '\x0A' is a bad character, and it should be removed from MPexploit.py:
- Executing the new MPexploit.py, restarting MicroP player, and opening MPexploit.mppl.
- Now, the buffer execution has been interrupted just after '0x0C'. This means that the character '0x0D' truncates the execution of the rest of the buffer. Following in dump:
- So, '\x0D' is a bad character, and it should be removed from MPexploit.py:
- Executing the new MPexploit.py, restarting MicroP player, and opening MPexploit.mppl.
- The program crashes, but now the execution of AllChars has been completed, from \x01 to \xFF, meaning that there no more bad characters. Following in dump, it is clear that all characters, from \0x01 to \xFF, have been executed:
- To sum it up, there are 3 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.
0x0D = Carriage Return = resets to the beginning of a line of text.
5 - Generating a shellcode
- msfvenom helps generating a shellcode, with these options:
a) payload: -p windows/messagebox
b) format = -f c, language C
- msfvenom helps generating a shellcode, with these options:
a) payload: -p windows/messagebox
b) format = -f c, language C
c) architecture = -a x86
d) bad characters = -b "\x00\x0A\x0D"
6 - Redirecting the flow executiond) bad characters = -b "\x00\x0A\x0D"
- 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 shellcode is located, pointed by EAX.
- One way of achieving that goal would be finding an instruction CALL EAX located in a memory section not subject to changes. Let's remember that techniques like ASLR or DEP rebase the memory address allocations in each reboot of the system.
- Looking for executable modules:
- For instance, clicking on USER32.DLL:
- Searching for a CALL EAX command:
- One CALL EAX is detected at 7748183D:
- The Python script is redefined to include the shellcode. A bunch of NOPs (\x90) is introduced before the shellcode, ensuring that the shellcode is actually be executed. Also, another set of NOPs (\x90) is introduced before 'BBBB'.
- The set of four 'B's on the Python exploit is replaced by the memory address 7748183D, introduced in reverse order '\3D\x18\x48\x77' due to the fact that x86 processor architecture follows the Little Endian format (least significant byte occupying the lowest memory position).
- The final MPexploit.py:
7 - Exploiting the victim
- As a result of launching MPexploit.py a new MPexploit.mppl file is created :
- MicroP is started at the victim Windows 7:
- Opening MPexploit.mppl from the Playlist:
- The attack is successful, because a message box appears at the victim Windows 7, according with the shellcode used at a previous point (5 - Generating a shellcode).