angr学习之ctf练习
前言
安装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练习相关推荐
- 符号执行:利用Angr进行简单CTF逆向分析
一.符号执行概括 简单的来说,符号执行就是在运行程序时,用符号来替代真实值.符号执行相较于真实值执行的优点在于,当使用真实值执行程序时,我们能够遍历的程序路径只有一条,而使用符号进行执行时,由于符号是 ...
- BUUCTF-[网鼎杯 2020 青龙组]singal——angr学习记录
学习结合b站的视频 环境配置:Ubuntu20.04+python3 angr安装教程 切换到angr环境:workon angr 退出angr环境:deactivate 什么 ...
- 个人总结-网络安全学习和CTF必不可少的一些网站
学习的地方很多,不能一一列举,一些优秀的网址和博客可能也没有提到,大家补充吧:P 就简单总结一些常用的吧,本人是十足的彩笔,还望大家多多指点,表哥们带我飞Orz http://www.sec-wiki ...
- 【转】个人总结-网络安全学习和CTF必不可少的一些网站
转自:http://blog.csdn.net/ida0918/article/details/52730662 学习的地方很多,不能一一列举,一些优秀的网址和博客可能也没有提到,大家补充吧:P 就简 ...
- angr学习笔记(13)(static_binary)
angr系列 00_angr_find 01_angr_avoid 02_angr_find_condition 03_angr_symbolic_registers 04_angr_symbolic ...
- angr学习笔记(11)(SimProcedure)
angr系列 00_angr_find 01_angr_avoid 02_angr_find_condition 03_angr_symbolic_registers 04_angr_symbolic ...
- angr学习笔记(10)(hook)
angr系列 00_angr_find 01_angr_avoid 02_angr_find_condition 03_angr_symbolic_registers 04_angr_symbolic ...
- angr学习笔记(9)(添加约束)
angr系列 00_angr_find 01_angr_avoid 02_angr_find_condition 03_angr_symbolic_registers 04_angr_symbolic ...
- angr学习笔记(8)(文件内容符号化)
angr系列 00_angr_find 01_angr_avoid 02_angr_find_condition 03_angr_symbolic_registers 04_angr_symbolic ...
最新文章
- swift_039(Swift中的KVC的使用方法)
- 配置toad远程连接oracle
- html实现全选 反选,jquery实现全选、不选、反选的两种方法
- JAVA中int、String的类型转换(亲测)
- Mybatis中trim的使用
- 云原生/低代码/数据科学/计算等方向内容整理志愿者招募了!
- matlab 微秒 符号,matlab处理csi
- Linux下安装Nexus-3.15私服
- docker-compose教程(安装,使用, 快速入门)
- 今晚8点不见不散!余承东Vlog如此夸赞华为Mate30系列新机
- Explicit 关键字和各种类型转换(转)
- VS运行程序时遇到0xc0150002的问题
- excel函数去重_【Excel VBA】使用字典快速对数据去重
- 证券分析软件测试面试题,光大证券面试经验
- 浅析网吧电影服务器配置与搭建(转)
- mat1 and mat2 shapes cannot be multiplied ( )的解决
- 直接从Google Play下载apk(附源码)
- 【Windows Esp32】基于 libjpeg-9e 编解码库的视频播放器
- win11右击文件夹假死
- java回溯算法解决数独_js回溯算法解决数独问题