Challenge Overview
I have a friend that enjoys coding and he hasn't
stopped talking about a snake recently
He left this file on my computer and dares me to
uncover a secret phrase from it. Can you assist?
Solution
To get the Python bytecode file: wget https://artifacts.picoctf.net/c_titan/31/snake
The first section in the byte code contains many LOAD_CONST calls which creates the input_list as seen in the bytecode. Sections 2 through 6 cover the key_str variable which can be a bit tricky.
2 84 LOAD_CONST 31 ('J')
86 STORE_NAME 1 (key_str)
This part uses LOAD_CONST for 'J' in key_str so it is now just 'J'.
3 88 LOAD_CONST 32 ('_')
90 LOAD_NAME 1 (key_str)
92 BINARY_ADD
94 STORE_NAME 1 (key_str)
Next, it loads '_', then loads the name key_str (not storing) than binary add so '_' + key_str, and with STORE_NAME it loads it into key_str. So now key_str is "_J".
4 96 LOAD_NAME 1 (key_str)
98 LOAD_CONST 33 ('o')
100 BINARY_ADD
102 STORE_NAME 1 (key_str)
Similar to the last one but LOAD_NAME and LOAD_CONST are flipped which means key_str + 'o' which means it's just appending it to key_string. So now key_str is "_Jo". Section 5 is the same format as section 4 but with the character '3' making key_string "_Jo3". Section 6 is the same format as section 3 so the final configuration of key_str would be "t_Jo3".
Section 9 and the corresponding disassembly near the bottom corresponds to this line of code: key_list = [ord(char) for char in key_str]. Section 11 makes the comparison with key_list and input_list and section 12 does the extend on key_list. Section 15 does the zip on input_list and key_list and section 18 has the join to the result_text variable. The result is the value of the flag.
Script:
input_list = [4, 54, 41, 0, 112, 32, 25, 49, 33, 3, 0, 0, 57, 32, 108, 23, 48, 4, 9, 70, 7, 110, 36, 8, 108, 7, 49, 10, 4, 86, 43, 108, 122, 14, 2, 71, 62, 115, 88, 78]
key_str = 't_Jo3'
key_list = [ord(char) for char in key_str]
while len(key_list) < len(input_list):
key_list.extend(key_list)
result = [a ^ b for a, b in zip(input_list, key_list)]
result_text = ''.join(map(chr, result))
print(result_text)
Running this script in Python gives the flag.
Flag: picoCTF{N0t_sO_coNfus1ng_sn@ke_30a...}