Bad Code is a misc challenge that was part of the MetaRed CTF 2022 (4th STAGE). Our task was to review a given file of python code. The script was supposed to print the flag, but it was broken. We had to fix the code in order to get the flag.

file.py

import random


def str_xor(secret, key):
    #extend key to secret length
    new_key = key
    i = 0
    while len(new_key) < len(secret):
        new_key = new_key + key[i]
        i = (i + 1) % len(key)        
   return "".join([chr(ord(secret_c) ^ ord(new_key_c)) for \
    (secret_c,new_key_c) in zip(secret,new_key)])


flag_enc = chr(0x01) + chr(0x21) + chr(0x08) + chr(0x19) + chr(0x21) \
    + chr(0x51) + chr(0x5c) + chr(0x40) + chr(0x3a) + chr(0x24) \
        + chr(0x5d) + chr(0x21) + chr(0x20) + chr(0x07) \
            + chr(0x0a) + chr(0x04),

flag = str_xor(flag_enc, 'enkidu')
  print('That is correct! Here\'s your flag: ' + flag)

Solution

If we just run the code, we get the following output:

$ python file.py
  File "/home/p2o/bad_code/file.py", line 12
    return "".join([chr(ord(secret_c) ^ ord(new_key_c)) for \
        (secret_c,new_key_c) in zip(secret,new_key)])
                                                    ^
IndentationError: unindent does not match any outer indentation level

To fix all errors, we had to add and remove some (), [], , and spaces.

$ diff file.py solve.py
1,3c1
< import random
< 
< 
---
> #!/usr/bin/env python
12,15c10
<    return "".join([chr(ord(secret_c) ^ ord(new_key_c)) for \
    (secret_c,new_key_c) in zip(secret,new_key)])
< 
< 
< flag_enc = chr(0x01) + chr(0x21) + chr(0x08) + chr(0x19) + chr(0x21) \
    + chr(0x51) + chr(0x5c) + chr(0x40) + chr(0x3a) + chr(0x24) \
        + chr(0x5d) + chr(0x21) + chr(0x20) + chr(0x07) \
            + chr(0x0a) + chr(0x04),
---
>     return "".join(chr(ord(secret_c) ^ ord(new_key_c)) for \
    secret_c,new_key_c in zip(secret,new_key))
16a12
> flag_enc = chr(0x01) + chr(0x21) + chr(0x08) + chr(0x19) + chr(0x21) \
    + chr(0x51) + chr(0x5c) + chr(0x40) + chr(0x3a) + chr(0x24) \
        + chr(0x5d) + chr(0x21) + chr(0x20) + chr(0x07) \
            + chr(0x0a) + chr(0x04)
19c15
<   print('That is correct! Here\'s your flag: ' + flag)
---
> print('That is correct! Here\'s your flag: ' + flag)

Final code:

#!/usr/bin/env python

def str_xor(secret, key):
    #extend key to secret length
    new_key = key
    i = 0
    while len(new_key) < len(secret):
        new_key = new_key + key[i]
        i = (i + 1) % len(key)        
    return "".join(chr(ord(secret_c) ^ ord(new_key_c)) for \
        secret_c,new_key_c in zip(secret,new_key))

flag_enc = chr(0x01) + chr(0x21) + chr(0x08) + chr(0x19) + chr(0x21) \
    + chr(0x51) + chr(0x5c) + chr(0x40) + chr(0x3a) + chr(0x24) \
        + chr(0x5d) + chr(0x21) + chr(0x20) + chr(0x07) \
            + chr(0x0a) + chr(0x04)
  
flag = str_xor(flag_enc, 'enkidu')
print('That is correct! Here\'s your flag: ' + flag)

Output:

That is correct! Here's your flag: dOcpE$9.QM9TEiam

Flag

The flag is “dOcpE$9.QM9TEiam”.