[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.

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 }

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

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:

134 AlertFast()
146 if(msg != NULL)
147 {
208 if(p && data->packet_flag)
209 {
210 fputc('\n', data->file);
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):

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:

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:

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:

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:

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 at ...13492...

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.snort.org/pipermail/snort-users/attachments/20050913/3105aacd/attachment.html>

More information about the Snort-users mailing list