一个菜鸡学习angr_CTF的开始

00_angr_find

第一步还是我们的ida来分析一下程序。看的出来,这个程序并不是很难,先把输入一个字符串password,然后进过一个循环的complex_function函数的加密。

complex_function函数内容如下,如果是逆向的话,只要把这个算法逆出来就好了,但是我们用angr,直接约束符号求解,我们不需要怎么管他怎么运算的,因为程序走的时候有分支,让程序走到等于的位置成了。

先用import angr导入模块,然后用angr.Project("文件"),来创建一个工程,这个创建工程呢就是把这个文件加载什么的搞进去了。

下一步我们就要给他初始化,告诉他从那开始执行。inti_state = p.factory.entry_state()这个就是初始化的入口状态。

那执行是谁来呢,执行是sm = p.factory.simulation_manager(inti_state),这个就是从初始划的地方开始执行。

那我们现在想要什么呢?我们想要他来到“good job”这个地方,那我们直接给他这个地方的地址sm.explore(find=0x08048678)用这个指令不断的去模拟去发现这个地址,每一个分支都是按条件分开的。可以看到我们找到一个。1个活动,16个死了,还有1个找到。

然后我们来看看这个找到的found肯定是一个数组了然后我们来看看这个找到的,found肯定是一个数组了,这就是我们找到的状态。

但是我们关心的是输入的是什么状态,标准输入是0,输出是1,也就是现在我们已经成功了,输入“JXWVXRKX”

成功了

import angr
p = angr.Project("./00_angr_find")
init_state = p.factory.entry_state()
sm = p.factory.simulation_manager(init_state)
sm.explore(find=0x08048678)
sm.found[0]
found_state = sm.found[0]
found_state.posix.dumps(0)
found_state.posix.dumps(1)

总结,整体下来感觉啥都没干,就是先初始化,然后给他执行到我们想要的位置,然后我们来看这个结果是啥就出了,刚开始学,比较简单理解也比较少,继续搞!

01_angr_avoid

第一题刚做的时候还是什么都不懂,也只知道现在这几个函数,到了第二题看了一下,感觉和第一题差不多,所以我直接使用了第一题的脚本,发现行不通,应该是路径爆炸了,一直是这样,然后才知道,有个函数交avoid不让他寻找。

首先我们ida打开程序,发现程序有点问题,出了mian函数外,其他的都可以反汇编,我当时就寻思着这也太难看了吧,然后又看着和上题差不多就直接套用了,结果是不行的。

后来看到有个函数交avoid_me,意思差不多就是不要找我。

那好,问题发现了,我们直接解决,前面的一下初始化,执行,都是一样的,直到寻找的时候不一样了,我们之前寻找都是sm.explore(find=0x地址),但是现在我们要不寻找地址,不然会路径爆炸应该是,所以我们要改成sm.explore(find=0x地址, avoid=0x地址),find是我们要找到的地址,avoid是我们不要找的地址。

运行结束后16个死亡,1个找到,8个未找,结果拿到

import angr
p = angr.Project("./00_angr_find")
init_state = p.factory.entry_state()
sm = p.factory.simulation_manager(init_state)
sm.explore(find=0x080485E5,avoid=0x080485A8)
sm.found[0]
found_state = sm.found[0]
found_state.posix.dumps(0)
# b'HUJOZMYS'
found_state.posix.dumps(1)
# b'Enter the password: '

又学到一个新知识呢

02_angr_condition

打开这个第二关后发现其实内容和第0个是一样的,但是我们就不要用ipython来写了,显得我们太low辣,所以我们开始学习写angr的脚本

在写脚本之前先导入环境improt angr,import sys

然后我们定义一个main函数,传一个argv,bin_path就等于argv[1]

然后主main这么写,直接执行,把参数传进来。

然后和之前一样新建一个工程angr.Project(bin_path),给初始化状态入口点init_state = p.factory.entry_state(),然后用simulation_manager模拟执行 ,sm = p.factory.simulation_manager(init_state)

然后跑起来之后呢,我们要有一个sm.explore(find=is_good, avoid=is_bad),我们之前都是直接接受一个地址,现在我们就直接接受一个函数,然后这个函数接受一个状态state

只要他的返回类型是布尔就可以了,就是状态里面进行判断是我们想要的就ture,isgood就是goodjob,然后我们用state.posix.dumps(1)来进行判读,isbad也是一样的。

最后我们用sm.found找到我们要的状态,然后我们用if判断,如果找到就直接输出就好了

import angr
import sys

def main(argv):
    bin_path = argv[1]

    p = angr.Project(bin_path)

    init_state = p.factory.entry_state()

    sm = p.factory.simulation_manager(init_state)

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

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

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

    if sm.found:
        found_state = sm.found[0]
        #print(1)
        print("Solution: {}".format(found_state.posix.dumps(0)))

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

唉,这个是第一次用python脚本写,之前两题都是用ipython来写的脚本,现在感觉脚本还是有难度的呜呜呜。我写完这个脚本调试好几次都没得到结果,后来才发现一些细小的问题呜呜呜呜呜~~~~

然后现在学到的都是通过found去找,找到我们要的地址,状态,找到了给我们返回,感觉angr吊嘟!

03_angr_symbolic_registers

唉从03开始angr用法啥的就是大难的增加了。这个03和之前有什么不一样呢,首先它有3个complex_function,然后它是输入也是不一样的。在这一题中首先因为有三个scanf的原因所以符号不好搞,但是说是新的angr已经可以解决这些个问题了,但我们还是用angr原本的方法来解决这个问题。

因为我们是scanf不好符号化,我们就可以不走scanf这个函数的,可以不走但是该有的值还得是要有的。从这我们可以看到scanf传入的值是放在eax,ebx,edx这个三个寄存器中,那我们就可以控制初始化开始的时候在scanf函数下面进行,也是就是0x8048980这位置

所以我们一开始就把这三个寄存器变成我们的符号向量。前面的创建工程什么的都是不变,主要是初始化我们要指定地址的初始化使用blank_state的参数,它可以接受一个addr,addr就是我们要从哪里开始的参数

给初始化之后呢,我们并不是马上执行,我们需要把符号向量赋值,才可以往下走。新建符号向量,32是他的大小。32位寄存器。像这个我们需要3个因为有3个寄存器。

现在3个符号向量有了,下面我们就要把这3个符号向量分别赋值到3个寄存器里面。

下面我就使用simulation_maager来运行

下面我就开始explore,还是一样的搞两个函数状态。

接下来就是我们要计算符号向量的值比起之前多了一个found_state.solver.eval(pass1)其他都是差不多的,然后最后输出我们用16进制,因为在程序中就是以16进制的方法输入的。

最后还是找到了答案

import angr
import sys
import claripy

def main(argv):

    bin_path = argv[1]
    p = angr.Project(bin_path)

    start_addr = 0x08048980
    init_state = p.factory.blank_state(addr = start_addr)


    pass1 = claripy.BVS('pass1', 32)
    pass2 = claripy.BVS('pass2', 32)
    pass3 = claripy.BVS('pass3', 32)

    init_state.regs.eax = pass1
    init_state.regs.ebx = pass2
    init_state.regs.edx = pass3

    sm = p.factory.simulation_manager(init_state)

    def is_good(state):
        return b'Good' in state.posix.dumps(1)
    def is_bad(state):
        return b'Try' in state.posix.dumps(1)

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

    if sm.found:
        found_state = sm.found[0]

        password1 = found_state.solver.eval(pass1)
        password2 = found_state.solver.eval(pass2)
        password3 = found_state.solver.eval(pass3)

        print("Solution {:x} {:x} {:x}".format(password1, password2,password3))

    else:
        raise Exception('NO solution found')

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

这题的话主要还是用那3个寄存器符号向量来模拟scanf,初始化,然后执行explore去寻找,然后求解。

小总结一下吧,这个03与之前的3题开始不一样了,开始接触到angr越来越多的用法了,在后面的题目中我们肯定会遇到更多的用法,在这题中其实我已经有一些函数是看不懂的了,所以往下我来先看看一下angr中的函数!学习!话说angr真的很好用,都没有思考算法逆向直接求解。

Angr部分模块

才写4题但是吧,我觉得可以看看angr的一些模块了,因为有的函数我看的一头雾水。而且感觉这4题还是属于非常简单的angr题目,到后面才是大牛!看了toka✌的文章,来自己熟悉一下现在学到的模块Angr 使用技巧速通笔记(一) | TokameinE - 雨声淅淅沥沥,犬吠永不止息

首先我目前的大概的angr流程如下

import angr
p = angr.Project(bin_path)
init_state = p.factory.entry_state()
sm = p.factory.simulation_manager(init_state)
sm.explore(find=,avoid=)
if sm.found:
    found_state = sm.found[0]
    print("Solution: {}".format(found_state.posix.dumps(0)))
Project模块

angr.Project会加载二进制程序,angr会读取这个二进制的一些基本属性

project = angr.Project(path_to_binary, auto_load_libs=False)

factory模块

这个模块就是来将project实例化,我的感觉就是要用factory来执行我们project的二进制文件。

State模块

state包括了所有符号执行的符号。那这个是不是就是哪里需要哪里搬?不是太理解。然后entry_state是初始化外还有其他两个可以,其中blank_state是我用过的就在03。

blank_state:构造一个“空白板”空白状态,其中大部分数据未初始化。当访问未初始化的数据时,将返回一个不受约束的符号值。
entry_state:造一个准备在主二进制文件的入口点执行的状态。
full_init_state:构造一个准备好通过任何需要在主二进制文件入口点之前运行的初始化程序执行的状态,例如,共享库构造函数或预初始化程序。完成这些后,它将跳转到入口点。
call_state:构造一个准备好执行给定函数的状态。

Simulation Managers模块

个人理解就是在上面进行初始化的时候使用simulation managers来进行执行符号的运行。SM(Simulation Managers)是一个用来管理 State 的模块,它需要为符号指出如何运行。

看了这些模块,牛波一

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值