# LACTF – Private Bin * **Category:** Misc * **Author:** burturt ## Challenge > As cybersecurity pioneers, we love to use end-to-end encrypted platforms so that even if we are hacked, the data is safe, right? > > Actually, it turns out taking https://github.com/scarsz/bin and ripping out the XSS protection wasn't a good idea (hey, it was messing up sending html code!), as someone reported that they noticed some weird script running in some bin files! I've attached a copy so you can take a look. > > In completely unrelated news, a certain 3-letter agency has told us that we need to get the contents of a certain paste someone uploaded. Problem is, it's kinda been deleted. Not to worry! While we promised no web logs, we have packet logs! I've already narrowed down the network traffic to only that user. Convenient that they were connected to our network, huh? > > P.S. the bin server is still online if you need it. I have kinda forgotten the url though, sorry ¯\\_(ツ)\_/¯. It's hosted somewhere under lac.tf, and I'm sure you can figure it out using the packet capture. > > P.P.S. said 3-letter agency starts with an A, ends with an M, and has a C in it. > > P.P.P.S. No, there is no admin bot, and no, you do not need to hack the website. This is a MISC challenge, not a web one. ## Solution The challenge contains two files: [sus-script.html](./sus-script.html) and `private-bin.pcapng`. The first file is an XSS payload someone uploaded to the bin service. It doesn't seem helpful right now, so let's check out the network capture. One of the first things I like doing is going through the TCP streams. Stream 52 contains encrypted traffic to `https://privatebin-0191c4fc.lac.tf/`, which is the URL of the bin service. The site contains some interesting files: ![](https://i.imgur.com/1eazFi8.png) `sslkey.log` has the SSL secrets. These can be used to decrypt the captured traffic! ``` $ cat sslkey.log| head -n 3 # SSL key logfile generated by sslkeylog.c SERVER_HANDSHAKE_TRAFFIC_SECRET 825d21627b269f5743f3c821516d066deca910f4c6bc3c59efa5a96e4ea639a4 baead9f0f61f45abbcbf5430d21633678d4616c7a380de7e2f61ab2fd0910876df1ebdc40ac42ad03bbd9e994c176a2f CLIENT_HANDSHAKE_TRAFFIC_SECRET 825d21627b269f5743f3c821516d066deca910f4c6bc3c59efa5a96e4ea639a4 77788e83d07b8cb45e3f1fb74f779fa639e65bafd39abe9d1b75bdcc100e6a88a122f004695a439d980472ba4a7f77c2 ``` To do this, the keys are added to Wireshark using `Edit` > `Preferences` > `Protocols` > `TLS`. The traffic can be limited to the relevant conversation by applying the following filter: `ip.dst == 34.168.128.15 or ip.src == 34.168.128.15`. Now that the SSL keys have been added, each encrypted packet contains a `Decrypted TLS` tab. ![](https://i.imgur.com/exSlX3z.png) Now I can finally try understanding the traffic. It contains multiple HTTP requests/responses: 1. `GET /private-bin/1cca80be-1b8a-4837-bdb1-cb56199e6cd7 HTTP/1.1` This requests the user's notes. When I visit the same URL, it tells me the notes are no longer available: ![](https://i.imgur.com/wxgM8Cw.png) However, the PCAP contains the original response: [private-bin.html](./private-bin.html). The HTML contains a client-side script that sends the following prompt: ![](https://i.imgur.com/UEpRvsz.png) 2. `GET /private-bin/v1/1cca80be-1b8a-4837-bdb1-cb56199e6cd7.json HTTP/1.1` The script asks for the decryption key, then gets the encrypted data from `/private-bin/1cca80be-1b8a-4837-bdb1-cb56199e6cd7.json` and decrypts it on the client. Hence the `end-to-end encrypted platform` in the challenge prompt. The PCAP contains the encrypted data in JSON format. This data was sent over multiple TCP packets. Luckily, Wireshark automatically reassembles it in one of the tabs of the HTTP response. ![](https://i.imgur.com/2G5tuRY.png) 3. `POST / HTTP/1.1` Lastly, the user tries uploading a large zip file to the website and gets a `413 Request Entity Too Large` error. I downloaded the zip file from the PCAP, but it is password-protected. The PCAP does not contain any more traffic in that conversation, so I looked again at `sus-script.html`. It contains an XSS payload that: - fetches the user's encryption key and saves it in `key.txt` - generates a large `secret.txt` file with random data - zips both files with the password `testlactf123` - uploads this zip to the private-bin URL It seems our user visited the payload and had his key stolen. Indeed, I can extract the recovered zip file using the aforementioned password. The encryption key is inside: `3cVSg0HRNq8SmAezph2ZBDl6B4WeEcAg`. The easiest way to recover the private notes is to put the website source and encrypted JSON inside a folder and host a Python HTTP server. I also altered this line in the code to get the locally saved json file. ```js const data = await ky.default('2_response.json'); ``` Once the server is up, I enter the decryption key and get this menu: ![](https://i.imgur.com/VWhhkUz.png) Which contains the flag: ![](https://i.imgur.com/QVJU2Sb.jpg)