# ACSC Quals 2023 - pcap 1, 2 ###### tags: `writeup` ## Source Code [Gist](https://gist.github.com/t510599/986aacc2b96ae323e1ba2a0796ec0024) ## Recon By observing the protocol hierarchy statistics, I found that most of the Internet packets are encrypted traffic. ![protocol-statistics](https://i.imgur.com/B2uSBEL.png) So I decided to analyze the USB traffic. Find INTERFACE Descriptor response of HID device to identify the address of keyboard and mouse. filter: `usb.transfer_type == 2 && usb.endpoint_address.direction == 1 && usb.bDescriptorType == 4 && usb.bInterfaceClass == 3` ![interface-descriptor](https://i.imgur.com/G4HDJMF.png) By the `bInterfaceProtocol` field, it can be easily discovered that `usb.device_address == 12` is keyboard, and `usb.device_address == 13` is mouse. Use `tshark` to extract the data from `usbhid.data` field, also keep the `usb.device_address` for further processing. Since the URB_INTERRUPT caused by devices has frame length equals to 72, I also applied it to filter. ```bash tshark -r capture.pcapng -T fields -E separator=, -e usb.device_address -e usbhid.data "(usb.device_address == 12 || usb.device_address == 13) && usb.bus_id == 1 && usb.transfer_type == 1 && usb.endpoint_address.direction == 1 && frame.len == 72" > time.txt ``` Output would like this: ``` ... 13,0100ff000000ffff 13,0100ff000000ffff 13,0101000001000000 13,0101000001000000 13,0000000000000000 13,0000000000000000 13,0000010000000100 13,0000010000000100 12,0000160000000000 12,0000160000000000 12,0000000000000000 ... ``` Where the number before comma is device address, and the rest is HID data. ## Processing Data We can refer to HID spec or simply wireshark to know how to decode the data. ### Keyboard ![hid-keyboard](https://i.imgur.com/Uwun7uu.png) The keyboard part I modified from [USB Keyboard packet capture analysis](https://naykisec.github.io/USB-Keyboard-packet-capture-analysis/) by naykisec, but removed the multiline part. I also used the buffer to deduplicate the input text or the output would look like this: ``` sslliiddddeeeessss..ggggoooogglleeee..ccoooommCCTTFF IInnttttttrroo PPrrrreesssseeeennttaaaattiiiioonnHHooww ttoo bbee ggoooodd aaaatt CCTTFFss//AA bbeeggiinnnneeeerr''ss gguuuuiiddddeeDDoonnoottcchheeaaaattGGgguuuueessssiiiinnnnggiissggooooddTTtthhiiiiss iiiiss aaaannnn eexxxxaaaammpppppplleeee ooooffff aaaa ffllllaaaagg::AACCSSCC{{ff00rr33nnss11ccss__iiss__ss00__ffuunn}}IIff yyoooouuuu ccccaaaann rrrreeeeeeaaaadd tttttthhiissss mmmmeessssaaggggee ccoonnnnggrraaaattss!!11BBuuuutt tttthheeee ffllaaaagggg yyoooouu sssseeeeee nnnnooww iiiissss nnnnooootttt tthhhheeee aacccceeeepptteeeeeedd ffllllaaaagg..IInnssppeeeecctt tttthhhheeee ppppaaaacccckkeeeettttssss mmmmmmmmrrrreeee ddddeeeeppllyy aaaanndddd yyoooouuuu wwwwiillll rrrreevvvveeaaaall mmmmmmrrrreeee iiiinnffoorrrrmmaaaattiiiioonn aaaabboooouuuutttt wwwwhhhhaaaatttt iissss hhhhaaaappppeeeenniiiinngg..II''mm wwwwrrrriittttiiiinnnngggg tttthhhhhhiissss hheerrrree ootthhhheeeerrrrwwiissssee 1111000000 ppeeeeoooopppplllleeee wwiillll ddmm mmmmeeee ttttoo ssssaayy tttthhaaaatt tttthhee ffllaaaagggg iiss nnnnooootttt wwoorrrrkkiiiinnnngg oooooorr tthhhheeee cccchhaalllleennggggee iiiissss bbrrookkeenn..BBttww II ddoonn''tttt lliikkeeee ffoorreennssssiiccccssss ttoooo.. ::)) ``` After deduplicate: ``` slides.google.comCTF Intro PresentationHow to be good at CTFs/A beginner's guideDonotcheatGguessingisgoodTthis is an example of a flag:ACSC{f0r3ns1cs_is_s0_fun}If you can read this message congrats!1But the flag you see now is not the accepted flag.Inspect the packets more deeply and you will reveal more information about what is happening.I'm writing this here otherwise 1000 people will dm me to say that the flag is not working or the challenge is broken.Btw I don't like forensics too. :) ``` p.s. In fact I found that my `array()` is implemented wrongly, but it works. With only the keyboard signals, part 1 can be solved. flag: `ACSC{f0r3ns1cs_is_s0_fun}` ### Mouse ![hid-mouse](https://i.imgur.com/mAT0mzb.png) The X and Y (2 bytes each, little endian) in the packet is in fact the movement instead of the position, so I convert it into absolute position for the ease of visualization. In addtion, I also label the `mouseup` and `mousedown` event, so I can identify the dragging behavior. In order to prevent the overflow of cursor, I restricted the canvas in 6000 * 4000. And to make the animation faster, only the points that is far away enough ($ |x\prime - x| + |y\prime - y| > 100 $) would be shown. Run `python parse.py` to convert `time.txt` into `preview.txt` for visualization. ## Visualization ![web](https://i.imgur.com/b155EwP.png) I utilized web for the visualization. The pink dots represents the `mousedown` click, and the blue dots are the cursor position that the author started typing. The cursor would become red if the author was pressing the mouse then. Since my screen is not large enough, I scaled the axis by 0.2 to fit all clicks. By observing the pink and blue dots' occurence order, position, and also the timing of typing, we can guess that some text were typed in a textbox. (ex. `Do`, `not`, `cheat`, `Guessing`, `is`, `good`, `ACSC{`, etc.) The pink dots' frequently appeared around `slides.google.com` may be the menu of create a new textbox. After the knowledge of textboxes, it can be noticed that these textboxes were rearranged by dragging them around. So just keep track of which textbox was dragged and where it was placed, we can solve the flag of part 2. flag: `ACSC{Guessing_is_not_good}` To make the process more clear, I make a version (after the game) that would mark the position of textbox, and also how they were dragged around. Please use `preview-textbox.js` instead of the one I used during the contest (`preview.js`). Demo: ![textbox-flag](https://i.imgur.com/IVKfJll.png) [Online Demo](https://acsc-2023-quals-pcap-preview.pages.dev/preview) p.s. Because one cannot `fetch()` the local file, you have to open it with a web server, such as `python -m http.server`.