日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

CTF——angr使用学习记录

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

?初始化:

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

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

import?claripy?

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

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

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

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

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

?表示從標(biāo)準(zhǔn)輸入讀取一個(gè)字節(jié)?

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

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

sm = p.factory.simulation_manager(state)

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

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

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

sm.found.posix.dumps(1)?

?最后的輸出

sm.found.posix.dumps(0)?

found的輸入

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

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

在使用符號(hào)變量后,不能通過posix.dump來獲取標(biāo)準(zhǔn)輸入,而應(yīng)該獲取符號(hào)變量的值,simgr.one_found.solver.eval函數(shù)可以獲取符號(hào)變量的值

相關(guān)使用方法:

寄存器的符號(hào)化:

import angr import claripy p = angr.Project('')init_addr = 0x08048980 #scanf的下一條指令地址 state = p.factory.blank_state(addr=init_addr) #創(chuàng)建一個(gè)狀態(tài),并將該地址賦給它,也就是跳過輸入,直接執(zhí)行下一條指令,此處使用.blank_state()而不再是.entry_state()#定義三個(gè)位向量,即三個(gè)輸入 p1 = claripy.BVS('p1',32) #32位寄存器(符號(hào)向量) p2 = claripy.BVS('p2',32) p3 = claripy.BVS('p3',32)state.regs.eax = p1 #.regs.eax 訪問eax這個(gè)寄存器 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)#將探索成功時(shí)的第一個(gè)輸入賦給flag1,下面兩個(gè)類似flag2 = find_state.solver.eval(p2)flag3 = find_state.solver.eval(p3)print('{:x} {:x} {:x}'.format(flag1,flag2,flag3))

棧的符號(hào)化:

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之后的地址,之所以是這兒,是因?yàn)樯弦恍?#39;add esp,10h'的作用是清理scanf的??臻gstate = p.factory.blank_state(addr=start_addr)#因?yàn)樘^了scanf函數(shù),所以我們需要模擬它的整個(gè)操作(對(duì)棧的操作)#state.stack_push(state.regs.ebp)state.regs.ebp = state.regs.esp #初始化ebp、espspace = 0x8 #一個(gè)變量占4個(gè)空間,所以兩個(gè)就是8state.regs.esp -= space #模擬scanf時(shí)棧的情況(剔除了對(duì)空間的浪費(fèi),即只開辟了兩個(gè)變量的空間)ps1 = claripy.BVS('ps1',32) #符號(hào)化兩個(gè)輸入ps2 = claripy.BVS('ps2',32)state.stack_push(ps1) #將符號(hào)化的輸入入棧state.stack_push(ps2)#至此對(duì)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)

內(nèi)存的符號(hào)化:

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)建四個(gè)位向量,模擬輸入p1 = claripy.BVS('p1',64) #一個(gè)變量輸入8個(gè)字符,一個(gè)字符8位bit,總共64bitp2 = claripy.BVS('p2',64)p3 = claripy.BVS('p3',64)p4 = claripy.BVS('p4',64)#開始對(duì)輸入進(jìn)行模擬state.memory.store(0x0A1BA1C0,p1)#讓四個(gè)位向量指向輸入在內(nèi)存中的地址state.memory.store(0x0A1BA1C8,p2)state.memory.store(0x0A1BA1D0,p3)state.memory.store(0x0A1BA1D8,p4)#scanf模擬結(jié)束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?來把指定地址的二進(jìn)制代碼替換為?python?代碼。angr?在模擬執(zhí)行程序時(shí),執(zhí)行每一條指令前會(huì)檢測(cè)該地址處是否已經(jīng)被?hook?,如果是就不執(zhí)行這條語句,轉(zhuǎn)而執(zhí)行hook?時(shí)指定的?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就會(huì)去執(zhí)行 hook_demo state = p.factory.blank_state(addr=0x0804846B, add_options={"SYMBOLIC_WRITE_ADDRESSES"})#創(chuàng)建一個(gè) state , 因?yàn)橐鶅?nèi)存里面設(shè)置 符號(hào)量 ( BVS ),設(shè)置SYMBOLIC_WRITE_ADDRESSES u = claripy.BVS("u", 8) state.memory.store(0x0804A021, u) #新建一個(gè) 8 位長度的符號(hào)量,并把它存到 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?時(shí),會(huì)執(zhí)行 這個(gè)函數(shù),同時(shí)把 當(dāng)前的?state?對(duì)象作為參數(shù)傳遞過去

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

優(yōu)化:

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

對(duì)simgr開啟LAZY_SOLVES選項(xiàng),該選項(xiàng)可不在運(yùn)行時(shí)實(shí)時(shí)檢查當(dāng)前條件能否到達(dá)目標(biāo)位置。雖然這樣無法規(guī)避一些無解的情況,但可以顯著提高效率

報(bào)錯(cuò):?

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

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

參考:

??????大佬的代碼

大佬的博客

大佬的博客

總結(jié)

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

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