Skip to content

Instantly share code, notes, and snippets.

@hugsy
Created April 14, 2019 00:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hugsy/cd9502bb23082ea0e2fdb426c23b0ae8 to your computer and use it in GitHub Desktop.
Save hugsy/cd9502bb23082ea0e2fdb426c23b0ae8 to your computer and use it in GitHub Desktop.
#!/usr/bin/python3
#
# Emulation script for "i_can_count_8484ceff57cb99e3bdb3017f8c8a2467" from 0x56556104 to 0x56556109
#
# Powered by gef, unicorn-engine, and capstone-engine
#
# @_hugsy_
#
from __future__ import print_function
import collections
import capstone, unicorn
registers = collections.OrderedDict(sorted({'$eax': unicorn.x86_const.UC_X86_REG_EAX,'$ebx': unicorn.x86_const.UC_X86_REG_EBX,'$ecx': unicorn.x86_const.UC_X86_REG_ECX,'$edx': unicorn.x86_const.UC_X86_REG_EDX,'$esp': unicorn.x86_const.UC_X86_REG_ESP,'$ebp': unicorn.x86_const.UC_X86_REG_EBP,'$esi': unicorn.x86_const.UC_X86_REG_ESI,'$edi': unicorn.x86_const.UC_X86_REG_EDI,'$eip': unicorn.x86_const.UC_X86_REG_EIP,'$eflags': unicorn.x86_const.UC_X86_REG_EFLAGS,'$cs': unicorn.x86_const.UC_X86_REG_CS,'$ss': unicorn.x86_const.UC_X86_REG_SS,'$ds': unicorn.x86_const.UC_X86_REG_DS,'$es': unicorn.x86_const.UC_X86_REG_ES,'$fs': unicorn.x86_const.UC_X86_REG_FS,'$gs': unicorn.x86_const.UC_X86_REG_GS}.items(), key=lambda t: t[0]))
uc = None
verbose = False
syscall_register = "$eax"
flag_buf_addr = 0x56558048
check_buf = 0x565580e8
is_valid_char = False
current_char = 0
current_iter = 0
current_idx = 0
class FoundException(Exception): pass
def code_hook(emu, address, size, user_data):
global is_valid_char, current_iter
if address == 0x56555A76:
# current_char = emu.reg_read( registers["$eax"]) & 0xff
current_iter += 1
if address == 0x56555F9A: # call printf --> win
raise Exception("we're done")
if address == 0x56555f75: # cmp
# we control eax
dl = emu.reg_read( registers["$edx"]) & 0xff
al = emu.reg_read( registers["$eax"]) & 0xff
if al == dl and (current_iter-1) == current_idx:
# print("(%d) i=%d %x = %x" % (current_idx, current_iter, al, dl))
is_valid_char = True
return
def print_reg(emu, reg):
print("{:7s} = {:#04x} ".format(reg, emu.reg_read( registers[reg])))
return
def reset():
emu = unicorn.Uc(unicorn.UC_ARCH_X86, unicorn.UC_MODE_32 | unicorn.UC_MODE_LITTLE_ENDIAN)
emu.reg_write(unicorn.x86_const.UC_X86_REG_EAX, 0xb)
emu.reg_write(unicorn.x86_const.UC_X86_REG_EBX, 0x56558000)
emu.reg_write(unicorn.x86_const.UC_X86_REG_ECX, 0x56559160)
emu.reg_write(unicorn.x86_const.UC_X86_REG_EDX, 0xf7fb4890)
emu.reg_write(unicorn.x86_const.UC_X86_REG_ESP, 0xffffd440)
emu.reg_write(unicorn.x86_const.UC_X86_REG_EBP, 0xffffd468)
emu.reg_write(unicorn.x86_const.UC_X86_REG_ESI, 0xf7fb3000)
emu.reg_write(unicorn.x86_const.UC_X86_REG_EDI, 0x0)
emu.reg_write(unicorn.x86_const.UC_X86_REG_EIP, 0x56556104)
emu.reg_write(unicorn.x86_const.UC_X86_REG_EFLAGS, 0x282)
# Mapping /home/hugsy/ctf/plaidctf_2019/i can count/i_can_count_8484ceff57cb99e3bdb3017f8c8a2467: 0x56555000-0x56557000
emu.mem_map(0x56555000, 0x2000, 0o5)
emu.mem_write(0x56555000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0x56555000.raw', 'rb').read())
# Mapping /home/hugsy/ctf/plaidctf_2019/i can count/i_can_count_8484ceff57cb99e3bdb3017f8c8a2467: 0x56557000-0x56558000
emu.mem_map(0x56557000, 0x1000, 0o1)
emu.mem_write(0x56557000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0x56557000.raw', 'rb').read())
# Mapping /home/hugsy/ctf/plaidctf_2019/i can count/i_can_count_8484ceff57cb99e3bdb3017f8c8a2467: 0x56558000-0x56559000
emu.mem_map(0x56558000, 0x1000, 0o3)
emu.mem_write(0x56558000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0x56558000.raw', 'rb').read())
# Mapping [heap]: 0x56559000-0x5657b000
emu.mem_map(0x56559000, 0x22000, 0o3)
emu.mem_write(0x56559000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0x56559000.raw', 'rb').read())
# Mapping /lib32/libc-2.27.so: 0xf7dde000-0xf7fb0000
emu.mem_map(0xf7dde000, 0x1d2000, 0o5)
emu.mem_write(0xf7dde000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0xf7dde000.raw', 'rb').read())
# Mapping /lib32/libc-2.27.so: 0xf7fb0000-0xf7fb1000
emu.mem_map(0xf7fb0000, 0x1000, 0o0)
# Mapping /lib32/libc-2.27.so: 0xf7fb1000-0xf7fb3000
emu.mem_map(0xf7fb1000, 0x2000, 0o1)
emu.mem_write(0xf7fb1000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0xf7fb1000.raw', 'rb').read())
# Mapping /lib32/libc-2.27.so: 0xf7fb3000-0xf7fb4000
emu.mem_map(0xf7fb3000, 0x1000, 0o3)
emu.mem_write(0xf7fb3000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0xf7fb3000.raw', 'rb').read())
# Mapping : 0xf7fb4000-0xf7fb7000
emu.mem_map(0xf7fb4000, 0x3000, 0o3)
emu.mem_write(0xf7fb4000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0xf7fb4000.raw', 'rb').read())
# Mapping : 0xf7fcf000-0xf7fd1000
emu.mem_map(0xf7fcf000, 0x2000, 0o3)
emu.mem_write(0xf7fcf000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0xf7fcf000.raw', 'rb').read())
# Mapping [vdso]: 0xf7fd4000-0xf7fd6000
emu.mem_map(0xf7fd4000, 0x2000, 0o5)
emu.mem_write(0xf7fd4000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0xf7fd4000.raw', 'rb').read())
# Mapping /lib32/ld-2.27.so: 0xf7fd6000-0xf7ffc000
emu.mem_map(0xf7fd6000, 0x26000, 0o5)
emu.mem_write(0xf7fd6000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0xf7fd6000.raw', 'rb').read())
# Mapping /lib32/ld-2.27.so: 0xf7ffc000-0xf7ffd000
emu.mem_map(0xf7ffc000, 0x1000, 0o1)
emu.mem_write(0xf7ffc000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0xf7ffc000.raw', 'rb').read())
# Mapping /lib32/ld-2.27.so: 0xf7ffd000-0xf7ffe000
emu.mem_map(0xf7ffd000, 0x1000, 0o3)
emu.mem_write(0xf7ffd000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0xf7ffd000.raw', 'rb').read())
# Mapping [stack]: 0xfffdd000-0xffffe000
emu.mem_map(0xfffdd000, 0x21000, 0o3)
emu.mem_write(0xfffdd000, open('/tmp/gef-i_can_count_8484ceff57cb99e3bdb3017f8c8a2467-0xfffdd000.raw', 'rb').read())
emu.hook_add(unicorn.UC_HOOK_CODE, code_hook)
return emu
def bf_idx(idx, flag):
global is_valid_char, current_iter, current_idx
current_idx = idx
charset = bytearray(b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~')
is_valid_char = False
for c in charset:
current_iter = 0
mem = bytes( flag + bytearray([c,]) )
uc = reset()
uc.mem_write(flag_buf_addr, mem)
try:
uc.emu_start(0x56555a45, 0x56555FB6)
if is_valid_char:
return c
except Exception as e:
print(e)
raise Exception("failed to find char idx %d" % idx)
if __name__ == "__main__":
flag = bytearray(b"")
for i in range(0, 19, 1):
c = bf_idx(i, flag)
# print("[%d] Found valid char '%c'" % (i, c))
flag += bytearray([c,])
print("current_flag=" + "".join([chr(x) for x in flag]))
# unicorn-engine script generated by gef
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment