Angr не может решить проблему googlectf для начинающих
Я студент, изучаю сердитый впервые.
Я смотрю код в этом URL.
https://github.com/Dvd848/CTFs/blob/master/2020_GoogleCTF/Beginner.md
import angr
import claripy
FLAG_LEN = 15
STDIN_FD = 0
base_addr = 0x100000 # To match addresses to Ghidra
proj = angr.Project("./a.out", main_opts={'base_addr': base_addr})
flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(FLAG_LEN)]
flag = claripy.Concat( *flag_chars + [claripy.BVV(b'\n')]) # Add \n for scanf() to accept the input
state = proj.factory.full_init_state(
args=['./a.out'],
add_options=angr.options.unicorn,
stdin=flag,
)
# Add constraints that all characters are printable
for k in flag_chars:
state.solver.add(k >= ord('!'))
state.solver.add(k <= ord('~'))
simgr = proj.factory.simulation_manager(state)
find_addr = 0x101124 # SUCCESS
avoid_addr = 0x10110d # FAILURE
simgr.explore(find=find_addr, avoid=avoid_addr)
if (len(simgr.found) > 0):
for found in simgr.found:
print(found.posix.dumps(STDIN_FD))
https://github.com/google/google-ctf/tree/master/2020/quals/reversing-beginner/attachments
Это ответ новичка googlectf.
Но приведенный выше код не работает. Это не дает мне ответа.
Я хочу знать, почему код не работает.
Когда я выполняю этот код, вывод был пуст.
Я запускаю код с python3 в Ubuntu 20.04 в wsl2
Спасибо.
1 ответ
Я считаю, что этот скрипт ничего не печатает, потому что angr не может найти решение, а затем завершает работу. Вы можете доказать это, добавив в свой скрипт следующее:
else:
raise Exception('Could not find the solution')
Если возникает исключение, допустимое решение не найдено.
С точки зрения того, почему это не работает, этот код выглядит как копирование и вставка из нескольких разных источников, поэтому он довольно запутан.
Например, способ передачи символа флага на стандартный ввод не идеален. По умолчанию stdin — это SimPackets , поэтому лучше оставить его таким.
Следующий скрипт решает задачу, я прокомментировал его, чтобы помочь вам понять. Вы заметите, что изменениеstdin=angr.SimPackets(name='stdin', content=[(flag, 15)])
кstdin=flag
приведет к сбою сценария по причине, упомянутой выше.
import angr
import claripy
base = 0x400000 # Default angr base
project = angr.Project("./a.out")
flag = claripy.BVS("flag", 15 * 8) # length is expected in bits here
initial_state = project.factory.full_init_state(
stdin=angr.SimPackets(name='stdin', content=[(flag, 15)]), # provide symbol and length (in bytes)
add_options ={
angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY,
angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS
}
)
# constrain flag to common alphanumeric / punctuation characters
[initial_state.solver.add(byte >= 0x20, byte <= 0x7f) for byte in flag.chop(8)]
sim = project.factory.simgr(initial_state)
sim.explore(
find=lambda s: b"SUCCESS" in s.posix.dumps(1), # search for a state with this result
avoid=lambda s: b"FAILURE" in s.posix.dumps(1) # states that meet this constraint will be added to the avoid stash
)
if sim.found:
solution_state = sim.found[0]
print(f"[+] Success! Solution is: {solution_state.posix.dumps(0)}") # dump whatever was sent to stdin to reach this state
else:
raise Exception('Could not find the solution') # Tell us if angr failed to find a solution state
Немного мелочи - на самом деле есть несколько «решений», которые программа примет, хотя я думаю, что сервер флагов CTF принимает только одно.
❯ echo -ne 'CTF{\x00\xe0MD\x17\xd1\x93\x1b\x00n)' | ./a.out
Flag: SUCCESS