The force is with those who read the source.

Internetwache CTF 2016: A numbers game II (code 70)

2016-03-03

Description

Math is used in cryptography, but someone got this wrong. Can you still solve the equations?
Hint: You need to encode your answers.
Attachment: code70.zip

Exploit

This challenge is different from A numbers game (code 50) with only an additional encode/decode process. The encode function has been provided.

1
2
3
4
5
6
7
8
9
10
11
12
13
def encode(self, eq):
out = []
for c in eq:
q = bin(self._xor(ord(c),(2<<4))).lstrip("0b")
q = "0" * ((2<<2)-len(q)) + q
out.append(q)
b = ''.join(out)
pr = []
for x in range(0,len(b),2):
c = chr(int(b[x:x+2],2)+51)
pr.append(c)
s = '.'.join(pr)
return s

The result of the encoded equations look like:

Level 1.: 4.4.5.3.3.3.3.3.3.3.5.6.3.3.3.3.3.4.3.4.3.4.4.4.3.3.3.3.3.4.6.4.3.3.3.3.3.4.3.6.3.4.4.3

What encode function does is

  1. Xor every charactors with 32 (e.g. ‘x’ -> 88)
  2. Convert every charactors to the binary form with padding 0 (e.g. 88 -> ‘01011000’)
  3. Concatenate the result in 2.
  4. Convert every two digits into integer and plus 51 (e.g. ‘01011000’ -> [52, 52, 53, 51])
  5. Convert the numbers above to charactors and concatenate them with ‘.’ (e.g. [52, 52, 53, 51] -> ‘4.4.5.3’)

To decode, just reverse the process above. With the encode and decode function, we can use the same program shown in A numbers game (code 50) to solve the program and get the flag.

solve.pydownload
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
from pwnlib.tubes.remote import remote

def decode(cypher):
b = ''
for c in cypher.split('.'):
b += bin(ord(c)-51)[2:].rjust(2, '0')

eq = ''
for i in range(0, len(b), 8):
eq += chr(int(b[i:i+8], 2)^32)

return eq

def encode(eq):
out = []
for c in eq:
q = bin(ord(c)^(2<<4)).lstrip("0b")
q = "0" * ((2<<2)-len(q)) + q
out.append(q)
b = ''.join(out)
pr = []
for x in range(0,len(b),2):
c = chr(int(b[x:x+2],2)+51)
pr.append(c)
s = '.'.join(pr)
return s

r = remote('188.166.133.53', 11071)

while True:
lines = r.recvlines(2)
print '\n'.join(lines)

eq = decode(lines[1].split()[2])
print 'equation:', eq
sp = eq.split()

if sp[1] == '+':
x = int(sp[4]) - int(sp[2])
elif sp[1] == '-':
x = int(sp[4]) + int(sp[2])
elif sp[1] == '*':
x = int(sp[4]) / int(sp[2])
elif sp[1] == '/':
x = int(sp[4]) * int(sp[2])

print 'x = ', x
print 'encode: ', encode(str(x))
r.sendline(encode(str(x)))

Flag: IW{Crypt0_c0d3}


Blog comments powered by Disqus