使用angr和Radare解决CMU的二进制炸弹

前言

最近在学习angr的使用,主要是如何利用angr来进行符号执行分析。发现了国外一篇比较实用的文章介绍如何使用angr和Radare(二进制分析框架)来分析CMU的二进制炸弹问题。故在此翻译一下这篇文章的工作。

angr

angr是一个使用python语言编写的二进制分析框架,它主要是进行静态和动态的符号分析,现已成为CTF比赛的一大利器。angr最主要的一个工具就是符号执行,具体的符号执行可以参考MIT的一个课程(需要梯子才可以观看)。

Radare2

radare2是从零开始重写radare,以便提供一组库和工具来处理二进制文件。

在这篇文章里是先用的Radare2对二进制炸弹进行分析,弄清二进制文件的逻辑关系,然后再用angr的符号执行工具解出答案。关于radare2工具的介绍可以参考Radare2 Book

所面临的问题

要用angr和radare2所解决的问题是CMU的二进制炸弹,我们在此只分析phase2部分,如果对其他部分有兴趣的话可以参考我的另一篇博客对二进制炸弹做了全面的分析。phase2主要是要求输入6个正确的数字。

Crack

Radare2分析

  1. 使用Radare2加载程序,并输入aaa开始分析二进制程序

  2. 首先利用Radare2中的工具afl来查找符合条件的函数。使用afl并且grep(使用符号~来代表)筛选关键字, 可以看到筛选结果中有phase2。

  3. 使用seek工具来定位到我们感兴趣的函数处,此处为sym.phase_2函数。并用pdf([p]rint [d]issembly of [f]unction)命令来展示该函数的内容。

  4. 如何要展示函数中的控制流程图可以在Radare2中使用VV(两个大写的V)指令。

  5. 为了进行符号执行,我们必须弄清楚程序的输入是什么,通过radare工具反汇编出来的代码可以看出,函数read_six_numbers很有可能就是处理输入的函数。

  6. 在radare2中使用ga指令进入read_six_numbers函数, 具体的函数代码如下所示:

可以看出该函数中以六个数字作为scanf函数的输入,所以我们就将此作为输入。

  1. 接下来我们需要分析符号执行所需要开始的代码处,符号执行不能走的路径以及要到达的目标代码处。

    从上图可以看出0x400f10和0x400f20处的代码都调用explode_bomb函数。


具体的explode_bomb函数如上图所示,我们可以看出该函数会调用exit函数,所以我们要避免走到explode_bomb函数中去。即避免走到0x400f10和0x400f20。
要到达的目标函数我们可以设置到从phase2函数中返回。我们将调用完read_six_numbers函数后一条指令即0x400f0a作为程序分析的开始处。

angr分析

具体的angr分析代码如下所示:

## Binary found here: http://csapp.cs.cmu.edu/3e/bomb.tar

import angr, logging
from subprocess import Popen, PIPE
from itertools import product
import struct

def main():
    proj = angr.Project('bomb', load_options={'auto_load_libs':False})

    logging.basicConfig()
    logging.getLogger('angr.surveyors.explorer').setLevel(logging.DEBUG)

    def nop(state):
        return

    bomb_explode = 0x40143a

    # Start analysis at the phase_2 function after the sscanf
    state = proj.factory.blank_state(addr=0x400f0a)

    # Sscanf is looking for '%d %d %d %d %d %d' which ends up dropping 6 ints onto the stack
    # We will create 6 symbolic values onto the stack to mimic this
    for i in xrange(6):
        state.stack_push(state.se.BVS('int{}'.format(i), 4*8))

    # Attempt to find a path to the end of the phase_2 function while avoiding the bomb_explode
    path = proj.factory.path(state=state)
    ex = proj.surveyors.Explorer(start=path, find=(0x400f3c,),
                                 avoid=(bomb_explode, 0x400f10, 0x400f20,),
                                 enable_veritesting=True)
    ex.run()
    if ex.found:
        found = ex.found[0].state

        answer = []

        for x in xrange(3):
            curr_int = found.se.any_int(found.stack_pop())

            # We are popping off 8 bytes at a time
            # 0x0000000200000001

            # This is just one way to extract the individual numbers from this popped value
            answer.append(str(curr_int & 0xffffffff))
            answer.append(str(curr_int>>32 & 0xffffffff))

        return ' '.join(answer)

def test():
    assert main() == '1 2 4 8 16 32'

if __name__ == '__main__':
    print(main())
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,关于如何使用angr以及如何解决实际问题的探讨思考,我可以给您一些建议和想法。 首先,angr是一种开源的二进制分析框架,它可以用于模拟程序执行、符号执行、约束求解等任务。使用angr可以帮助我们分析程序的行为,发现安全漏洞,解决Bug等问题。 对于如何使用angr,我认为可以从以下几个方面入手: 1. 理解angr的基本原理和工作流程:学习angr的工作原理和流程是非常关键的,它可以帮助我们更好地理解angr的各个模块和函数,并且可以提高我们的分析效率和准确性。 2. 了解angr的API和使用方法:angr提供了丰富的API和使用方法,包括路径分析、符号执行、约束求解等功能。我们可以通过掌握这些API和使用方法,来实现我们的分析策略,并且解决实际问题。 3. 掌握相应的工具和技术:除了angr本身之外,使用angr还需要掌握一些相关的工具和技术,例如IDA Pro、Ghidra等反汇编工具、Python编程、Shell编程等。这些工具和技术可以帮助我们更好地使用angr进行分析和解决问题。 针对如何解决实际问题,我认为可以从以下几个方面思考: 1. 确定分析目标和关键点:在使用angr进行分析之前,我们需要明确自己的分析目标和关键点,例如发现程序漏洞或者解决程序性能问题等。只有明确了分析目标和关键点,我们才能有针对性地进行分析,并且解决实际问题。 2. 制定分析策略和方案:在明确了分析目标和关键点之后,我们需要制定相应的分析策略和方案。例如,我们可以通过符号执行来发现程序中的漏洞,或者通过约束求解来解决程序的性能问题等。根据不同的分析目标和关键点,我们可以选择不同的分析策略和方案。 3. 结合实际应用场景和技术实践:除了掌握angr和相关工具和技术之外,我们还需要结合实际应用场景和技术实践,来解决实际问题。例如,在分析某个程序时,我们需要了解该程序所使用的编程语言、数据类型和算法等,以便更好地使用angr进行分析,解决实际问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值