Angr从0到0的成长之路 (三)
本文最后更新于525 天前,其中的信息可能已经过时!

前言

本文可视为angr_CTF 07-09的题目wp,且每题均为独立思考并结合出题人的解题脚本进行改进

0x0.07_angr_symbolic_file

首先进行了一个读取,将输入读进buffer中,进行了一个ignore_me函数,出来后将buffer 置空并从文件中读取长度为64的字节,最后进行检验

没啥好说的,反复横跳没看出来这个函数有啥用,直接写

import angr 
import claripy
import sys

def main(argv):
    path = argv[1]
    p = angr.Project(path,auto_load_libs = False)
    start_address = 0x080495B6
    init_state = p.factory.blank_state(addr = start_address)
    
    password = claripy.BVS('password',64)
    init_state.memory.store(0x804C0A0,password)
    
    sm = p.factory.simgr(init_state)
    
    def is_sucessful(state):
        stdout_output = state.posix.dumps(1)
        return True if  b'Good Job.' in stdout_output else False

    def should_abort(state):
        stdout_output = state.posix.dumps(1)
        return True if b'Try again.' in stdout_output else False
    
    sm.explore(find = is_sucessful,avoid = should_abort)
    
    if sm.found:
        solution_state = sm.found[0]
        solution = solution_state.solver.eval(password,cast_to = bytes).decode()
        print(solution)
    else:
        print('Not Found')
           
if __name__ == '__main__':
    main(sys.argv)   

我直接创建在读文件之后的state,并没用到文件有关的东西,而出题人的思路是将load的文件进行替换,将函数中的文件换成我们自己写的一个”xxx.txt”,在我们的txt中写一个变量,然后我们就可以利用angr进行解题

import angr 
import claripy
import sys

def main(argv):
    path = argv[1]
    p = angr.Project(path,auto_load_libs = False)
    start_address = 0x08049550
    init_state = p.factory.blank_state(addr = start_address)
    
    filename = 'XZDBXDHZ.txt'
    password = claripy.BVS('password',64)
    #init_state.memory.store(0x804C0A0,password)
    #创建的新文件包括(文件名,内容,文件大小) PS:不要忘记文件大小
    password_file = angr.storage.SimFile(filename, content = password,size = 64)
    init_state.fs.insert(filename, password_file)
    
    sm = p.factory.simgr(init_state)
    
    def is_sucessful(state):
        stdout_output = state.posix.dumps(1)
        return True if  b'Good Job.' in stdout_output else False

    def should_abort(state):
        stdout_output = state.posix.dumps(1)
        return True if b'Try again.' in stdout_output else False
    
    sm.explore(find = is_sucessful,avoid = should_abort)
    
    if sm.found:
        solution_state = sm.found[0]
        solution = solution_state.solver.eval(password,cast_to = bytes).decode()
        print(solution)
    else:
        print('Not Found')
           
if __name__ == '__main__':
    main(sys.argv)   

0x1.08_angr_constraints

解法不唯一啊,感觉可以直接一把梭,但是写出代码来会发现这个脚本效率太低了跑不出来,感觉是检查的那个函数太啰嗦了,如果可以提前终止main的流程并且将password与给定的字符串进行比较就好了

出题人也是这样设计的,简单了解下这个脚本中用到的函数,给出exp

import angr 
import claripy
import sys

def main(argv):
    path = argv[1]
    p = angr.Project(path,auto_load_libs = False)
    start_address = 0x08049360
    init_state = p.factory.blank_state(addr = start_address)
    
    init_state.memory.store(0x0804C030,b"NSERNWOZEBCQYBTR")
    password = claripy.BVS('password', 16*8)
    init_state.memory.store(0x0804C040,password)
    
    sm = p.factory.simgr(init_state)
                          #当遇到检测函数的时候就停下来
    sm.explore(find = 0x080493AE)
    
    if sm.found:
        solution_state = sm.found[0]
                          #将该state的某个值提取出来(目标地址,目标大小字节)
        password_encode = solution_state.memory.load(0x0804C040,0x10)
                          #增加限制条件
        solution_state.add_constraints(password_encode == b"NSERNWOZEBCQYBTR")
        solution = solution_state.solver.eval(password,cast_to = bytes).decode()
        print(solution)
    else:
        print('Not Found')
           
if __name__ == '__main__':
    main(sys.argv)   

0x2.09_angr_hooks

这个题是把input拆成了两部分,分别加密并无直接的联系,所以可以写两个angr脚本分别求出来然后拼起来就是答案

题目给了提示hook,简单看了一下没有hook函数,然后就感觉大事不妙(不是哥们,我只会逆不会写这玩意啊),直接学习出题人的脚本

import angr 
import claripy
import sys

def main(argv):
    path = argv[1]
    p = angr.Project(path,auto_load_libs = False)
    init_state = p.factory.entry_state()
      #(调用函数地址,跳过的函数长度)
    @p.hook(0x080493CE, length = 0x8)
    def skip_check_equals_(state):
        input_string = state.memory.load(0x0804C044,0x10)
        #claripy.If(expression, ret_if_true, ret_if_false)
        #在gcc中函数调用的返回值被存在aex中
        state.regs.eax = claripy.If(input_string == "EEWBFSFFWZUYKKKM"
        ,claripy.BVV(1,32),claripy.BVV(0,32))
    
    sm = p.factory.simgr(init_state)
    
    def is_sucessful(state):
        stdout_output = state.posix.dumps(1)
        return True if  b'Good Job.' in stdout_output else False

    def should_abort(state):
        stdout_output = state.posix.dumps(1)
        return True if b'Try again.' in stdout_output else False
    
    sm.explore(find = is_sucessful,avoid = should_abort)
    
    if sm.found:
        solution_state = sm.found[0]
        solution = solution_state.posix.dumps(0)
        print(solution)
    else:
        print('Not Found')
           
if __name__ == '__main__':
    main(sys.argv)   

今天的题就做到这吧 : )

挖个坑,后续会在每个文章的结尾总结一下本文get到的新知识,希望不会鸽 : (

如果本文对您有帮助,能否给个一键三连 (bushi)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇