baby arx
Description
I heard that add-rotate-xor are good operations for a cipher so I tried to make my own…
Steps
The challenge is a python script that reads the flag as bytes then initializes the class baby_arx with the flag as the key and then runs it through the cipher by calling the method b and then prints the flag which is commented out at the bottom of the file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class baby_arx():
def __init__(self, key):
assert len(key) == 64
self.state = list(key)
def b(self):
b1 = self.state[0]
b2 = self.state[1]
b1 = (b1 ^ ((b1 << 1) | (b1 & 1))) & 0xff
b2 = (b2 ^ ((b2 >> 5) | (b2 << 3))) & 0xff
b = (b1 + b2) % 256
self.state = self.state[1:] + [b]
return b
def stream(self, n):
return bytes([self.b() for _ in range(n)])
FLAG = open('./flag.txt', 'rb').read().strip()
cipher = baby_arx(FLAG)
out = cipher.stream(64).hex()
print(out)
# cb57ba706aae5f275d6d8941b7c7706fe261b7c74d3384390b691c3d982941ac4931c6a4394a1a7b7a336bc3662fd0edab3ff8b31b96d112a026f93fff07e61b
by analyzing the ciphered flag and creating a dummy test flag starting with the normal DUCTF{ we get the first 12 characters from the cipher correct meaning that we can brute force the flag by writing a loop that compares each character individually.
Solution
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
from string import printable
class baby_arx:
def __init__(self, key):
assert len(key) == 64
self.state = list(key)
def b(self):
b1 = self.state[0]
b2 = self.state[1]
b1 = (b1 ^ ((b1 << 1) | (b1 & 1))) & 0xFF
b2 = (b2 ^ ((b2 >> 5) | (b2 << 3))) & 0xFF
b = (b1 + b2) % 256
self.state = self.state[1:] + [b]
return b
def stream(self, n):
return bytes([self.b() for _ in range(n)])
def split_out(out):
return [out[i : i + 2] for i in range(0, len(out), 2)]
FLAG = "DUCTF{" + "?" * 57 + "}"
FLAGLIST = [c for c in FLAG]
FLAG = FLAG.encode()
expected = split_out(
"cb57ba706aae5f275d6d8941b7c7706fe261b7c74d3384390b691c3d982941ac4931c6a4394a1a7b7a336bc3662fd0edab3ff8b31b96d112a026f93fff07e61b"
)
out = ""
while out != expected:
# attempt to bruteforce
found = True
i = 0
location = FLAG.find(b"?")
while found and i < len(printable):
FLAGLIST[location] = printable[i]
FLAG = "".join(FLAGLIST).encode()
# encrypt the flag
guess = ""
cipher = baby_arx(FLAG)
out = cipher.stream(64).hex()
out = split_out(out)
# print the progress
print(
f'{"".join(out[location])} {"".join(expected[location])} {"".join(FLAGLIST)}',
)
if out[location - 1] == expected[location - 1]:
found = False
FLAG = "".join(FLAGLIST).encode()
i += 1
Flag
DUCTF{i_d0nt_th1nk_th4ts_h0w_1t_w0rks_actu4lly_92f45fb961ecf420}
This post is licensed under CC BY 4.0 by the author.