Guidepoint Security CTF 2021 - Ssxor (crypto)
For this challenge we get an encrypted string and the python script that was used to generate it:
2e1209315c05627148004b3b46160a565858560a16463b4b00487162055c3109122e
import binascii
flag = 'StormCTF{Crypto4:blahblahblah}'
flag_rev = list(flag[::-1])
stuff = zip(flag, flag_rev)
x = lambda x,y: chr(ord(x) ^ ord(y))
out = list()
out += [x(s[0],s[1]) for s in stuff]
final = [str(b, 'ascii') for b in [binascii.hexlify(bytes(x, 'utf-8')) for x in out]]
print(''.join(final))
stuff = zip(flag_rev, out)
out = list()
out += [x(s[0],s[1]) for s in stuff]
print(''.join(out))
Basically all this script does it take the flag and XOR it with a the flag reversed. This gives the output an interesting property, namely that the first half of the output string is the same as the second half of the string backwards. After all, if you have flag
and XOR it with galf
your first output char f^g
is going to be the same as your last output char g^f
.
Now comes the part where we take some serious advantage of the fact that we know what format the flag is going to be in, we only don’t know what blahblahblah
should be. We do know that the known half of the flag is the same length as the unknown half, and that XOR is a symmetric operation. (A^B=C
, A^C=B
, C^B=A
) When we XOR our known half with the ciphertext of the known half we get the “keystream” back, but in this case our “keystream” will be the second half of our flag reversed.
from pwn import *
import binascii
data=binascii.unhexlify("2e1209315c05627148004b3b46160a565858560a16463b4b00487162055c3109122e")
print(data)
crib = "StormCTF{Crypto4:"
section = data[0:17]
print(crib)
print(section)
end = pwnlib.util.fiddling.xor(crib, section)[::-1].decode('utf-8')
print(f"{crib}{end}")
b'.\x12\t1\\\x05bqH\x00K;F\x16\nVXXV\n\x16F;K\x00Hqb\x05\\1\t\x12.'
StormCTF{Crypto4:
b'.\x12\t1\\\x05bqH\x00K;F\x16\nVX'
StormCTF{Crypto4:bbeb6B9C376F1Cff}