愤怒永远不会结束

逆向工程 愤怒
2021-06-13 21:56:52

我创建了以下 c 程序作为概念证明。当我试图用愤怒来分析它时,它永远不会结束。

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

char *secret = "password";

int compare(char *string)
{
    int i, c=0;
    for (i=0; i< strlen(secret); i++)
    {
        if (string[i] == secret[i])
            c++;
    }
    if (c == 8)
        printf("You won");
    return 0;
}
int main(int argc, char **argv)
{
    char input[50];
    scanf("%s", input);
    compare(input);
    return EXIT_SUCCESS;
}

脚本如下:

#!/usr/bin/env python

import angr
import sys
import logging
import claripy

FIND = 0x00000000000011dd
LEN = 8 

def basic_symbolic_execution():
    p = angr.Project('test', load_options={'auto_load_libs':False})

    flag = claripy.BVS('flag', LEN * 8)

    st = p.factory.entry_state(
        stdin=flag,
    )

    sm = p.factory.simulation_manager(st)
    sm.explore(find=FIND, num_find=1)

    print("Found solution")
    out = b''

    for pp in sm.deadended:
        out = pp.posix.dumps(1)
        print(out)

    import IPython; IPython.embed()

def test():
    r = basic_symbolic_execution()

if __name__ == '__main__':
    sys.stdout.buffer.write(basic_symbolic_execution())

我还尝试在 c++ 的地址上使用 explore 8 次,然后检查 stdin 并完成,但结果全为零。我想知道你们中是否有人遇到过类似的事情,以及你们的解决方案是什么。

1个回答

根据您的 FIND 地址,您的二进制文件似乎是用 PIE 编译的。请验证这一点。Angr 将在 0x400000 的基地址加载启用 PIE 的精灵,将其添加到您的 FIND 地址,以便 angr 能够解决这个问题。

我对您的脚本进行了一些更改,以使其检测到“密码”。

import angr
import sys
import logging
import claripy

FIND = 0x00400672
LEN = 8

def basic_symbolic_execution():
    p = angr.Project('x', load_options={'auto_load_libs':False})

    flag = claripy.BVS('flag', LEN * 8)

    st = p.factory.entry_state(
        stdin=flag,
    )

    sm = p.factory.simulation_manager(st)
    sm.explore(find=FIND, num_find=1)

    print("Found solution")
    out = b''

    for pp in sm.found:
        out = pp.posix.dumps(0)
        print(out)
        print(pp.solver.eval(flag, cast_to=str))

    import IPython; IPython.embed()

def test():
    r = basic_symbolic_execution()

if __name__ == '__main__':
    basic_symbolic_execution()

为了寻找这实际上达到了你需要遍历您查找地址状态foundsimulation_manager

根据 man stdin

在程序启动时,与流 stdin、stdout 和 stderr 关联的整数文件描述符分别为 0、1 和 2。

所以要获得输入,您需要使用 pp.posix.dumps(0)

我还添加了如何使用solver找到的状态来解决您设置的约束,如flag.

对我来说,二进制文件中的 printf 也有偏移。

$ gcc -no-pie -fno-pic x.c -o x
$ r2 -AA x -qc "pdf @ sym.compare ~won"    
│       │   0x00400672      bf7d074000     mov edi, str.You_won        ; 0x40077d ; "You won"