The Three-Eyed Oracle¶
chall.py
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import random
import signal
import subprocess
import socketserver
FLAG = b'HTBREDACTED'
prefix = random.randbytes(12)
key = random.randbytes(16)
def encrypt(key, msg):
msg = bytes.fromhex(msg)
crypto = AES.new(key, AES.MODE_ECB)
padded = pad(prefix + msg + FLAG, 16)
return crypto.encrypt(padded).hex()
def challenge(req):
req.sendall(b'Welcome to Klaus\'s crypto lab.\n' +
b'It seems like there is a prefix appended to the real firmware\n' +
b'Can you somehow extract the firmware and fix the chip?\n')
while True:
req.sendall(b'> ')
try:
msg = req.recv(4096).decode()
ct = encrypt(key, msg)
except:
req.sendall(b'An error occurred! Please try again!')
req.sendall(ct.encode() + b'\n')
class incoming(socketserver.BaseRequestHandler):
def handle(self):
signal.alarm(1500)
req = self.request
challenge(req)
class ReusableTCPServer(socketserver.ForkingMixIn, socketserver.TCPServer):
pass
def main():
socketserver.TCPServer.allow_reuse_address = True
server = ReusableTCPServer(("0.0.0.0", 1337), incoming)
server.serve_forever()
if __name__ == "__main__":
main()
enkripsi menggunakan AES.ECB, memiliki kelemahan pada ECB, contoh
enc = "xxxxxxxxxxxxxxxx"
cipher = "<block_enkripsi>"
enc = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
cipher = "<block_enkripsi><block_enkripsi>"
# dengan nilai block_enkripsi yg sama
ide dekripsi
padded = prefix + msg + flag
padded = ???????????? + xxxx + yyyyyyyyyyyyyyyy yyyyyyyyyyyyyyyy yyyyyyyyyyyyyyyy yyyyyyyyyyyyyyyy + HTB{selamat_kamu_berhasil}
output = <block_enkripsi_1> <block_enkripsi_2> <block_enkripsi_3> <block_enkripsi_2> <block_enkripsi_3> <block_enkripsi_4>
yyyyyyyyyyyyyyyy yyyyyyyyyyyyyyyy yyyyyyyyyyyyyyyy yyyyyyyyyyyyyyyy HTB{...
yyyyyyyyyyyyyyyy yyyyyyyyyyyyyyy(0..}) yyyyyyyyyyyyyyyy yyyyyyyyyyyyyyyH TB{...
yyyyyyyyyyyyyyyy yyyyyyyyyyyyyyH(0..}) yyyyyyyyyyyyyyyy yyyyyyyyyyyyyyHT B{...
yyyyyyyyyyyyyyyy yyyyyyyyyyyyyHT(0..}) yyyyyyyyyyyyyyyy yyyyyyyyyyyyyHTB {...
flag.py
from pwn import *
import string
url = "138.68.161.126"
port = 31192
target = remote(url, port)
p = b'78787878'
y = b'7979797979797979797979797979797979797979797979797979797979797979'
st = string.printable
f = b''
print(target.recvuntil(b'> ').decode(),end='')
inp = p+y+y
target.send(inp)
print(inp.decode())
output = target.recv().decode()
print(output,end='')
for i in range(len(inp)):
y = y[:-2]
for j in st:
f += hex(ord(j))[2:].encode()
s = p+y+f+y
tmp = target.recvuntil(b'> ').decode()
print(tmp,end='')
target.send(s)
print(bytes.fromhex(s.decode()))
resp = target.recv().decode()
print(resp,end='')
if resp[32:96] == resp[96:160]:
flag = bytes.fromhex(f.decode())
print(flag)
break
else:
f = f[:-2]
# ^C manually
flag