Hack the following server.
http://10.0.106.(team number)/
User NamePassword
guestpassword
admin(Unknown)
Note: You do not have to use way of brute force or DoS to solve this challenge. Please do not put a load on bandwidth or disk space.
題目給了一個網站,具備以下2種功能:
upload:http://10.0.106.10/tmctf2019/upload.php
download:http://10.0.106.10/tmctf2019/download.php
對於上傳,可以指定public / private上傳,對於download也可以指定public / private下載,上傳至public的文件,只能用download的public文件下載。
也就是説題目給了我們一個文件上傳,一個文件下載,而對於目錄的劃分(public / private),現在看不出多大作用來。
隨便測試了一通,發現文件上傳時,會拼接sha256的後綴,例如上傳:
1.jpg
得到的文件名會變為:
1.jpg_sha256(salt '1.jpg')
所以無法控制後綴,而嘗試登陸功能注入和弱密碼爆破登入也無法突破,無法將身份轉換為admin,陷入僵局。
那麼自然想到掃一掃目錄,可以發現文件夾:
http://10.0.106.10/tmctf2019/include/
該文件夾並沒有做權限控制,我們可以看到如下4個文件:
files.inc
functions.php
import_theme.inc
login.php
顯然我們只能讀取.inc文件,php文件會被解析無法直接訪問源碼。
import_theme.inc
files.inc
代碼審計
既然有文件上傳和文件下載,這勢必是我們解題的主要突破口,故此審計了一下,發現:
我們很難直接進行目錄穿越,無論上傳還是下載,都會在最後進行限制。
同時通過源碼,我們可以發現還存在一個theme功能,但是需要admin授權:
check_login_session_admin();
但是該功能並沒有相應的目錄穿越限制:
我們觀察到會有解壓7z的操作,這裏不難想到軟連接 / 寫php後門,因為解壓目錄在web路徑下。
但是這一切都需要我們先變成admin身份,否則將無法利用theme功能。
admin身份偽造
那麼如何變成admin呢?我們注意到一個特別點:
session_save_path("/var/tmctf/");
題目將session文件都置於
/var/tmctf
而我們的上傳目錄位於:
即如果我們上傳到public,路徑為:
/var/tmctf/public/
如果我們上傳到private,則路徑為:
/var/tmctf/private/guest/
但是有意思的是,對於我們的$attr,也就是public / private,並沒有任何的限制,我們可以將其指定為:
.
這樣我們的上傳路徑將變為:
/var/tmctf/./
即可和session文件共享目錄,但是新的問題又來了,我們如何拿到session文件內容格式呢?
這裏注意到download功能,其文件讀取路徑為:
所以我們同理,可以將attr賦值為.,這樣即可讀取/var/tmctf目錄下任意文件,而我們知道session文件格式為:
sess_phpsessid
故此,可以嘗試讀取session文件,可以發現文件內容為:
username|s:5:"guest";remote_addr|s:13:"192.168.10.27";
於是我們可以偽造session文件內容為:
username|s:5:"admin";remote_addr|s:13:"192.168.10.27";
但是上傳後,發現我們的文件名變為:
sess_d182e6417ac7068fb6e4788a44264ab61d5cc43a56f4f3796ffafb0d50bffsky_7470b54ce8e4f6016425b5113ae9425e7d6b6582cb6473e8b7e95278fd3e9e3e
也就意味着我們的phpsession id為:
d182e6417ac7068fb6e4788a44264ab61d5cc43a56f4f3796ffafb0d50bffsky_7470b54ce8e4f6016425b5113ae9425e7d6b6582cb6473e8b7e95278fd3e9e3e
但是phpsessionid中無法帶入下劃線,故此會觸發報錯:
Warning: session_destroy(): Trying to destroy uninitialized session in /var/www/html/tmctf2019/include/functions.php on line 16
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/tmctf2019/include/functions.php:16) in /var/www/html/tmctf2019/include/functions.php on line 17
那麼我們該如何bypass sha256後綴拼接呢?
不難想到,我們可以上傳sess文件名,拼接上後綴後,可以變為:
sess_7470b54ce8e4f6016425b5113ae9425e7d6b6582cb6473e8b7e95278fd3e9e3e
那麼這樣,我們即可拿到不帶無效字母的phpsessionid,讀取驗證:
發現我們成功偽造了admin的sessionid,至此登入,我們可以變成admin,看見theme功能。
任意7z上傳
拿到theme功能後,不容樂觀,我們發現了新的問題:
對於任意文件上傳,後綴總會被拼接上sha256,我們上傳的7z都會變成類似:
answer.7z_bab6c9f7fc17fbc85916afe883ac4cb5030e3089cc8086e71ef4669f9b5decc5
故此無法通過.7z拼接的文件存在check,同時00截斷無效。
除此之外,我們發現管理員的private,出題人預留了一個answer.7z_bab6c9f7fc17fbc85916afe883ac4cb5030e3089cc8086e71ef4669f9b5decc5:
下載解壓後,發現是解密腳本:
該壓縮包的路徑為:
/var/tmctf/private/admin/answer.7z_bab6c9f7fc17fbc85916afe883ac4cb5030e3089cc8086e71ef4669f9b5decc5
而我們目前的路徑為
/usr/local/tmctf/theme/$theme.7z
但是無論如何控制$theme上跳,指定路徑,都無法bypass .7z的後綴拼接。
那麼如何上傳出.7z結尾的文件,成為了難題。
回到上傳點,我們分析路徑構造:
我們關注到,路徑構造為
/var/tmctf/ $attr / filename _ hash_file
我們可以如下方式bypass:
attr = skynb.7z
這樣得到的文件路徑為
/var/tmctf/skynb.7z/ filename _ hash_file
這樣即可截斷後面的hash_file拼接,構造出:
/var/tmctf/skynb.7z
我們再控制theme為:
theme = ../../../../../../../var/tmctf/skynb
即可讓服務端解壓任意7z至目錄:
/var/www/html/skins/css/theme/
同理,我們可以如法炮製,上傳題目給的answer.7z,並讓其解壓至目錄:
/var/www/html/skins/css/theme/
訪問:
http://10.0.106.10/skins/css/theme/answer.php