SSRF全称:Server-Side Request Forgery,即 服务器端请求伪造。是一个由攻击者构造请求,在目标服务端执行的一个安全漏洞。攻击者可以利用该漏洞使服务器端向攻击者构造的任意域发出请求,目标通常是从外网无法访问的内部系统。简单来说就是利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网进行攻击
当攻击者想要访问服务器B上的服务,但是由于存在防火墙或者服务器B是属于内网主机等原因导致攻击者无法直接访问。如果服务器A存在SSRF漏洞,这时攻击者可以借助服务器A来发起SSRF攻击,通过服务器A向主机B发起请求,达到攻击内网的目的。
示例:
漏洞场景:某网站有一个在线加载功能可以把指定的远程文章加载到本地,链接如下:
http://www.xxx.com/article.php?url=https://blog.csdn.net/qq_43531669/article/details/112498646
假如系统没有对url参数进行任何的检查,就可以构造其他的请求,例如:
http://www.xxx.com/article.php?url=http://127.0.0.1:22
http://www.xxx.com/article.php?url=file:///etc/passwd
http://www.xxx.com/article.php?url=dict://127.0.0.1:22/data:data2 (dict可以向服务端口请求data data2)
http://www.xxx.com/article.php?url=gopher://127.0.0.1:2233/_test (向2233端口发送数据test,同样可以发送POST请求)
http://payloads.net/ssrf.php?url=file:///c:/windows/win.ini
...
很多网站提供了从其他的服务器上获取数据的功能。通过指定的URL,网站可以从其他地方获取图片、下载文件、读取文件内容等。SSRF的实质就是利用存在缺陷的Web站点作为代理攻击远程和本地的服务器。
SSRF漏洞形成的原因大都是由于服务端提供了从其他服务器获取数据的功能但没有对目标地址做过滤与限制。攻击者可以利用改漏洞获取内部系统的一些信息(因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内网系统)。
内网服务防御相对外网服务来说一般会较弱,甚至部分内网服务为了运维方便并没有对内网的访问设置权限验证,所以存在SSRF时,通常会造成较大的危害。
1)显示对攻击者的响应(Basic)
它显示对攻击者的响应,因此在服务器获取攻击者要求的URL后,它将把响应发送回攻击者。返回结果到客户端,如传送一个网址,会返回这个网址的界面或对应的 html 代码。
2)不显示响应(Blind)
和上面正好相反,不会返回结果到客户端。
当您从未从初势请求中获取有关目标服务的任何信息时,就会发生这种ssrf。通常,攻击者将提供url,但是该url中的数据将永远不会返回给攻击者。要在这种情况下确认漏洞,攻击者必须使用Burp,DNSbin等类似工具。这些工具可以通过强制服务器向攻击者控制的服务器发出DNS或HTTP请求来确认服务器是易受攻击的。这种ssrf通常易于验证,但难以利用。
3)Semi-ssrf
与Blind相似,这种ssrf不会返回相关结果请求的所有详细信息,但是会暴露一些数据。
这可能是部分数据或错误信息,他们为攻击者提供了更多信息。
有时,关于请求的元数据(例如响应时间)也可以视为Semi-ssrf,因为它们允许攻击者验证请求是否成功。这种ssrf通常足以验证漏洞,但并不总是能够提取敏感数据。
因为SSRF漏洞是构造服务器发送请求的安全漏洞,所以我们可以通过抓包分析发送的请求是否是由服务器端发送的来判断是否存在SSRF漏洞。
在页面源码中查找访问的资源地址,如果该资源地址类型为http://www.xxx.com/a.php?image=地址就可能存在SSRF漏洞。
1)基本判断(排除法)
例如:
http://www.douban.com/***/service?image=http://www.baidu.com/img/bd_logo1.png
排除法一:
你可以直接右键图片,在新窗口打开图片,如果是浏览器上URL地址栏是 http://www.baidu.com/img/bd_logo1.png,说明不存在 SSRF 漏洞。
排除法二:
你可以使用 burpsuite 等抓包工具来判断是否不是SSRF,首先 SSRF 是由服务端发起的请求,因此在加载图片的时候,是由服务端发起的,所以在我们本地浏览器的请求中就不应该存在图片的请求,在此例子中,如果刷新当前页面,有如下请求,则可判断不是SSRF。(前提设置 burpsuite 截断图片的请求,默认是放行的)
(1) 分享功能:通过URL地址分享文章等,例如如下地址:
http://share.xxx.com/index.php?url=http://www.xxx.com
通过url参数的获取来实现点击链接的时候跳到指定的分享文章。如果在此功能中没有对目标地址的范围做过滤与限制则就存在着SSRF漏洞。
(2)图片加载/下载:通过URL地址加载或下载图片:
http://image.xxx.com/image.php?image=http://www.xxx.com
图片加载存在于很多的编辑器中,编辑器上传图片处加载设定好的远程服务器上的图片地址,如果没对加载的参数做限制可能造成SSRF。
(3)图片/文章收藏功能:
http://title.xxx.com/title?title=http://title.xxx.com/xxx
例如 title参数是文章的标题地址,代表了一个文章的地址链接,如果收藏功能采用了此种形式保存文章,则在没有限制参数的形式下可能存在SSRF。
(4)转码服务:通过URL地址把原地址的网页内容调优使其适合手机屏幕浏览。
(5)在线翻译:给网址翻译对应网页的内容。
(6)邮件系统:比如接收邮件服务器地址。
(7)利用参数中的关键字查找:
关键字:
share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain...
总的来说,需要从远程服务器请求资源的网站都有可能存在SSRF漏洞。
部分存在漏洞,或者可能产生SSRF的功能中做了白名单或者黑名单的处理,来达到阻止对内网服务和资源的攻击和访问。因此想要达到SSRF的攻击,需要对请求的参数地址做相关的绕过处理,常见的绕过方式如下:
(1)利用@,当网站限制只能访问 http://www.xxx.com类型的域名时,可以采用http基本身份认证的方式绕过,如:http://[email protected]
在对@解析域名中,不同的处理函数存在处理差异,例如:
http://[email protected]@www.ccc.com
在PHP的parse_url中会识别 www.ccc.com,而libcurl则识别为 www.bbb.com。
(1)采用短网址绕过
(2)利用特殊域名,xip.io可以指向任意域名(原理是DNS解析),即 127.0.0.1.xip.io,可以解析为127.0.0.1
(3)采用进制转换,127.0.0.1 八进制:0177.0.0.1
;十六进制:0x7f.0.0.1
;十进制:2130706433
(4)利用[::]
,http://[::]:80/
会解析为 http://127.0.0.1
(5)添加端口号,http://127.0.0.1:8080
(6)利用句号,127。0。0。1
会解析为 127.0.0.1
(7)采用302跳转
(1)采用302跳转
(2)采用短地址
file_get_contenets()、fscokopen()、curl_exec()、fopen()、readfile()
(1)file_get_contents()
$url = $_GET['url'];;
echo file_get_contents($url);
?>
file_get_content
函数从用户指定的url获取内容,然后指定一个文件名j进行保存,并展示给用户。file_put_content函数把一个字符串写入文件中。
(2)fsockopen()
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数据的获取,该函数使用socket(端口)跟服务器建立tcp连接,传输数据。变量host为主机名,port为端口,errstr表示错误信息将以字符串的信息返回,30为时限
(3)curl_exec()
if (isset($_POST['url'])){
$link = $_POST['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;
}
?>
curl_exec
函数用于执行指定的cURL会话
1、禁止跳转
2、禁用除http和https外的协议,如:file://
、gopher://
、dict://
等。
3、限制请求的端口为http常用的端口,如 80、443、8080。
4、统一错误信息,避免用户可以根据错误信息来判断远程服务器的端口状态。
5、对请求地址设置白名单或者限制内网IP,以防止对内网进行攻击。
1、项目编辑器、新建项目,添加素材导出,抓取中间的两个POST数据包
https://aod.xxxx.com/add/editor
2、数据包1:
上传素材,并保存当前的项目
POST /api/web/screenEditor/save HTTP /1.1
Host:aod.xxx.com
Cookie:xxx=xxx
{"layout":{"type":"3","material":"name","url":"https//xxx.com/1.png"}}
第一步:将素材地址图片的域名,替换为Dnslog服务器,保存项目
保存生成了项目id:5fecc2b0eaxxxxf2d627a9
3、数据包2:
将保存后的项目id,导出为项目压缩包程序
POST /api/web/screenEditor/export HTTP/1.1
Host:aod.xxx.com
Cookie:xxx=xxx
{"id":"5fecc2b0eaxxxxf2d627a9"}
4、保存项目时,上传素材时添加的dnslog服务器,在导出时,会被服务器进行访问,触发漏洞
这个漏洞相当于是没有回显的SSRF漏洞,可以进行一些端口探测,内网访问的危害
总结:
1、除了常规的参数型的SSRF漏洞,此类保存并导出型也尤为常见
2、利用了导出项目必要的远程拉取附件的功能
1、首先,系统地址为:`http://xxx-desktop.xxx.com/,访问如下:
打开发现一片空白页面,但是空白页面并不代表是真的空白,HTML源码中可能会加载一些JavaScript文件。
2、查看页面源码,发现仅仅只有一个Jquery文件:/libs/plugins/jquery.js
经过对此JavaScript文件的审计发现:
此处jquery.js完全仅为前端文件,无任何可利用的信息,这样表面上并没有可用信息
3、因为打开链接是个空白页面,猜测可能还会有一层Web目录。于是尝试直接对当前URL进行一集目录扫描:(原因是找寻是否有隐藏功能点)
最终仅扫描到了3个403页面:基本上每个网站都会存在的/html
、/css/
、js
目录。/js/、/css/等此类目录一般存在一些静态文件,几乎是每个Web应用都会存在的
4、测试到这里没有任何可用信息,于是对/js/目录,进行JavaScript文件的爆破。终于获取到了可用信息:
获取到了3个真实存在的JavaScript文件。
5、之后审计JavaScript源码发现,common.js
中含有一些接口信息:
发现了接口目录:/xxxapi/
,JavaScript文件的注释信息中心存在生产环境的描述。通过注释猜解,此接口目录是真实存在并可以使用的接口。
6、又在另一处爆破出的JS文件apply.js
文件中发现了接口:/file/pdf/view?file=
7、将之前获取到的接口目录/xxxapi/
与系统接口file/pdf/view?file=
进行组合拼接,组成接口URL:http://xxx-desktop.xxx.com/xxxapi/file/pdf/view?file=
8、http://xxx-desktop.xxx.com/xxxapi/file/pdf/view?file=
对file参数进行了文件读取、SSRF漏洞测试等,最终发现SSRF漏洞存在,VPS监听请求测试,成功:
9、接下来利用SSRF进行内网资源的请求尝试,由于在之前的测试中,通过审计JavaScript文件已经收集到了一些内网资产,所以直接进行测试访问即可。
10、测试访问内网Elasticsearch服务:http://10.x.x.191:9200
测试访问内网的其他Web服务:http://10.x.x.65:8081
,均成功
总结:
没有任何可利用的信息情况下,爆破一级目录
、二级目录
,甚至爆破JavaScript文件
、爆破接口
也不失为发现漏洞的好办法
1、首先登陆平台、进行任务考试
2、考试会加载图片:(图片剪辑类型的考试)
3、此处在测试时,发现需要将Burpsuite的数据包过滤功能全部放开,才能显示出数据包:
show all显示全部数据包,原本的文件类型处,默认隐藏Images、CSS、Binary
Hide隐藏,仅添加过滤一些无关紧要的后缀文件。
4、抓取到获取图片的URL:http://www.xxx.com/api/internal/file?xxxx_url=https://static.xxxx.com/obk/crowdsourcing/b1dd193cxxxxxxf4f7e215aae737110e.png?xxxx_token=eyJhbGciOiJIUzl1NilslnR5cxxxxx
其中,经过测试后xxxx_url
参数存在SSRF漏洞,可直接访问内网其他资产。
此处有一个影响漏洞进一步利用的关键:不能破坏此参数的结构,也就是:后半部分的图片后缀
、jwt token参数
不能变更。
5、这样就存在一个问题,即便存在SSRF漏洞,图片后缀却不能更改,这也就导致,无论访问任何内网资产,都必须携带xxx.png?xxx_token=jwt_token
,如下:
http://10.1.1.1/.png?xxxx_token=eyJhbGciOiJIUzl1NilslnR5cxxxxx
6、拿一个主页举例:http://www.timelinesec.com/.png?xxx_token=1123
虽然后面的xxx_token参数不会影响访问,但是只要携带.png
,基本必定是访问任何资产都是404页面,相当于访问资产的png文件。因此,如果必须携带png后缀的话,此处漏洞仅仅能用来探测Web服务的是否开放,而不能构造访问各种功能路径
7、为了扩大该漏洞危害,想到了前端H5功能路由时常用的/#/
目录,当/#/
目录用在它不能发挥作用的地方,会造成截断URL的效果。
如:http://www.timelinesec.com/#/.png?xxx_token=1123
8、于是利用此种方法,即可忽视必须要携带的:.png?xxx_token=xxx
9、成功构造访问内网的URL:
https://xxx.com/api/internal/file?xxx_url=http://10.8.7.30/%23/
xxx.png?aidp_token=xxx
利用/#/
达成欺骗,起到仅访问#号前资产的效果
总结:
1、修改Burpsuite默认的过滤配置,可以发现更多的东西
2、需要截断URL的场景可利用/#/进行截断
引用文章
https://cloud.tencent.com/developer/article/2103240