tunnel.log

The purpose of Zeek’s tunnel.log is to identify encapsulated traffic. A common use case in modern networks involves encapsulating IPv6 traffic within IPv4. It’s also entirely possible to tunnel IPv4 over IPv6. This document will provide a few examples of how Zeek interprets tunneled traffic. The author captured the first example on his home network. The remainder appear courtesy of the PacketLife Web site operated by Jeremy Stretch:

https://packetlife.net/captures/category/tunneling/

For full details on each field in the tunnel.log file, please refer to Tunnel::Info.

Teredo

The following example demonstrates Teredo traffic generated by a Microsoft game console. Teredo is an encapsulation protocol whereby IPv4 carries IPv6 traffic.

https://docs.microsoft.com/en-us/windows/win32/teredo/portal

tcpdump and tshark

Here is tcpdump output for the traffic in question:

00:55:58.290539 IP 192.168.4.31.3074 > 40.84.25.61.65444: UDP, length 61
00:55:59.321945 IP 192.168.4.31.3074 > 40.84.25.61.3544: UDP, length 61
00:55:59.337323 IP 40.84.25.61.3544 > 192.168.4.31.3074: UDP, length 109

Here is tshark output for the traffic in question:

1 192.168.4.31 3074 40.84.25.61  65444 UDP 103 3074 → 65444 Len=61
2 fe80::ffff:ffff:fffe 3074 ff02::2      3544 ICMPv6 103 Router Solicitation
3 fe80::8000:f227:d7ab:e6c3 3544 fe80::ffff:ffff:fffe 3074 ICMPv6 151 Router Advertisement

Notice that tshark shows frames 2 and 3 as IPv6, whereas tcpdump shows them as IPv4.

Let’s take a closer look at frame 2 to see the encapsulation in detail:

Frame 2: 103 bytes on wire (824 bits), 103 bytes captured (824 bits)
    Encapsulation type: Ethernet (1)
    Arrival Time: Dec 15, 2020 00:55:59.321945000 UTC
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1607993759.321945000 seconds
    [Time delta from previous captured frame: 1.031406000 seconds]
    [Time delta from previous displayed frame: 1.031406000 seconds]
    [Time since reference or first frame: 1.031406000 seconds]
    Frame Number: 2
    Frame Length: 103 bytes (824 bits)
    Capture Length: 103 bytes (824 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:ip:udp:teredo:ipv6:icmpv6]
Ethernet II, Src: bc:83:85:56:2f:67, Dst: fc:ec:da:49:e0:10
    Destination: fc:ec:da:49:e0:10
        Address: fc:ec:da:49:e0:10
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Source: bc:83:85:56:2f:67
        Address: bc:83:85:56:2f:67
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 192.168.4.31, Dst: 40.84.25.61
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 89
    Identification: 0xbb91 (48017)
    Flags: 0x0000
        0... .... .... .... = Reserved bit: Not set
        .0.. .... .... .... = Don't fragment: Not set
        ..0. .... .... .... = More fragments: Not set
        ...0 0000 0000 0000 = Fragment offset: 0
    Time to live: 128
    Protocol: UDP (17)
    Header checksum: 0x78aa [validation disabled]
    [Header checksum status: Unverified]
    Source: 192.168.4.31
    Destination: 40.84.25.61
User Datagram Protocol, Src Port: 3074, Dst Port: 3544
    Source Port: 3074
    Destination Port: 3544
    Length: 69
    Checksum: 0x7fdc [unverified]
    [Checksum Status: Unverified]
    [Stream index: 1]
Teredo IPv6 over UDP tunneling
    Teredo Authentication header
        Client identifier length: 0
        Authentication value length: 0
        Nonce value: 6aeec3b128884291
        Confirmation byte: 00
Internet Protocol Version 6, Src: fe80::ffff:ffff:fffe, Dst: ff02::2
    0110 .... = Version: 6
    .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT)
        .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0)
        .... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000
    Payload Length: 8
    Next Header: ICMPv6 (58)
    Hop Limit: 255
    Source: fe80::ffff:ffff:fffe
    Destination: ff02::2
Internet Control Message Protocol v6
    Type: Router Solicitation (133)
    Code: 0
    Checksum: 0x7d38 [correct]
    [Checksum Status: Good]
    Reserved: 00000000

The bolded elements show an ICMPv6 message inside an IPv6 packet, inside a UDP datagram, inside a IPv4 packet. Frame 3 is similar.

conn.log

The conn.log for this traffic contains the following:

{
  "ts": 1607993759.321945,
  "uid": "CO9T0A3FPac5ig4hud",
  "id.orig_h": "192.168.4.31",
  "id.orig_p": 3074,
  "id.resp_h": "40.84.25.61",
  "id.resp_p": 3544,
  "proto": "udp",
  "service": "teredo",
  "duration": 0.015377998352050781,
  "orig_bytes": 61,
  "resp_bytes": 109,
  "conn_state": "SF",
  "missed_bytes": 0,
  "history": "Dd",
  "orig_pkts": 1,
  "orig_ip_bytes": 89,
  "resp_pkts": 1,
  "resp_ip_bytes": 137
}

This first conn.log entry addresses frames 2 and 3 in the original packet capture. Zeek identifies Teredo as the service within a UDP datagram. Port 3544 UDP appears to be associated with Teredo per Microsoft’s documentation. Port 3074 UDP appears to be associated with Microsoft game consoles as well, perhaps due to NAT traversal. Note the uid field. It will appear again shortly.

{
  "ts": 1607993758.290539,
  "uid": "CUqiKk4m6VpWwcaJ4l",
  "id.orig_h": "192.168.4.31",
  "id.orig_p": 3074,
  "id.resp_h": "40.84.25.61",
  "id.resp_p": 65444,
  "proto": "udp",
  "conn_state": "S0",
  "missed_bytes": 0,
  "history": "D",
  "orig_pkts": 1,
  "orig_ip_bytes": 89,
  "resp_pkts": 0,
  "resp_ip_bytes": 0
}

This second conn.log entry refers to frame 1 in the packet capture. Note the uid field. It will appear again shortly as well.

{
  "ts": 1607993759.321945,
  "uid": "CoiibpW4Ov0n1xvj",
  "id.orig_h": "fe80::ffff:ffff:fffe",
  "id.orig_p": 133,
  "id.resp_h": "ff02::2",
  "id.resp_p": 134,
  "proto": "icmp",
  "conn_state": "OTH",
  "missed_bytes": 0,
  "orig_pkts": 1,
  "orig_ip_bytes": 48,
  "resp_pkts": 0,
  "resp_ip_bytes": 0,
  "tunnel_parents": [
    "CO9T0A3FPac5ig4hud"
  ]
}

Here Zeek has created a new conn.log entry for the ICMPv6 traffic carried within a tunnel. The UID of the original connection carrying this traffic appears in the tunnel_parents field. It refers to the first entry in the conn.log.

{
  "ts": 1607993758.290539,
  "uid": "C6Gikx4eC6wXR3xOqg",
  "id.orig_h": "fe80::8000:ffff:ffff:fffe",
  "id.orig_p": 133,
  "id.resp_h": "ff02::2",
  "id.resp_p": 134,
  "proto": "icmp",
  "conn_state": "OTH",
  "missed_bytes": 0,
  "orig_pkts": 1,
  "orig_ip_bytes": 48,
  "resp_pkts": 0,
  "resp_ip_bytes": 0,
  "tunnel_parents": [
    "CUqiKk4m6VpWwcaJ4l"
  ]
}

Similar to the previous conn.log entry, here is another tunneled ICMPv6 message. This corresponds to the second conn.log entry reviewed earlier.

{
  "ts": 1607993759.337323,
  "uid": "C8h2gZ3EjWUW5xKh2",
  "id.orig_h": "fe80::8000:f227:d7ab:e6c3",
  "id.orig_p": 134,
  "id.resp_h": "fe80::ffff:ffff:fffe",
  "id.resp_p": 133,
  "proto": "icmp",
  "conn_state": "OTH",
  "missed_bytes": 0,
  "orig_pkts": 1,
  "orig_ip_bytes": 88,
  "resp_pkts": 0,
  "resp_ip_bytes": 0,
  "tunnel_parents": [
    "CO9T0A3FPac5ig4hud"
  ]
}

Zeek creates a final conn.log entry for tunneled traffic. This also corresponds to the first conn.log entry by virtue of its tunnel_parent value.

tunnel.log

Zeek’s tunnel.log offers the following entries for this encapsulated traffic.

{
  "ts": 1607993758.290539,
  "uid": "CUqiKk4m6VpWwcaJ4l",
  "id.orig_h": "192.168.4.31",
  "id.orig_p": 3074,
  "id.resp_h": "40.84.25.61",
  "id.resp_p": 65444,
  "tunnel_type": "Tunnel::TEREDO",
  "action": "Tunnel::DISCOVER"
}
{
  "ts": 1607993759.321945,
  "uid": "CO9T0A3FPac5ig4hud",
  "id.orig_h": "192.168.4.31",
  "id.orig_p": 3074,
  "id.resp_h": "40.84.25.61",
  "id.resp_p": 3544,
  "tunnel_type": "Tunnel::TEREDO",
  "action": "Tunnel::DISCOVER"
}
{
  "ts": 1607993759.337323,
  "uid": "CO9T0A3FPac5ig4hud",
  "id.orig_h": "192.168.4.31",
  "id.orig_p": 3074,
  "id.resp_h": "40.84.25.61",
  "id.resp_p": 3544,
  "tunnel_type": "Tunnel::TEREDO",
  "action": "Tunnel::CLOSE"
}
{
  "ts": 1607993759.337323,
  "uid": "CUqiKk4m6VpWwcaJ4l",
  "id.orig_h": "192.168.4.31",
  "id.orig_p": 3074,
  "id.resp_h": "40.84.25.61",
  "id.resp_p": 65444,
  "tunnel_type": "Tunnel::TEREDO",
  "action": "Tunnel::CLOSE"
}

The action messages indicate how Zeek is tracking the connections. When it first identifies a tunnel, it reports DISCOVER. When it assesses that the tunnel is no longer used, Zeek reports CLOSE.

The take-away from this activity is that Zeek has identified Teredo traffic. The tunnel.log entries abstract the somewhat complicated detailed logs and produce results that are a bit friendlier to the analyst. Here we see that the systems involved are opening and closing Teredo tunnels. If this is not authorized traffic, it is enough to begin a more detailed investigation.

IP in IP

The next example shows transporting IPv4 inside IPv4 traffic. RFC 1853 states:

“The IP in IP encapsulation Protocol/Payload number 4 RFC 1700 has long been used to bridge portions of the Internet which have disjoint capabilities or policies.”

This is another encapsulation method that might surprise an analyst or network administrator, assuming it is not authorized for use.

tcpdump and tshark

Here is tcpdump’s view of the sample traffic:

12:12:06.059907 IP 10.0.0.1 > 10.0.0.2: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 4, seq 0, length 80 (ipip-proto-4)
12:12:06.067958 IP 10.0.0.2 > 10.0.0.1: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 4, seq 0, length 80 (ipip-proto-4)
12:12:06.075906 IP 10.0.0.1 > 10.0.0.2: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 4, seq 1, length 80 (ipip-proto-4)
12:12:06.083920 IP 10.0.0.2 > 10.0.0.1: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 4, seq 1, length 80 (ipip-proto-4)
12:12:06.091909 IP 10.0.0.1 > 10.0.0.2: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 4, seq 2, length 80 (ipip-proto-4)
12:12:06.099922 IP 10.0.0.2 > 10.0.0.1: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 4, seq 2, length 80 (ipip-proto-4)
12:12:06.107906 IP 10.0.0.1 > 10.0.0.2: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 4, seq 3, length 80 (ipip-proto-4)
12:12:06.116057 IP 10.0.0.2 > 10.0.0.1: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 4, seq 3, length 80 (ipip-proto-4)
12:12:06.123910 IP 10.0.0.1 > 10.0.0.2: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 4, seq 4, length 80 (ipip-proto-4)
12:12:06.131919 IP 10.0.0.2 > 10.0.0.1: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 4, seq 4, length 80 (ipip-proto-4)

Here is tshark’s view of the first packet:

Frame 1: 134 bytes on wire (1072 bits), 134 bytes captured (1072 bits)
    Encapsulation type: Ethernet (1)
    Arrival Time: Jun 21, 2008 12:12:06.059907000 UTC
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1214050326.059907000 seconds
    [Time delta from previous captured frame: 0.000000000 seconds]
    [Time delta from previous displayed frame: 0.000000000 seconds]
    [Time since reference or first frame: 0.000000000 seconds]
    Frame Number: 1
    Frame Length: 134 bytes (1072 bits)
    Capture Length: 134 bytes (1072 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:ip:ip:icmp:data]
Ethernet II, Src: c2:00:57:75:00:00, Dst: c2:01:57:75:00:00
    Destination: c2:01:57:75:00:00
        Address: c2:01:57:75:00:00
        .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Source: c2:00:57:75:00:00
        Address: c2:00:57:75:00:00
        .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 10.0.0.1, Dst: 10.0.0.2
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 120
    Identification: 0x0014 (20)
    Flags: 0x0000
        0... .... .... .... = Reserved bit: Not set
        .0.. .... .... .... = Don't fragment: Not set
        ..0. .... .... .... = More fragments: Not set
        ...0 0000 0000 0000 = Fragment offset: 0
    Time to live: 255
    Protocol: IPIP (4)
    Header checksum: 0xa76b [validation disabled]
    [Header checksum status: Unverified]
    Source: 10.0.0.1
    Destination: 10.0.0.2
Internet Protocol Version 4, Src: 1.1.1.1, Dst: 2.2.2.2
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x0014 (20)
    Flags: 0x0000
        0... .... .... .... = Reserved bit: Not set
        .0.. .... .... .... = Don't fragment: Not set
        ..0. .... .... .... = More fragments: Not set
        ...0 0000 0000 0000 = Fragment offset: 0
    Time to live: 255
    Protocol: ICMP (1)
    Header checksum: 0xb57f [validation disabled]
    [Header checksum status: Unverified]
    Source: 1.1.1.1
    Destination: 2.2.2.2
Internet Control Message Protocol
    Type: 8 (Echo (ping) request)
    Code: 0
    Checksum: 0x4305 [correct]
    [Checksum Status: Good]
    Identifier (BE): 4 (0x0004)
    Identifier (LE): 1024 (0x0400)
    Sequence number (BE): 0 (0x0000)
    Sequence number (LE): 0 (0x0000)
    Data (72 bytes)

0000  00 00 00 00 00 09 3b 38 ab cd ab cd ab cd ab cd   ......;8........
0010  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
0020  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
0030  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
0040  ab cd ab cd ab cd ab cd                           ........
        Data: 0000000000093b38abcdabcdabcdabcdabcdabcdabcdabcd...
        [Length: 72]

Note that both renditions depict the outer and inner IP addresses in use, as well as the encapsulated ICMP traffic.

conn.log

Zeek creates a single conn.log entry for this traffic.

{
  "ts": 1214050326.059907,
  "uid": "CaG4lb2HwGhNGLo1d2",
  "id.orig_h": "1.1.1.1",
  "id.orig_p": 8,
  "id.resp_h": "2.2.2.2",
  "id.resp_p": 0,
  "proto": "icmp",
  "duration": 0.07201194763183594,
  "orig_bytes": 360,
  "resp_bytes": 360,
  "conn_state": "OTH",
  "missed_bytes": 0,
  "orig_pkts": 5,
  "orig_ip_bytes": 500,
  "resp_pkts": 5,
  "resp_ip_bytes": 500,
  "tunnel_parents": [
    "CllZAw139PBBVBawlj"
  ]
}

Notice the only conn.log entry lists the encapsulated source and destination IP addresses for the traffic, i.e., 1.1.1.1 and 2.2.2.2. To see the outer IP addresses, we need to look for the tunnel_parents connection in the tunnel.log.

tunnel.log

The tunnel.log also contains a single entry:

{
  "ts": 1214050326.059907,
  "uid": "CllZAw139PBBVBawlj",
  "id.orig_h": "10.0.0.1",
  "id.orig_p": 0,
  "id.resp_h": "10.0.0.2",
  "id.resp_p": 0,
  "tunnel_type": "Tunnel::IP",
  "action": "Tunnel::DISCOVER"
}

Here we learn that the outer IP addresses are 10.0.0.1 and 10.0.0.2. The tunnel type is IP. The action of Tunnel::DISCOVER means that Zeek has identified a new tunnel or encapsulation.

IP over IP via GRE

Let’s look at a more common variation of IP within IP. This method uses Generic Routing Encapsulation, or GRE.

tcpdump and tshark

Here is tcpdump’s view of the traffic:

12:06:06.434897 IP 10.0.0.1 > 10.0.0.2: GREv0, length 104: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 2, seq 0, length 80
12:06:06.442931 IP 10.0.0.2 > 10.0.0.1: GREv0, length 104: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 2, seq 0, length 80
12:06:06.450900 IP 10.0.0.1 > 10.0.0.2: GREv0, length 104: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 2, seq 1, length 80
12:06:06.498938 IP 10.0.0.2 > 10.0.0.1: GREv0, length 104: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 2, seq 1, length 80
12:06:06.506904 IP 10.0.0.1 > 10.0.0.2: GREv0, length 104: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 2, seq 2, length 80
12:06:06.514914 IP 10.0.0.2 > 10.0.0.1: GREv0, length 104: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 2, seq 2, length 80
12:06:06.522905 IP 10.0.0.1 > 10.0.0.2: GREv0, length 104: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 2, seq 3, length 80
12:06:06.570925 IP 10.0.0.2 > 10.0.0.1: GREv0, length 104: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 2, seq 3, length 80
12:06:06.578905 IP 10.0.0.1 > 10.0.0.2: GREv0, length 104: IP 1.1.1.1 > 2.2.2.2: ICMP echo request, id 2, seq 4, length 80
12:06:06.586923 IP 10.0.0.2 > 10.0.0.1: GREv0, length 104: IP 2.2.2.2 > 1.1.1.1: ICMP echo reply, id 2, seq 4, length 80

Here is tshark’s view of the first packet:

Frame 1: 138 bytes on wire (1104 bits), 138 bytes captured (1104 bits)
    Encapsulation type: Ethernet (1)
    Arrival Time: Jun 21, 2008 12:06:06.434897000 UTC
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1214049966.434897000 seconds
    [Time delta from previous captured frame: 0.000000000 seconds]
    [Time delta from previous displayed frame: 0.000000000 seconds]
    [Time since reference or first frame: 0.000000000 seconds]
    Frame Number: 1
    Frame Length: 138 bytes (1104 bits)
    Capture Length: 138 bytes (1104 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:ip:gre:ip:icmp:data]
Ethernet II, Src: c2:00:57:75:00:00, Dst: c2:01:57:75:00:00
    Destination: c2:01:57:75:00:00
        Address: c2:01:57:75:00:00
        .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Source: c2:00:57:75:00:00
        Address: c2:00:57:75:00:00
        .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 10.0.0.1, Dst: 10.0.0.2
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 124
    Identification: 0x000a (10)
    Flags: 0x0000
        0... .... .... .... = Reserved bit: Not set
        .0.. .... .... .... = Don't fragment: Not set
        ..0. .... .... .... = More fragments: Not set
        ...0 0000 0000 0000 = Fragment offset: 0
    Time to live: 255
    Protocol: Generic Routing Encapsulation (47)
    Header checksum: 0xa746 [validation disabled]
    [Header checksum status: Unverified]
    Source: 10.0.0.1
    Destination: 10.0.0.2
Generic Routing Encapsulation (IP)
    Flags and Version: 0x0000
        0... .... .... .... = Checksum Bit: No
        .0.. .... .... .... = Routing Bit: No
        ..0. .... .... .... = Key Bit: No
        ...0 .... .... .... = Sequence Number Bit: No
        .... 0... .... .... = Strict Source Route Bit: No
        .... .000 .... .... = Recursion control: 0
        .... .... 0000 0... = Flags (Reserved): 0
        .... .... .... .000 = Version: GRE (0)
    Protocol Type: IP (0x0800)
Internet Protocol Version 4, Src: 1.1.1.1, Dst: 2.2.2.2
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 100
    Identification: 0x000a (10)
    Flags: 0x0000
        0... .... .... .... = Reserved bit: Not set
        .0.. .... .... .... = Don't fragment: Not set
        ..0. .... .... .... = More fragments: Not set
        ...0 0000 0000 0000 = Fragment offset: 0
    Time to live: 255
    Protocol: ICMP (1)
    Header checksum: 0xb589 [validation disabled]
    [Header checksum status: Unverified]
    Source: 1.1.1.1
    Destination: 2.2.2.2
Internet Control Message Protocol
    Type: 8 (Echo (ping) request)
    Code: 0
    Checksum: 0xbfd4 [correct]
    [Checksum Status: Good]
    Identifier (BE): 2 (0x0002)
    Identifier (LE): 512 (0x0200)
    Sequence number (BE): 0 (0x0000)
    Sequence number (LE): 0 (0x0000)
    Data (72 bytes)

0000  00 00 00 00 00 03 be 70 ab cd ab cd ab cd ab cd   .......p........
0010  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
0020  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
0030  ab cd ab cd ab cd ab cd ab cd ab cd ab cd ab cd   ................
0040  ab cd ab cd ab cd ab cd                           ........
        Data: 000000000003be70abcdabcdabcdabcdabcdabcdabcdabcd...
        [Length: 72]

Note that both renditions depict the outer and inner IP addresses in use, as well as the encapsulated ICMP traffic. This time, in contrast with the previous example, the inner traffic follows a GRE header.

conn.log

Zeek creates a single conn.log entry for this traffic:

{
  "ts": 1214049966.434897,
  "uid": "Cxg76d2N73I9DhmZ5l",
  "id.orig_h": "1.1.1.1",
  "id.orig_p": 8,
  "id.resp_h": "2.2.2.2",
  "id.resp_p": 0,
  "proto": "icmp",
  "duration": 0.15202593803405762,
  "orig_bytes": 360,
  "resp_bytes": 360,
  "conn_state": "OTH",
  "missed_bytes": 0,
  "orig_pkts": 5,
  "orig_ip_bytes": 500,
  "resp_pkts": 5,
  "resp_ip_bytes": 500,
  "tunnel_parents": [
    "C2ELkSIprfG0oMEae"
  ]
}

As with the previous example, the only conn.log entry lists the encapsulated source and destination IP addresses for the traffic, i.e., 1.1.1.1 and 2.2.2.2. To see the outer IP addresses, we need to look for the tunnel_parents connection in the tunnel.log.

tunnel.log

The tunnel.log also contains a single entry:

{
  "ts": 1214049966.434897,
  "uid": "C2ELkSIprfG0oMEae",
  "id.orig_h": "10.0.0.1",
  "id.orig_p": 0,
  "id.resp_h": "10.0.0.2",
  "id.resp_p": 0,
  "tunnel_type": "Tunnel::GRE",
  "action": "Tunnel::DISCOVER"
}

We see again that the outer IP addresses are 10.0.0.1 and 10.0.0.2. The tunnel type is GRE, unlike the previous IP. The action of Tunnel::DISCOVER means that Zeek has identified a new tunnel or encapsulation.

IPv4 in PPP in GRE in IPv4 in IPv6

We’ve saved the most complicated example for last.

In this example, we see the following very complicated protocol stack:

Ethernet II
802.1Q virtual LAN (VLAN)
IPv6
IPv4
GRE
Point-to-Point Protocol (PPP)
IPv4
UDP
Domain Name System

I am not sure what created this trace, although I suspect it may be from a mobile asset.

tcpdump and tshark

Here is tcpdump’s view of the sample traffic:

03:35:03.821897 IP6 2402:f000:1:8e01::5555 > 2607:fcd0:100:2300::b108:2a6b: IP 16.0.0.200 > 192.52.166.154: GREv1, call 6016, seq 430001, ack 539254, length 119: IP 172.16.44.3.40768 > 8.8.8.8.53: 42540+ AAAA? xqt-detect-mode2-97712e88-167a-45b9-93ee-913140e76678. (71)

03:35:04.035791 IP6 2607:fcd0:100:2300::b108:2a6b > 2402:f000:1:8e01::5555: IP 192.52.166.154 > 16.0.0.200: GREv1, call 17, seq 539320, length 190: IP 8.8.8.8.53 > 172.16.44.3.40768: 42540 NXDomain 0/1/0 (146)

Here is tshark’s view of the first packet:

Frame 1: 197 bytes on wire (1576 bits), 197 bytes captured (1576 bits)
    Encapsulation type: Ethernet (1)
    Arrival Time: Dec  3, 2014 03:35:03.821897000 UTC
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1417577703.821897000 seconds
    [Time delta from previous captured frame: 0.000000000 seconds]
    [Time delta from previous displayed frame: 0.000000000 seconds]
    [Time since reference or first frame: 0.000000000 seconds]
    Frame Number: 1
    Frame Length: 197 bytes (1576 bits)
    Capture Length: 197 bytes (1576 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:vlan:ethertype:ipv6:ip:gre:ppp:ip:udp:dns]
Ethernet II, Src: 00:12:1e:f2:61:3d, Dst: c5:00:00:00:82:c4
    Destination: c5:00:00:00:82:c4
        Address: c5:00:00:00:82:c4
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...1 .... .... .... .... = IG bit: Group address (multicast/broadcast)
    Source: 00:12:1e:f2:61:3d
        Address: 00:12:1e:f2:61:3d
        .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
    Type: 802.1Q Virtual LAN (0x8100)
802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 100
    000. .... .... .... = Priority: Best Effort (default) (0)
    ...0 .... .... .... = DEI: Ineligible
    .... 0000 0110 0100 = ID: 100
    Type: IPv6 (0x86dd)
Internet Protocol Version 6, Src: 2402:f000:1:8e01::5555, Dst: 2607:fcd0:100:2300::b108:2a6b
    0110 .... = Version: 6
    .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT)
        .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0)
        .... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000
    Payload Length: 139
    Next Header: IPIP (4)
    Hop Limit: 246
    Source: 2402:f000:1:8e01::5555
    Destination: 2607:fcd0:100:2300::b108:2a6b
Internet Protocol Version 4, Src: 16.0.0.200, Dst: 192.52.166.154
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 139
    Identification: 0x8caf (36015)
    Flags: 0x0000
        0... .... .... .... = Reserved bit: Not set
        .0.. .... .... .... = Don't fragment: Not set
        ..0. .... .... .... = More fragments: Not set
        ...0 0000 0000 0000 = Fragment offset: 0
    Time to live: 64
    Protocol: Generic Routing Encapsulation (47)
    Header checksum: 0x75fe [validation disabled]
    [Header checksum status: Unverified]
    Source: 16.0.0.200
    Destination: 192.52.166.154
Generic Routing Encapsulation (PPP)
    Flags and Version: 0x3081
        0... .... .... .... = Checksum Bit: No
        .0.. .... .... .... = Routing Bit: No
        ..1. .... .... .... = Key Bit: Yes
        ...1 .... .... .... = Sequence Number Bit: Yes
        .... 0... .... .... = Strict Source Route Bit: No
        .... .000 .... .... = Recursion control: 0
        .... .... 1... .... = Acknowledgment: Yes
        .... .... .000 0... = Flags (Reserved): 0
        .... .... .... .001 = Version: Enhanced GRE (1)
    Protocol Type: PPP (0x880b)
    Payload Length: 103
    Call ID: 6016
    Sequence Number: 430001
    Acknowledgment Number: 539254
Point-to-Point Protocol
    Address: 0xff
    Control: 0x03
    Protocol: Internet Protocol version 4 (0x0021)
Internet Protocol Version 4, Src: 172.16.44.3, Dst: 8.8.8.8
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
        0000 00.. = Differentiated Services Codepoint: Default (0)
        .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
    Total Length: 99
    Identification: 0x0000 (0)
    Flags: 0x4000, Don't fragment
        0... .... .... .... = Reserved bit: Not set
        .1.. .... .... .... = Don't fragment: Set
        ..0. .... .... .... = More fragments: Not set
        ...0 0000 0000 0000 = Fragment offset: 0
    Time to live: 60
    Protocol: UDP (17)
    Header checksum: 0x5667 [validation disabled]
    [Header checksum status: Unverified]
    Source: 172.16.44.3
    Destination: 8.8.8.8
User Datagram Protocol, Src Port: 40768, Dst Port: 53
    Source Port: 40768
    Destination Port: 53
    Length: 79
    Checksum: 0x2d23 [unverified]
    [Checksum Status: Unverified]
    [Stream index: 0]
Domain Name System (query)
    Transaction ID: 0xa62c
    Flags: 0x0100 Standard query
        0... .... .... .... = Response: Message is a query
        .000 0... .... .... = Opcode: Standard query (0)
        .... ..0. .... .... = Truncated: Message is not truncated
        .... ...1 .... .... = Recursion desired: Do query recursively
        .... .... .0.. .... = Z: reserved (0)
        .... .... ...0 .... = Non-authenticated data: Unacceptable
    Questions: 1
    Answer RRs: 0
    Authority RRs: 0
    Additional RRs: 0
    Queries
        xqt-detect-mode2-97712e88-167a-45b9-93ee-913140e76678: type AAAA, class IN
            Name: xqt-detect-mode2-97712e88-167a-45b9-93ee-913140e76678
            [Name Length: 53]
            [Label Count: 1]
            Type: AAAA (IPv6 Address) (28)
            Class: IN (0x0001)

Both tcpdump and tshark show the three levels of IP addresses used in this complicated frame.

conn.log

Let’s see what Zeek makes of this complicated exchange.

{
  "ts": 1417577703.821897,
  "uid": "CiJXLc43tlknoHbXH9",
  "id.orig_h": "172.16.44.3",
  "id.orig_p": 40768,
  "id.resp_h": "8.8.8.8",
  "id.resp_p": 53,
  "proto": "udp",
  "service": "dns",
  "duration": 0.21389389038085938,
  "orig_bytes": 71,
  "resp_bytes": 146,
  "conn_state": "SF",
  "missed_bytes": 0,
  "history": "Dd",
  "orig_pkts": 1,
  "orig_ip_bytes": 99,
  "resp_pkts": 1,
  "resp_ip_bytes": 174,
  "tunnel_parents": [
    "CBvCtfO5sjjyQb2V4"
  ]
}

We see Zeek has burrowed all the way down to the innermost IP address, 172.16.44.3, making a DNS request to 8.8.8.8.

tunnel.log

Zeek’s tunnel.log contains two entries for this session.

{
  "ts": 1417577703.821897,
  "uid": "CPnYZx2edh7O2ueTm4",
  "id.orig_h": "2402:f000:1:8e01::5555",
  "id.orig_p": 0,
  "id.resp_h": "2607:fcd0:100:2300::b108:2a6b",
  "id.resp_p": 0,
  "tunnel_type": "Tunnel::IP",
  "action": "Tunnel::DISCOVER"
}
{
  "ts": 1417577703.821897,
  "uid": "CBvCtfO5sjjyQb2V4",
  "id.orig_h": "16.0.0.200",
  "id.orig_p": 0,
  "id.resp_h": "192.52.166.154",
  "id.resp_p": 0,
  "tunnel_type": "Tunnel::GRE",
  "action": "Tunnel::DISCOVER"
}

Zeek displays the two outer IP addresses, and ties them to the inner address using the uid field. The uid matches the tunnel_parents field in the conn.log.

dns.log

For completeness, let’s take a look at the dns.log Zeek created for this activity.

{
  "ts": 1417577703.821897,
  "uid": "CiJXLc43tlknoHbXH9",
  "id.orig_h": "172.16.44.3",
  "id.orig_p": 40768,
  "id.resp_h": "8.8.8.8",
  "id.resp_p": 53,
  "proto": "udp",
  "trans_id": 42540,
  "query": "xqt-detect-mode2-97712e88-167a-45b9-93ee-913140e76678",
  "qclass": 1,
  "qclass_name": "C_INTERNET",
  "qtype": 28,
  "qtype_name": "AAAA",
  "rcode": 3,
  "rcode_name": "NXDOMAIN",
  "AA": false,
  "TC": false,
  "RD": true,
  "RA": false,
  "Z": 0,
  "rejected": false
}

Here is a AAAA query, meaning the client wants the IPv6 address for the domain listed in the query. As you might guess, the DNS server reply (not shown here) is for a root name server.

Conclusion

Zeek’s tunnel.log is a useful way to accomplish two tasks. First, the presence of a tunnel.log in your collection of Zeek outputs means Zeek has detected and reported on encapsulated traffic. If you do not expect to see such activity in your environment, it is worth investigating. Second, the tunnel.log provides a means to show the outermost IP addresses associated with the activity reported in the conn.log when encapsulation is present.