master
Raw Download raw file
 1#!/usr/bin/env python3
 2import itertools
 3import signal
 4from time import sleep
 5from pwn import *
 6
 7class Exploit:
 8    def __init__(self, filename: str):
 9        self.filename = filename
10        self.patched = "arcadian_patched"
11        self.elf = ELF(self.filename)
12        self.p = process(self.elf.path)
13
14    def get_flag(self, token: bytes) -> None:
15        self.p.recvuntil(token)
16        flag = self.p.recvuntil(b"}").decode('utf-8')
17        log.success(f"{token.decode('utf-8')} = {flag}")
18
19    def stage1(self) -> None:
20        addr = 0x9d28                        # patch off the first check to get first flag
21        self.elf.write(addr, b"\x30\xc0")    # xor al,al to pass the test
22        self.elf.save(self.patched)
23        self.elf = ELF(self.patched)
24        self.p = process(self.elf.path)
25        self.p.sendline(b"lol lol lol lol")
26        self.get_flag(b"TOKEN1: ")
27
28    def stage2(self) -> None:
29        # I brute forced this solution with another program
30        stage2_solution = b"L R U D L X"
31        self.p.recvuntil(b"Enter your 6 moves: >")
32        self.p.sendline(stage2_solution)
33        self.get_flag(b"TOKEN2: ")
34        # Need this for stage3
35        gdb.attach(self.p, gdbscript='continue')
36
37    def stage3(self) -> None:
38        self.p.recvuntil(b"Decrypting TOKEN3 in 5 seconds")
39        sleep(5)
40        self.p.send_signal(signal.SIGTRAP)
41        log.info("Hit continue on gdb twice!")
42        self.p.sendline(b"dump")
43        self.get_flag(b"TOKEN3: ")
44
45    def stage4(self) -> None:
46        self.elf = ELF(self.patched)
47        stage4_lock_offset = self.elf.sym['STAGE4_LOCK']    # Be 31337 and just use pwnt00ls
48        self.elf.write(stage4_lock_offset, b"\x00")
49        self.elf.save(self.patched)
50        self.elf = ELF(self.patched)
51        self.p = process([self.elf.path, '--stage', '4'])
52        self.p.send(b'\n')
53        self.get_flag(b"TOKEN4: ")
54
55    def stage5(self) -> None:
56        # The most meme stage of them all lmao easiest one
57        cipher = [0xF5,0xE5,0xE4,0xEB,0xD2,0xEB,0xF9,0xEF,0x80,0xDC,0x99,0xD5,0x80,0x84,0x81,0xC9]
58        base_key = 0xa5
59        results = ""
60        for c in cipher:
61            results += chr(c ^ base_key)
62            base_key += 1
63        log.success(f"FLAG = {results}")
64        self.p = process([self.elf.path, '--stage', '5'])
65        self.p.sendline(results.encode('utf-8'))
66        self.p.interactive()
67
68if __name__ == "__main__":
69    e = Exploit("./arcadian")
70    e.stage1()
71    e.stage2()
72    e.stage3()
73    e.stage4()
74    e.stage5()