這篇主要用來記錄近期幾場CTF的一些Writeup和心得
DEFCON CTF 2018 Qual
這場比賽我們隊和台大還有交大等隊伍一起組成聯隊
見識到其他隊伍跟自己的差距,學了很多
Easy Pisy
這題有兩個功能:sign
跟execute
sign只給我們sign ECHO指令(他會用OCR去辨識pdf上的文字)
execute功能如果給正確的signature,他就會去執行pdf上面的指令
所以如果我們有辨法構造或繞過signature就能搞定這題惹
這題比較難發現的關鍵點是,openssl_verify
在sign前使用SHA1
也就是說可以去撞SHA1 Collision
可以使用這個Tool來輔助:https://github.com/nneonneo/sha1collider/
產生兩個pdf檔: (1) ECHO kaibro (2) EXECUTE cat flag
然後用這個Tool去撞SHA1 Collsion
比較麻煩的點是,他的OCR有點不太精準,很多字型他都辨識得很差,可能要多踹幾次
成功後,兩個pdf檔就有相同SHA1 hash
,但兩個pdf用OCR辨識出來的文字不同
我撞出來的兩個pdf如下:
https://github.com/w181496/CTF/blob/master/defcon2018-qual/EasyPisy/echo.pdf
https://github.com/w181496/CTF/blob/master/defcon2018-qual/EasyPisy/execute.pdf
先sign pdf(1),之後把得到的SHA1 hash和pdf(2)一起丟去execute,就拿到FLAG惹
OOO{phP_4lw4y5_d3l1v3r5_3h7_b35T_fl4g5}
PHP Eval White-List
這題出壞惹
直接system("../flag")
就噴FLAG
exzendtential-crisis
這題很容易可以發現LFI:
http://d4a386ad.quals2018.oooverflow.io/essays.php?preview&name=../../../../../etc/passwd
可以透過LFI去讀essays.php、login.php、register.php的源碼
會發現login.php會去call一個奇怪的function: check_credentials
register.php也是: create_user
估計就是他自己寫的extension
翻一下php.ini
,可以找到mydb.so
的路徑
用LFI把他載下來: /essays.php?preview&name=../../../../../usr/lib/php/20151012/mydb.so
用ida pro去看,可以發現它DB是用SQLite
mydb.so有db路徑,所以可以把他的DB載下來 (但因為file_get_contents
有長度限制,所以沒辦法載完整的)
會發現目標的帳號跟密碼: sarte:5f0e11fe91a3196d7bf8e80a7ee0bbdf516b1952a57569e4809a9e7bf21ad0f6
賽中有試著去撞,但撞不出來 (SHA256攪20次)
然後就是一連串崩潰逆向
翻了一下之後,一直覺得這題應該是想考SQL Injection (因為裡面特別去擋SQL Injection payload,又擋不完整)
然後他還會把參數裡面的'
換成''
原本以為簡單的\'
=> \''
就能惹,後來才知道原來SQLite不能這樣跳脫QQ
賽後才知道原來洞在:
check_hacking_attempt()
裡username可以蓋超過username_check,然後蓋到下面的table_name
source code在這: https://github.com/o-o-overflow/chall-exzendtential-crisis/blob/master/src/c/
賽中是有踹出來username長度限制大概到111,但沒發現他是蓋到table_name
所以最後payload只要這樣就能繞過惹:
username=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABusers where rowid=1;--&password=a
因為AA...AAB
後面的users where rowid=1
會蓋到table_name
所以這邊snprintf(cmd, sizeof(cmd), "select rowid from %s where username = '%s' and password = '%s';", table_name, username, password);
就可以注入惹
整體來說,這場的確很多黑人問號的題目
(雖然也是有一些好題目)
不少題目都有猜測或暴力的成分在裡頭
Web題也是一堆都要去逆向.so
檔,很不web
不過隊友太Carry,最後聯隊還是拿到22名 跪惹
第一次參加DEFCON Qual就打進決賽,運氣真的很好XD
0ctf 2018 Qual
EzDoor
這題蠻有趣的,第一次碰opcache
他有幾個小功能,可以看phpinfo、上傳檔案等
雖然能上傳,但是會檢查副檔名有沒有出現h,有的話就算不合法
stristr(pathinfo($name)["extension"], "h"))
傳其他檔案上去都不能直接訪問,會403,所以就是要想辦法蓋index.php
move_uploaded_file()
可以覆蓋舊檔案,但是index.php副檔名有h,要想辦法繞
直覺想到以前看過的一招: index.php/.
但是這招沒辦法覆寫舊檔案,只能寫新檔案
改用a/../index.php/.
就能成功覆寫,這跟他底層實作有關,可以去翻source code
賽後才知道這是非預期解法XD
然後翻一下/var/www/html/flag/
下面,會看到有個檔案93f4c28c0cf0b07dfd7012dca2cb868cc0228cad
裡頭是OPcache Byte code
內容乍看之下是在做一連串flag的加解密
大概就猜想可能要去逆向它
於是找到這個Tool有Disassembler: https://github.com/GoSecure/php7-opcache-override
但是踹了很久一直Fail,一開始還要裝特定版本的construct套件
也修正opcache中間少一個NULL Byte的問題,結果還是不行,就卡在這沒解出來Orz
賽後才知道Tool沒處理到某些opcode,要手動修正去逆向…
修正後可以還原出以下pseudo code:
|
|
後面就是去逆向然後推FLAG惹
VXCTF 2018
這是vxcon的一場小CTF,雖然沒啥人參加
不過題目其實蠻有趣的
我也不小心刷了個第四名XDD
PHP of PHP
網站有兩個功能:(1)view
(2)diff
view可以看各個版本的php.net源碼
diff可以比較跟目前的差異 (用diff比)
看一下source,會發現她用JS送request
view是直接用GET訪問取得內容
diff是用POST送JSON過去要內容
送的都是"版本名/index"
看到這個直覺就是LFI
把diff的request改成{"version":"/etc/passwd"}
Bang! 噴出來惹 果然可以LFI
再來就踹{"version":"/v*/w*/h*/d*"}
看diff.php源碼
噴出這段關鍵code:
|
|
可以明顯看到,這裡可以Command Injection
只是他有擋掉特殊符號和一些關鍵字
而換行雖然沒擋,可是json_decode不吃換行
但是json_decode
可以吃\n
和\t
,他decode會自動轉成換行
不能ls,可以這樣列目錄: {"version":"\necho\t*"}
再來可以發現存在這個檔案: /th1s_i5_4_l0n9_f0ld3r_n4me/7hi5_i5_a_s3cre7_fi13
直接讀出來就是FLAG: {"version":"/th*/7*"}
vxctf{YezWiiWerBorn2MakeHistory}
Patch Peep Huck (w)
這題應該是這場Web最有趣的一題XD
很幸運的這題我拿到首殺
最後也只有兩隊解出來
題目長這樣:
|
|
!!$l='tmp_name'
會把$l
設成'tmp_name'
,並且因為NOT
運算,最後整句結果是1
也就是$_FILES[!!$l='tmp_name']
實際上就是存取$_FILES[1]
$I['size']>>7
是判斷size不能超過這個大小,否則這邊會變成True,就沒辦法include檔案了
重點在最後一個條件: preg_match('/\w/',join(file($I[$l])))
這邊是取出我們上傳的檔案的內容,如果裡面有出現英數字或底線,就不給你include
所以我們就是構造個「不用到英數字和底線」的webshell
方法非常多,我這邊是用XOR去構造system字串和我要執行的command
My Payload:
|
|
他其實在做的就是system("cat /????")
vxctf{Symb01icExecut10nCanPhuck}
Codegate 2018 qual
SimpleCMS
這題是Code Review題目
蠻明顯感覺就是在考SQL Injection
但擋了一堆東西
可以發現col
參數沒有擋#
和:
所以可以註解掉後面整句SQL
那要怎麼利用這個點呢
search
參數可以塞換行(%0a
)!!
換行之後可以繼續接SQL,這是這題最好玩的小trick
透過註解+換行把中間一段不想要的SQL註解掉
後面就可以去Union based注入惹
只是這題他有擋information.schema
沒辦法知道表名、欄位名
這裡可以用到另一個小trick
因為他的table engine是innodb
我們可以這樣撈表名:
/index.php?act=board&mid=search&type=2&col=title|idx%23&search=%0a)union+select+1,table_name,3,4,5 from mysql.innodb_table_stats limit 2,1--+
爆flag也可以不需要Column name就撈出來:
/index.php?act=board&mid=search&type=2&col=title|idx%23&search=%0a)union+select+c,2,3,4,5 from (SELECT 1 a,2 b,3 c, 4 d UNION SELECT * FROM 41786c497656426a6149_flag)x limit 1,1--+
l4w
題目:
|
|
這是我過年時做的一題
很有趣的php題
超愛這種短小又很吃技巧的題目XD
這題解法很多,所以做完可以學到很多
他限制了很多,例如不能出現連續長度4以上的英文數字底線等
然後送過去的payload,他只會取前30 Bytes去eavl
最後要去讀localhost:8888
才能拿到FLAG
我自己一開始的方法就跟vxctf那題一樣,用xor構造system
但太容易超過長度30,就放棄了
我後來的解法是: ?%E2%81%A3=`$_`;//;a=sle;b=ep;$a$b 10;
`$_`;//;
後面可以接指令
然後把shell script用類似HITCON CTF 2017 Babyfirst的技巧寫進/tmp
再把Reverse shell噴回來
但噴回來還有個坑XD
他沒有nc
, curl
, wget
, telnet
…等指令
要怎麼去讀localhost:8888 ?
後來我發現他有busybox
,裏頭有telnet
可以用
所以busybox telnet localhost 8888
就讀出FLAG惹
其他人還有用cat < /dev/tcp/0/8888
或ssh -v 0 8888
的
更多解法可以看writeup: https://github.com/l4wio/CTF-challenges-by-me/tree/master/lixi_2018/writeup