angr-in-action/crackmes/study/3/solve.py

73 lines
3.0 KiB
Python

# в случае корректного ключа в реестре выведет "Error writing new value."\"New value written to the registry.\n";
import angr
import time
import claripy
GREEN = "\033[92m"
PURPLE = "\033[35m"
RESET = "\033[0m"
RED = "\033[31m"
INPUT_DATA = None
def RegOpenKeyExW(state: angr.SimState):
state.regs.eax = claripy.BVV(0, 32)
def RegQueryValueExW(state: angr.SimState):
state.regs.eax = claripy.BVV(0, 32)
def RegGetValueW(state: angr.SimState):
global INPUT_DATA, INPUT_SIZE
INPUT_DATA = state.solver.BVS('input_data', 8 * INPUT_SIZE)
state.memory.store(state.regs.rbp - 0x118, INPUT_DATA) # потому что _BYTE pvData[256]; // [rsp+60h] [rbp-118h] BYREF
state.regs.eax = claripy.BVV(0, 32)
def RegSetValueExW(state: angr.SimState):
state.regs.eax = claripy.BVV(0, 32)
def puts(state: angr.SimState): pass
if __name__ == "__main__":
# Загрузка бинарного файла
print(f"{GREEN}Uploading executable file to angr...{RESET}")
proj = angr.Project('test3.exe', auto_load_libs=False)
print(f"{GREEN}The executable has been uploaded to angr!{RESET}")
ENTRY_POINT = 0x140001000 # Адрес функции main
TARGET_ADDR = 0x1400010F9 # Целевой адрес, нахождение на нем означает что программа взломана
# Хуки
proj.hook(0x14000103A, RegOpenKeyExW, length=6)
proj.hook(0x14000106F, RegQueryValueExW, length=6)
proj.hook(0x1400010AF, RegGetValueW, length=6)
proj.hook(0x1400010EF, RegSetValueExW, length=6)
proj.hook(0x14000112D, puts, length=6)
# Перебираем размер входных данных от 1 до 20
for INPUT_SIZE in range(1, 21):
print(f"{GREEN}Trying input size: {INPUT_SIZE}{RESET}")
# Создаем начальное состояние
state = proj.factory.entry_state(
addr=ENTRY_POINT,
add_options={angr.options.ZERO_FILL_UNCONSTRAINED_REGISTERS,
angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY}
)
# Инициализация стека
state.regs.rbp = 0x7ffffffffffffff
state.regs.rsp = 0x7ffffffffffffff
# Запуск симуляции
simgr = proj.factory.simulation_manager(state)
start_time = time.time()
simgr.explore(find=TARGET_ADDR)
elapsed = time.time() - start_time
# Проверка результата
if simgr.found:
found_state = simgr.found[0]
input_data = found_state.solver.eval(INPUT_DATA, cast_to=bytes)
print(f"{GREEN}Success cracked! Input: {PURPLE}{input_data}{PURPLE}{RESET}")
print(f"{GREEN}Pwd cracking time = {elapsed}{RESET}")
break # Выход из цикла, если найдено решение
else:
print(f"{RED}Failed with input size {INPUT_SIZE}{RESET}")
else:
print(f"{RED}Failed to find a solution with input sizes from 1 to 20{RESET}")