全國大學生資訊保安競賽—創新實踐能力賽初賽wp
前兩天打了國賽的初賽,再次被自己菜哭555
MISC
簽到
the_best_ctf_game
下載下來附件拖入notepad++,看到有類似flag的字樣
再放到010editor裡
看到了頭和尾,直接一個個輸入拼起來就好了
flag{65902f26-0d6e-463f-bc63-2df733e47fbe}
WEB
easyphp
開啟環境看到顯示的原始碼
這段程式碼大體意思就是先建立一個子程序,然後建立成功後去進行程序控制,如果進城異常退出的話,就返回phpinfo,後面就是對傳參a進行過濾。
審計過後發現有個敏感函式call_user_func_array(),這個函式是回撥函式,並把一個數組引數作為回撥函式的引數。
在程式碼中還發現了會用正則過濾變數a,不能直接傳pcntl_wait()而使子程序終端
後來想到我們可以通過給a變數傳入call_user_func(),然後給b傳pcntl_wait()來繞過正則過濾從而得到phpinfo
Payload: ?a=call_user_func&b=pcntl_wait
可以得到phpinfo頁面,本來想通過phpinfo來看一下有沒有可利用的函式來getshell的,結果發現flag就在phpinfo中
easytrick
拿到題目發現是反序列化。目的是執行echo file_get_contents(“/flag”)語句。因此需要構造物件的兩個成員,trick1和trick2長度小於5,md5相等,但是兩者不相等。
由於在程式碼剛開始的部分有強制型別轉換
!==當判斷兩者型別不同後,就會直接返回True。因此只要傳入的trick1和trick2是同類型但不是String型別即可。
!=則會先轉換二者型別,因此需要使用傳入的引數在強制型別轉換為String後,再次轉換不能復原的型別。
實驗發現使用NAN(Not a Number)符合以上條件:
使用如下程式碼構造payload:
O:5:"trick":2:{s:6:"trick1";d:NAN;s:6:"trick2";d:NAN;}
傳入payload獲得最終結果:
rceme
打開發現有原始碼
將$_GET['a']的值傳入了parserIfLabel函式
經過資訊蒐集後發現本題程式碼為CVE-2019-9041漏洞的魔改題
傳入的a需要滿足次正則要求,即{if:}開頭,{end if}結尾
之後經過多層過濾後在{if:}的:與}之間的語句會被拼接到
而被執行,在經過多次本地除錯後發現形似?a={if:1)*要執行程式碼*if(1}{end if}
的payload可以被成功拼接並執行
下一步表示繞過過濾函式danger_key()
發現過濾的很死,eval,assert以及回撥函式啥的都被ban了
想到用字串拼接來繞過,但是回撥函式被ban了,後查閱資料發現array_map()也能來掉用函式
後來構造payload ?a={if:1)array_map('sys'.'tem',['cat /flag']);if(1}{end if}
併成功的到flag
Reverse
Re_Z3
拖進IDA進行反編譯
找到main函式後進行反彙編出虛擬碼
可以整理出其中的邏輯,首先將unk_404020處的字串讀入Dst賦給Dst。然後讀取使用者42位的輸入。以七個字母為一組組成七元一次方程組,等式左側的部分即是Dst中的值。後續的方程引數都相同,僅僅是方程左側的數值不同。
這裡使用python的scipy庫解方程,exp如下:
import numpy as np
from scipy.linalg import solve
Dst=[
[0x4f17,0x9cf6,0x8ddb,0x8ea6,0x6929,0x9911,0x40a2],
[0x2f3e,0x62b6,0x4b82,0x486c,0x4002,0x52d7,0x2def],
[0x28dc,0x640d,0x528f,0x613b,0x4781,0x6b17,0x3237],
[0x2a93,0x615f,0x50be,0x598e,0x4656,0x5b31,0x313a],
[0x3010,0x67fe,0x4d5f,0x58db,0x3799,0x60a0,0x2750],
[0x3759,0x8953,0x7122,0x81f9,0x5524,0x8971,0x3a1d]]
a=np.array([[12,53,6,34,58,36,1],
[83,85,12,73,27,96,52],
[78,53,24,36,86,25,46],
[39,78,52,9,62,37,84],
[23,6,14,74,48,12,83],
[27,85,92,42,48,15,72],
[4,6,3,67,0,26,68]])
for i in Dst:
b=np.array(i)
x=solve(a,b)
for j in x:
print(chr(int(round(j))),end='')
執行得到最終答案:flag{7e171d43-63b9-4e18-990e-6e14c2afe648}
Hyperthreading
程式有反除錯,呼叫win下的IsDebuggerPresent,先使用IDA搜尋字串,找到debug欄位,檢視交叉引用,定位到反調函式進行patch,之後拖進Ollydbg,隨便輸入一個值,發現flag長度42位,驗證方式是逐字元對使用者輸入的字元做加密後進行對比。
找到關鍵cmp,位置在0x401306(基址401000),對cmp下的jnz進行patch,改為nop,並將0x40130F處的2Ah改成FFh,即去除對比後不成功的跳轉,並且將程式的flag對比操作次數從0x2a改為0xff。
之後拖入OLLYDBG 關鍵cmp處下斷。
輸入abcdefghijklmnopqrstuvwxyz1234567890-{}
按順序記錄cl的值,獲得一個每個字母對應十六進位制的對映表
通過字串定位方法發現sub_401270中的byte_402150即為加密的flag,逐位與使用者輸入對比。
根據前一步動態除錯patch後的程式獲得的abcdefghijklmnopqrstuvwxyz1234567890-{}對映表就可解出flag{a959951b076ca047840add7093583251ca92}
提交後發現不正確,觀察flag發現需要把0換為減號
最終flag為flag{a959951b-76ca-4784-add7-93583251ca92}
Crypto
bd
使用CTF-RSA-TOOLS 解出m
M轉為16進製為
666c61677b64333735323533382d393064302d633337332d636665662d3932343764336531363834387d
發現是16進位制的flag
兩個一組,寫指令碼解出flag{d3752538-90d0-c373-cfef-9247d3e16848}
PWN
babyjsc
根據題目嘗試連線:
可以根據報錯得知,題目環境使用python搭建,並使用input讀入
根據得到的原始碼也可以驗證這一點,因此可以使用input的漏洞,input()函式如果接收的是計算式,會執行得到結果。
此處嘗試根據該漏洞傳入程式碼執行,利用的os模組的system()方法執行系統命令 __import__('os').system('ls')。命令成功被執行,說明漏洞存在:
發現flag並不在根目錄,嘗試查詢flag:
找到flag位置讀取,得到最終結果: