首先我是直接在kali中安裝的,也是邊練邊學的。
嗯,要在純凈python環境,所以是在?virtualenv 虛擬環境里,也不是特別會用這個,按照教程一步步做的
source venv/bin/activate
進入了對應環境
退出是
deactivate
?en,ipython交互性確實好一些
00_angr
import angr
p=angr.Project('./dist/00_angr_find')
init_state=p.factory.entry_state()
sm=p.factory.simulation_manager(init_state)
sm.explore(find=0x8048678)
# sm.found[0]
found_state=sm.found[0]
found_state.posix.dumps(0)
得到正確字符串?
01_angr
嗯,最好都加一個 avoid=? ,也可以加快模擬
02_angr
sm.explore( )參數也可以是字符串。
不知道為什么寫地址跑不出來。
import angr
p=angr.Project('./dist/02_angr_find_condition')
init_state=p.factory.entry_state()
sm=p.factory.simulation_manager(init_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:found_state=sm.found[0]print(found_state.posix.dumps(0))
使用指定地址作為目標(find=address
)沒有預期的效果,但使用字符串匹配時卻可以正常工作。這可能是由于以下幾種原因:
-
路徑爆炸:
angr
在分析復雜的二進制程序時可能會遇到路徑爆炸問題,即存在大量的執行路徑。設置特定地址作為目標可能無法讓angr
找到正確的路徑,因為它可能在其他路徑上花費太多時間或資源。 -
目標地址不可達:目標地址可能并不是代碼執行的直接目標。例如,如果目標地址在特定條件下才能被執行,而條件不滿足,
angr
就無法到達該地址。 -
代碼優化或跳轉:編譯器的優化可能導致目標地址的直接訪問變得復雜,例如內聯函數或跳轉指令。字符串匹配可能會更直接地找到這些代碼片段。
-
符號執行約束:
angr
依賴于符號執行來探索程序的執行路徑。如果約束條件太復雜或過于松散,可能無法正確解析所有可能的執行路徑。
03_angr
是有三個輸入,angr好像不支持多個輸入
定義為符號變量(BVS
)并表示為比特向量(bit vectors)
嗯,就是起始位置可以自定義,變量可以自己通過寄存器設置
存儲在寄存器中了
import angr
import claripy
p=angr.Project('./dist/03_angr_symbolic_registers')
state_addr=0x08048980
init_state=p.factory.blank_state(addr=state_addr)
pass1=claripy.BVS('pass1',32)
pass2=claripy.BVS('pass2',32)
pass3=claripy.BVS('pass3',32)
init_state.regs.eax=pass1
init_state.regs.ebx=pass2
init_state.regs.edx=pass3sm=p.factory.simulation_manager(init_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:found_state=sm.found[0]password1=found_state.solver.eval(pass1)password2=found_state.solver.eval(pass2)password3=found_state.solver.eval(pass3)# input hex(not dos)print("Solution: {:x} {:x} {:x}".format(password1,password2,password3))
else:raise Exception("No Solution")
是要十六進制的輸入
04_angr
變量在堆棧中,需要先模擬堆棧
那個ebp是父ebp,保存完父函數ebp才開辟本函數棧空間,當函數執行完以后會有一個pop ebp恢復父函數ebp,但是因為我們要執行的代碼與父函數無關,只用執行到find的地方就可以了,不用返回父函數接著執行,所以保存不保存父函數ebp都無所謂
import angr
p=angr.Project('./dist/04_angr_symbolic_stack')
state_addr=0x08048697
init_state=p.factory.blank_state(addr=state_addr)# 布局堆棧
padding_size=8
init_state.stack_push(init_state.regs.ebp)
init_state.regs.ebp=init_state.regs.esp
init_state.regs.esp-=padding_size# 變量
pass1=init_state.solver.BVS('pass1',32)
pass2=init_state.solver.BVS('pass2',32)
init_state.stack_push(pass1)
init_state.stack_push(pass2)sm=p.factory.simgr(init_state)
#==sm=p.factory.simulation_manager(init_sate)
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:found_state=sm.found[0]password1=found_state.solver.eval(pass1)password2=found_state.solver.eval(pass2)print("Solution: {} {}".format(password1,password2))
else:raise Exception("Solution not find")
05_angr
變量寫在內存中
scanf('%8s',unk_404233)? 大小 8 個字節
import angr
p=angr.Project('./dist/05_angr_symbolic_memory')
state_addr=0x08048601
init_state=p.factory.blank_state(addr=state_addr)
p1=init_state.solver.BVS('p1',64)
p2=init_state.solver.BVS('p2',64)
p3=init_state.solver.BVS('p3',64)
p4=init_state.solver.BVS('p4',64)
p1_addr=0x0A1BA1C0
p2_addr=0x0A1BA1C8
p3_addr=0x0A1BA1D0
p4_addr=0x0A1BA1D8
init_state.memory.store(p1_addr,p1)
init_state.memory.store(p2_addr,p2)
init_state.memory.store(p3_addr,p3)
init_state.memory.store(p4_addr,p4)sm=p.factory.simgr(init_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:found_state=sm.found[0]pass1=found_state.solver.eval(p1,cast_to=bytes)pass2=found_state.solver.eval(p2,cast_to=bytes)pass3=found_state.solver.eval(p3,cast_to=bytes)pass4 = found_state.solver.eval(p4, cast_to=bytes)print("Solution: {} {} {} {}".format(pass1.decode('utf-8'),pass2.decode('utf-8'),pass3.decode('utf-8'),pass4.decode('utf-8')))print("Solution: {} {} {} {}".format(pass1,pass2,pass3,pass4))
else:raise Exception('no solution')
#Solution: NAXTHGNR JVSFTPWE LMGAUHWC XMDCPALU
#Solution: b'NAXTHGNR' b'JVSFTPWE' b'LMGAUHWC' b'XMDCPALU'
符號變量 p1
等被定義為 64 位比特向量。cast_to=bytes
可以將這些比特向量轉化為對應的字節表示。否則,默認情況下,eval
可能返回一個整數表示。?
06_angr
動調分配內存-->指定一塊內存給他用
import angr
p=angr.Project('./dist/06_angr_symbolic_dynamic_memory')
state_addr=0x08048699
init_state=p.factory.blank_state(addr=state_addr)
# open space
print('ESP:',init_state.regs.esp)
# 0x7fff0000 not started
buffer0=0x7fff0000-100
buffer1=0x7fff0000-200
# buffer==pointer
buffer0_addr=0x0ABCC8A4
buffer1_addr=0x0ABCC8AC
init_state.memory.store(buffer0_addr,buffer0,endness=p.arch.memory_endness)
init_state.memory.store(buffer1_addr,buffer1,endness=p.arch.memory_endness)
p1=init_state.solver.BVS('p1',64)
p2=init_state.solver.BVS('p2',64)
init_state.memory.store(buffer0,p1)
init_state.memory.store(buffer1,p2)sm=p.factory.simgr(init_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:found_state=sm.found[0]pass1=found_state.solver.eval(p1,cast_to=bytes)pass2=found_state.solver.eval(p2,cast_to=bytes)print("Solution: {} {} ".format(pass1.decode('utf-8'),pass2.decode('utf-8')))
else:raise Exception('no solution')
那個endness 好像是端序問題
07_angr
有一個對文件讀取的操作,ignore應該是要avoid的,但不是好像
首先,文件名也可符號化