$ file 02_angr_find_condition
02_angr_find_condition: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=6bc3ff3d86d24ca7f2828d05496d14647eb2012d, not stripped
“Good Job.”을 출력해주는 경로의 주소를 알 수 없는 경우이다.
패스워드가 맞을 경우 “Good Job.”을, 틀릴 경우 “Try again.”을 출력해주는 것을 알기 때문에, 이 출력되는걸 기반으로 가능한 경로를 찾아서 solution을 찾는다.
#!/usr/bin/python
import angr
import sys
# create angr project
project = angr.Project('./02_angr_find_condition')
# set starting state from main()
state = project.factory.entry_state(add_options={angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY, angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS})
# create simulation manager initializing with starting state
simgr = project.factory.simgr(state)
# dump whatever printed out by the binary into string and find path include good in string
# avoid path including Try
simgr.explore(find=lambda s: b'Good' in s.posix.dumps(sys.stdout.fileno()), avoid=lambda s: b'Try' in s.posix.dumps(sys.stdout.fileno()))
# if found stash is not empty, print found address, decoded solution
if simgr.found:
print('find address:', end= ' ')
print(simgr.found[0])
print('solution:', end=' ')
print(simgr.found[0].posix.dumps(0).decode())
else:
raise Exception('error: could not find solution')
sys.stdout.fileno() 로 바이너리가 출력하는 것을 모두 문자열로 덤프하고, 여기에 ‘Good’이 있으면 해당 경로에서 상태를 find stash로, ‘Try’가 있으면 해당 상태를 avoid stash에 넣는다.
found에서 바이너리가 출력하는 문자열을 출력해보면 solution을 구할 수 있다.
[angr_ctf] 04_angr_symbolic_stack (0) | 2022.05.14 |
---|---|
[angr_ctf] 03_angr_symbolic_registers (0) | 2022.05.14 |
[angr_ctf] 01_angr_avoid (0) | 2022.05.14 |
[angr_ctf] 00_angr_find (0) | 2022.05.14 |
GoogleCTF 2016 unbreakable_0 (0) | 2022.05.11 |