SSRF简介
(服务端请求伪造)是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。
file_get_contents(),fsockopen(),curl_exec()三个函数使用不当时将会造成ssrf。
SSRF的危害
1、探测内网信息。
2、攻击内网或本地其他服务。
3、利用file协议读取本地文件。
4、对内网web应用进行指纹识别。
5、端口扫描。
gopher、dict协议以及redis服务、Curl 命令
Gopher 协议可以做很多事情,特别是在 SSRF 中可以发挥很多重要的作用。利用此协议可以攻击内网的 FTP、Telnet、Redis、Memcache,也可以进行 GET、POST 请求。
DICT协议,一个字典服务器协议,A Dictionary Server Protocol,允许客户端在使用过程中访问更多字典并且该协议约定服务器端侦听端口号:2628。
redis服务是在6379端口开启的。
curl命令:
curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。
不带有任何参数时,curl 就是发出 GET 请求eg: curl https://www.example.com
-v参数输出通信的整个过程,用于调试。我们便可以利用-v参数进行读取文件:
1、使用file协议curl -v file:///etc/passwd
2、使用ftp协议 curl -v "ftp://127.0.0.1:端口/info"
3、用dict协议 curl -v "dict://127.0.0.1:端口/info"
4、使用gopher协议 curl -v "gopher://127.0.0.1:端口/_info"
SSRF利用一
file()与file_get_content()的区别
PHP中file() 函数和file_get_contents() 函数的作用都是将整个文件读入某个介质,其主要区别就在于这个介质的不同。file() 函数是将文件读入一个数组中,而file_get_contents()是将文件读入一个字符串中。
file() 函数是把整个文件读入一个数组中,然后将文件作为一个数组返回。数组中的每个单元都是文件中相应的一行,包括换行符在内。如果失败,则返回 false。
file_get_contents() 函数是把整个文件读入一个字符串中。和 file() 一样,不同的是file_get_contents() 把文件读入一个字符串。file_get_contents() 函数是用于将文件的内容读入到一个字符串中的首选方法。如果操作系统支持,还会使用内存映射技术来增强性能。
SSRF利用二
①访问正常文件
访问正常的文件,提交参数[?url=http://www.xxx.com/robots.txt]
②端口扫描
当访问未开放端口,脚本会显示空白或者报错。提交参数[?url=dict://127.0.0.1:2333]
当访问开放端口时,脚本会显示banner 信息。
提交参数[?url=dict://172.16.132.152:22](有成功率)
提交参数[?url=dict://127.0.0.1:3306]
提交参数[?url=dict://127.0.0.1:21]
③读取本地系统文件
利用file 协议可以任意读取系统本地文件,提交参数
[?url=file://c:windowssystem32driversetchosts]
④内网Web应用指纹识别
识别内网应用使用的框架,平台,模块以及cms可以为后续的渗透测试提供很多帮助。
大多数web应用框架都有一些独特的文件和目录。
通过这些文件可以识别出应用的类型,甚至详细的版本。
根据这些信息就可以针对性的搜集漏洞进行攻击。
比如可以通过访问下列文件来判断phpMyAdmin是否安装以及详细版本。
[?url=http://localhost/phpmyadmin/README]
⑤攻击内网应用
内网的安全通常都很薄弱,溢出、弱口令等一般都是存在的。
通过ssrf攻击,可以实现对内网的访问,从而可以攻击内网应用或者本地机器,获得shell,这里的应用包括服务、Web 应用等。
仅仅通过get方法可以攻击的web应用有很多,比如struts2命令执行等。
靶场演示
靶场一:(SSRF - curl)
1、进入靶场页面,这句话是一个链接,点击如图所示。
2、查看一波源代码。
3、查看URL可知跳转路径,
4、修改URL,比如:http://www.baidu.com
5、我们可以把URL后面的内容换成同一网络的其他服务器上地址和端口,探测内网的其他信息,比如端口开放情况,也可以访问某一个文件夹,这种get类型的数据我们通过修改URL的内容就可以了。我们看一下后台的代码,如果没有做好过滤,就可以通过curl这个方法获取到内网的其他服务器上的信息,也可以对网络上的进行读取:
靶场二:(SSRF - file_get_content)
1、进入靶场依然是
2、查看url
3、查看一波源代码
4、file_get_contents() 函数把整个文件读入一个字符串中。其实和 file()函数 一样,不同的是 file_get_contents() 把文件读入一个字符串。
file_get_contents() 函数是用于将文件的内容读入到一个字符串中的首选方法。如果操作系统支持,还会使用内存映射技术来增强性能。
//读取PHP文件的源码:php://filter/read=convert.base64-encode/resource=ssrf.php //内网请求:http://x.x.x.x/xx.index
意味着file_get_contents里面带有php:// filter 我们用这个就可以来读取php源码,所以我们来构造URL:
http://localhost/pikachu/vul/ssrf/ssrf_fgc.php?file=php://filter/read=convert.base64-encode/resource=ssrf.php
5、然后网页出现了乱码。
6、利用解码工具。
SSRF防御
①限制协议
仅允许http和https请求。
②限制IP
设置URL白名单,避免应用被用来获取内网数据,攻击内网。
③限制端口
限制请求的端口为http常用的端口,比如,80,443,8080,8090。
④过滤返回信息
验证远程服务器对请求的响应是比较简单的方法。
⑤统一错误信息
防止用户可以根据错误信息来判断远端服务器的端口状态,禁止30x跳转。
参考
https://blog.csdn.net/weixin_30633949/article/details/97824781
https://blog.csdn.net/qq_41901122/article/details/104231760
https://www.cnblogs.com/tr1ple/p/11065224.html
http://cnblogs.com/3cH0-Nu1L/p/13462107.html
http://cnblogs.com/3cH0-Nu1L/p/13466451.html