Information#
CTF#
- Name : Hexpresso FIC CTF 2020 Prequalification Round
- Website : ctf.hexpresso.fr
- Type : Online
- Format : Jeopardy
Step 1#
Let's see the source CTRL+U, there is a script:
1 | const play = () => { |
Solution by Shrewk to decode the previous encoding:
1 | var u_u = "CTF.By.HexpressoCTF.By.Hexpresso"; |
So the link for the next step is:
https://ctf.hexpresso.fr/1f1bd383026a5db8145258efb869c48f
.
Step 2#
https://ctf.hexpresso.fr/1f1bd383026a5db8145258efb869c48f
Old EXFIL but Gold#
Nous soupçonnons une exfiltration de données. Nous avons capturé des données réseaux, à vous d'extraire le lien pour la prochaine étape !
Open the pcap with Wireshark, it seems like a DNS exfiltration/tunneling. Let's look at my WU inception challenge during hxp CTF 2017. Let's read again the SANS whitepaper Detecting DNS Tunneling.
But here we don't need to find which tool was used for the DNS exfiltration
because in frame n°4, which is a HTTP GET on /index.html
we can see the
following content:
1 |
|
It's a directory listing and there are some files of interest:
0days/
(folder)plan de domination du monde
(troll)dnstunnel.py
which must be the DNS tunneling tool usedsshdRCE_preauth.c
let's see later if it is useful or not
Then there is another HTTP GET for retrieving dnstunnel.py
:
1 | #! /usr/bin/python3 |
There is some redundancy, so we must remove it before decoding.
1 | redundancy = random.randint(2,16) |
Also the key is only 2 hexadecimal character long (because a decimal between 13 and 254 is chosen), and that will be the 2 first characters of each chunk.
1 | key = random.randint(13,254) |
Also once deciphered the 4 first chars of the message should be the sequence id of the message so we must be able to put them back in the right order.
1 | chunk = "%04d%s"%(s,chunk) |
Let's use tshark to extract the data:
tshark -r capture.pcap -Y 'ip.dst == 172.16.42.222 && dns' -T fields -e 'dns.qry.name'
ip.dst == 172.16.42.222
filter with the destination IPdns
filter to keep only DNS traffic (we should have only A queries)-T fields -e 'dns.qry.name'
Display only the DNS query name field| tr "\n" ','
replace newlines with a space to get a computable list
1 | $ tshark -r capture.pcap -Y 'ip.dst == 172.16.42.222 && dns' -T fields -e 'dns.qry.name' | tr "\n" ' ' |
Let's decode that with a ruby script:
1 |
|
We can see a message like the following, the problem now is the redundancy.
1 | {0=>"Congratulations!! Y", |
To see the range of redundancy we have let's replace the previous display with:
1 | # See redundancy ranges |
We have the following:
1 | 0-19 |
The easiest way is to store each char in an array or a hash and then remove duplicates.
Let's change our display with
1 | all_chars = {} |
Now we have this output:
1 | Congratulations!! You did it so far! |
So the link to step 3 is:
1 | $ printf %s 'NB2HI4DTHIXS6Y3UMYXGQZLYOBZGK43TN4XGM4RPGU3TSODDME2DOZDBMNSTKYZVMU3GIMZVGI4TMOJQMM4DMMZTG42QU===' | base32 -d |