Cisco Logo


Security

When news of Conficker surfaced I obtained a traffic sample from our botnet honeynet. I wanted to see what relevant aggregate information I could extract and see if there was any specific indication of Conficker activity. Using some lightweight tools I was able to quickly analyze my traffic sample and focus further research. I find that these high level analysis techniques lead me to ask the more interesting questions and, more importantly, come to my rescue when I’m pressed for time. Below, I share a little about how I deconstructed the traffic sample, briefly discuss visualization and turn to IPS and Global Correlation to get a bigger perspective on what was happening. Some of my colleagues here in Cisco Security Intelligence Operations (SIO) find these techniques useful so I thought I would pass them on in the hopes that others will as well. I’d like to hear from some of you on your favorite tools and tricks for this sort of sleuth work.

There are some things I should point out before delving into my traffic sample:

Packet grepping with tshark

Not surprisingly, the first tool I turned to was Wireshark. Everyone knows and loves Wireshark but tshark, its extremely powerful command line companion, often flies under the radar. Most of what I discuss will be around using tshark. Keep in mind that my goal isn’t to be exhaustive. It’s to get my feet wet and pique my curiosity before turning to more involved analysis techniques.

Let’s take a look at my traffic capture and tshark’s default output:

x
~
_
xterm: default output
$ tshark -r traffic_sample.pcap | wc -l
449802
$

$ tshark -r traffic_sample.pcap | head -n 5
  1   0.000000 tty.honeynet.eg -> vex.honeynet.eg SSL Continuation Data
  2   0.000030 tty.honeynet.eg -> tty.honeynet.eg SSL Continuation Data
  3   0.000082 tty.honeynet.eg -> vex.honeynet.eg SSL Continuation Data
  4   0.000495 vex.honeynet.eg -> tty.honeynet.eg TCP pvsw-inet > https [ACK] Seq=1 Ack=2563 Win=65535 Len=0
  5   0.000499 tty.honeynet.eg -> tty.honeynet.eg TCP pvsw-inet > https [ACK] Seq=1 Ack=1183 Win=65535 Len=0
$

We’ve got almost 450,000 packets to sift through!

To me, tshark’s most useful feature is that it allows me to use Wireshark’s extensive dissectors to find exactly what I’m looking for and display it in the way that’s most helpful to me. Using these features we can do some rudimentary netflow-type analysis. For example, we can determine the TCP and UDP flows that see the most traffic by passing tshark output to our friends sort, uniq and head:

x
~
_
xterm: netflow analysis
$ tshark -r traffic_sample.pcap -T fields -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport
tty.honeynet.eg   443     vex.honeynet.eg    2441
tty.honeynet.eg   443     tty.honeynet.eg   2441
tty.honeynet.eg   443     vex.honeynet.eg    2441
vex.honeynet.eg    2441    tty.honeynet.eg   443
tty.honeynet.eg   2441    tty.honeynet.eg   443
...
$ tshark -r traffic_sample.pcap -T fields -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport tcp | sort | uniq -c | sort -brnk1 | head -n 10
   3161 paz.network.eg  6000    bid.honeynet.eg  2967
   3111 foe.network.eg 6000    bid.honeynet.eg  8090
   3100 foe.network.eg 6000    bid.honeynet.eg  8089
   3096 foe.network.eg 6000    bid.honeynet.eg  8088
   3096 foe.network.eg 6000    bid.honeynet.eg  808
   2328 and.network.eg 19877   tty.honeynet.eg   22
   2137 tty.honeynet.eg   22      and.network.eg 19877
    805 tty.honeynet.eg   443     sal.network.eg   1397
    564 sal.network.eg   1397    tty.honeynet.eg   443
    372 foe.network.eg 6000    vex.honeynet.eg    808
$ tshark -r traffic_sample.pcap -T fields -e ip.src -e udp.srcport -e ip.dst -e udp.dstport udp | sort | uniq -c | sort -brnk1 | head -n 10
  52378 lad.honeynet.eg   55178   met.network.eg   53
  52375 met.network.eg   53      lad.honeynet.eg   55178
   7421 was.network.eg   49271   tty.honeynet.eg   9994
   1999 vex.honeynet.eg    137     tty.honeynet.eg   137
   1999 bid.honeynet.eg  137     tty.honeynet.eg   137
   1921 vex.honeynet.eg    137     phi.honeynet.eg  137
    517 tty.honeynet.eg   32768   sal.network.eg   902
    199 ala.network.eg    41620   bid.honeynet.eg  137
    190 vex.honeynet.eg    138     tty.honeynet.eg   138
    190 bid.honeynet.eg  138     tty.honeynet.eg   138

Let’s continue digging. Some things I’d like to know: Which hosts are connecting to my network? Which external hosts are my hosts connecting to? And over what ports? This should be pretty straight-forward… all I need to do is see who’s opening TCP connections. Below, I use tshark’s display filter to limit the packets displayed to those with a SYN bit set.

x
~
_
xterm: syn bit set
$ tshark -r traffic_sample.pcap tcp.flags.syn eq 0x1
 22   0.597630 old.network.eg -> bid.honeynet.eg TCP ddrepl > microsoft-ds [SYN] Seq=0 Win=65535 Len=0 MSS=1460
 26   0.642020 gee.network.eg -> bid.honeynet.eg TCP vsat-control > microsoft-ds [SYN] Seq=0 Win=16384 Len=0 MSS= 1440
 29   0.737034 viz.network.eg -> bid.honeynet.eg TCP tsilb > microsoft-ds [SYN] Seq=0 Win=65535 Len=0 MSS=1460
 47   1.464693 add.network.eg -> gag.honeynet.eg TCP 4195 > microsoft-ds [SYN] Seq=0 Win=65535 Len=0 MSS=1440
 59   1.795854 nbs.network.eg -> bid.honeynet.eg TCP http > 7893 [SYN, ACK] Seq=0 Ack=0 Win=16384 Len=0 MSS=1460
 80   1.991162 vex.honeynet.eg -> tty.honeynet.eg TCP netangel > https [SYN] Seq=0 Win=65535 Len=0 MSS=1460
 81   1.991164 tty.honeynet.eg -> tty.honeynet.eg TCP netangel > https [SYN] Seq=0 Win=65535 Len=0 MSS=1460
 82   1.991396 tty.honeynet.eg -> tty.honeynet.eg TCP https > netangel [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1 380
...
...

Notice that frames 59 and 82 have both the SYN and ACK bits set. What I wanted was packets with only the SYN bit set because this indicates that the sending host is attempting to initiate a TCP connection. To do this, I need to know the value of the TCP header’s flags field when the only bit set is the SYN bit set. There are many ways to do this if I don’t feel like thinking in binary. First, I can use Scapy, another one my favorite tools. Second, I can use tshark’s PDML output. For the latter, I need to know which frame has only the SYN bit set ahead of time. Both techniques are demonstrated below:

x
~
_
xterm: finding tcp flags field values
$ scapy
WARNING: IPv6 support disabled in Python. Cannot load scapy IPv6 layers.
INFO: Can't import python gnuplot wrapper . Won't be able to plot.
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
WARNING: Failed to execute tcpdump. Check it is installed and in the PATH
Welcome to Scapy (2.0.1)
>>> a = TCP()
>>> a.flags='S'
>>> a.sprintf("%r,TCP.flags%")
'2'
>>> a.flags='SA'
>>> a.sprintf("%r,TCP.flags%")
'18'
>>> hex(int(a.sprintf("%r,TCP.flags%")))
'0x12'
$ tshark -c 1 -r traffic_sample.pcap -T pdml frame.number eq 421513 and tcp | grep tcp.flags
    <field name="tcp.flags" showname="Flags: 0x02 (SYN)" size="1" pos="47" show="0x02" value="02">
      <field name="tcp.flags.cwr" showname="0... .... = Congestion Window Reduced (CWR): Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="02"/>
      <field name="tcp.flags.ecn" showname=".0.. .... = ECN-Echo: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="02"/>

      <field name="tcp.flags.urg" showname="..0. .... = Urgent: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="02"/>
      <field name="tcp.flags.ack" showname="...0 .... = Acknowledgement: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="02"/>
      <field name="tcp.flags.push" showname=".... 0... = Push: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="02"/>
      <field name="tcp.flags.reset" showname=".... .0.. = Reset: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="02"/>
      <field name="tcp.flags.syn" showname=".... ..1. = Syn: Set" size="1" pos="47" show="1" value="1" unmaskedvalue="02">
      <field name="tcp.flags.fin" showname=".... ...0 = Fin: Not set" size="1" pos="47" show="0" value="0" unmaskedvalue="02"/>

$

We now know that if the only bit set in a TCP header’s flags field is the SYN bit that it will have a value of 2. If it has both the SYN and ACK bits set, it will have a value of 18 (0x12). Using this, I can return to leaning on tshark’s display filters to show packets that have only the SYN bit set. Instead of looking at tcp.flags.syn I need look at tcp.flags. This seems obvious to me now but it didn’t occur to me at first; initially I experimented with the bitwise_and and slice operators. Now that we know how to filter packets with only a SYN bit set, we can extend display filters even further and limit output to packets coming from our subnet. That’s right! Wireshark allows users to specify subnets as display filter criteria.

x
~
_
xterm: filtering by subnets
$ tshark -r traffic_sample.pcap -T fields -e ip.src -e tcp.srcport -e ip.dst -e tcp.dstport tcp.flags eq 0x2 and ip.dst eq honeynet.eg/16 | sort | uniq -c | sort -brn -k1 | head -n 10
   3161 paz.network.eg  6000    bid.honeynet.eg  2967
   3111 foe.network.eg 6000    bid.honeynet.eg  8090
   3100 foe.network.eg 6000    bid.honeynet.eg  8089
   3096 foe.network.eg 6000    bid.honeynet.eg  8088
   3096 foe.network.eg 6000    bid.honeynet.eg  808
    372 foe.network.eg 6000    vex.honeynet.eg    808
    366 foe.network.eg 6000    vex.honeynet.eg    8089
    313 foe.network.eg 6000    vex.honeynet.eg    8090
    280 foe.network.eg 6000    vex.honeynet.eg    8088
    264 paz.network.eg  6000    vex.honeynet.eg    2967

Huh. I’ll have to look into that port 6000 traffic later. I’ll also take a closer look at what both foe.network.eg and bid.honeynet.eg are up to. In the meantime, I can use filters to display:

x
~
_
xterm: finding top offenders
$ # The 5 hosts on my honeynet that get the most SYN packets.
$ tshark -r traffic_sample.pcap -T fields -e ip.dst tcp.flags eq 0x02 and ip.dst eq "honeynet.eg/16" | sort | uniq -c | sort -brn -k 1 | head -n 5
  46736 bid.honeynet.eg
   8100 tty.honeynet.eg
   7513 vex.honeynet.eg
   3328 gag.honeynet.eg
   2486 sat.honeynet.eg
$ # The 5 hosts on my honeynet that initiate the most outbound connections.
$ tshark -r traffic_sample.pcap -T fields -e ip.src tcp.flags eq 0x02 and ip.src eq "honeynet.eg/16" | sort | uniq -c | sort -brn -k 1 | head -n 5
  86196 sat.honeynet.eg
   1866 vex.honeynet.eg
   1849 tty.honeynet.eg
    297 lab.honeynet.eg
    102 pow.honeynet.eg
$ # The 5 external hosts that initate the most connections to my honeynet.

$ tshark -r traffic_sample.pcap -T fields -e ip.src tcp.flags eq 0x02 and ip.dst eq "honeynet.eg/16" and ip.src ne "honeynet.eg/16" | sort | uniq -c | sort -brn -k 1 | head -n 5
  15881 foe.network.eg
   8087 ida.network.eg
   3926 rod.network.eg
   3891 paz.network.eg
   1773 ray.network.eg

There’s foe.network.eg and bid.honeynet.eg again. I’ll call them “sore thumb 1″ and “sore thumb 2″ from now on. There are three caveats to highlight here. First, it is extremely important to pay close attention to how we’re specifying direction. Notice that in the first example above I used dst, in the second I used src and in the third I mixed both src and dst. Second, note that some protocol fields can be accessed via different filters. For example, filtering by “ip.addr” will search both ip.src and ip.dst fields. Third, sometimes a single packet can contain multiple fields with the same name. For example, an ICMP packet can contain two ip.src fields: one for the outer IP layer and the other for the IP layer that sits on top of the ICMP layer. I demonstrate this below by showing that an ICMP packet packet going from mig.honeynet.eg to lay.network.eg will be displayed when using a display filter of either “ip.src eq mig.honeynet.eg” or “ip.dst eq mig.honeynet.eg”:

x
~
_
xterm: multiple instances of the same field
$ tshark -r ping.pcap
  1   0.000000 mig.honeynet.eg -> lay.network.eg ICMP Destination unreachable (Port unreachable)
$ tshark -r ping.pcap ip.src eq mig.honeynet.eg
  1   0.000000 mig.honeynet.eg -> lay.network.eg ICMP Destination unreachable (Port unreachable)
$ tshark -r ping.pcap ip.dst eq mig.honeynet.eg
  1   0.000000 mig.honeynet.eg -> lay.network.eg ICMP Destination unreachable (Port unreachable)
$ tshark -V -r ping.pcap ip.dst eq mig.honeynet.eg
...
...
    [Protocols in frame: eth:ip:icmp:ip:udp:data]
...
...
Internet Protocol, Src: mig.honeynet.eg (mig.honeynet.eg), Dst: lay.network.eg (20
auk.network.eg)
...
...
    Source: mig.honeynet.eg (mig.honeynet.eg)
    Destination: lay.network.eg (lay.network.eg)
Internet Control Message Protocol
    Type: 3 (Destination unreachable)
    Code: 3 (Port unreachable)
    Checksum: 0x9aa1 [correct]
    Internet Protocol, Src: lay.network.eg (lay.network.eg), Dst: mig.honeynet.eg (mig.honeynet.eg)
...
...
        Source: lay.network.eg (lay.network.eg)
        Destination: mig.honeynet.eg (mig.honeynet.eg)
$ tshark -r ping.pcap -T pdml ip.dst eq mig.honeynet.eg | grep ip.src
    <field name="ip.src" showname="Source: mig.honeynet.eg (mig.honeynet.eg)" size="4" pos="26" show="mig.honeynet.eg" value="xxxxxxxx"/>
    <field name="ip.src_host" showname="Source Host: mig.honeynet.eg" hide="yes" size="4" pos="26" show="mig.honeynet.eg" value="xxxxxxxx"/>
      <field name="ip.src" showname="Source: lay.network.eg (lay.network.eg)" size="4" pos="54" show="lay.network.eg" value="xxxxxxxx"/>

      <field name="ip.src_host" showname="Source Host: lay.network.eg" hide="yes" size="4" pos="54" show="lay.network.eg" value="xxxxxxxx"/>
$

It becomes apparent rather quickly that I need to distinguish between attempted connections and successful connections. In other words, what I really care about is looking at connections that are in the SYN_RVCD state because then I at least know that the port in question is listening for incoming connection requests and is therefore more interesting. We found out earlier that tcp.flags will be set to 0x12 if both the SYN and ACK bits are turned on. Below, I get the top 5 hosts on the honeynet that are responding to connection requests by filtering for SYN/ACK responses from port 445. Notice that the top 5 hosts sending SYN/ACK responses below are different than the top 5 hosts that get SYN packets above. This validates our concern.

x
~
_
xterm: syn and ack bits set
$ tshark -r traffic_sample.pcap tcp.flags eq 0x12 and ip.src eq "honeynet.eg/16" and tcp.srcport eq 445 | head -n 5
219   4.658323 lad.honeynet.eg -> tim.network.eg TCP microsoft-ds > lkcmserver [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460
372   7.906750 sat.honeynet.eg -> ray.network.eg  TCP microsoft-ds > 55499 [SYN, ACK] Seq=0 Ack=1 Win=17520 Len=0 MSS=1460
442   9.311976 ere.honeynet.eg -> ray.network.eg  TCP microsoft-ds > 47017 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460
458   9.387011 lad.honeynet.eg -> chi.network.eg TCP microsoft-ds > 15709 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460
465   9.430407 lad.honeynet.eg -> chi.network.eg TCP microsoft-ds > 15720 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460
$
$ tshark -r traffic_sample.pcap -T fields -e ip.src tcp.flags eq 0x12 and ip.src eq honeynet.eg/16 and tcp.srcport eq 445 | sort | uniq -c | sort -rnb -k 1 | head -n 5
   1028 sat.honeynet.eg
    519 lad.honeynet.eg
    500 ere.honeynet.eg
     21 rae.honeynet.eg
     10 pro.honeynet.eg

Up to this point, all we know for sure is that hosts on my network are listening for connections on TCP port 445. I’d like to dig deeper. According to Microsoft, the vulnerable RPC uuid is 4b324fc8-1670-01d3-1278-5a47bf6ee188. If we see this uuid in our traffic capture we have more evidence that Conficker is spreading. As you may expect, Wireshark makes it easy to filter by uuid:

x
~
_
xterm: filtering by ms-rpc interface
$ tshark -r traffic_sample.pcap -T fields -e dcerpc.cn_bind_to_uuid | grep - | sort | uniq -c
      5 12345778-1234-abcd-ef00-0123456789ac
     13 3919286a-b10c-11d0-9ba8-00c04fd92ef5
     85 4b324fc8-1670-01d3-1278-5a47bf6ee188
$

3919286a-b10c-11d0-9ba8-00c04fd92ef5 is the RPC interface for the Local Security Authority Subsystem Service (LSASS). A vulnerability (CVE-2003-0533) in this service was exploited by the Sasser worm. 12345778-1234-abcd-ef00-0123456789ac is the RPC interface for Security Account Manager (SAM).

So, we know that vulnerable RPC interfaces are being called. We can also show that the TCP payload contains byte sequences that correspond to Conficker.A and Conficker.B shellcode:

x
~
_
xterm: hunting for shellcode
$  tshark -r traffic_sample.pcap tcp contains e8:ff:ff:ff:ff:c2:5f:8d:4f:10:80:31:c4:41:66:81 and tcp.dstport eq 445 | grep -v Retransmission | shuf -n 10
44800 680.094661 log.network.eg -> sat.honeynet.eg SRVSVC NetPathCanonicalize request
117739 1709.278701 cup.network.eg -> sat.honeynet.eg SRVSVC NetPathCanonicalize request
148006 2115.057841 joy.network.eg -> sat.honeynet.eg SRVSVC NetPathCanonicalize request
9476 164.171395 ian.network.eg -> sat.honeynet.eg SRVSVC NetPathCanonicalize request
51944 800.585453 pin.network.eg -> sat.honeynet.eg SRVSVC NetPathCanonicalize request
32784 544.978680 big.network.eg -> sat.honeynet.eg SRVSVC NetPathCanonicalize request
76211 1230.059103 the.network.eg -> sat.honeynet.eg SRVSVC NetPathCanonicalize request
135633 1922.571202  trw.network.eg -> vex.honeynet.eg SRVSVC NetPathCanonicalize request
298896 4054.865260 ftc.network.eg -> sat.honeynet.eg SRVSVC NetPathCanonicalize request
187360 2763.170242 won.network.eg -> sat.honeynet.eg SRVSVC NetPathCanonicalize request
$

It would be nice if I could easily isolate individual tcp streams in my traffic sample. This has been possible for a while now using Wireshark’s “Follow TCP Stream” function. Mike Hall is credited for implementing the “Follow TCP Stream” function in Wireshark. He sits just down the hall from me. He told me he implemented it on a cross-country road trip because he “had an itch”. I’m pretty sure he wasn’t driving while he wrote the code but you never know with Mike. Anyway, for a long time this function was only available via the Wireshark gui. You select a packet, right click and select “Follow TCP Stream”. As of September 2008, you also can isolate packets belonging to a given stream from the command line by filtering for tcp.stream. Once you have a tcp.stream ID, you can get a list of all frames in that stream and write those frames to a new pcap file using editcap. There are some limitations to using this approach for larger traffic samples. Namely the list of tcp streams can get rather long and editcap limits the number of packets it handles. Still, I wanted to mention this approach because editcap is helpful in many circumstances.

x
~
_
xterm: extracting tcp streams using editcap
$ export tcp_streams=$(tshark -r traffic_sample.pcap -T fields -e tcp.stream dcerpc.cn_bind_to_uuid eq 4b324fc8-1670-01d3-1278-5a47bf6ee188 | tr '\n' ' ')
$ echo $tcp_streams
767 791 790 1042 1091 1498 2066 2472 2495 2571 2714 2862 6654 6669 6716 7182 7219 8866 8990 9074 9739 10646 10881 12641 12857 14121 14186 15001 14992 19602 19589 19661 20228 21015 21103 21473 22487 22869 23423 23533 23832 24005 24164 24338 24364 24707 42649 42720 42794 43129 43178 45803 46495 50504 51824 52932 54609 55593 57208 59116 60015 61611 62134 63482 64040 64826 65624 66440 67902 69525 69466 71763 72063 74254 74748 78440 79903 81060 84389 84503 85120 85390 88252 91150 91465
$ tshark -r traffic_sample.pcap -T fields -e frame.number tcp.stream eq 23832 > frame_numbers.txt
$ wc -w frame_numbers.txt
26 frame_numbers.txt
$ editcap -r traffic_sample.pcap stream_23832.pcap $(< frame_numbers.txt)
Add_Selected: 182700
Not inclusive ... 182700
Add_Selected: 182701
...
...
Add_Selected: 188919
Not inclusive ... 188919

Instead of using editcap I choose to simply wrap tshark’s -w flag in a for loop to generate pcaps containing unique TCP streams. Below I create a subdirectory with pcaps for each TCP stream containing our uuid of interest. Having these individual files is convenient for further research.

x
~
_
xterm: extracting tcp streams using tshark
$ echo "$tcp_streams" | wc -w
85
$ for x in $tcp_streams; do tshark -r traffic_sample.pcap -w individual_streams/"${x}".pcap tcp.stream eq $x; echo "Finished stream ${x}"; done
Finished stream 767
Finished stream 791
Finished stream 790
...
...
...
Finished stream 88252
Finished stream 91150
Finished stream 91465

Now we have 85 pcap files with each containing a TCP stream where there is an attempt to bind to 4b324fc8-1670-01d3-1278-5a47bf6ee188.

Visualizing traffic with Graphviz

Sometimes ideas click if I see data represented visually. Graphviz makes it easy to construct graphs that visualize traffic flow. One thing I was curious to see was which hosts on my honeynet the top 5 external hosts attempted to connect to. I can generate these images in only a few commands:

x
~
_
xterm: visualizing a specific attacker’s activity
$ export top_5_external=$(tshark -r ../traffic_sample.pcap -T fields -e ip.src tcp.flags eq 0x02 and ip.dst eq "honeynet.eg/16" and ip.src ne "honeynet.eg/16" | sort | uniq -c | sort -brn -k 1 | head -n 5 | grep -o "[^ ]*$")
$ echo $top_5_external
foe.network.eg ida.network.eg rod.network.eg paz.network.eg ray.network.eg
$ for ip in $top_5_external
> do
>     tshark -r ../traffic_sample.pcap -T fields -e ip.src -e ip.dst "ip.src eq honeynet.eg/16 and ip.dst eq ${ip} and not icmp" | sort | uniq > ${ip}
> done
$ ls
rod.network.eg  ray.network.eg  ida.network.eg  paz.network.eg  foe.network.eg
$ mkdir graphs
$ for datafile in $(find . -maxdepth 1 -type f);
> do
>     ../mkgraph.py -f ${datafile} -n "honeynet.eg/16" | dot -Tpng -o ./graphs/${datafile}.png;
> done
$ ls graphs/
rod.network.eg.png  ray.network.eg.png  ida.network.eg.png  paz.network.eg.png  foe.network.eg.png
$ ../mkgraph.py -f foe.network.eg -n "honeynet.eg/16"
graph G
{
rankdir=LR
ranksep=3
subgraph cluster0 {
"bid.honeynet.eg"
"lad.honeynet.eg"
"lac.honeynet.eg"
"ere.honeynet.eg"
"rae.honeynet.eg"
"vex.honeynet.eg"
"pro.honeynet.eg"
"sat.honeynet.eg"
}
"lad.honeynet.eg" -- "foe.network.eg"
"bid.honeynet.eg" -- "foe.network.eg"
"rae.honeynet.eg" -- "foe.network.eg"
"vex.honeynet.eg" -- "foe.network.eg"
"sat.honeynet.eg" -- "foe.network.eg"
"ere.honeynet.eg" -- "foe.network.eg"
"pro.honeynet.eg" -- "foe.network.eg"
"lac.honeynet.eg" -- "foe.network.eg"
}

mkgraph.py is a script I wrote that parses tshark output and generates a dot file that dot will use to generate a graph. Below is one of the images generated (click for a larger version). Notice that foe.network.eg, “sore thumb 1″, has been quite busy. (My script for sanitizing IPs chose foe.network.eg on its own… it could be self-aware)

Another thing I was interested to see was the source ports responding to connection attempts to and from vex.honeynet.eg, one of my top 5 hosts. I removed port 80 for keep the graph simple.

x
~
_
xterm: visualizing connections to and from a given host
$ tshark -r traffic_sample.pcap -T fields -e ip.src -e ip.dst -e tcp.srcport ip.addr eq vex.honeynet.eg and tcp.flags eq 0x12 and tcp.srcport ne 80 | sort | uniq > tcp_flows.txt
$ ./mkgraph.py -f tcp_flows.txt -n "honeynet.eg/16" > tcp_flows.dot
$ dot -Gsize="5,5" -Tpng -o tcp_flows.png tcp_flows.dot
$ cat tcp_flows.dot
digraph G
{
rankdir=LR
ranksep=3
subgraph cluster0 {
"tty.honeynet.eg"
"vex.honeynet.eg"
}
"tty.honeynet.eg" -> "vex.honeynet.eg" [label="443"]
"vex.honeynet.eg" -> "dec.network.eg" [label="23"]
"vex.honeynet.eg" -> "crt.network.eg" [label="445"]
"vex.honeynet.eg" -> "bye.network.eg" [label="23"]
"vex.honeynet.eg" -> "trw.network.eg" [label="445"]
"vex.honeynet.eg" -> "ida.network.eg" [label="139"]
"vex.honeynet.eg" -> "ida.network.eg" [label="445"]
"vex.honeynet.eg" -> "ivy.network.eg" [label="23"]
"vex.honeynet.eg" -> "sum.network.eg" [label="139"]
"vex.honeynet.eg" -> "sum.network.eg" [label="445"]
"vex.honeynet.eg" -> "vet.network.eg" [label="23"]
"ncr.network.eg" -> "vex.honeynet.eg" [label="6005"]
"bud.network.eg" -> "vex.honeynet.eg" [label="443"]
"nat.network.eg" -> "vex.honeynet.eg" [label="10010"]
"bin.network.eg" -> "vex.honeynet.eg" [label="10010"]
"sci.network.eg" -> "vex.honeynet.eg" [label="25511"]
"des.network.eg" -> "vex.honeynet.eg" [label="10192"]
}

Here’s the image Graphviz generated (click for a larger version):

I’m only scratching the surface when it comes to visualizing my traffic sample. I could use Scapy’s rich features to generate dot files that will tell me all sorts of details about my traffic. Scapy also comes with some visualization capability out of the box. One thing I’d like to do is graph the spread of Conficker to and within my honeynet.

What did my IPS and Network Participation tell me?

Obviously there’s a lot of data that can be extracted from these 450,000 packets. I was curious to see what other vulnerabilities were being exploited so I ran the traffic through my IPS. Some of the vulnerabilities that the IPS detected in my traffic sample are below:

Back to Conficker though…I was curious to see how widespread attacks from my top 5 attackers were. That is, were these attackers a problem for my honeynet only or did we see attacks from them elsewhere on the Internet? I checked Network Participation data for the top 5 external hosts that connected to the vulnerable RPC interface on my honeynet. Not surprisingly, I saw some of these IP addresses triggering Conficker-related signatures in several locations.

So in the end…

Well, there we go. I have some good insight into the traffic capture we started with and we were able to perform this analysis quickly and easily from the command line. I know network-level things like who’s attacking us and who’s getting attacked. I know packet-level things like which streams contain Conficker shellcode. I even have some basic visualization. Now I can do further research like target specific hosts for both network and host-level forensics or extract binaries from TCP streams for disassembly and behavioral analysis. What I’d like to hear is what tools/techniques others use to do this sort of quick research. The fun starts now.

In an effort to keep conversations fresh, Cisco Blogs closes comments after 90 days. Please visit the Cisco Blogs hub page for the latest content.

11 Comments.


  1. I like your post! Great work. Have you seen http://secviz.org? People use all kinds of other tools to visualize security related data. One other tool is AfterGlow (http://afterglow.sf.net). It is very simple to use and lets you configure your graphs via a property file. It makes it really easy to assign color, shape, etc. to your nodes. Check it out.

       1 like

  2. Raffy, thanks for the compliment and for the links. I’ll definitely check out AfterGlow.

       0 likes

  3. Brilliant stuff! Nice to see people using the command line.

       0 likes

  4. You should check out Collaborative Network Forensics that we just launched on pcapr:http://www.pcapr.net/forensicsYou get full-text and contextual search/extract on over 25 million packets!

       0 likes

  5. Anoter nice thing to look at is the Clarified Analyzer, which lets you find the needle from the pcap and view neat (and useful) visualizations.https://www.clarifiednetworks.com/Clarified Analyzer

       0 likes

  6. Hi,but it is possible to use this procedure to file of traffic saved in pcapformat ?thank you

       0 likes

  7. Antonio, you can use tshark to view files in a variety of packet capture formats including pcap. Run editcap -F”" to see a list of supported formats.”

       0 likes

  8. Just announced xtractr today: http://bit.ly/d7yrKl Thought you might find it useful.

       0 likes

  9. Awesome blogpost. Maybe the best stuff a read for long time. Do you see any chance to share mkgraph.py?

       0 likes

  10. Uwe,Sure. I’ll send it to you via email.

       0 likes

  11. This is a very interesting and creative way of using tshark to sort through this. There is also a free online Web2.0 tool that does just that but in just seconds. Would probably save a lot of time using that tool. They call it xtractr and leverage tshark as well but with less scripting involved as it has a great UI.http://www.pcapr.net/xtractr

       0 likes

  1. Return to Countries/Regions
  2. Return to Home
  1. All Security
  2. Return to Home