Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save disconnect3d/424e89c4c550f0d7d016398a8e14fe33 to your computer and use it in GitHub Desktop.
Save disconnect3d/424e89c4c550f0d7d016398a8e14fe33 to your computer and use it in GitHub Desktop.
Solution for sorcerery crackme2000 task from DefCon Quals CTF
"""
Solution from Disconnect3d [playing in Just Hit the Core]
"""
import os
import angr
import pwn
import subprocess
def crack_bin(binary):
p = angr.Project(binary, load_options={'auto_load_libs': False})
cfg_fast = p.analyses.CFG()
exit_func = p.kb.functions.function(name='exit')
free_func = p.kb.functions.function(name='free')
pthread_mutex_unlock_func = p.kb.functions.function(name='pthread_mutex_unlock')
malloc_func = p.kb.functions.function(name='malloc')
base_addr = 0x400000
start_addr = 0x4036A3 # condition blocks start here
# some bss memory region we will use to read the flag(?) content from
bss_addr = 0x21BCE8
cmd = 'objdump -Mintel -d {} | grep "mov rax,QWORD PTR \\[rsp+0x8\\]"'.format(binary)
tmp = subprocess.check_output(cmd, shell=True)
tmp = tmp.strip()
tmp = tmp[:tmp.index(':')]
win_addr = base_addr + int('0x' + tmp, 16)
"""
.text:000000000040369F mov rdi, [rsp+0B8h+var_B8] ; ptr
START HERE ---> .text:00000000004036A3 mov cl, [rdi]
So that we .text:00000000004036A5 cmp cl, 6Eh
can set rdi .text:00000000004036A8 jnz loc_4010E6
to any address
and read flag(?)
value later on
"""
# creating state that will be used for path exploration/traversal
state = p.factory.blank_state(addr=start_addr, add_options={'BYPASS_UNSUPPORTED_SYSCALL'})
# Setting RDI so we will know the address of string in the future
state.regs.rdi = bss_addr
# creating path group which will start on the given state and will be used for path exploration
pg = p.factory.path_group(state)
# explore the possibilities! find the win scenario path & state, avoid some stuff...
r = pg.explore(find=win_addr, avoid=[exit_func.addr, pthread_mutex_unlock_func])
# previous exploration - it didn't work well for all of the binaries.
#r = pg.explore(find=free_func.addr, avoid=exit_func.addr)
# take the path that found winning address
found = r.found[0]
string = found.state.se.any_str(found.state.memory.load(bss_addr, 64))
print "Binary %s = '%s'" % (binary, string)
return string
data = {}
binaries = os.listdir('.')
for bin in binaries:
print('Analysing %s' % bin)
data[bin] = crack_bin(bin)
"""
# Code below launches binaries with their inputs to get outputs, not really needed.
def out(binary, stdin):
p = pwn.process(binary)
p.sendline(stdin)
r = p.recvall()
print r
return r
#
# a = []
# for k, v in data.items():
# a.append(out(k, v))
"""
k = pwn.remote('cm2k-sorcery_13de8e6bf26e435fc43efaf46b488eae.quals.shallweplayaga.me', 12002)
k.recvuntil('followed by a newline\n')
while True:
binary = k.recvuntil('\n')[:-1]
print('GOT: %s' % binary)
d = data[binary]
print('SENDING: %s' % d)
k.sendline(pwn.b64e(d))
k.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment