diff --git a/Day 24/HV23 b/Day 24/HV23 new file mode 100755 index 0000000..816157d Binary files /dev/null and b/Day 24/HV23 differ diff --git a/Day 24/decode.py b/Day 24/decode.py new file mode 100644 index 0000000..57846c3 --- /dev/null +++ b/Day 24/decode.py @@ -0,0 +1,95 @@ +import struct +from hackingscripts import util +from PIL import Image +from pyzbar.pyzbar import decode + +def bit_stream_to_qr(bit_stream, qr_size=(29, 32), pix_size=10): + img = Image.new("RGB", (qr_size[1] * pix_size, qr_size[0] * pix_size)) + pix = img.load() + + columns = ["" for r in range(qr_size[1])] + for i, b in enumerate(bit_stream): + columns[i % qr_size[1]] += b + + for ci, column in enumerate(columns): + for ri, b in enumerate(column): + color = (0,0,0) if b == "1" else (255,255,255) + for xi in range(pix_size): + for yi in range(pix_size): + pix[ci*pix_size+xi,ri*pix_size+yi] = color + + return img + +def apply_scramble(data, loop_count, shift_direction, shift_type_1, shift_type_2): + for i in range(loop_count): + if shift_direction == 0: + if shift_type_1 != -1: + offset = 0x70 + shift_type_1 + value = data[offset] + for x in range(0x1c+1): + data[offset] = data[offset - 4] + offset -= 4 + data[offset + 4] = value + if shift_type_2 != -1: + offset = shift_type_2 * 4 + value = data[offset] + for x in range(3+1): + data[offset] = data[offset + 1] + offset += 1 + data[offset - 1] = value + elif shift_direction == 1: + if shift_type_2 != -1: + offset = 3 + shift_type_2 * 4 + value = data[offset] + for x in range(3+1): + data[offset] = data[offset - 1] + offset -= 1 + data[offset + 1] = value + if shift_type_1 != -1: + offset = shift_type_1 + value = data[offset] + for x in range(0x1c + 1): + data[offset] = data[offset + 4] + offset += 4 + data[offset - 4] = value + else: + raise + return data + +def bytes_to_bit_stream(data, qr_size=(29, 32)): + bit_stream = "" + for v in data: + bit_stream += util.lpad(bin(v)[2:], 8, "0") + bit_stream = bit_stream[0:qr_size[0] * qr_size[1]] + return bit_stream + +if __name__ == "__main__": + + with open("HV23", "rb") as f: + prog_data = f.read() + + QR_DATA = bytearray(prog_data[0x8a3e:0x8a3e+0x70+7]) + SCRAMBLE_DATA = prog_data[0x628:0x628+0x60] + NUM_SCRAMBLES = 0x18 + assert len(SCRAMBLE_DATA) == NUM_SCRAMBLES * 4 + + scrambles = [] + for scramble in range(0, NUM_SCRAMBLES*4, 4): + scramble_data = SCRAMBLE_DATA[scramble:scramble+4] + shift_type_2, shift_type_1, loop_count, shift_direction = struct.unpack("bbBB", scramble_data) + scrambles.append((loop_count, shift_direction, shift_type_1, shift_type_2)) + + data = QR_DATA + while True: + for scramble in scrambles: + data = apply_scramble(data, *scramble) + bit_stream = bytes_to_bit_stream(data) + + # last 3 columns are all white? we might have a valid QR-code + if all(bit_stream[row*32+29:row*32+32] == "000" for row in range(29)): + img = bit_stream_to_qr(bit_stream) + decoded_objects = decode(img) + if decoded_objects: + img.save(f"qr_code.png") + print("[+] Flag:", decoded_objects[0].data.decode()) + exit() diff --git a/Day 24/qr_code.png b/Day 24/qr_code.png new file mode 100644 index 0000000..7051342 Binary files /dev/null and b/Day 24/qr_code.png differ diff --git a/Day 24/s/STARTUP-SEQUENCE b/Day 24/s/STARTUP-SEQUENCE new file mode 100755 index 0000000..9a7c80a --- /dev/null +++ b/Day 24/s/STARTUP-SEQUENCE @@ -0,0 +1 @@ +sys:HV23 \ No newline at end of file diff --git a/Day 24/santas-shuffled-surprise.adf b/Day 24/santas-shuffled-surprise.adf new file mode 100644 index 0000000..6d97963 Binary files /dev/null and b/Day 24/santas-shuffled-surprise.adf differ