Snort DNS
preprocessor
It is not unusual for firewalls to allow DNS traffic to
connect from a host (pc) to an arbitrary server on the internet. This
makes it an ideal vehicle for user's unregulated traffic. This plugin
watches this traffic on two levels. The first verifies that UDP port 53
traffic is composed of the correct data structures. The second watches
the connections between client and server, and makes sure that each
request is getting a single response.
Software:
Click on the following links to download the complete source code.
Follow directions below (or see README.PLUGINS).
snort_dns_package1.4.tar.gz
Example A.C.I.D Screenshot can be seen here.
Change log:
spp_dns_session changes for 1.4.1 : 7/23/02
- Andreas Östling provided a quick patch for null
arguments in snort.conf file. Thanks!
spp_dns_session changes for 1.4 : 7/15/02
- Added new check for multiple responses to a client query.
Changed debug info to new 1.9 handlers. Checked source against a series
of recursive attacks, modify header files for 1.9 additions. Also
modified the logging functionality to keep it updated with newer
preprocessors.
spp_dns_session changes for 1.3 : 7/08/02
- Audited code against Bind 8.3.3 - no major changes, but
the special() call has been augmented with "(" and ")" characters.
Note, this is the last version for 1.8.x .
spp_dns_session changes for 1.2 : 2/19/02
- Removed dependency on -lresolv libraries by digging out
all the routines from bind and jamming them into the spp.
- Expressly define header options and begin making room for
clean/unclean decision based on header contents.
- Removed include requirements for arpa/nameser_compat.h,
arpa/nameser.h and resolv.h by rudely packing them into the generic
header for the spp.
spp_dns_session changes for 1.1 : 1/21/02
- Added GPL to code. Doh!
- Changed the number of connection attempts to three before
setting off an alarm. DNS requests on a fast LAN will normally be 1:1
to server responses. On a slower WAN connection we may see two or three
client connection attempts (with same UDP port and DNS ID number)
before a response is heard (depending on the client being used). This
should greatly reduce the number of false alerts
Theory of Operation
The preprocessor will look at all UDP traffic going to and
from port 53. This covers most standard DNS query and response
behavior. When a packet is received, it is first run through a series of
generic resolver routines based on the BSD version of Bind. If the
packet fails to successfully decode the packet (for example it is a
instant messenger communication), it is logged and an alarm is thrown.
If, after successful decoding, there is data remaining, it too is
flagged as an error condition.
If an individual were to stream data through snort via
legitimate DNS packets, the previous analysis would not pick up the
problem. To solve this, the preprocessor keeps track of DNS query -
response pairs via the source port, destination port and ID number
triplet. When a query is seen, an entry is made into the session list.
After, responses are compared to the list entries. If there is a
matching entry it is adjusted to reflect this new information. If there
is no such entry, this is seen as an error condition. If there has
been a response already, this is also flagged as an error condition.
An important tuning value is the number of seconds that
packets are allowed to live on the list. The default value for this is
20 seconds. If it is set too low, slow responses will be missed and
there will be too many "ANSWER_ERROR_CONDITION" messages. If it is too
high, the list will grow unreasonably large and overall Snort
performance will be impacted.
There are four messages given by the plugin:
- spp_dns(%d): resource record expansion failure
This error indicates that the UDP port 53 traffic can not be fit into
the resolver templates. This usually indicates that there is traffic
going out/in that is not legitimate DNS data.
- spp_dns(%d): extra data in dns packet
This indicates that there is data left over in the packet after the
resolver takes it apart. This is unusual since there is no place in the
protocol for this sort of thing. I did not see this message with
legitimate traffic over a period of a month or so, but an unusual
client/server may do this.
- spp_dns(%d): unknown DNS session traffic
Here we have session traffic that the proprocessor doesn't know what to
do with. This is expected behavior once in a while, but if there are a
series of them in a row it may be worth investigating.
- spp_dns(%d): multiple responses to query - possible
spoof
In this situation, we are seeing more than one reply to the users
question. This is suspicous behavior since you are only suposed to get
one response back from a unique server. If there is more than one reply
with the same IP and ID information, somthing may be wrong. There is a
window where the check is done to reduce the (slight) possablilty of a
false positive.
With (%d) being the snort sensor number.
As mentioned above, the most useful parameter to tune will
be the lifetime timeout value for linked list members. In general the
default value of 20 seconds does not lead to too many false alarms, but
if the network connection is a little slow, you will probably need to
turn up this value. If the snort instance is running between two fast
lans, it may be advised to lower the value for performance reasons.
The other three flags are self explanatory. Each will
disable one of the mechanisms used by the plugin. If there is no
session monitoring, the multiple response flag will be ignored.
Gratitude
I would like to thank Martin Roesch and the entire snort
community for providing a well written code base to work from. I have
borrowed liberally from the general snort code and have learned
enormously from this work. The Oreilly "DNS and Bind" book and Stevens
"TCP IP Illustrated" have made the complex DNS protocol less mysterious.