新知识

为找的 malloc_chunk 地址保存时 需要加上 endness 参数 endness=p.arch.memory_endness 保证程序的大小端保存相同

init_state.memory.store(buffer0,fake_malloc_chunk_0,endness=p.arch.memory_endness)

分析

这次的输入保存在 动态分配中。 我们就要利用 angr 来符号话这样的输入。

我们要做的就是用 在 scanf 之后 进入 让伪造好我们的 参数地址的环境 (为了让angr脚本能正常运行)

buffer0_addr → buffer0 → malloc_chunk

# -*- encoding: utf-8 -*-
from __future__ import print_function
import angr
import sys
import claripy
'''
@文件        :angr_exp.py
@时间        :2020/04/24 11:46:50
@作者        :0xc4m3l
'''
def main(argv):
    bin_patch = argv[1]
    p  = angr.Project(bin_patch)
    
    start_addr = 0x8048699
    init_state = p.factory.blank_state(addr = start_addr) 

    an0 = init_state.solver.BVS('an0', 64)
    an1 = init_state.solver.BVS('an1', 64)

    print("ESP:",init_state.regs.esp)
    fake_malloc_chunk_0 = 0x7ffefffc-0x100
    fake_malloc_chunk_1 = 0x7ffefffc-0x200

    buffer0 = 0x9FD92AC
    buffer1 = 0x9FD92B4

    # buffer0 -> fake_malloc_chunk_0 (符号指令)
    # 为找的 malloc_chunk 地址保存时 需要加上 endness 参数 endness=p.arch.memory_endness  保证程序的大小端保存相同
    init_state.memory.store(buffer0,fake_malloc_chunk_0,endness=p.arch.memory_endness)
    init_state.memory.store(buffer1,fake_malloc_chunk_1,endness=p.arch.memory_endness)
    init_state.memory.store(fake_malloc_chunk_0,an0)
    init_state.memory.store(fake_malloc_chunk_1,an1)

    sm = p.factory.simgr(init_state)

    def is_good(state):
        return b"Good Job" in state.posix.dumps(1)

    def is_bad(state):
        return b"Try again" in state.posix.dumps(1)

    sm.explore(find = is_good, avoid = is_bad)

    if sm.found:
        found_state = sm.found[0]
        password0 = found_state.solver.eval(an0, cast_to = bytes).decode('utf-8')
        password1 = found_state.solver.eval(an1, cast_to = bytes).decode('utf-8')
        print("solution : {} {}".format(password0,password1))
    else:
        raise Exception ("no found")

if __name__ == '__main__':
    main(sys.argv)