Post

TryHackMe (TShark) - Writeup

A writeup for TryHackMe’s Tshark room.

Reading PCAP Files

For this task, we were given a PCAP file called dns_1617454996618.cap

Question: How many packets are in the dns.cap file?

Flag: 38

To analyze the PCAP file, we can use the -r option of tshark. This allows us to see all the packets of the PCAP file. To get the flag, simply look at the last packet’s index.

1
2
3
4
5
6
7
8
9
10
11
$ tshark -r dns_1617454996618.cap | tail
   29 271.262407 192.168.170.20 → 192.168.170.8 DNS 166 Standard query response 0x208a NS isc.org NS ns-ext.nrt1.isc.org NS ns-ext.sth1.isc.org NS ns-ext.isc.org NS ns-ext.lga1.isc.org
   30 271.279695  217.13.4.24 → 192.168.170.56 DNS 129 Standard query response 0x326e No such name SRV _ldap._tcp.Default-First-Site-Name._sites.dc._msdcs.utelsystems.local
   31 271.280350 192.168.170.56 → 217.13.4.24  DNS 98 Standard query 0xf161 SRV _ldap._tcp.dc._msdcs.utelsystems.local
   32 271.297651  217.13.4.24 → 192.168.170.56 DNS 98 Standard query response 0xf161 No such name SRV _ldap._tcp.dc._msdcs.utelsystems.local
   33 271.298194 192.168.170.56 → 217.13.4.24  DNS 140 Standard query 0x8361 SRV _ldap._tcp.05b5292b-34b8-4fb7-85a3-8beef5fd2069.domains._msdcs.utelsystems.local
   34 271.317878  217.13.4.24 → 192.168.170.56 DNS 140 Standard query response 0x8361 No such name SRV _ldap._tcp.05b5292b-34b8-4fb7-85a3-8beef5fd2069.domains._msdcs.utelsystems.local
   35 271.419659 192.168.170.56 → 217.13.4.24  DNS 83 Standard query 0xd060 A GRIMM.utelsystems.local
   36 271.436583  217.13.4.24 → 192.168.170.56 DNS 83 Standard query response 0xd060 No such name A GRIMM.utelsystems.local
   37 278.861300 192.168.170.56 → 217.13.4.24  DNS 83 Standard query 0x7663 A GRIMM.utelsystems.local
   38 278.879313  217.13.4.24 → 192.168.170.56 DNS 83 Standard query response 0x7663 No such name A GRIMM.utelsystems.local
Question: How many A records are in the capture? (Including responses)

Flag: 6

To get all the A records, we can set the display filter to dns.qry.type == 8 using -Y option. We can also make things easier by piping the output to the wc command to count all the lines. To learn more about DNS types, click here

1
2
3
4
5
6
7
8
9
$ tshark -r dns_1617454996618.cap -Y "dns.qry.type == 1"
    9  92.189905 192.168.170.8 → 192.168.170.20 DNS 74 Standard query 0x75c0 A www.netbsd.org
   10  92.238816 192.168.170.20 → 192.168.170.8 DNS 90 Standard query response 0x75c0 A www.netbsd.org A 204.152.190.12
   35 271.419659 192.168.170.56 → 217.13.4.24  DNS 83 Standard query 0xd060 A GRIMM.utelsystems.local
   36 271.436583  217.13.4.24 → 192.168.170.56 DNS 83 Standard query response 0xd060 No such name A GRIMM.utelsystems.local
   37 278.861300 192.168.170.56 → 217.13.4.24  DNS 83 Standard query 0x7663 A GRIMM.utelsystems.local
   38 278.879313  217.13.4.24 → 192.168.170.56 DNS 83 Standard query response 0x7663 No such name A GRIMM.utelsystems.local
$ tshark -r dns_1617454996618.cap -Y "dns.qry.type == 1" | wc -l
6
Question: Which A record was present the most?

Flag: GRIMM.utelsystems.local

To get which record was present the most, we can append -T fields -e dns.qry.name to get the names of the DNS. We can also pipe the output to sort and uniq commands to count each name’s occurrences.

1
2
3
4
5
6
7
8
9
10
$ tshark -r dns_1617454996618.cap -Y "dns.qry.type == 1" -T fields -e dns.qry.name
www.netbsd.org
www.netbsd.org
GRIMM.utelsystems.local
GRIMM.utelsystems.local
GRIMM.utelsystems.local
GRIMM.utelsystems.local
$ tshark -r dns_1617454996618.cap -Y "dns.qry.type == 1" -T fields -e dns.qry.name | sort | uniq -c
      4 GRIMM.utelsystems.local
      2 www.netbsd.org

DNS Exfil

For this task, we were given a PCAP file called dns_exfil_1617459299197.PCAP

Question: How many packets are in this capture?

Flag: 125

Just like we did before, we can use the -r option to read the PCAP file.

1
2
3
4
5
6
7
8
9
10
11
$ tshark -r dns_exfil_1617459299197.PCAP | tail
  116   7.245048  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A G.m4lwhere.org
  117   7.263699 192.168.1.200 → 192.168.1.8  DNS 90 Standard query response 0xbeef A G.m4lwhere.org A 52.207.163.69
  118   7.373057  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A W.m4lwhere.org
  119   7.391566 192.168.1.200 → 192.168.1.8  DNS 90 Standard query response 0xbeef A W.m4lwhere.org A 52.207.163.69
  120   7.530259  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A I.m4lwhere.org
  121   7.549069 192.168.1.200 → 192.168.1.8  DNS 90 Standard query response 0xbeef A I.m4lwhere.org A 52.207.163.69
  122   7.681131  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A L.m4lwhere.org
  123   7.760756 192.168.1.200 → 192.168.1.8  DNS 90 Standard query response 0xbeef A L.m4lwhere.org A 52.207.163.69
  124   7.810871  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A 5.m4lwhere.org
  125   7.829560 192.168.1.200 → 192.168.1.8  DNS 90 Standard query response 0xbeef A 5.m4lwhere.org A 52.207.163.69
Question: How many DNS queries are in this PCAP? (Not responses!)

Flag: 56

Before we search how many queries there are, first we need to find the right filter. After searching the web, I found out that the way to do this is by using the -G option of the tshark. This will cause tshark to dump all available fields. We can also filter the output by piping it to grep.

1
2
3
4
5
6
7
8
9
10
11
$ tshark -G | grep dns | grep response | head
F       Length dns.length     FT_UINT16 dns     BASE_DEC    0x0 Length of DNS-over-TCP request or response
F       Response dns.flags.response     FT_BOOLEAN   dns    16 0x8000   Is the message a response?
F       Conflict dns.flags.conflict     FT_BOOLEAN   dns    16 0x400    Did we receive multiple responses to a query?
F       Response In     dns.response_in FT_FRAMENUM  dns     0x0        The response to this DNS query is in this frame
F       Request In      dns.response_to FT_FRAMENUM  dns     0x0        This is a response to the DNS query in this frame
F       Retransmitted response. Original response in dns.retransmit_response_in FT_FRAMENUM     dns             0x0     This is a retransmitted DNS response
F       Unsolicited     dns.unsolicited FT_BOOLEAN   dns    0 0x0       This is an unsolicited response
F       DNS response retransmission     dns.retransmit_response FT_NONE dns             0x0
F       DNS response(s) cflow.pie.ntop.dns_response  FT_STRING cflow            0x0
F       DnsResponseCode cflow.pie.gigamon.dnsresponsecode   FT_UINT8    cflow   BASE_DEC        0x0

Now we can use the dns.flags.response as a display filter.

1
2
3
4
5
6
7
8
9
10
11
$ tshark -r dns_exfil_1617459299197.PCAP -Y "dns.flags.response == 0" | head
    1   0.000000  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A M.m4lwhere.org
    4   0.137203  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A Z.m4lwhere.org
    7   0.278367  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A W.m4lwhere.org
   10   0.411408  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A G.m4lwhere.org
   13   0.546370  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A C.m4lwhere.org
   16   0.685319  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A Z.m4lwhere.org
   19   0.836122  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A 3.m4lwhere.org
   20   0.961352  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A 3.m4lwhere.org
   24   1.105976  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A O.m4lwhere.org
   26   1.263586  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A R.m4lwhere.org

After verifying that we have the right output. We can now count the packets.

1
2
$ tshark -r dns_exfil_1617459299197.PCAP -Y "dns.flags.response == 0" | wc -l
56
Question: What is the DNS transaction ID of the suspicious queries (in hex)?

Flag: 0xbeef

Doing what we did above, we can find the appropriate field for this.

1
2
3
4
$ tshark -G | grep dns | grep transaction
F       Transaction ID  dns.id  FT_UINT16       dns  BASE_HEX 0x0       Identification of transaction
F       DNS query transaction Id        cflow.pie.ntop.dns_query_id     FT_UINT16       cflow   BASE_DEC        0x0
F       DNS Transaction Id    cflow.pie.ixia.dns-transaction-id FT_UINT16       cflow   BASE_HEX        0x0     DNS Transaction Identifier

We can then use this field to get the flag

1
2
$ tshark -r dns_exfil_1617459299197.PCAP -T fields -e dns.id | uniq
0xbeef
Question: What is the string extracted from the DNS queries?

Flag: MZWGCZ33ORUDC427NFZV65BQOVTWQX3XNF2GQMDVG5PXI43IGRZGWIL5

Remember how we used to filter all the DNS queries? We need to do it again to get the flag. Notice that after filtering all the DNS queries, we can see that each entry has a different subdomain.

1
2
3
4
5
6
7
8
9
10
11
$ tshark -r dns_exfil_1617459299197.PCAP -Y "dns.flags.response == 0" | head
    1   0.000000  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A M.m4lwhere.org
    4   0.137203  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A Z.m4lwhere.org
    7   0.278367  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A W.m4lwhere.org
   10   0.411408  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A G.m4lwhere.org
   13   0.546370  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A C.m4lwhere.org
   16   0.685319  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A Z.m4lwhere.org
   19   0.836122  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A 3.m4lwhere.org
   20   0.961352  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A 3.m4lwhere.org
   24   1.105976  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A O.m4lwhere.org
   26   1.263586  192.168.1.8 → 192.168.1.200 DNS 74 Standard query 0xbeef A R.m4lwhere.org

This is my favorite part! Using the standard GNU tools, we can manipulate the output to get the flag.

rev - Reverses each line of text.

1
2
3
4
5
6
7
8
9
10
11
$ tshark -r dns_exfil_1617459299197.PCAP -Y "dns.flags.response == 0" | rev | head
gro.erehwl4m.M A feebx0 yreuq dradnatS 47 SND 002.1.861.291 → 8.1.861.291  000000.0   1
gro.erehwl4m.Z A feebx0 yreuq dradnatS 47 SND 002.1.861.291 → 8.1.861.291  302731.0   4
gro.erehwl4m.W A feebx0 yreuq dradnatS 47 SND 002.1.861.291 → 8.1.861.291  763872.0   7
gro.erehwl4m.G A feebx0 yreuq dradnatS 47 SND 002.1.861.291 → 8.1.861.291  804114.0   01
gro.erehwl4m.C A feebx0 yreuq dradnatS 47 SND 002.1.861.291 → 8.1.861.291  073645.0   31
gro.erehwl4m.Z A feebx0 yreuq dradnatS 47 SND 002.1.861.291 → 8.1.861.291  913586.0   61
gro.erehwl4m.3 A feebx0 yreuq dradnatS 47 SND 002.1.861.291 → 8.1.861.291  221638.0   91
gro.erehwl4m.3 A feebx0 yreuq dradnatS 47 SND 002.1.861.291 → 8.1.861.291  253169.0   02
gro.erehwl4m.O A feebx0 yreuq dradnatS 47 SND 002.1.861.291 → 8.1.861.291  679501.1   42
gro.erehwl4m.R A feebx0 yreuq dradnatS 47 SND 002.1.861.291 → 8.1.861.291  685362.1   62

cut -d'.' -f3 - Splits the string with a dot as a delimiter then gets the third string in the array.

1
2
3
4
5
6
7
8
9
10
11
$ tshark -r dns_exfil_1617459299197.PCAP -Y "dns.flags.response == 0" | rev | cut -d'.' -f3 | head
M A feebx0 yreuq dradnatS 47 SND 002
Z A feebx0 yreuq dradnatS 47 SND 002
W A feebx0 yreuq dradnatS 47 SND 002
G A feebx0 yreuq dradnatS 47 SND 002
C A feebx0 yreuq dradnatS 47 SND 002
Z A feebx0 yreuq dradnatS 47 SND 002
3 A feebx0 yreuq dradnatS 47 SND 002
3 A feebx0 yreuq dradnatS 47 SND 002
O A feebx0 yreuq dradnatS 47 SND 002
R A feebx0 yreuq dradnatS 47 SND 002

cut -d' ' -f1 - Splits the string with space as a delimiter then gets the first string in the array.

1
2
3
4
5
6
7
8
9
10
11
$ tshark -r dns_exfil_1617459299197.PCAP -Y "dns.flags.response == 0" | rev | cut -d'.' -f3 | cut -d' ' -f1 | head
M
Z
W
G
C
Z
3
3
O
R

tr -d '\n' && echo - Removes newline characters from the output and prints a newline.

1
2
$ tshark -r dns_exfil_1617459299197.PCAP -Y "dns.flags.response == 0" | rev | cut -d'.' -f3 | cut -d' ' -f1 | tr -d '\n' && echo
MZWGCZ33ORUDC427NFZV65BQOVTWQX3XNF2GQMDVG5PXI43IGRZGWIL5
Question: What is the flag?

Flag: flag{th1s_is_t0ugh_with0u7_tsh4rk!}

With my previous experiences playing CTF, I know that the string we got from the previous question is encoded using base32 because it only uses capital letters. We can verify this by piping base32 -d to the previous command, before echoing.

1
2
$ tshark -r dns_exfil_1617459299197.PCAP -Y "dns.flags.response == 0" | rev | cut -d'.' -f3 | cut -d' ' -f1 | tr -d '\n' | base32 -d && echo
flag{th1s_is_t0ugh_with0u7_tsh4rk!}

Or we can just use the magic operation in Cyberchef 1

This post is licensed under CC BY 4.0 by the author.

Trending Tags