# Vault - IJCTF 2021

A robber broke into our vault in the middle of night. There's an indication
that the robber tried to steal some items which are considered as confidential
assets. Could you figure it out?

Flag format: `IJCTF{[a-f0-9]{32}}`

Author: `Avilia#1337`

Hint #1: "When the incident happened, the attacker got into our `IP over ICMP`
tunnel network to access an `HTTP/2` web-server with `SSL` enabled."

Hint #2: "Even so, our captured logs aren't precise enough. Each packet has an
unusual timestamp and it's kinda messy..."

[log.tar.xz](http://www.ijctf.tk/files/f98de00081d25c6c97d40ae157bb4338/log.tar.xz)

## Investigating the packet capture

We are provided with a `log.tar.xz` archive from the challenge description,
which we can decompress using `xz` and `tar` as so:

`$ xz -d log.tar.xz`

`$ tar -xvf log.tar`

This should produce a `log.pcap` file.

Running `strings` against the `.pcap` file, we pipe the output to `sort` and
`uniq` to only display unique entries, then `grep ......` to display only
lines with length greater or equal to 6:

`$ strings log.pcap | sort | uniq | grep ......`

```  
...  
CLIENT_RANDOM  
Compressed: 202  
Extracting archive: flag.zip  
p7zip Version 16.02 (locale=C.UTF-8,Utf16=on,HugeFiles=on,32 bits,1 CPU LE)  
&p/home/pi/projects/ctf  
python3 download.py flag.zip  
python3 download.py pass.txt  
uid=1000(pi) gid=1000(pi)
groups=1000(pi),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),105(input),109(netdev),114(docker),116(lpadmin),997(gpio),998(i2c),999(spi)  
whoami  
xargs -n1 -a sslkeylogfile  
```

We see mentions of files `flag.zip`, `pass.txt`, `download.py`, and
`sslkeylogfile`, as well as commands such as `id`, `python3` and `xargs` being
run.

Opening the packet capture file `log.pcap` in Wireshark, we see a conversation
between `192.168.1.30` and `192.168.1.205` through ICMP (ping), along with
some fragmented IPv4 packets.

1\. From the first hint, we know that the attacker used an IP over ICMP tunnel
network to access an HTTP/2 web server with SSL.  
2\. From the second hint, we also know that the capture logs were imprecise
and the packet timestamps were unusual.

Looking at Wireshark, we notice some of the packets have negative time values.
This should not be possible, packets cannot travel back in time before the
capture started. Also, the frame numbers are all over the place and are not
ordered correctly.

We can fix the packet ordering issue using the `reordercap` tool, which should
come installed with Wireshark:

`$ reordercap log.pcap log_ordered.pcap`

If the reordering was successful, there should be 167 fragmented IPv4 packets
with size of 1514 bytes in the newly created `log_ordered.pcap` file. With the
ordering fixed, we can then start analysing the individual packets.

## Splicing the packet headers

Looking at one of the fragmented IPv4 packets, we see that there is a data
segment with 1480 bytes of data:

![https://i.imgur.com/tYUEddZ.png](https://i.imgur.com/tYUEddZ.png)

At first, the data may look like random bytes. But, if we look carefully, we
can see there is a malformed Ethernet header, followed by an IP header, and
then a TCP header:

![https://i.imgur.com/5FixP4u.png](https://i.imgur.com/5FixP4u.png)

Searching for the bytes in the malformed Ethernet header `00 00 4a e3 f9 24 34
44 68 61 6e 73 07`, we were able to determine the specific application used to
establish the ICMP tunnel, called "Hans"
([https://github.com/friedrich/hans](https://github.com/friedrich/hans/blob/master/src/worker.h)).
This header is inserted by the Hans application. We can also see the `0x07`
byte at the end, which is defined as `TYPE_DATA` in the source code under
`src/worker.h`:

```cpp  
enum Type  
{  
TYPE_RESET_CONNECTION = 1,  
TYPE_CONNECTION_REQUEST = 2,  
TYPE_CHALLENGE = 3,  
TYPE_CHALLENGE_RESPONSE = 4,  
TYPE_CONNECTION_ACCEPT = 5,  
TYPE_CHALLENGE_ERROR = 6,  
TYPE_DATA = 7,  
TYPE_POLL = 8,  
TYPE_SERVER_FULL = 9  
};  
```

We know the TCP data inside of the ICMP data has to contain the TLS traffic
which the attacker used to exfiltrate data, or the handshakes associated with
them. If we can somehow restore the original TLS packets, then there is a
possibility where we can extract the session keys and use them to decrypt the
rest of the packets.

This can be achieved by transplanting the Ethernet header from the ICMP packet
to the ICMP data segment, and removing the magic/type header inserted by Hans.
In fact, we can simplify it to only one cut operation by removing the TCP
header and the Hans header altogether.

Using the `editcap` tool and following the documentation
[here](https://www.wireshark.org/docs/man-pages/editcap.html), we cut away 33
bytes (20 bytes from TCP header of ICMP + 13 bytes from Hans) starting from
offset byte 15 (after 14 bytes from Ethernet header of ICMP) for each packet,
then export the packets into a `log_chopped.pcap` file:

`$ editcap -C 15:33 log_ordered.pcap log_chopped.pcap`

Opening `log_chopped.pcap` file in Wireshark, we see the ICMP packets have now
changed into either TCP or Socks packets, the source/destination address and
ports have also changed. This is likely because the attacker used a Socks
proxy when attacking our victim. To combat this and allow Wireshark to read
the traffic properly as TLS, we can add an entry to the "Decode As" list under
the "Analyze" tab, pointing port 1080 to TLS:

![https://i.imgur.com/XYZz0Xq.png](https://i.imgur.com/XYZz0Xq.png)

This basically tells Wireshark to treat all traffic on TCP port 1080 as TLS,
and not as Socks.

## Extracting the TLS session keys

Earlier, when we did `strings` on the `log.pcap` file, we noticed that the
attacker ran `xargs -n1 -a sslkeylogfile` on the victim's system, which would
effectively print the contents of `sslkeylogfile` to the output stream. We
should be able to follow this output as it is not protected by TLS, and
recover the TLS session keys.

From the [Mozilla NSS key log
documentations](https://developer.mozilla.org/en-
US/docs/Mozilla/Projects/NSS/Key_Log_Format), we know the `sslkeylogfile`
follows a format of `<Label> <space> <ClientRandom> <space> <Secret>`.
`ClientRandom` is encoded as 64 hexadecimal characters, and `Secret` is
encoded as 96 hexadecimal characters (for TLS 1.0-2). For example, a key may
look like this:

```  
CLIENT_RANDOM cf6b8752f4b47c9c28b07ba7da366f98afcc335931f08df83c30ebe2c7bcce32
a832cf19fa6b414fce74fa796b39d898c0825991547eebd20abe951ad2c586490d2703e4f596de3b6b4be417a2caa250  
```

In `log_chopped.pcap`, we use Wireshark's search feature to look for the
string `CLIENT_RANDOM` in the packet bytes. Select any packet from the search
result and follow the TCP stream by right-clicking on it then clicking `Follow
-> TCP Stream`. This should open a new window showing the entire stream as
ASCII:

![https://i.imgur.com/txTocC4.png](https://i.imgur.com/txTocC4.png)

From here, it is trivial to extract the contents of `sslkeylogfile`. We can
simply copy all lines containing the session keys starting from
`CLIENT_RANDOM` and paste them into a file named `sslkeylogfile.txt`.

Though, we're not done quite yet. Since the attacker used `xargs -n1` to
display each argument into separate lines, the format of our keys is going to
be incorrect. We need to replace the line characters `\n` between
`ClientRandom` and `Secret` into space characters, and this can be done using
`paste` as so:

`$ paste -d" " - - - < sslkeylogfile.txt > sslkeylogfile`

The `sslkeylogfile` should now contain 166 keys, as seen here:

`$ wc sslkeylogfile && md5sum sslkeylogfile`

```  
166 498 29216 sslkeylogfile  
9776acd3c0499be64e9653cb27f30720 sslkeylogfile  
```

With the session keys extracted, we can then decrypt the packets.

## Injecting secrets and decrypting TLS traffic

There are two ways we can approach the decryption:

1\. Use Wireshark's built-in support for master secret log files for TLS under
`Preferences -> Protocol -> TLS -> (Pre)-Master-Secret log filename`, select
the `sslkeylogfile` we just extracted, and the packets will be automatically
decrypted by Wireshark in the GUI.  
2\. Use `editcap` to inject the secret to the `.pcap` file, as so:

`$ editcap --inject-secrets tls,sslkeylogfile log_chopped.pcap
log_decrypted.pcap`

Either methods will allow us to read the contents of the packets, but the
`editcap` approach will allow us to use command-line tools later to recover
the files more easily. If you want to hand transcribe hexadecimals later on,
then choose method 1. ;)

## Recovering flag.zip and pass.txt

Looking at the HTTP/2 packets in `log_decrypted.pcap` with filter `http2`, we
see there are GET requests to `/files/flag.zip` and `/files/pass.txt`:

![https://i.imgur.com/N9bZFyg.png](https://i.imgur.com/N9bZFyg.png)

Alongside the `HEADERS` and `Magic` packets, we also see many `DATA` packets.
Inspecting them further with Wireshark, we see that each of the `DATA` packet
has a status of `206 Partial Content`, they each carry either 1 or 2 bytes of
data depending on if the `Content-Type` header is `text/plain` or
`application/zip`, and nearly all of them have an unusual header `Content-
Range`.

![https://i.imgur.com/YmYfG18.png](https://i.imgur.com/YmYfG18.png)

In essence, what's happening here - is that the attacker is gradually sending
either 1 or 2 bytes of data through HTTP/2. The bytes are ordered by the
`Content-Range` header. For example, `bytes 22-23/202` would mean the data in
the packet belongs in byte locations 22 to 23, out of 202 bytes. This implies,
in order for us to recover the two files, we need to piece together the
individual bytes of data from all of the `DATA` packets according to the
`Content-Range` header.

It is possible to recover the files by hand transcribing the hexadecimals from
all 166 packets (if you're up for the task). Fortunately, there is a tool that
can help us with this. We can use `tshark`, which is a packet analysis tool
much like Wireshark, but it is capable of quickly exporting the packets' range
and data as columns in the command-line, allowing us to easily recover the
bytes.

`$ tshark -r log_decrypted.pcap -Y "http2" -T fields -e http2.headers.range -e http2.data.data | xargs -n2 > bytes.txt`

Here, we first take `log_decrypted.pcap` as the input file (`-r`), using
`http2` as the display filter (`-Y`), and printing the fields (`-T`) of
`http2.headers.range` and `http2.data.data` (`-e`). We also pipe the output to
`xargs -n2` to make each packet display neatly on one line instead of two, and
finally output it to a `bytes.txt` file. The file should look something like
this:

```  
bytes=53-53 31  
bytes=34-34 32  
bytes=27-27 39  
bytes=52-52 36  
bytes=55-55 66  
...  
```

We have the hexadecimal bytes of `flag.zip` and `pass.txt`, but the bytes are
mixed together in one file and we want to separate them. To do this, we can
pass it through a few more filters:

`$ cat bytes.txt | awk 'length($2)==2 {print $0}' | cut -d"=" -f2 | sort -n`

This reads the contents of `bytes.txt`, and prints the line if the byte column
has a length of 2. Then removes the "bytes=" string before the range, and
sorts the values numerically. The result should be the hexadecimal bytes of
`pass.txt` in order of the range, and will look something like this:

```  
0-0 30  
1-1 65  
2-2 64  
3-3 62  
4-4 63  
...  
```

We can verify that no bytes are missing from the output, and that all bytes
are in the correct order.

Now, we just have to remove the range column and we will get the password's
hex:

`$ cat bytes.txt | awk 'length($2)==2 {print $0}' | cut -d"=" -f2 | sort -n | cut -d" " -f2 > pass.hex`

To convert it from hexadecimal to bytes, we can use `xxd`:

`$ xxd -r -p pass.hex > pass.txt`

Now repeat the process for `flag.zip`, but this time using `length($2)==4`
instead. We can also skip the intermediate hex file as so:

`$ cat bytes.txt | awk 'length($2)==4 {print $0}' | cut -d"=" -f2 | sort -n | cut -d" " -f2 | xxd -r -p > flag.zip`

## Getting the flag

Now all that's left to do is decompress `flag.zip` using `pass.txt` and get
the flag!

`$ unzip flag.zip`

```  
Archive: flag.zip  
[flag.zip] flag.txt password:
0edbca2531daefac9c5c84c016792713fd23681ea8bc1b3d088b617f75940313  
extracting: flag.txt  
```

`$ cat flag.txt`

```  
IJCTF{aa51f2cc8eaf466a277da70db3a3c576}  
```

## Resources

1\. friedrich/hans: IP over ICMP -
[https://github.com/friedrich/hans](https://github.com/friedrich/hans)  
2\. editcap - The Wireshark Network Analyzer 3.4.7 -
[https://www.wireshark.org/docs/man-
pages/editcap.html](https://www.wireshark.org/docs/man-pages/editcap.html)  
3\. NSS Key Log Format - Mozilla | MDN - [https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format)  
4\. Wireshark Tutorial: Decrypting HTTPS Traffic -
[https://unit42.paloaltonetworks.com/wireshark-tutorial-decrypting-https-
traffic/](https://unit42.paloaltonetworks.com/wireshark-tutorial-decrypting-
https-traffic/)  
5\. Decrypting TLS Streams With Wireshark: Part 1 -
[https://blog.didierstevens.com/2020/12/14/decrypting-tls-streams-with-
wireshark-part-1/](https://blog.didierstevens.com/2020/12/14/decrypting-tls-
streams-with-wireshark-part-1/)  
6\. tshark - The Wireshark Network Analyzer 3.4.7 -
[https://www.wireshark.org/docs/man-
pages/tshark.html](https://www.wireshark.org/docs/man-pages/tshark.html)

Original writeup (https://blog.adelaideb9.com/ctf/write-ups/2021-07-26-vault-
ijctf-2021).# IJCTF 2020 - vault

## Description  
>We locked our secret box, You can directly ping the bot (@Vault #8895 ) using
"start" to get the secret but we don't know the door code we used random()
also we used sleep(10).  
shift register...

Author : `Harsh` and `warlock_rootx`

**Hint**  
* if pin in user_input():

## Solution

We started to talk with the discord bot (```start```):  
Time to test your lock picking skills

```  
I AM

_ _ _ _ _ _ _

LOCKED

[ 0 ] [ 1 ]  
```  
We guessed that the vault password was seven character long and contained only
0 and 1.

After some random test we realized that some times a password was accepted
(and we were prompted with the next phase of the lock picking) and other times
it was wrong.

We understood (Hint) that the password had to be a substring of the text we
submitted.  
Discord limit the length of a message by 2000 character, too little to list
all the possibilities of the pin with lenghts of seven in binary.  
Luckily we knew the [De Brujin
sequence](https://en.wikipedia.org/wiki/De_Bruijn_sequence).  
We generated all the string for the various lock picking test.

Time to test your lock picking skills  
```  
I AM

_ _ _ _ _ _ _

LOCKED

[ 0 ] [ 1 ]  
```  
>00000001000001100001010000111000100100010110001101000111100100110010101001011100110110011101001111101010110101111011011101111111000000

First lock opened! Hurry up and open the next one before the gaurds show up  
```  
I AM

_ _ _ _ _ _

LOCKED

[ 4 ] [ 5 ] [ 6 ]  
```  
>44444454444464444554444564444654444664445454445464445554445564445654445664446454446464446554446564446654446664454454464454554454564454654454664455454455464455554455564455654455664456454456464456554456564456654456664464464554464564464654464664465454465464465554465564465654465664466454466464466554466564466654466664545454645455545455645456545456645464645465545465645466545466645545545645546545546645554645555545555645556545556645564645565545565645566545566645645646545646645654645655545655645656545656645664645665545665645666545666646464655464656464665464666465465466465555465556465565465566465655465656465665465666466466555466556466565466566466655466656466665466666555555655556655565655566655655656655665655666656565666566566666644444

Second Lock Opened! Dang your a professional. Third lock now...  
```  
I AM

_ _ _ _

LOCKED

[ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ]  
```  
>5555655575558555955665567556855695576557755785579558655875588558955965597559855995656575658565956665667566856695676567756785679568656875688568956965697569856995757585759576657675768576957765777577857795786578757885789579657975798579958585958665867586858695876587758785879588658875888588958965897589858995959665967596859695976597759785979598659875988598959965997599859996666766686669667766786679668766886689669766986699676768676967776778677967876788678967976798679968686968776878687968876888688968976898689969697769786979698769886989699769986999777787779778877897798779978787978887889789878997979887989799879998888988998989999555

Third lock open, now you have to be fast.  
```  
I AM

_ _ _ _ _

LOCKED

[ 1 ] [ 2 ] [ 3 ] [ 4 ]  
```  
>11111211113111141112211123111241113211133111341114211143111441121211213112141122211223112241123211233112341124211243112441131211313113141132211323113241133211333113341134211343113441141211413114141142211423114241143211433114341144211443114441212212123121241213212133121341214212143121441221312214122221222312224122321223312234122421224312244123131231412322123231232412332123331233412342123431234412413124141242212423124241243212433124341244212443124441313213133131341314213143131441321413222132231322413232132331323413242132431324413314133221332313324133321333313334133421334313344134141342213423134241343213433134341344213443134441414214143141441422214223142241423214233142341424214243142441432214323143241433214333143341434214343143441442214423144241443214433144341444214443144442222232222422233222342224322244223232232422333223342234322344224232242422433224342244322444232332323423243232442332423333233342334323344234242343323434234432344424243242442433324334243432434424433244342444324444333334333443343433444343443444441111

Fourth lock open. Come on just two more...  
```  
I AM

_ _ _ _

LOCKED

[ 0 ] [ 1 ] [ 2 ] [ 5 ] [ 8 ] [ 9 ]  
```  
>000010002000500080009001100120015001800190021002200250028002900510052005500580059008100820085008800890091009200950098009901010201050108010901110112011501180119012101220125012801290151015201550158015901810182018501880189019101920195019801990202050208020902110212021502180219022102220225022802290251025202550258025902810282028502880289029102920295029802990505080509051105120515051805190521052205250528052905510552055505580559058105820585058805890591059205950598059908080908110812081508180819082108220825082808290851085208550858085908810882088508880889089108920895089808990909110912091509180919092109220925092809290951095209550958095909810982098509880989099109920995099809991111211151118111911221125112811291152115511581159118211851188118911921195119811991212151218121912221225122812291252125512581259128212851288128912921295129812991515181519152215251528152915521555155815591582158515881589159215951598159918181918221825182818291852185518581859188218851888188918921895189818991919221925192819291952195519581959198219851988198919921995199819992222522282229225522582259228522882289229522982299252528252925552558255925852588258925952598259928282928552858285928852888288928952898289929295529582959298529882989299529982999555585559558855895598559958585958885889589858995959885989599859998888988998989999000

Last one...  
```  
I AM

_ _ _ _ _ _ _ _ _ _ _

LOCKED

[ 0 ] [ 1 ]  
```

The minimum length of the De Bruijn sequence is 2058... We deleted the last 58
character and it still worked.  
>000000000001000000000110000000010100000000111000000010010000000101100000001101000000011110000001000100000010011000000101010000001011100000011001000000110110000001110100000011111000001000010000010001100000100101000001001110000010100100000101011000001011010000010111100000110001000001100110000011010100000110111000001110010000011101100000111101000001111110000100001100001000101000010001110000100100100001001011000010011010000100111100001010001000010100110000101010100001010111000010110010000101101100001011101000010111110000110001100001100101000011001110000110100100001101011000011011010000110111100001110001000011100110000111010100001110111000011110010000111101100001111101000011111110001000100100010001011000100011010001000111100010010011000100101010001001011100010011001000100110110001001110100010011111000101000110001010010100010100111000101010010001010101100010101101000101011110001011001100010110101000101101110001011100100010111011000101111010001011111100011000111000110010010001100101100011001101000110011110001101001100011010101000110101110001101100100011011011000110111010001101111100011100101000111001110001110100100011101011000111011010001110111100011110011000111101010001111011100011111001000111110110001111110100011111111001001001010010010011100100101011001001011010010010111100100110011001001101010010011011100100111011001001111010010011111100101001011001010011010010100111100101010011001010101010010101011100101011011001010111010010101111100101100111001011010110010110110100101101111001011100110010111010100101110111001011110110010111110100101111111001100110110011001110100110011111001101001110011010101100110101101001101011110011011010100110110111001101110110011011110100110111111001110011110011101010100111010111001110110110011101110100111011111001111010110011110110100111101111001111101010011111011100111111011001111111010011111111101010101011010101011110101011011101010111011010101111110101101011101011011011010110111110101110111101011110111010111110110101111111101101101111011011101110110111111101110111111011110111110111111111110000000000

```  
IJCTF{0p3n3d_d3_bru1jn_v4ul75}  
```

Original writeup
(https://github.com/Bonfee/CCIT20-writeups/tree/master/IJCTF2020/vault).https://sekai.team/blog/insomni-hack-teaser-2022/vault/

Original writeup (https://sekai.team/blog/insomni-hack-teaser-2022/vault/).Main function calls deobfuscate:

```gdb  
0x000000000000131d <+84>: call 0x1185 <deobfuscate>  
```

So, stepping with gdb, we can see the deobfuscated flag in the stack, pointed
by some registers:

```  
RAX 0x5555555592a0 ◂— 'gigem{p455w0rd_1n_m3m0ry1}'  
```

# FLAG  
```  
gigem{p455w0rd_1n_m3m0ry1}  
```  

Original writeup
(https://github.com/Internaut401/CTF_Writeup/blob/master/2020/TAMUctf/vault.md)..

Original writeup (https://rawsec.ml/en/WPICTF-2018-write-ups/#200-vault-web).tl;dr: Google chrome has a timing attack with :visited css selector. Adapt the
PoC from [WONTFIXed chrome bug
report](https://bugs.chromium.org/p/chromium/issues/detail?id=252165#c2) to
find the the report a link bot's browser history.

Original writeup (http://bawolff.blogspot.com/2021/10/write-up-
pbctf-2021-vault.html).Original writeup (https://youreinthebutter.zone/writeups/pingctf2022/vault/).