[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <6A81BBDAF5E91C47B8856DA5B952B1FE7E526B@nv08.nv.doe.gov>
Date: Tue, 13 Sep 2005 07:47:59 -0700
From: "Ferguson, Justin (IARC)" <FergusonJ@...doe.gov>
To: "'snort-devel@...ts.sourceforge.net'" <snort-devel@...ts.sourceforge.net>
Cc: "'snort-users@...ts.sourceforge.net'" <snort-users@...ts.sourceforge.net>,
"'bugtraq@...urityfocus.com'" <bugtraq@...urityfocus.com>
Subject: Snort DoS Fallacies
Hello,
The recent advisory from the Snort team in regards to the DoS in the
PrintTCPOptions() function of log.c is incorrect in a couple regards.
Firstly, and most importantly- You _do not_ have to be running snort with
-v, there are several execution path's in snort that leads to the function
PrintTCPOptions(), excerpts from relevant code are below:
First, let's us realize how the code gets to PrintTCPOptions().
PrintTCPOptions() is called by PrintTCPHeader(), which in turn is called by
PrintIPPKT(), see below for relevant code snippets-- The line numbers are
from the current CVS version of snort pulled down aprox. 1 hour ago.
snort/src/log.c
315 PrintIPPkt()
[...]
337 if(!p->frag_flag)
338 {
339 switch(p->iph->ip_proto)
340 {
341 case IPPROTO_TCP:
342 if(p->tcph != NULL)
343 {
344 PrintTCPHeader(fp, p);
345 }
snort/src/log.c
934 PrintTCPHeader()
[...]
962 /* dump the TCP options */
963 if(p->tcp_option_count != 0)
964 {
965 PrintTcpOptions(fp, p);
966 }
So we see here that, if someone is to call PrintIPPacket(), and the packet
is not a fragment, and its protocol is TCP then we call TCPHeader() and once
inside of PrintTCPHeader(), if the option_count is not 0, then we call
PrintTCPOptions.
Now a quick grep(1) of the source tree reveals several possible ways to end
up at PrintIPPkt(), relevant source below:
First, if we are using the option -A fast:
snort/src/output-plugins/spo_alert_fast.c
134 AlertFast()
[...]
146 if(msg != NULL)
147 {
[...]
208 if(p && data->packet_flag)
209 {
210 fputc('\n', data->file);
211
212 if(p->iph)
213 PrintIPPkt(data->file, p->iph->ip_proto, p);
Second, if we are logging in ASCII mode (a lot of people):
snort/src/output-plugins/spo_log_ascii.c
112 LogAscii()
[...]
137 if(p)
138 {
139 if(p->iph)
140 PrintIPPkt(log_ptr, p->iph->ip_proto, p);
Also, in the frag3 preprocessor, also I'm not sure what the point of
defining DEBUG_FRAG3 at compile time would be (at least in this code
segment), as the execution flow is exactly the same:
snort/src/preprocessors/spp_frag3.c
2929 Frag3Rebuild()
[...]
3117 #ifdef DEBUG_FRAG3
[...]
3122 if (DEBUG_FRAG & GetDebugLevel())
3123 {
[...]
3126 PrintIPPkt(stdout, defrag_pkt->iph->ip_proto, defrag_pkt);
[...]
3129 }
3130 #endif
[...]
3133 PrintIPPkt(stdout, defrag_pkt->iph->ip_proto, defrag_pkt);
It can also be called in the stream4 preprocessor, if a few debugging
conditions are met:
snort/src/preprocessors/stream4.c
4682 BuildPacket()
[...]
4841 #ifdef DEBUG
[...]
4852 if (DEBUG_STREAM & GetDebugLevel())
4853 {
[...]
4856 PrintIPPkt(stdout, IPPROTO_TCP, stream_pkt);
[...]
4863 }
4864 #endif
And finally, as the snort authors suggested, if you are using -v:
snort/src/snort.c
766 /* print the packet to the screen */
767 if(pv.verbose_flag)
768 {
769 if(p.iph != NULL)
770 PrintIPPkt(stdout, p.iph->ip_proto, &p);
Additionally, as the second part of the misrepresentation of data, there is
several bugs in PrintTCPOptions(), which is apparent by the changes they
made-- these include nearly all of the TCP options, not just SACK. These
include the following options:
TCPOPT_MAXSEG, TCPOPT_WSCALE, TCPOPT_ECHO, TCPOPT_ECHOREPLY,
TCPOPT_TIMESTAMP, TCPOPT_CC, TCPOPT_CCNEW, TCPOPT_CCECHO, and _any_
unrecognized or invalid option.
However, the snort team did say one thing correctly, and that these all are
NULL pointer dereferences, and therefore only a DoS and not exploitable to
run arbitrary code.
Best Regards,
J. Ferguson
Intrusion Analyst
NNSA Information Assurance Response Center (IARC)
fergusonj@...doe.gov
Content of type "text/html" skipped
Powered by blists - more mailing lists