符号执行之angr初探

angr学习

作为一个新手+菜鸡,接触到这个还是因为之前网鼎杯的一道逆向,当时并不知道angr,是想了半天逆出来的,比赛结束之后看了师傅的wp才发现还有这个好用的东西,于是开始学习记录一下。

一开始偷懒在win10下装的,后来不知道elf文件可不可以再win10下用angr(是可以的)然后就想着在ubuntu配置了环境,安装了一下

记录一个小坑
一开始不会用,进入python环境后,import angr,报错
后来发现应该先

workon angr
调换环境

然后先简单的学习了一下angr
附上链接:这位师傅的简单分析

以ais3_creakme这题为例子
载入ida找到主函数
在这里插入图片描述
找到关键点,发现他的入口点
在这里插入图片描述
找到要开始的地址和要避免的地址(好像可以减少运算,不过这个运算量看起来也不大233333)

import angr
import claripy
p=angr.Project('./ais3_crackme',auto_load_libs=False)
'''选择要分析的文件'''
argv1=claripy.BVS('argv1',24*8)
'''建立一个容器(莫名想到了z3)'''
st=p.factory.entry_state(args=['./ais3_crackme',argv1])
sm=p.factory.simgr(state)
'''新建一个模拟器,也可以用project.factory.simulation_manager'''
good=0x400602
'''正确输出点'''
bad=0x40060E
'''避免输出点'''
sm.explore(find=good,avoid=bad)
'''程序执行到此'''
if sm.found:
    find_state=sm.found[0]
print(find_state.solver.eval(argv1),cast_to=str)

本来想用libnum的,可能libnum没装好。。n2s没有成功(也许是不小心装到了py3的环境上)

然后是网鼎杯的这次一道逆向,发现大佬们都是秒题,菜鸡想了好久
附上一位师傅的wp,angr写法的,写的很简单很暴力了

师傅的wp

我一开始跑的时候出了一点点小问题不过问题不大,已经顺利解决了

import angr
p = angr.Project(’./signal.exe’)
///这个路径是按照自己的来改的
state = p.factory.entry_state()
sm = p.factory.simulation_manager(state)
def good(state):
return b"good" in state.posix.dumps(1)

def bad(state):
return b"what" 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(flag)
///上述是引用师傅的wp

然后下面是我自己当天写的。。很复杂。。。

v1=[0xa,4,0x10,8,3,5,1,4,0x20,8,5,3,1,3,2,8,0xb,
            1,0xc,8,4,4,1,5,3,8,3,0x21,1,0xb,0x8,0xb,1,4,9,8,3,
            0x20,1,2,0x51,8,4,0x24,1,0xc,8,0xb,1,5,2,8,2,0x25,
            1,2,0x36,8,4,0x41,1,2,0x20,8,5,1,5,3,8,2,0x25,
            1,4,9,8,3,0x20,1,2,0x41,8,0xc,1,7,0x22,7,0x3f,7,
            0x34,7,0x32,7,0x72,7,0x33,7,0x18,7,0xa7,
            7,0x31,7,0xf1,7,0x28,7,0x84,
            7,0xc1,7,0x1e,7,0x7a]
//dump出的有一个1,给我去掉了,v4数组只有15个数,却有161,应该跳过了一个,然后v4里面也没有相同的数
print(len(v1))   
v4=[0]*15
v3=[0]*15
v7=0
v9=15
v6=14
v4=[122, 30, 193, 132, 40, 241, 49, 167, 24, 51, 114, 50, 52, 63, 34]
//这个v4数组是逆序
print(len(v4))
for i in range(len(v1)-1,-1,-1):
    if(v1[i]==1):
        v5=v4[v7]
        v7+=1
        v9-=1
    if(v1[i]==12):
        v3[v9]=v5-1
    if(v1[i]==11):
        v3[v9]=v5+1
    if(v1[i]==8):
        v5=v3[v6]
        v6-=1
    if(v1[i]==2):
        v3[v9]=v5-v1[i+1]
    if(v1[i]==3):
        v3[v9]=v5+v1[i+1]
    if(v1[i]==4 ):
        v3[v9]=v5^v1[i+1]
    if(v1[i]==5):
        v3[v9]=v5//v1[i+1]
    else :
        continue
print(v4)
print(v3)

很复杂感觉没什么学习的价值,不过这次学到了符号执行也算是有了收获,打算和着z3一起再学习学习

看到了github上angr的练习题,还有b站的讲解视频,继续学习
持续更新。。希望我别鸽

angr_ctf

这个文件里面都有答案的,感觉能过的题目我就简单写写,没见过的就留着提醒愚蠢又健忘的自己。。

  1. 00
import angr
p=angr.Project('./00_angr_find')
state=p.factory.entry_state()
sm=p.factory.simgr(state)
sm.explore(find=0x08048678)
print(sm.found[0].posix.dumps(0))

这里后来vim编辑的时候出了一点点小差错,好像是什么设置了readonly,esc之后, :wq!就可以了

  1. 01
import angr
p=angr.Project('./01_angr_avoid')
st=p.factory.entry_state()
sm=p.factory.simgr(st)
sm.explore(find=0x080485E0,avoid=0x080485F2)
print(sm.found[0].posix.dumps(0))
  1. 02
import angr
p=angr.Project('./02_angr_find_condition')
state=p.factory.entry_state()
sm=p.factory.simgr(state)
good=lambda s:b'Good Job' in s.posix.dumps(1)
bad=lambda s:b'Try again' in s.posix.dumps(1)
sm.explore(find=good,avoid=bad)
if sm.found:
    found_state=sm.found[0]
print(found_state.posix.dumps(0))

  1. 03
    这一题的输入三个,直接跳过这个输入,从输入的参数分别放入了,eax,ebx,edx开始
import angr
import claripy
p=angr.Project('./03_angr_symbolic_registers')
state=p.factory.entry_state(addr=0x08048980)
sm=p.factory.simgr(state)
f1 = claripy.BVS('f1',32)
f2 = claripy.BVS('f2',32)
f3 = claripy.BVS('f3',32)
state.regs.eax = f1
state.regs.ebx = f2
state.regs.edx = f3

def good(state):
    return b'Good Job' in state.posix.dumps(1)
sm.explore(find=good)

if sm.found:
    found_state = sm.found[0]
flag1 = found_state.solver.eval(f1)
flag2 = found_state.solver.eval(f2)
flag3 = found_state.solver.eval(f3)
print("{} {} {}".format(flag1,flag2,flag3))

说实话今天也是第一次用vim来写脚本。。。菜鸡还要不断地学习,不过越学越觉得所学甚少
待更新

z3简单写写

一些z3求解exp:https://github.com/0vercl0k/z3-playground

基本一些格式

from z3 import *
solver = Solver()
//创建约束求解器
if solver.check()==sat:
//判断是否有解
print solver.model()

一个测试的小脚本

from z3 import *
x = Real('x')
y = Real('y')
s = Solver()
s.add(x + y > 5, x > 1, y > 1)
print(s.check())
print(s.model())
from z3 import *
a2= BitVec('a2',64)
a3 = BitVec('a3',64)
a4 = BitVec('a4',64)
//应该是可以一起写的
s = Solver()
s.add(a2 - a3 == 2482827844)
s.add(a3 + a4 == 347363266)
s.add(a2 - a4 == 1308246284)
if s.check() == sat:
    m = s.model()
    for i in m:
        print(i,end=" ")
        print(m[i],end=" ")

libnum

数字型与字符串之间的转换:

import libnum
libnum.s2n()
libnum.n2s()//数字转字符串
libnum.b2s()
libnum.s2b()//二进制转字符串
libnum.generate_prime()生成质数
libnum.factorize()因数分解

现在linux上都可以在py3的版本上安装z3和libnum了
记一个题目:https://blog.csdn.net/xiangshangbashaonian/article/details/82788155
改天去做做。。。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值