CTF-writeups

Some CTF writeups

Project maintained by Qyn-CTF

RunRonRun - Medium

Description:

Run Ron, Run!


First looks

We’re given a python file with the challenge source code:

#!/usr/bin/env python3

try:
from Crypto.Cipher import ARC4
except:
print("PyCryptoDome is not installed!")
exit(1)

from secret import FLAG
import os

def roncrypt_flag(offset):
key = os.urandom(16)
cipher = ARC4.new(key)
return cipher.encrypt(FLAG[offset:])

def main():

while True:
offset = int(input("Enter Offset>"))

if not (0 <= offset < len(FLAG)):
print("Offset is not in allowed range!")
exit(2)

encryted_flag = roncrypt_flag(offset)
print(encryted_flag.hex())

if __name__ == '__main__':
main()


From here, we can see that it just simply encrypts the flag starting from a given offset with random keys.
From wikipedia, we can read about the second output output byte: The best such attack is due to Itsik Mantin and Adi Shamir who showed that the second output byte of the cipher was biased toward zero with probability 1/128 (instead of 1/256)., which actually just means that we should see the second byte twice as much as the rest. This we can easily exploit.
For example, we can write a function that just checks every offset.

Solving

from pwn import *

def findOffset(offset, r):
indexes = {}
amount = 256*64
for i in range(amount):
r.sendline(str(offset))
for i in range(amount):
r.recvuntil("Enter Offset>")

res = r.recvline()
data = bytes.fromhex(res.decode())
byte = chr(data[1])
if byte not in indexes:
indexes[byte] = 0
indexes[byte]+=1
sortedIndexes = sorted(indexes, key=indexes.get, reverse=True)
return sortedIndexes[0]



Note that we’re using a simple trick to speed everything up, by sending all the offsets first instead of waiting for a response and then sending the offsets.
And we can bring it all together like this:

def main():
flag = "CSCG{"
r = remote("xxxxx-runronrun.challenge.broker.cscg.live", 31337, ssl=True)
while True:
offset = len(flag)-1
char = findOffset(offset, r)
flag += char
offset+=1
print(flag)


We already guessed that the flag starts with CSCG{, because all flags do.
Running this will give us the flag:
CSCG{schnieke}

Home