日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CTF——angr使用学习记录

發(fā)布時間:2025/3/21 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CTF——angr使用学习记录 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?初始化:

p = angr.Project('./test',load_options={"auto_load_libs":False})

載入文件,auto_load_libs設置為false,大概是啟用angr自帶的函數(shù)定義,避免一些邏輯過于復雜,機器跑不出來。

import?claripy?

arg?=?claripy.BVS(‘a(chǎn)rg1′,?8)

我們使用claripy這個模塊來定義抽象的數(shù)據(jù),claripy的BVS函數(shù)可以創(chuàng)建一個指定長度的抽象數(shù)據(jù),BVS函數(shù)要求兩個參數(shù),第一個參數(shù)為變量名,第二個參數(shù)為變量長度。符號化變量;

state?=?p.factory.entry_state(args=argv)?

entry_state()函數(shù)接收一個list作為程序的命令行參數(shù)并且返回程序入口的狀態(tài)

state.posix.files[0].read_from(1)

?表示從標準輸入讀取一個字節(jié)?

st?=?p.factory.blank_state(addr=)

創(chuàng)建一個?blank_state?對象,這個對象里面很多東西都是未初始化的,當程序訪問未初始化的數(shù)據(jù)時,會返回一個不受約束的符號量

sm = p.factory.simulation_manager(state)

表示從state這個地址開始執(zhí)行。

sm.explore(find=0x400676,avoid=[0x40073d])

當探索到find地方,就是想要的答案,avoid就是需要避免的地方。

sm.found.posix.dumps(1)?

?最后的輸出

sm.found.posix.dumps(0)?

found的輸入

sm.found.solver.eval(arg1,cast_to?= str)

使用約束求解引擎獲取命令行參數(shù),類型為字符串,

在使用符號變量后,不能通過posix.dump來獲取標準輸入,而應該獲取符號變量的值,simgr.one_found.solver.eval函數(shù)可以獲取符號變量的值

相關使用方法:

寄存器的符號化:

import angr import claripy p = angr.Project('')init_addr = 0x08048980 #scanf的下一條指令地址 state = p.factory.blank_state(addr=init_addr) #創(chuàng)建一個狀態(tài),并將該地址賦給它,也就是跳過輸入,直接執(zhí)行下一條指令,此處使用.blank_state()而不再是.entry_state()#定義三個位向量,即三個輸入 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))

棧的符號化:

import angr import claripy import sys def main(argv):p = angr.Project('')def good(state):return b'Good Job.' in state.posix.dumps(1)def bad(state):return b'Try again.' in state.posix.dumps(1)#創(chuàng)建開始狀態(tài)start_addr = 0x08048697 #scanf之后的地址,之所以是這兒,是因為上一行'add esp,10h'的作用是清理scanf的棧空間state = p.factory.blank_state(addr=start_addr)#因為跳過了scanf函數(shù),所以我們需要模擬它的整個操作(對棧的操作)#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的模擬過程就完成了#創(chuàng)建模擬管理器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))if __name__ == '__main__':main(sys.argv)

內存的符號化:

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)#創(chuàng)建四個位向量,模擬輸入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) #創(chuàng)建模擬管理器 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)

?hook:

在?angr?中使用?hook?來把指定地址的二進制代碼替換為?python?代碼。angr?在模擬執(zhí)行程序時,執(zhí)行每一條指令前會檢測該地址處是否已經(jīng)被?hook?,如果是就不執(zhí)行這條語句,轉而執(zhí)行hook?時指定的?python?處理代碼。

#!/usr/bin/env python # coding=utf-8 import angr import claripy def hook_demo(state):state.regs.eax = 0state.regs.ebx = 0xdeadbeef p = angr.Project("./examples/sym-write/issue", load_options={"auto_load_libs": False}) p.hook(addr=0x08048485, hook=hook_demo, length=2) # 使用 p.hook 把 0x08048485 處的 2 字節(jié)的指令 為 hook_demo,之后執(zhí)行 0x08048485就會去執(zhí)行 hook_demo state = p.factory.blank_state(addr=0x0804846B, add_options={"SYMBOLIC_WRITE_ADDRESSES"})#創(chuàng)建一個 state , 因為要往內存里面設置 符號量 ( BVS ),設置SYMBOLIC_WRITE_ADDRESSES u = claripy.BVS("u", 8) state.memory.store(0x0804A021, u) #新建一個 8 位長度的符號量,并把它存到 0x0804A021 (全局變量 u 的位置) sm = p.factory.simgr(state) sm.explore(find=0x080484DB) st = sm.found[0] print hex(st.se.eval(st.regs.ebx))

?p.hook(addr=0x08048485,?hook=hook_demo,?length=2)

p.hook_symbol('想要被hook的函數(shù)名', 自己定義的替換函數(shù)名,replace=True)

  • addr?為待?hook?指令的地址

  • hook?為?hook?的處理函數(shù),在執(zhí)行到?addr?時,會執(zhí)行 這個函數(shù),同時把 當前的?state?對象作為參數(shù)傳遞過去

  • length?為 待?hook?指令的長度,在 執(zhí)行完?hook?函數(shù)以后,angr?需要根據(jù)?length?來跳過這條指令,執(zhí)行下一條指令

優(yōu)化:

simgr.one_active.options.add(angr.options.LAZY_SOLVES)

對simgr開啟LAZY_SOLVES選項,該選項可不在運行時實時檢查當前條件能否到達目標位置。雖然這樣無法規(guī)避一些無解的情況,但可以顯著提高效率

報錯:?

The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.

我們后面程序的地址要加上基址偏移。

參考:

??????大佬的代碼

大佬的博客

大佬的博客

總結

以上是生活随笔為你收集整理的CTF——angr使用学习记录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。