CTF2021 - GuessKey2
Crypto
No hay descripcion del desafio, solamente nos adjuntan un zip.
Analizar el codigo
El primer paso es analizar el codigo del archivo que nos adjuntan en el zip:
GuessKey.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
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 random import randint
import os
from flag import flag
N=64
key=randint(0,2**N)
# print key
key=bin(key)[2:].rjust(N,'0')
count=0
while True:
p=0
q=0
new_key=''
zeros=[0]
for j in range(len(key)):
if key[j]=='0':
zeros.append(j)
p=zeros[randint(0,len(zeros))-1]
q=zeros[randint(0,len(zeros))-1]
try:
mask=int(raw_input("mask:"))
except:
exit(0)
mask=bin(mask)[2:]
if p>q:
tmp=q
q=p
p=tmp
cnt=0
for j in range(0,N):
for j in range(0,N):
if j in range(p,q+1):
new_key+=str(int(mask[cnt])^int(key[j]))
else:
new_key+=key[j]
cnt+=1
cnt%=len(mask)
key=new_key
try:
guess=int(raw_input("guess:"))
except:
exit(0)
if guess==int(key,2):
count+=1
print 'Nice.'
else:
count=0
print 'Oops.'
if count>2:
print flag
El codigo es igual que el del desafio GuessKey, la unica diferencia es que esta vez no se imprime el valor de la variable key.
Elaborar el exploit
Esta vez no vale con elegir 0 de mascara e introducir la clave 3 veces seguidas porque no conocemos la clave.
El truco esta en dos puntos: la clave key no se reestablece tras cada modificacion y la variable “q” en algun momento tomare el valor de la posicion del 0 menos significativo en la clave “key” en binario.
Sabiendo esto, podemos hacer un xor con 1 continuamente, dejando a 1 todos los 0 de la clave, desde el menos significativo hasta el mas significativo (de derecha a izquierda). Sabremos que ya hemos dejado toda la clave a 1 cuando al establecer el valor de “guess” a “2^64 - 1” el servidor nos responda con “Nice.” en vez de “Oops.”, en este punto solo tendremos que enviar 0 como mascara y el valor anterior como “guess” y ya obtendremos la flag:
exploit.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
26
#!/usr/bin/python3
from pwn import *
#p = process("./GuessKey_Fix.py")
p = remote("52.163.228.53", 8082)
while True:
p.recvuntil("mask:")
p.send("1\n")
p.recvuntil("guess:")
p.send("18446744073709551615\n")
check=p.recvuntil(".")
print(check)
if(check==b'Nice.'):
p.recvuntil("mask:")
p.send("0\n")
p.recvuntil("guess:")
p.send("18446744073709551615\n")
p.recvuntil("mask:")
p.send("0\n")
p.recvuntil("guess:")
p.send("18446744073709551615\n")
p.recvuntil("Nice.\n")
print(p.recvuntil("}"))
p.close()
exit(0)