Post

Xor Pain

This is a writeup of the crypto challenge XOR pain from the Security Valley CTF

Premise

There is a piece of code and a text file. Make it work!!

Link: https://github.com/SecurityValley/PublicCTFChallenges/tree/master/crypto/xor_hell

Challenge code:

peace_of_code.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#/usr/bin/python3

def read_flag_from_disk():
    with open("./challenge.txt") as flag:
        return bytes.fromhex(flag.read().strip())

def xor(flag, key):
    out = b""

    for i in range(len(flag)):
        out += bytes([flag[i] ^ key[i % len(key)]])

    return out

def main():
    
    res = xor(
        read_flag_from_disk(),
        b"0"
    )

    print(res)

if __name__ == "__main__":
    main()

Challenge ciphertext:

1
3c0804390c0b1415571d321307083807080b0332081a1938000b381602124e10

Solution

We have 2 strengths in this challenge that we’re going to have to utilize. The one is the fact that XORing is reversible, the second is that we know the flag format, that being SecVal{flag}. because we know the first 6 characters, SecVal, we can use a Known-plaintext attack.

We can do this by using CyberChef and using the from hex and XOR brute force modules. We can then take the first 4 characters from the encoded string, and take the result that match our sought after string. In the case of the first characters, it is Se which gives us 6f6d, for cV we get the key 676f and for the final 2 characters, al we get the last piece of the key, 6d67.

We can string these 3 pieces together to get the full key: 6f6d676f6d67. If we now remove the XOR bruteforce decoder from CyberChef and replace it with a simple XOR and enter our key, we can run it against the full ciphertext.

Doing this with the the ciphertext prints out the flag: SecVal{[REDACTED]}

This post is licensed under CC BY 4.0 by the author.