FCSC 2023 - Baleine sous graviers - Forensics

8 minute read

Here is the write-up of “Baleine sous graviers”, a forensics challenge of the FCSC 2023 which involves investigation of multiple pcap files.

Description

The security analysts of a telecom operator are facing a major problem. For the past few days, an alert on their intrusion detection system keeps getting raised by their behavioral analysis probe. The probe indicates that the traffic captured on some core network links is abnormal. Here is the topology of the operator’s core network: After several nights of traffic analysis, our analysts were unable to find the cause of this alert. Could you help them identify the cause of this abnormal traffic from a set of pcap files containing traffic captured on the network core?

Author : Ludo

Two files are given, the topology image, and an archive with all the pcap files.

Discovery

$ ls
r10_gi01.pcap  r11_gi00.pcap  r1_gi00.pcap  r2_gi00.pcap  r3_gi00.pcap  r3_gi03.pcap  r4_gi00.pcap  r5_gi01.pcap  r6_gi00.pcap  r6_gi03.pcap  r6_gi06.pcap  r7_gi02.pcap  r8_gi02.pcap  r9_gi01.pcap  r9_gi04.pcap
r10_gi02.pcap  r11_gi01.pcap  r1_gi01.pcap  r2_gi02.pcap  r3_gi01.pcap  r3_gi04.pcap  r4_gi01.pcap  r5_gi02.pcap  r6_gi01.pcap  r6_gi04.pcap  r6_gi07.pcap  r7_gi03.pcap  r8_gi03.pcap  r9_gi02.pcap  r9_gi05.pcap
r10_gi03.pcap  r11_gi02.pcap  r1_gi02.pcap  r2_gi03.pcap  r3_gi02.pcap  r3_gi05.pcap  r4_gi03.pcap  r5_gi03.pcap  r6_gi02.pcap  r6_gi05.pcap  r7_gi01.pcap  r8_gi01.pcap  r9_gi00.pcap  r9_gi03.pcap

The first task is to move each capture with its corresponding router into a folder to make it more clear.

By analyzing the topology and the files given, we could assume few things :

  • We don’t have captures from the externals networks (172.16.X.0/24)
  • We don’t have captures of the switches
  • We don’t know what we need to search, probably an attack or an exfiltration of data which will give us a flag.

Protocols analysis

Let’s fire up wireshark to check some PCAP files to see what’s going on.

The captures were very similar.

There is a huge HTTP traffic from a same User-Agent : Fuzz Faster U Fool v2.0.0. This User-Agent refer to this tool : https://github.com/ffuf/ffuf which is basically a web fuzzer to find path on a web server for example.

There is a nginx server on each border router 172.16.X.1 and every router is being fuzzed.

To be sure that we could filter this traffic, we could filter the http reponse to code different than 404 (http.response.code != 404) and we could see that there are only 200 code responses on the default nginx page (index.html). We could also check the nginx version (1.23.3) which is not vulnerable to a known exploit.

So now we could create this little script to obtain new captures with no HTTP traffic (which was on the port 80) to make our wireshark less laggy and get a better view of the traffic.

#!/bin/bash

pcap_files=$(find . -type f -name "*.pcap" -print)

for pcap_file in $pcap_files; do
    new_file="${pcap_file%.*}-filter.pcap"
    tshark -r "$pcap_file" -Y "!(tcp.port == 80)" -w "$new_file"
done

Now, my goal was to make the analysis easier. I checked if there’s a tool which allow merging pcap files by removing the duplicated packets (same timestamp & data) because there are multiples files which captured the same traffic (for example, R1-Gi00 and R2-Gi00)

I found mergecap ! The command is really simple : mergecap -w MERGE-FILTER.pcap PCAP_to_merge_1.pcap PCAP_to_merge_2.pcap ...

$ mergecap -w MERGE-FILTER-no-http.pcap */*filter*
$ ls -lha MERGE-FILTER-no-http.pcap
-rw-rw-r-- 1 itarow itarow 53M avril 29 13:25 MERGE-FILTER-no-http.pcap

Only have 53Mo, that’s a good new. Let’s analyze it.

A cool feature in wireshark is protocol Hierarchy (Statistics Menu), self-explanatory.

Most packets are :

If we follow the principle that the traffic is hidden in a protocol not used much in the network, we could check the ICMP traffic.

There are almost ping requests, but I also found some “Time To Leave exceeded” packets, which act as a rabbit hole for me. If we don’t filter the traffic on port 80, there are many. I thought that It could be a sort of custom ICMP exfiltration using the destination port or the sequence number of the packet. I also watched the timing which could be possible as a type of exfiltration. But those packets were just normal and maybe generated by the abundant requests on the network, especially on the port 80 with the fuzzer.

I also wanted to check the rest of the TCP traffic which was not on port 80, because it’s the most common protocol and an exploit or malicious traffic have a high probability to be on it.

The traffic seems to be interesting, there are TCP data on many commons port (21,443,8888,…) but we can’t see any data transmitted, many TCP errors and communication problem. When seeing this, I thought there was a problem with mergecap or with the multiples pcap files which doesn’t give us the traffic clearly. But after some time, I realized that this traffic is just a port scan (nmap scan or something similar) to make noise on the network.

We eliminate another protocol :).

At this time I started to look at BFD protocol. His role is to detect faults or anomalies between routers/switches. Here after is a good link which explain the protocol : https://networktechstudy.com/home/learning-about-bidirectional-forwarding-detection-bfd. For us, we just need to know that there are Control & Echo packets sent between routers.

During the challenge I filtered this protocol, I was convinced that I needed to find an exploit on the network and I didn’t find things about exploiting BFD protocol, or precedent CTF challenges which talk about it. We will see it was a mistake :/ …

So I started to look at OSPF protocol. OSPF is just a routing protocol used by routers. Looks pretty interesting because it’s a good target for an attacker. They are many topics about OSPF attacks on the internet, so I read some of them (example : https://github.com/lizitong67/OSPF_Attack_and_Detection)

I started to look at routing tables and messages transmitted to see if they weren’t a router or a switch which was compromised and used by the attacker to modify the routing tables of the other ones. Spoiler: Found nothing :( It was hard to understand the attacks, and also, how could I find a path to a flag with it ..

The other interesting protocol is ARP, used to associate an IP address and a mac address. We could try to observe a known attack called ARP spoofing.

Nothing on this side, just classical ARP requests and responses.

At this moment I was desperate x). I just had no idea what I’ve missed and what do I need to find. So I just kept scrolling on the pcap files, trying to play with filters and mergecap to obtain a new view of the traffic.

Conversations analysis

During my searches, I used the conversations menu in wireshark to see which IPs communicate each other, how many packets they exchanged, etc…

My mistake which wasted me sometimes was to not do it on the merged pcap with no filter, because It makes my wireshark very laggy and slow. So I just observed conversations of other pcap files and filtered pcap, which made me lose the information to see.

Here is the result of conversation menu in the merged pcap with no filters :

There are 179 different IPs, and two of them are impostors :) It is necessary to look precisely, but there are two IPs, 172.16.1.5 and 172.16.3.5 which are not in the network core.

If we take our precedent words :

We don’t have captures from the externals networks (172.16.X.0/24)

But here, we have two IPs which are external of the core network because they are in .5.

Let’s filter them in wireshark to see what is the traffic between them.

It’s BFD Control protocol ! (the one that I thought useless) only from 172.16.1.5 to 172.16.3.5.

And we could also see something very interesting in the packet, in the BFD checksum field, the JPEG header bytes !

So we know we have it, it’s an exfiltration of an image in the network using the BFD protocol.

Get this flag

Now I thought with one tshark command this could be done. I merged the pcap from the R1 router, to be sure to catch all the traffic from the 172.16.1.5.

The command extract every bfd checksum with tshark, remove the \n and convert the hex to bytes.

$ mergecap -w MERGE_R1.pcap r1_gi00.pcap r1_gi01.pcap r1_gi02.pcap
$ tshark -r MERGE_R1.pcap  -Y "ip.dst == 172.16.3.5 && bfd.checksum" -T fields -e bfd.checksum | tr -d "\n" | xxd -r -p > TEST

So close of the flag x). We could even see the top of the meme.

I struggled a little bit on this part, with making a script with pyshark, to do the same thing, but have a similar result, I knew there was something wrong.

I thought it was a problem with mergecap which merging badly the pcap files and keep duplicate data, but It wasn’t this problem.

So I started to examine the BFD data in each capture, r1_gi00,r1_gi01,r1_gi02. The data was mixed but always in a time crescent, but I was not totally sure of this.

A few minutes after, I was wondering if there weren’t an indicator of the packet number, in the BFD messages, which could allow us to sort the packets in the good order. And there’s one, “Sequence Number” !

You can see it on this wireshark screenshot.

Now we just need to sort the packets by their sequence number and remove the duplicate.

With the help of chat GPT we could quickly make a python script to do this with the library pyshark :

import pyshark

filter_criteria = "ip.src == 172.16.1.5 && ip.dst == 172.16.3.5 && bfd"

capture_files = ["r1_gi00-filter.pcap", "r1_gi01-filter.pcap", "r1_gi02-filter.pcap"]
checksums = {}
for file in capture_files:
    cap = pyshark.FileCapture(file, display_filter=filter_criteria)
    for packet in cap:
        #print(dir(packet.bfd))
        seq_num = int(packet.bfd.auth_seq_num,16)
        checksum = packet.bfd.checksum
        if seq_num not in checksums:
            checksums[seq_num] = checksum

sorted_keys = sorted(checksums.keys())

for key in sorted_keys:
    seq_num = key
    checksum = checksums[key]
    #print(f"Sequence number : {hex(seq_num)}   Checksum : {checksum}")
    print(f"{checksum.replace(':','')}")

Run it :

python3 ../script.py | tr -d "\n" | xxd -r -p > FLAGZ.jpg

And get it :

Flag : FCSC{D2EDDAB260D333F74E2C6DD973561498}

Conclusion

It was difficult to sort this amount of data and challenging ! It helped me to step up in pcap investigation. It will remind me the importance of statistics in pcap files.