BSidesCBR 2017 CTF Write-Up: Needleinahaystack

Hello everyone!

Such a long time since I didn’t post any article. Here is a quick write-up for the BSidesCBR Cryto challenge for “needleinahaystack”.

Before diving in the challenge, huge props to all the organizers and OJ for making those challs available to everyone with Docker containers and stuff (more write-ups coming soon).

If you guys want to give it a shot, here you go, all challs are available here. The challenge we will discuss in this post (needleinahaystack) is located here.

The description was fairly short:

Single byte XOR's are easy to solve... 
But can you find the needle in the haystack? One of these are the flag XOR'd with a single byte. 
Look at the contents of single_byte_xor.

So basically, you get one file, full of hex encoded strings and you need to retrieve the flag. Since we knew flags were something like “BSIDES_CTF{BLABLABLA}”, what I imagined was:

Hex decoding the strings XOR’ing the first character with ‘B’ to get the XOR key. (Equation was: ‘B’ ^ key = first_char). Since we had the first character and we knew the flag was starting with ‘B’, it is trivial to get the key. Then iterate all over the string with the XOR key we retrieved Check if the the output string contains ‘BSIDES_CTF’ (aka. the flag) This Python code does not check if the string contains ‘BSIDES’ before outputing it on the screen, it just checks that the second character was an ’S’ to it brings couple of false positives, but still works.

with open('/tmp/single_byte_xor.txt') as f:
    data = f.readlines()

for line in data:
    line = line.rstrip()
    if len(line) > 0:
        tmp = line.decode('hex')
        key = ord(tmp[0]) ^ ord('B')
        if chr(ord(tmp[1]) ^ key) == 'S':
            print "\n\nline: {}, key: {}".format(line, key)
            for char in tmp:
                print "{}".format(chr(ord(char) ^ key)),

And the output is:

$ python get_strings.py

line: 1809ddd2e826fb2c96cb51aa71c94af8e425d55eb47327c6d9ea158b0206fc31bb99d482, key: 90
B S � � � | � v � �
                    � + �  � �  �  � ) } � � � O � X \ � k � � � �

line: f8e9bce065cb70d51b505a4492433938fe11bb94d02efbdd417e1bbf312002fc8b43f732, key: 186
B S  Z � q � o � � � � ( � � � D �  . j � A g � � �  � � � F 1 � M �

line: eafbac7a084b2c7bbafb9a5d235cb66a63d395e5f53e1034465e3cc3b13f09a62cff263e, key: 168
B S  � � � � �  S 2 � � �  � � { = M ] � � � � � � k  � �  � W � �

line: ddccd6dbdaccc0dccbd9e4ecaef1f8f3fac0dde6a8fac0e7afedc0f6ecc0daabece6e29f, key: 159
B S I D E S _ C T F { s 1 n g l e _ B y 7 e _ x 0 r _ i s _ E 4 s y }

line: c5d4ed7aba829f720d4dbec30f9fbc77fa18c444d45b1200b72c4343f5d47396c17ac574, key: 135
B S j � =   � � � 9 D �  ; � } � C � S � � � 0 � � � r S �  F � B �

Et voilà! We got the flag : BSIDES_CTF{s1ngle_By7e_x0r_is_E4sy}.

Feel free to check the other challenges if you have some time, the web ones are pretty funny.