Tags: wireshark braille usb
Rating:
Description
I have a feeling there is a flag there somewhere
Files given
feel-it
Solution
First let's identify what our feel-it
file is:
$ xxd feel-it.pcap | head
0000000: 0a0d 0d0a a000 0000 4d3c 2b1a 0100 0000 ........M<+.....
0000010: ffff ffff ffff ffff 0200 3600 496e 7465 ..........6.Inte
0000020: 6c28 5229 2043 6f72 6528 544d 2920 6937 l(R) Core(TM) i7
0000030: 2d37 3630 3055 2043 5055 2040 2032 2e38 -7600U CPU @ 2.8
0000040: 3047 487a 2028 7769 7468 2053 5345 342e 0GHz (with SSE4.
0000050: 3229 0000 0300 1f00 4c69 6e75 7820 342e 2)......Linux 4.
0000060: 3133 2e32 2d31 2d74 702d 7831 2d63 6172 13.2-1-tp-x1-car
0000070: 626f 6e2d 3574 6800 0400 1900 4475 6d70 bon-5th.....Dump
0000080: 6361 7020 2857 6972 6573 6861 726b 2920 cap (Wireshark)
0000090: 322e 342e 3200 0000 0000 0000 a000 0000 2.4.2...........
We can see the strings "Dumpcap" and "Wireshark". So we have a packet capture file, and we can use (surprisingly) Wireshark to analyse it.
We can see many packets Wireshark identified as "USB" and "USBHID". So we are not dealing with network traffic, but some sort of peripheral device connected to a computer. First we should try to identify what device it is. Among the first packets we can see some that are GET DESCRIPTOR Response STRING
.
(packet 12) Manufacturer is confidential
(packet 10) and so is product string
(packet 14) not to mention serial number
This is not terribly useful and clearly some information is hidden from us. Hopefully we can still identify what device it is simply by looking at the data that is being transmitted. If we skim through the packets, we can see a couple that are SET_REPORT Request
and seem to carry 64 bytes of data in a field called "data fragment". The data carried over these packets seems to grow larger and larger (i.e. less null bytes, more non-null bytes) as time goes on. We can use tshark
to extract all the data fragments from the packet capture:
$ tshark -F pcap -Tfields -e usb.data_fragment -r feel-it.pcap | grep -v "^$"
02:00:04:53:49:03:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55:55 02:00:54:42:53:1d:15:1e:00:01:1d:00:41:5e:24:4e:4f:4a:06:00:1e:11:2d:1e:00:3a:0a:19:1b:11:1e:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 ... etc etc
(grep -v "^$"
was used to filter out empty lines, representing packets that do not have a USB data fragment.)
Many of the packets seem identical, however. Let's focus on the ones that actually carry data:
$ tshark -F pcap -Tfields -e usb.data_fragment -r feel-it.pcap | grep "02:00:54:42:53"
02:00:54:42:53:1d:15:1e:00:01:1d:00:41:5e:24:4e:4f:4a:06:00:1e:11:2d:1e:00:3a:0a:19:1b:11:1e:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:43:57:47:5e:5e:7d:00:22:28:16:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:49:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:49:5e:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:49:5e:4b:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:49:5e:4b:2a:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:49:5e:4b:ea:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:49:5e:cb:2a:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:49:de:4b:2a:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:c9:5e:4b:2a:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:c9:5e:4b:2a:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:de:4b:2a:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:cb:2a:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:ea:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:2e:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:2e:19:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:2e:19:11:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:2e:19:d1:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:2e:d9:11:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:d9:11:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:2e:d9:11:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:d9:11:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:d9:11:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:d1:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:38:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:38:0e:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:38:0e:3c:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:38:0e:3c:3c:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:38:0e:3c:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:38:0e:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:38:0e:12:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:38:0e:12:12:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:38:0e:12:12:05:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:6a:07:11:1b:0a:1e:48:0e:13:11:07:07:00:18:7b:2b:00:49:5e:4b:2a:13:02:19:11:38:01:1d:19:38:0e:12:12:05:3b:c0:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
02:00:54:42:53:1d:15:1e:00:01:1d:00:41:5e:24:4e:4f:4a:06:00:1e:11:2d:1e:00:3a:0a:19:1b:11:1e:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
(file with the extracted data)
This may not be obvious, but the data looks very much like somebody is typing characters into a terminal. The 00
bytes represent the empty space after the command. c0
is present at the end of most lines, it is probably a cursor character. In general, the line is growing one character at a time. And another strong clue - whenever c0
is NOT present at the end of the line, we can tell that the cursor is moving back across the already typed text. It is setting the the 2 highest bits of whichever value it is currently hovering over, then when more characters appear, the cursor moves with the rest of the line towards the right.
So great, this is somebody typing into a terminal. But what? The data is not in ASCII. We can make some additional observations. Here is a fragment of the data, highlighting the end of the command line, and omitting 00
bytes for clarity.
38:01:1d:19:38:0e:c0
38:01:1d:19:38:0e:3c:c0
38:01:1d:19:38:0e:3c:3c:c0
38:01:1d:19:38:0e:3c:c0
38:01:1d:19:38:0e:c0
38:01:1d:19:38:0e:12:c0
38:01:1d:19:38:0e:12:12:c0
38:01:1d:19:38:0e:12:12:05:c0
38:01:1d:19:38:0e:12:12:05:3b:c0
What happened here?
The character 3c
was entered twice. Then it was deleted, and replaced with two 12
bytes. The user was typing a word with a doubled letter, then replaced it with a different doubled letter. Perhaps fat fingers, something like:
some text some text some text sw_
some text some text some text swr_
some text some text some text swrr_
some text some text some text swr_
some text some text some text sw_
some text some text some text swe_
some text some text some text swee_
some text some text some text sweet_
Whatever it was, we now have pretty solid evidence that we are dealing with an encoding / encryption that encodes single characters only, independent of their position on the line, or the packet they occur in, or the current time, etc. Something like a monoalphabetic substitution cipher. (Caesar's? Single-byte XOR? Affine?)
However, try as we might, our team could not decrypt these characters. We had the data being entered input for more than 24 hours without making much sense of it. On the morning of the second day I had some time to think:
This made me think of 7-segment LCD displays. In particular, the seventh bit would represent the lowest segment of the character. Then the cursor would simply be an underscore-like character. Moving over a character would underline it if possible. I thought the eighth bit could be the decimal point that's not really a part of the character - then the user could always tell which character was selected.
Returning to the data example above, it would look something like:
- - - - -
| | | | | | |
- - -
| | | | | | |
- - -
----------------------------------
- - - - - -
| | | | | | | |
- - - -
| | | | | | | |
- - - -
----------------------------------
- - - - - - -
| | | | | | | | |
- - - - -
| | | | | | | | |
- - - - -
etc
But applying the standard orderings of the segments as shown on Wikipedia didn't produce anything meaningful. Perhaps we simply need to find the correct bit-to-segment mapping? The challenge description did not mention that the flag would be in non-standard format. Hence we have to be able to find CTF{...}
in the data somehow. We could represent ctf
like this:
-
| |
- - -
| | |
- -
While we do not know the exact mapping of bits, we know how many bits should be 1
. In the above, we are looking for a sequence like 3, 4, 4
in the data. Additionally, the t
has all the bits of c
plus one more. The f
has three bits of t
, but not the one from c
, and then one additional bit.
There are other ways to display CTF
, e.g. with a capital C. No matter how we searched the bits of the data, however, we could not find a suitable pattern.
We spent quite a bit more thinking 7-segment display is still the answer, somehow.
But at some point it hit me: the challenge is called "Feel it". Sometimes there are red herrings in challenge descriptions, but this would be a huge one. The description of the challenge needs to be considered a part of the challenge in a good CTF, subtly but clearly (once understood) guiding the players towards the correct solution.
So far we have not used the description. What can you feel? What kind of display relies not on the sense of sight, but the sense of touch? It is a Braille display! Almost immediately this seemed like an excellent fit for the data. Another characteristic of the data (also true for the 7-segment display idea) was that the lack of characters, i.e. spaces and the empty space after the line, was represented with 00
bytes. To represent a space in Braille you simply put no dots, i.e. empty space. So a 00
byte make sense as a space character in Braille.
But we still had the same problem: how to map the bits to the dots of Braille characters? Why do some characters use 7 bits, despite Braille technically being a 6-bit encoding? Trying to find CTF
in the beginning of the "command line" did not really help, since the number of bits did not really agree with what CTF
is in Braille. We can, however, apply the same method as before - look for a pattern in the number of dots. In fact, since 7 bits were being used, we performed a lenient search - look for patterns that have at least as many bits set as it would take to represent CTF
.
Here is what CTF
is like in Braille:
oo o oo
oo o
o
C T F
2 bits, 4 bits, 3 bits. Converting the data fragment bytes to binary (only keeping the lowest 7 bits), there are multiple places where this pattern could fit:
$ haxe --run PatternFind
02: [0,0,0,0,0,1,0]: 1
00: [0,0,0,0,0,0,0]: 0
54: [1,0,1,0,1,0,0]: 3
42: [1,0,0,0,0,1,0]: 2 MATCH
53: [1,0,1,0,0,1,1]: 4 MATCH
6A: [1,1,0,1,0,1,0]: 4
07: [0,0,0,0,1,1,1]: 3
11: [0,0,1,0,0,0,1]: 2
1B: [0,0,1,1,0,1,1]: 4
0A: [0,0,0,1,0,1,0]: 2
1E: [0,0,1,1,1,1,0]: 4
48: [1,0,0,1,0,0,0]: 2
0E: [0,0,0,1,1,1,0]: 3
13: [0,0,1,0,0,1,1]: 3
11: [0,0,1,0,0,0,1]: 2
07: [0,0,0,0,1,1,1]: 3
07: [0,0,0,0,1,1,1]: 3
00: [0,0,0,0,0,0,0]: 0
18: [0,0,1,1,0,0,0]: 2 MATCH
7B: [1,1,1,1,0,1,1]: 6
2B: [0,1,0,1,0,1,1]: 4
00: [0,0,0,0,0,0,0]: 0
49: [1,0,0,1,0,0,1]: 3 MATCH
5E: [1,0,1,1,1,1,0]: 5 MATCH
4B: [1,0,0,1,0,1,1]: 4
2A: [0,1,0,1,0,1,0]: 3
13: [0,0,1,0,0,1,1]: 3
02: [0,0,0,0,0,1,0]: 1
19: [0,0,1,1,0,0,1]: 3
11: [0,0,1,0,0,0,1]: 2
38: [0,1,1,1,0,0,0]: 3
01: [0,0,0,0,0,0,1]: 1
1D: [0,0,1,1,1,0,1]: 4
19: [0,0,1,1,0,0,1]: 3
38: [0,1,1,1,0,0,0]: 3
0E: [0,0,0,1,1,1,0]: 3
12: [0,0,1,0,0,1,0]: 2
12: [0,0,1,0,0,1,0]: 2
05: [0,0,0,0,1,0,1]: 2
3B: [0,1,1,1,0,1,1]: 5
C0: [1,0,0,0,0,0,0]: 1
The initial three don't seem to work out. But 00:49:5E:4B
actually works as <space>CTF
! All three characters have one extra bit set - this could indicate that they are uppercase. In regular English Braille capital characters are indicated with a special character preceding the letter that is meant to be capital. This might be impractical for a computer terminal.
00: [0,0,0,0,0,0,0]: 0
49: [1,0,0,1,0,0,1]: 3 C
5E: [1,0,1,1,1,1,0]: 5 T
4B: [1,0,0,1,0,1,1]: 4 F
^
uppercase
The three following bits represent the right column of the Braille grid, and the three last bits represent the left column. Let's see what the full line looks like:
o o o o oo o o o o o o o o
o o o oo o o o oo o oo o oo o o o
o o o o o o o
o oo oo oo o oo o o oo o o o oo oo o
o oo o oo o o oo o o o o o o o
o o o o o o o
o o oo
o oo oo oo
o o o
If we try to decode these character using the standard English Braille alphabet, we get more useful data, but a lot of the characters have special meaning rather than representing a single character:
o o o o oo o o o o o o o o
o o o oo o o o oo o oo o oo o o o
o o o o o o o
, in? , h ow? l e g i t ?? s h e l l
o oo oo oo o oo o o oo o o o oo oo o
o oo o oo o o oo o o o o o o o
o o o o o o o
?? ?? ?? c t f ow? h ,? d e ?? a n d ??
o o oo
o oo oo oo
o o o
s ?? ?? k ??
The ??
are meant to be used as parts of special "abbreviations" in Braille, consisting of multiple characters that represent a commonly-used English word. After searching through a couple abbreviation appendices, we could not find any suitable abbreviation for the three-character code on the start of the second line above. But we could clearly see that the flag would be something like CTF{hide_and_seek}
, we were very close.
Finally, we found Computer Braile Code, specifically meant to be used for Braille representations of computer data. When using this encoding, we get:
o o o o oo o o o o o o o o
o o o oo o o o oo o oo o oo o o o
o o o o o o o
1 9 1 h { l e g i t @ s h e l l
o oo oo oo o oo o o oo o o o oo oo o
o oo o oo o o oo o o o o o o o
o o o o o o o
^ } $ c t f { h 1 d e _ a n d _
o o oo
o oo oo oo
o o o
s 3 3 k }
It is possible that the first five bytes are not Braille characters, but control data for the device.
We have the flag, but let's decrypt the full user interaction:
1 91Hnot an AT-SPI2 text widget
1 91HBRLTTY 5.6
1 91H
1 91H{legit@shell ^}$
1 91H{legit@shell ^}$C
1 91H{legit@shell ^}$CT
1 91H{legit@shell ^}$CTF
1 91H{legit@shell ^}$CTF{
1 91H{legit@shell ^}$CTF{
1 91H{legit@shell ^}$CTF{
1 91H{legit@shell ^}$CTF{
1 91H{legit@shell ^}$CTF{
1 91H{legit@shell ^}$ CTF{
1 91H{legit@shell ^}$ CTF{
1 91H{legit@shell ^}$ CTF{
1 91H{legit@shell ^}$ CTF{
1 91H{legit@shell ^}$ CTF{
1 91H{legit@shell ^}$ CTF{h
1 91H{legit@shell ^}$ CTF{h?
1 91H{legit@shell ^}$ CTF{h?d
1 91H{legit@shell ^}$ CTF{h?de
1 91H{legit@shell ^}$ CTF{h?dE
1 91H{legit@shell ^}$ CTF{h?De
1 91H{legit@shell ^}$ CTF{hDe
1 91H{legit@shell ^}$ CTF{h?De
1 91H{legit@shell ^}$ CTF{hDe
1 91H{legit@shell ^}$ CTF{h1De
1 91H{legit@shell ^}$ CTF{h1dE
1 91H{legit@shell ^}$ CTF{h1de
1 91H{legit@shell ^}$ CTF{h1de_
1 91H{legit@shell ^}$ CTF{h1de_a
1 91H{legit@shell ^}$ CTF{h1de_an
1 91H{legit@shell ^}$ CTF{h1de_and
1 91H{legit@shell ^}$ CTF{h1de_and_
1 91H{legit@shell ^}$ CTF{h1de_and_s
1 91H{legit@shell ^}$ CTF{h1de_and_s#
1 91H{legit@shell ^}$ CTF{h1de_and_s##
1 91H{legit@shell ^}$ CTF{h1de_and_s#
1 91H{legit@shell ^}$ CTF{h1de_and_s
1 91H{legit@shell ^}$ CTF{h1de_and_s3
1 91H{legit@shell ^}$ CTF{h1de_and_s33
1 91H{legit@shell ^}$ CTF{h1de_and_s33k
1 91H{legit@shell ^}$ CTF{h1de_and_s33k}
1 91Hnot an AT-SPI2 text widget
CTF{h1de_and_s33k}