Our SOC team detected suspicious activity in Network Traffic, the machine has been compromised and company information that should not have been there has now been stolen – it’s up to you to figure out what has happened and what data has been taken.
A host in the capture fetched a PE DLL over plain HTTP from an external server, which started the compromise. The DLL is Pikabot, a loader that then spoke HTTPS to several hosts on non-standard ports, each presenting a self-signed certificate. Afterwards the host generated thousands of DNS queries for random-looking subdomains of a single domain, which is a DNS tunnel and the likely route for the data theft the scenario describes. The whole chain is readable from one packet capture, with VirusTotal supplying the malware family and first-seen date.
evidence/capture.pcap → read with tshark. Single network capture covering the download, the TLS sessions and the DNS trafficTimestamp note: Task formats ask for UTC,
YYYY-MM-DD HH:MM:SS. The certificatenotBeforevalue is already UTC in the cert; for the first-seen date, see Q4.
Start with the TCP conversation table to see who the internal host talks to, then list HTTP requests. A single GET for an odd path stands out among the traffic, and the server answering it is the delivery host. Stream 1 carries the download.
tshark -r evidence/capture.pcap -q -z conv,tcp
tshark -r evidence/capture.pcap -Y http.request -T fields -e ip.dst -e http.request.full_uri
The response body on the Q1 stream is a PE DLL. Carve it out of the capture and hash it. HTTP object export is the obvious route, but it only recovered a fragment here, so reassemble the TCP stream from the raw follow output and hash that file instead.
tshark -r evidence/capture.pcap -q -z follow,tcp,raw,1
sha256sum work/stream.bin
Gotcha:
--export-objects httpwrote a DLL of only 1160 bytes, so its hash is wrong. Rebuild the body from the full stream (strip the HTTP headers) before hashing.
Look the Q2 hash up on VirusTotal. The popular threat label on the file report gives the family. The format mask (P*******) matches it.
On the same VirusTotal report, the “first seen in the wild” attribute is a different field from the first submission. Read the in-the-wild value, which is an epoch (1684504881), and convert it to UTC.
date -u -d @1684504881 '+%Y-%m-%d %H:%M:%S'
Gotcha: VirusTotal’s first submission (2023-05-17 19:04:23) is the more commonly used “first seen” and it was rejected here. This task wants the in-the-wild date.
Pull every certificate sent in a TLS handshake (tls.handshake.type == 11) with its issuer and subject. A self-signed certificate has identical issuer and subject. Three non-standard server ports present such certificates; list them in ascending order.
tshark -r evidence/capture.pcap -Y tls.handshake.type==11 -T fields -e ip.src -e tcp.srcport -e x509sat.printableString
The first malicious IP in the TLS list is 45.85.235.39, serving on port 2078 (from Q5). Dump that handshake in full with -V and read the localityName attribute inside the subject.
tshark -r evidence/capture.pcap -Y 'tls.handshake.type==11 && ip.src==45.85.235.39' -V
Same certificate as Q6. The validity block in the -V output holds notBefore, already in UTC.
tshark -r evidence/capture.pcap -Y 'tls.handshake.type==11 && ip.src==45.85.235.39' -V | grep -A3 -i validity
Count DNS query names across the capture. One parent domain accounts for over 7,000 queries, all to unique-looking subdomains under dns., which is the signature of data encoded into labels. This was identified from query volume and pattern rather than by decoding the payloads, so it is a reasoned conclusion that HTB accepted.
tshark -r evidence/capture.pcap -Y dns.flags.response==0 -T fields -e dns.qry.name | awk -F. '{print $(NF-1)"."$NF}' | sort | uniq -c | sort -rn | head
| Phase | Action |
|---|---|
| Initial Access | Host downloads a PE DLL over HTTP from 162.252.172.54 |
| Execution | The DLL is identified as Pikabot |
| Command and Control | HTTPS sessions to hosts on ports 2078, 2222 and 32999 with self-signed certificates |
| Exfiltration | Thousands of DNS queries to subdomains of one domain, used as a tunnel |
| Type | Value |
|---|---|
| IP (payload delivery) | 162.252.172[.]54 |
| IP (C2, port 2078) | 45.85.235[.]39 |
| C2 ports | 2078, 2222, 32999 |
| SHA256 (Pikabot DLL) | 9b8ffdc8ba2b2caa485cca56a82b2dcbd251f65fb30bc88f0ac3da6704e4d3c6 |
| Domain (DNS tunnel) | steasteel[.]net |
| Technique | ID | Description |
|---|---|---|
| Ingress Tool Transfer | T1105 | Pikabot DLL fetched over HTTP |
| Application Layer Protocol: Web Protocols | T1071.001 | HTTPS command and control |
| Encrypted Channel: Asymmetric Cryptography | T1573.002 | TLS sessions with self-signed certificates |
| Application Layer Protocol: DNS | T1071.004 | Tunnel through subdomains of one domain |
| Exfiltration Over Alternative Protocol: Unencrypted Non-C2 Protocol | T1048.003 | Data carried in DNS queries |
Plain HTTP delivery of a PE file is detectable on the wire. A client pulling a DLL from an unknown external IP by a bare path is visible in proxy and IDS logs. Block or alert on executable content types and MZ headers served over HTTP from uncategorised hosts.
Self-signed certificates on high ports are a cheap C2 signal. Three servers on 2078, 2222 and 32999 presented self-signed certs with odd subject values. Alert on TLS to non-standard ports where issuer equals subject, and log certificate fields with Zeek or similar.
DNS volume per parent domain exposes tunneling. Over 7,000 queries to unique subdomains of one domain stands out against normal resolver traffic. Rank queries by registered domain, watch label length and entropy, and force clients through a resolver that can block newly seen domains.
Do not trust a single extraction method for payload hashing. Object export truncated the DLL and gave a wrong hash. Reassemble the stream and confirm the file is a valid PE before submitting or pivoting on its hash.
A Pikabot DLL pulled over HTTP became self-signed TLS C2 and then a DNS tunnel out. Each stage used a different protocol, so only network-level visibility across HTTP, TLS and DNS ties the chain together.