Sguil: detecting ICMP anomolies

Recently Websense discovered malware that caused quite a lot of media attention, because it used ICMP to send personal data out of the victims pc or network. In many networks, outgoing ICMP is unrestricted because it can aid in solving connectivity and routing problems. While (partially) blocking outgoing ICMP would certainly solve this problem, not everone will be willing to do so. Note however that the idea of using ICMP as a covert channel is hardly new. Yesterday I wrote about creating custom Sancp queries and adding them to Sguil as canned reports. Today i tried to create a query that can be used to detect anomolies in ICMP traffic leaving your network. Like yesterday, i did this in the form of a ‘canned report’. One limitation is that there seems to be no way to get any information on exact ICMP codes and types. I tried to create a query that would do the following. I assumed that there are at least two ways the traffic can stand out. Either by it’s volume, or by non-default packet sizes. Normally ping uses a fixed packet size of 64 bytes on my Linux system, Windows 2000 defaults to 32 bytes. If the packet size is not what you would expect, something fishy might be going on. So the query tries to find the execptional cases in this respect. Volume is another factor. To tranfser substantial amounts of data through ICMP, the volume of the packets will need to be quite high as well. Note however that Linux’ ping utility for example pings until you tell it to stop, and it happened to me before that i accidently left it running an entire night, so a large volume doesn’t have to mean there is something wrong. The target IP is also very interesting. If it is IP belonging to Google there is a big chance that it is just a test. In the example below most volume is to 194.109.21.51 which is the server in my ISP’s network that can be reached under ‘ping.xs4all.nl’. In this report you can see that 192.168.1.2 pinged 145.97.193.148 with an average packet size of 1480 bytes, which is certainly not normal. It transfered 0.08MB to this IP. Another amount of 2.24MB was transfered to the IP 194.109.21.51, with a average packet size of 64.33 bytes. This is weird because it is not exactly 64 bytes, what I would expect. This can be explained by me running a default ping for a long time and after that doing a few tests with larger sizes.

August 18, 2006 · 4 min · inliniac

Sguil: creating custom reports

In the Sguil NSM system, Sancp plays a vital role. Sancp records session data, in which all connections are recorded. For all connections (and pseudo connections, think udp, icmp), Sancp records the number of bytes transfered, number of packets, start and end time, etc. This is very much useful information, of which Sguil only makes a subset accessable. Because the information is stored in a MySQL database, nothing prevents you from querying the database manually, which is what i did. However, David Bianco suggested that i could also add them as ‘canned reports’ to Sguil, which i did. At this stage i am mostly interested in the information from Sancp about the traffic volume. Which host(s) use the most bandwidth? Questions like this. Below i explain one of the ‘canned reports’ i created. This is the output of the query below. What it shows is that 192.168.1.2 in my lan downloaded 367MB from 145.97.193.148, and that it did this via http (protocol 6 is tcp, port is 80). Let’s have a look at the query. TOPTENWAN2LAN_SRC_DST_SER||Top b/w per serv. from WAN to LAN (downloads), flow from WAN-IPs to LAN-IPs, volume in MB||query||select sum(dst_bytes)/1048576 as my_dst_bytes, INET_NTOA(dst_ip), INET_NTOA(src_ip), ip_proto, dst_port from sancp INNER JOIN sensor ON sancp.sid=sensor.sid WHERE start_time > %%STARTTIME%% AND end_time 0 AND %%SENSORS%% and ((src_ip between INET_ATON(“192.168.0.0”) and INET_ATON(“192.168.255.255”)) or (src_ip between INET_ATON(“10.0.0.0”) and INET_ATON(“10.255.255.255”)) or (src_ip between INET_ATON(“172.16.0.0”) and INET_ATON(“172.31.255.255”))) and ((dst_ip not between INET_ATON(“192.168.0.0”) and INET_ATON(“192.168.255.255”)) and (dst_ip not between INET_ATON(“10.0.0.0”) and INET_ATON(“10.255.255.255”)) and (dst_ip not between INET_ATON(“172.16.0.0”) and INET_ATON(“172.31.255.255”))) GROUP BY src_ip,dst_ip,ip_proto,dst_port ORDER BY my_dst_bytes DESC LIMIT 10||5|| Copy-paste this into your /etc/sguild/sguild.reports and restart sguild. It should be available in the Sensor Reports window. The parts between percent signs are Sguil variables. The double pipes are separators between different sections of the line. The line starts with a sort of internal name for Sguil. What follows is the description as it will be show in the report selection screen and in the report itself. Next it is indicated that his is a query. After that the query itself. After the query in the last field it is indicated how many columns of data Sguil can expect from MySQL. Now the query. First, i select dst_bytes, dst_ip and src_ip, ip_proto and dst_port. The dst_bytes field contains the number of bytes flowing from dst_ip to src_ip. Because we use group later, we SUM dst_bytes. And because it is in bytes, we divide it by 1024*1024(=1048576) so the result will be megabytes. The result is stored in my_dst_bytes. We then make sure that the src_ip is in a private ip range and that dst_ip is not in a private ip-range. Then the grouping is done, followed by the ordering by my_dst_bytes. Easy huh! Naturally, this only works for networks that actually use private ip-ranges, but it should be easy to adapt if you use something else. Below, i have added another seven of these reports.

August 17, 2006 · 6 min · inliniac

Sguil: full content logging in combination with Snort_inline, revisited *again*

Note to self: never assume something works, instead, test it. Yesterday there was some discussion in the #snort channel over whether or not passing multiple interface to snort works or not. As a reminder, some time ago i noted that passing two interfaces to snort like this: ‘snort -i eth0:eth1’ worked just fine. However, common mentioned in irc that he could not imagine it to be working. Determined to proof him wrong, i decided to run a few test. On my gateway, i ran ‘snort -v -i eth0:eth1 ip proto 1’. This should print all ICMP packets to the screen for both interfaces. The first clue that something wasn’t right was this message: ...

August 9, 2006 · 2 min · inliniac

Sguil: full content logging in combination with Snort_inline, revisited

A few days ago i wrote about some challenges that my Snort_inline presented. Especially the full content logging wasn’t working quite as i would have liked. Logging on pseudo device ‘any’ didn’t work right because then the traffic that was NAT-ted was both recorded before NAT and after NAT. The solution I (with help of #snort-gui) came up with was using ‘-i any’ anyway, but exclude my public ip using a BPF filter. Later i saw Joel Esler write the solution in a unrelated problem to someone else. Sometimes solutions can be so simple! ...

July 30, 2006 · 1 min · inliniac

Sguil: sensor install gotcha: sancp

Today I installed a new sensor for Sguil. It went much better than before, but still i needed #snort-gui’s help again. The issue was that Sancp stats were not picked up by the sensor. It turns out that the default initscript for sancp uses an old and depreciated setting that tells sancp to log into the /snort_data/sensorname/sancp/today directory. The sensor expects it in /snort_data/sensorname/sancp. After changing that in the /etc/default/sancp file it worked like a charm. ...

July 29, 2006 · 1 min · inliniac

Sguil: full content logging in combination with Snort_inline

Just spend some time trying to get the transcripts part of Sguil working with my Snort_inline sensor. Without an obvious clue it returned no data for every alert that was received. After much trial and error, and especially much help by Bamm Visscher on IRC, i noticed that i recorded the full packet data from my ppp0 device. Then i remembered issues i had before with that, namely that the logging occurs after NAT. Snort_inline however, gets the packets from the system before NAT. That results in a mismatch causing the sensor not to be able to provide the transcript requested. Changing the interface to record the full packets from to eth0 solved the problem! ...

July 26, 2006 · 2 min · inliniac