前兩天打了國賽的初賽,再次被自己菜哭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位置讀取,得到最終結果: