From: Mike Perry [mikepery@MIKEPERY.LINUXOS.ORG] Sent: Sunday, July 25, 1999 3:28 PM To: BUGTRAQ@SECURITYFOCUS.COM Subject: All Hail The AntiAntiSniffer Sniffer! Hello once again folks. For those of you who didn't muck through the l0pht technical documentation, their AntiSniff product works in 3 ways: 1. OS dependant IP stack glitches which mostly revolve around ether frames that have a different hwaddr than your NIC not being dropped by a kernel when the interface is in promiscous mode, thus eliciting some sort of response from your kernel. 2. DNS lookups. When most sniffers are running, the resolve the IPs of the hosts they sniff, so all you have to to is send out some fake packets with fake IP headers, and listen for the sniffing host to try to resolve them via DNS. 3. Latency. When the interface is in promiscous mode, the device no longer drops eth frames not destined for it's hwaddr, so this dropping must be done in kernelspace or in userland (by the sniffer). The logging proccess and the context switch from kernel to userspace eat up a good amount of time, so all you have to do is send a lot of data to the network with bogus IP's, then ping all the machines. The sniffing machines will have to wade through all the bogus data, and thus their responses are much slower. I was most impressed with #3. It does work surprisingly well for detecting promiscous legitamate loggers. In fact, 3 days before this advisory, I was very surprised to see that when I ran icmplogger (from the jail package) my ping responses from myself dropped from 0.0 to 1.4ms, and to other machines from 0.3 to 1.5ms. That's well over the 4 fold increase reported in the l0pht paper. Ok, now how did I get around all these issues? Well, lets go one by one: 1. The Linux kernel is perfect (well, almost :). I checked the 2.2.10 source, and it in fact does always drop invalid eth frames destined for your machine when your are in promisc mode (see net/ipv4/ip_input.c). 2. All you have to do is use inet_ntoa() instead of gethostbyname() :) 3. This is where the REAL fun is. I designed a network load average evaluator that calculates a ms/packet rate. If the network falls below a user specified rate (ie LOTS of packets per ms), the sniffer does one of 3 things: 0. Will not trace more than a user specified number of conenctions (fall-back mode) a. Stopps queueing and logging connections to disk until the load average goes back up (LAZY mode) b. Drops the interface and goes to sleep if the load average for tcp connections only goes below a specified rate (PARANOID mode) c. Drops the interface and goes to sleep if the load average for ALL network packets goes below a specified rate (REALLY_PARANOID mode) Issues that I came across: 1. I randomized the sleep time so that we wouldn't be caught by a double scan that knows how long the default sleep time is for the sniffer. 2. The sniffer averages the load over a user specified number of packets. It may be possible to write a compact version of AntiSniff that gets the job done in a number of number of packets small enough to evade the default setting, but that can always be lowered :) 3. Some kernels don't like to work with the sniffer. In fact, I have a 486, a K6, and a dual PII 300 that I tested this thing on. It sniffs on the 486, but the kernel drops ALOT of packets, so the sniffer never sees the rate fall below the danger threshold. (I think this is because I set the CPU_IS_TO_SLOW option for the 486). The K6 works beautifully with the traffic detection, but will not sniff. Go figgure :) The only thing I can think of is that the K6 is configured no to use modules, perhaps this has some side effect in the socket PACKET code? The Dual PII 300 worked flawlessly. For more information, see the accomanied source file. I tired to make it as well commented as possible. It is based on the original LinSniffer by Mike Edulla. Linsniff666 (the modified version that uses linked lists) proved too unstable and looked too grossly ineffienct to use for something like this. My version does queue up connection in linked lists like linsniff666. I tried to make the sniffer as foolproof as possible to give the l0pht guys something to think about for revision 2.0. Remember, I did this all in only one night. I have no idea what a modivated hacker could do. Also, this is very beta. I know it will sniff. I haven't tested the linked list code very thouroghly, altho my brother and I did look over it for almost 2 hours, and it does seem to work pretty well. I have no idea about memory leaks, or extremely heavy loads. P.S. To all my friends, coworkers, and associates who thought I knew better than to do something like this, please understand that when I discovered I could call the program The AntiAntiSniffer Sniffer, I just couldn't resist :)