[Snort-users] Snort DoS Fallacies
Ferguson, Justin (IARC)
FergusonJ at ...13492...
Tue Sep 13 07:49:14 EDT 2005
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.
341 case IPPROTO_TCP:
342 if(p->tcph != NULL)
344 PrintTCPHeader(fp, p);
962 /* dump the TCP options */
963 if(p->tcp_option_count != 0)
965 PrintTcpOptions(fp, p);
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
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:
146 if(msg != NULL)
208 if(p && data->packet_flag)
210 fputc('\n', data->file);
213 PrintIPPkt(data->file, p->iph->ip_proto, p);
Second, if we are logging in ASCII mode (a lot of people):
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:
3117 #ifdef DEBUG_FRAG3
3122 if (DEBUG_FRAG & GetDebugLevel())
3126 PrintIPPkt(stdout, defrag_pkt->iph->ip_proto, defrag_pkt);
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:
4841 #ifdef DEBUG
4852 if (DEBUG_STREAM & GetDebugLevel())
4856 PrintIPPkt(stdout, IPPROTO_TCP, stream_pkt);
And finally, as the snort authors suggested, if you are using -v:
766 /* print the packet to the screen */
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.
NNSA Information Assurance Response Center (IARC)
fergusonj at ...13492...
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Snort-users