HackTheBox QuickR Challenge
https://app.hackthebox.com/challenges/119
Description
Let’s see if you’re a QuickR soldier as you pretend to be
Exploitation
#!/usr/bin/env python3
from pyzbar.wrapper import ZBarSymbol
from pyzbar.pyzbar import decode
from pwn import remote
from PIL import Image
import struct, sys
def parse_ip_port(arg):
return arg.split(':')[0], int(arg.split(':')[1])
if __name__ == '__main__':
if len(sys.argv) != 2: sys.exit(f"Usage: python {sys.argv[0]} <ip:port>")
ip, port = parse_ip_port(sys.argv[1])
io = remote(ip, port)
input_str = io.recvuntil(b'string:').decode('utf-8')
qr_code = input_str[548:]
qr_code_binary = qr_code.replace(' ', '')
qr_code_binary = qr_code_binary.replace('\x1B[7m', '1,').replace('\x1B[0m', '')
qr_code_binary = qr_code_binary.replace('\x1B[41m', '0,')
qr_code_binary = qr_code_binary[0:qr_code_binary.index('\t\n')].replace('\t', '')
qr_code_binary = qr_code_binary + ('0,' * 51) + '\n'
qr_code_binary = qr_code_binary[:-2]
visual = qr_code_binary.replace(',', '').replace('0', '\x1b[30;47m██\x1b[0m').replace('1', '\x1b[37;40m██\x1b[0m')
print(visual)
rows = qr_code_binary.count('\n')
qr_code_binary_arr = qr_code_binary.replace('\n', '').split(',')
size = 51, rows
arr_size = len(qr_code_binary_arr)
data = struct.pack('B' * arr_size, *[int(pixel) * 255 for pixel in qr_code_binary_arr])
img = Image.frombytes('L', size, data)
img.save('img.png')
img.close()
im = Image.open("img.png")
qr_out = decode(im, symbols=[ZBarSymbol.QRCODE])
if qr_out:
qr_data = qr_out[0].data.decode("utf-8").replace('=', '').replace('x', '*')
print(f"QR Data: {qr_data}")
qr_result = str(eval(qr_data)).encode('utf-8')
print(f"QR Result: {qr_result.decode('utf-8')}")
io.sendline(qr_result)
else:
print("No QR code found in the image.")
response = io.recvall().replace(b" \x1b[1m\x1b[92m",b"\x1b[1m\x1b[92m").decode('utf-8')
print(response)
Summary
QuickR: reduce the custom rules to a scriptable check and use the smallest reliable path to the flag.