前言

安装angr的链接:https://blog.csdn.net/qq_43682582/article/details/109790606
通过做ctf练习题来逐步熟悉angr的相关内容
相关文档: https://github.com/jakespringer/angr_ctf.
相关b站视频:https://space.bilibili.com/386563875/.
进入链接之后,这里面就是已经编译好的二进制文件,里面还有对应题目的解题框架和相关注释:
angr思路:根据当前一些自己的体会(未来也许会有修改),即重点就是确定开始执行的那个状态的具体地址,根据这些不同来写程序,如:对寄存器、对栈、对内存等。
新人菜鸟一枚,如果出现了错误或者遗漏的地方,希望各位师傅能够帮忙指点出来,Thanks♪(・ω・)ノ

00_angr_find:

目的:使学习者一个对angr有一个大体的了解,初步知道使用大致步骤

import angr
import sys
def main(argv): #定义主函数path_to_binary = '/home/yuan/ctf/angr/angr0/00_angr_find'  #被执行文件路径project = angr.Project(path_to_binary)   #以被执行文件路径创建项目#或者project = angr.Project('/home/yuan/ctf/angr/angr0/00_angr_find')initial_state = project.factory.entry_state()  #通过entry_state()创建一个默认初始状态,这个状态是为了告诉#angr该从哪里开始,此处为main()simulation = project.factory.simgr(initial_state)   #以该状态创建一个模拟管理器,这个模拟管理器里有许多工#具可以帮助搜索和执行二进制文件#或者simulation = project.factory.simulation_manager(initial_state),二者没有区别,只是前者更加方便写代码。。。print_good_address = 0x0804867D   #希望得到的输出的虚拟地址simulation.explore(find=print_good_address)  #开始执行直到到达希望的解决方案或者探索完所有的可能的路径#simulation.explore()方法将会建立一个名为simulation.found#状态列表来表示可以找到我们所希望的输出。如过没有找到,则#该列表会被置为false,反之为trueif simulation.found:   #检查是否发现了解决方案solution_state = simulation.found[0]print(solution_state.posix.dumps(sys.stdin.fileno()))  #打印出angr执行到这个状态时的输入,也就是我们所希望的flagelse:raise Exception('Cannot find')if __name__ == '__main__':main(sys.argv)

可以使用ida打开二进制文件进行地址的查看:

运行效果:

01_angr_avoid:

目的:让学习者使用一定的约束来减少运算量,以节省时间

import angr
import sysdef main(argv):p = angr.Project('/home/yuan/ctf/angr/angr1/01_angr_avoid')initial_state = p.factory.entry_state()sm = p.factory.simgr(initial_state)good_addr = 0x080485e5   #因为一般来讲一个二进制文件执行时是不会只有一个分支语句的#所以为了节省时间和对计算资源的浪费,需要添加约束来避免对一些无用语句的执行bad_addr = 0x080485f2    #此处即为输出为“Try again”的地址sm.explore(find=good_addr, avoid=bad_addr) #avoid就是.explore()里的第二个参数,也就是不想要执行到这里if sm.found:flag = sm.found[0]print(flag.posix.dumps(sys.stdin.fileno()))else:raise Exception('Cannot find')
if __name__ == '__main__':main(sys.argv)

运行效果:

02_angr_find_condition:

目的:掌握另一种判断输出状态的方法

import angr
p = angr.Project('/home/yuan/ctf/angr/angr2/02_angr_find_condition')
state = p.factory.entry_state()
sm = p.factory.simulation_manager(state)
def good(state):return b'Good Job.' in state.posix.dumps(1)  #希望得到的输出
def bad(state):return b'Try again.' in state.posix.dumps(1)   #不希望得到的输出
sm.explore(find = good, avoid = bad)
if sm.found:find_state = sm.found[0]flag = find_state.posix.dumps(0)print(str(flag,'utf-8'))
else:print("NO!!!!!!!!")

运行效果:

03_angr_registers:

目的:掌握对输入进寄存器的变量符号化的方法

import angr
import claripy
p = angr.Project('/home/yuan/ctf/angr/angr3/03_angr_symbolic_registers')init_addr = 0x08048980  #call scanf的下一条指令地址
state = p.factory.blank_state(addr=init_addr)  #创建一个状态,并将该地址赋给它,也就是跳过输入,直接执行下一条指令,此处使用.blank_state()而不再是.entry_state()
#虽然当前版本的angr已经支持scanf多个变量输入,但为了学习angr的另外一种方法,就按这种方法来吧。#定义三个位向量,即三个输入
p1 = claripy.BVS('p1',32)   #32位寄存器
p2 = claripy.BVS('p2',32)
p3 = claripy.BVS('p3',32)#将三个输入分别赋给存放输入的三个寄存器
state.regs.eax = p1    #.regs.eax 访问eax这个寄存器
state.regs.ebx = p2
state.regs.edx = p3#创建一个模拟管理器
sm = p.factory.simulation_manager(state)#定义函数
def good(state):return b'Good Job.' in state.posix.dumps(1)
def bad(state):return b'Try again.' in state.posix.dumps(1)#开始探索
sm.explore(find = good, avoid = bad)#探索成功时:
if sm.found:find_state = sm.found[0]flag1 = find_state.solver.eval(p1)        #将探索成功时的第一个输入赋给flag1,下面两个类似flag2 = find_state.solver.eval(p2)flag3 = find_state.solver.eval(p3)print('{:x} {:x} {:x}'.format(flag1,flag2,flag3))
else:print('No')

运行效果:

04_angr_symbolic_stack:

目的:掌握对输入进栈里的变量符号化的方法

import angr
import claripy
import sys
def main(argv):p = angr.Project('/home/yuan/ctf/angr/angr4/04_angr_symbolic_stack')def good(state):return b'Good Job.' in state.posix.dumps(1)def bad(state):return b'Try again.' in state.posix.dumps(1)#创建开始状态start_addr = 0x08048697  #scanf之后的地址,之所以是这儿,是因为上一行'add  esp,10h'的作用是清理scanf的栈空间state = p.factory.blank_state(addr=start_addr)#因为跳过了scanf函数,所以我们需要模拟它的整个操作(对栈的操作)#state.stack_push(state.regs.ebp)state.regs.ebp = state.regs.esp    #初始化ebp、espspace = 0x8                         #一个变量占4个空间,所以两个就是8state.regs.esp -= space   #模拟scanf时栈的情况(剔除了对空间的浪费,即只开辟了两个变量的空间)ps1 = claripy.BVS('ps1',32)       #符号化两个输入ps2 = claripy.BVS('ps2',32)state.stack_push(ps1)     #将符号化的输入入栈state.stack_push(ps2)#至此对scanf的模拟过程就完成了#创建模拟管理器simulation = p.factory.simgr(state)#开始探索simulation.explore(find=good,avoid=bad)if simulation.found:solution_state = simulation.found[0]flag1 = solution_state.solver.eval(ps1)flag2 = solution_state.solver.eval(ps2)print('{} {}'.format(flag1,flag2))else:print("AAAAAAA")if __name__ == '__main__':main(sys.argv)

运行效果:

05_angr_symbolic_memory

目的:掌握对输入进内存的变量符号化方法

import angr
import claripy
import sysdef main(argv):path = argv[1]p = angr.Project(path)start_addr = 0x08048601state = p.factory.blank_state(addr=start_addr)#创建四个位向量,模拟输入p1 = claripy.BVS('p1',64)   #一个变量输入8个字符,一个字符8位bit,总共64bitp2 = claripy.BVS('p2',64)p3 = claripy.BVS('p3',64)p4 = claripy.BVS('p4',64)#开始对输入进行模拟state.memory.store(0x0A1BA1C0,p1)#让四个位向量指向输入在内存中的地址state.memory.store(0x0A1BA1C8,p2)state.memory.store(0x0A1BA1D0,p3)state.memory.store(0x0A1BA1D8,p4)#scanf模拟结束sm = p.factory.simgr(state) #创建模拟管理器 def good(state):return b'Good Job.' in state.posix.dumps(1)def bad(state):return b'Try again.' in state.posix.dumps(1)sm.explore(find = good,avoid = bad)if sm.found:solution_state = sm.found[0]flag1 = solution_state.solver.eval(p1,cast_to=bytes)flag2 = solution_state.solver.eval(p2,cast_to=bytes)flag3 = solution_state.solver.eval(p3,cast_to=bytes)flag4 = solution_state.solver.eval(p4,cast_to=bytes)print("{} {} {} {}".format(flag1.decode('utf-8'),flag2.decode('utf-8'),flag3.decode('utf-8'),flag4.decode('utf-8')))else:print("NO")if __name__ == '__main__':main(sys.argv)

运行效果:

06_angr_symbolic_dynamic_memory

目的:对输入进堆空间的变量符号化

import angr
import sys
import claripy
def main(argv):path = argv[1]p = angr.Project(path)start_addr = 0x08048699state = p.factory.blank_state(addr=start_addr)p0 = claripy.BVS('p0',8*8)p1 = claripy.BVS('p1',8*8)#print("ESP:",state.regs.esp)   查看当前esp地址,用作开辟堆空间fake_p0 =0x7fff0000-0x100      #在堆中开辟的空间的地址,是一个随机地址memory_p0 = 0x0ABCC8A4   #存放指向堆中空间的地址信息的地址state.memory.store(memory_p0, fake_p0, endness=p.arch.memory_endness)   #angr默认大端存放数据,需要转换为小端存放fake_p1=0x7fff0000-0x200memory_p1 = 0x0ABCC8ACstate.memory.store(memory_p1, fake_p1, endness=p.arch.memory_endness)state.memory.store(fake_p0,p0)state.memory.store(fake_p1,p1)sm = p.factory.simgr(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:solution_state = sm.found[0]solution0 = solution_state.se.eval(p0,cast_to=bytes).decode('utf-8')solution1 = solution_state.se.eval(p1,cast_to=bytes).decode('utf-8')print("{} {}".format(solution0, solution1))else:print("NO!")if __name__ == '__main__':main(sys.argv)

运行效果:

后记

先到这里,(#.#)

angr学习之ctf练习相关推荐

  1. 符号执行:利用Angr进行简单CTF逆向分析

    一.符号执行概括 简单的来说,符号执行就是在运行程序时,用符号来替代真实值.符号执行相较于真实值执行的优点在于,当使用真实值执行程序时,我们能够遍历的程序路径只有一条,而使用符号进行执行时,由于符号是 ...

  2. BUUCTF-[网鼎杯 2020 青龙组]singal——angr学习记录

    ​​​​​​学习结合b站的视频 环境配置:Ubuntu20.04+python3 ​​​​​​angr安装教程 切换到angr环境:workon angr 退出angr环境:deactivate 什么 ...

  3. 个人总结-网络安全学习和CTF必不可少的一些网站

    学习的地方很多,不能一一列举,一些优秀的网址和博客可能也没有提到,大家补充吧:P 就简单总结一些常用的吧,本人是十足的彩笔,还望大家多多指点,表哥们带我飞Orz http://www.sec-wiki ...

  4. 【转】个人总结-网络安全学习和CTF必不可少的一些网站

    转自:http://blog.csdn.net/ida0918/article/details/52730662 学习的地方很多,不能一一列举,一些优秀的网址和博客可能也没有提到,大家补充吧:P 就简 ...

  5. angr学习笔记(13)(static_binary)

    angr系列 00_angr_find 01_angr_avoid 02_angr_find_condition 03_angr_symbolic_registers 04_angr_symbolic ...

  6. angr学习笔记(11)(SimProcedure)

    angr系列 00_angr_find 01_angr_avoid 02_angr_find_condition 03_angr_symbolic_registers 04_angr_symbolic ...

  7. angr学习笔记(10)(hook)

    angr系列 00_angr_find 01_angr_avoid 02_angr_find_condition 03_angr_symbolic_registers 04_angr_symbolic ...

  8. angr学习笔记(9)(添加约束)

    angr系列 00_angr_find 01_angr_avoid 02_angr_find_condition 03_angr_symbolic_registers 04_angr_symbolic ...

  9. angr学习笔记(8)(文件内容符号化)

    angr系列 00_angr_find 01_angr_avoid 02_angr_find_condition 03_angr_symbolic_registers 04_angr_symbolic ...

最新文章

  1. swift_039(Swift中的KVC的使用方法)
  2. 配置toad远程连接oracle
  3. html实现全选 反选,jquery实现全选、不选、反选的两种方法
  4. JAVA中int、String的类型转换(亲测)
  5. Mybatis中trim的使用
  6. 云原生/低代码/数据科学/计算等方向内容整理志愿者招募了!
  7. matlab 微秒 符号,matlab处理csi
  8. Linux下安装Nexus-3.15私服
  9. docker-compose教程(安装,使用, 快速入门)
  10. 今晚8点不见不散!余承东Vlog如此夸赞华为Mate30系列新机
  11. Explicit 关键字和各种类型转换(转)
  12. VS运行程序时遇到0xc0150002的问题
  13. excel函数去重_【Excel VBA】使用字典快速对数据去重
  14. 证券分析软件测试面试题,光大证券面试经验
  15. 浅析网吧电影服务器配置与搭建(转)
  16. mat1 and mat2 shapes cannot be multiplied ( )的解决
  17. 直接从Google Play下载apk(附源码)
  18. 【Windows Esp32】基于 libjpeg-9e 编解码库的视频播放器
  19. win11右击文件夹假死
  20. java回溯算法解决数独_js回溯算法解决数独问题

热门文章

  1. USB Type-C引脚解析 CC、DFP、UFP、DRP用途解析
  2. USB-DFP UFP DRP模式
  3. 大学计算机基础 贾学明,关于组织本、专科学生参加计算机应用能力考试的通知...
  4. 什么是EJB?EJB是基于哪些技术实现的?
  5. CDH6.3.2详细安装
  6. 数据结构~07.栈和队列的基本概念
  7. TLP(Transmission Line Pulse)
  8. DBeaver显示Unknown database错误
  9. 【C语言】将十进制数转化为二进制并输出
  10. 简单探寻GCC编译器背后的故事