目录
一、官方介绍
二、开始闯关吧
第1关 SSRF(curl)
1、file协议查看本地文件
2、ftp协议查看内网ftp服务器上的文件
3、dict协议扫描内网主机开放端口
第2关 SSRF(file_get_content)
1、file读取本地文件
2、php://filter/读php源代码
3、http协议请求内网资源
4、为啥ftp不行呢?
本节引用内容来自pikachu漏洞平台
SSRF(Server-Side Request Forgery:服务器端请求伪造)
其形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,但又没有对目标地址做严格过滤与限制
导致攻击者可以传入任意的地址来让后端服务器对其发起请求,并返回对该目标地址请求的数据
数据流:攻击者----->服务器---->目标地址
根据后台使用的函数的不同,对应的影响和利用方法又有不一样PHP中下面函数的使用不当会导致SSRF: file_get_contents() fsockopen() curl_exec() 如果一定要通过后台服务器远程去对用户指定("或者预埋在前端的请求")的地址进行资源请求,则请做好目标地址的过滤。 你可以根据"SSRF"里面的项目来搞懂问题的原因
这一关刚进去是这样的,按照指示点击下图红框框里面的链接
然后就得到了下图红框框里的带参数的url,参数名是url,参数值是一个url(emmmm……)
然后……不太懂php的curl,于是百度一下
看一下菜鸟教程的介绍(https://www.runoob.com/php/php-ref-curl.html)
PHP支持的由Daniel Stenberg创建的libcurl库允许你与各种的服务器使用各种类型的协议进行连接和通讯。
libcurl目前支持http、https、ftp、gopher、telnet、dict、file和ldap协议。libcurl同时也支持HTTPS认证、HTTP POST、HTTP PUT、 FTP 上传(这个也能通过PHP的FTP扩展完成)、HTTP 基于表单的上传、代理、cookies和用户名+密码的认证。
PHP中使用cURL实现Get和Post请求的方法
这些函数在PHP 4.0.2中被引入。
先来看个比较熟悉的协议。file协议可以查看本地文件。
输入payload:http://192.168.101.16/pikachu/vul/ssrf/ssrf_curl.php?url=file:///c:/windows/system32/drivers/etc/hosts
可以查看文件C:\Windows\System32\drivers\etc\hosts的内容
再来看一个ftp协议。
如果192.168.101.16这台pc可访问另一台pc(比如192.168.101.14)上的ftp服务,就可以通过这个ssrf漏洞结合ftp协议阅读ftp目录下的内容。
先在192.168.101.14上起一个ftp协议(我用的wftpd32,挺方便),新建用户,用户名和密码都是ele,目录也要设置一下
然后再用另外一台虚拟机模拟攻击,输入payload:http://192.168.101.16/pikachu/vul/ssrf/ssrf_curl.php?url=ftp://ele:ele@192.168.101.14/1.txt
可以读到内网ftp服务器上的文件内容。(不知道为啥结尾多个1,这么一看,上面file协议读取的文件内容结尾也多个1)
使用dict协议可以获取内网主机开放端口相应服务的指纹信息,比如内网主机192.168.101.14上开了ftp服务的话,就可以通过payload:http://192.168.101.16/pikachu/vul/ssrf/ssrf_curl.php?url=dict://192.168.101.14:21
获取到下图红框框中的内容
下面来用burpsuite的intruder模块来扫描192.168.101.14上的开放端口
首先用burpsuite抓包,找到下面这样的报文,send to intruder
按照下图这样配置intruder,出于时间考虑,爆破0~1023端口试试
觉得慢可以把线程数调大点
爆破出来的结果挺出乎意料的,除了十几个Status是503 Service Unavailable,其他全是200 OK,想想也不可能。
想了一下,如果端口开放有服务的话,应该会有服务的指纹信息显示在网页上,因此爆破结果应该以response报文的长度排序,长度比大多数端口长的应该就是开放端口。
如上图所示,response报文长度比大部分端口长的有21,912,902以及443
912和902都是VMware,443端口是https.
在192.168.101.14上命令行输入netstat -ano来看一下扫描结果是否准确:
从上图可见,1023以内的开放端口除了135和443,其他都被扫出来了。135是RPC,445是共享文件夹和打印机用到的端口。。这两个为啥扫不出来有大神知道吗?
====================================================================================================================================
简单看一下代码,其实贴在这里我只是方便自己看curl的使用示例ヾ(^▽^*)))
注意下图中有错误,扫描端口用dict协议,不能用http协议,我试过了>︿<
一进来是这么个玩意儿,还是点一下红框框里的链接
同样的流程,同样的套路,又得到一个带参数的链接,参数名file,参数值是个url,或者说,是个文件路径
file_get_content()函数我也不认识,看名字大概是读取文件内容的,网上搜一下,又搜到菜鸟教程https://www.runoob.com/php/func-filesystem-file-get-contents.html
file_get_contents() 把整个文件读入一个字符串中。
该函数是用于把文件的内容读入到一个字符串中的首选方法。如果服务器操作系统支持,还会使用内存映射技术来增强性能。
嗯,确实是个读文件的。
一说到读文件首先就想到file协议了,先来试一下payload:http://192.168.101.16/pikachu/vul/ssrf/ssrf_fgc.php?file=file:///c:/windows/win.ini
读取成功了~这关结尾就没有奇奇怪怪地多个1,不错不错
php伪协议中有个读php源代码的php://filter/,来试试这个好不好使。比如我想看rce.php的源代码,就输入payload:http://192.168.101.16/pikachu/vul/ssrf/ssrf_fgc.php?file=php://filter/read=convert.base64-encode/resource=../rce/rce.php
网页上就输出base64编码的rce.php的源代码了
复制出来之后在网上解个码
我这儿环境比较简陋。。在靶场所在pc可达的另一台pc(192.168.101.14)上起了个简单的http服务(python3 -m http.server 80)
然后浏览器输入payload:http://192.168.101.16/pikachu/vul/ssrf/ssrf_fgc.php?file=http://192.168.101.14/1.txt
就成功读取到1.txt的内容啦
试了下ftp,没有成功欸,为啥呢?
payload是:http://192.168.101.16/pikachu/vul/ssrf/ssrf_fgc.php?file=ftp://ele:ele@192.168.101.14/1.txt
报错了。。
我到wftpd32的界面上去对比了一下,上一关正常的请求是下图这样
这关报错的请求是下图这样,比正常请求多个/,着玩意儿怎么多出来的呀!!!???
=======================================================================================================================================
源代码有点无聊,但为了对称,还是po一下,嘻嘻~