SSRF就是Server-side request forgery的简称,主要是指一个攻击者通过篡改诱导服务器发起一个没有授权的或者和业务实际需求目的不一致的请求,核心就是Server发起了一个攻击者伪造的请求。
关于伪造请求,就需要了解一个请求的几个组成部分,一个HTTP的主要组成部分如下:
HTTP://IP|domainname:port/path?querystring
这里的请求伪造应该是包括这个请求里的任何一个组成部分,包括协议、IP或者域名、端口、路径以及查询参数。
一般Web站点使用的都是HTTP或者HTTPS,如果攻击者可以将协议修改为:file://,?phar:// ,data://或者ftp://等协议,就可能通过这些协议访问相关资源。例如:通过file://etc/passwd,可以访问passwd文件。
预防方法就是:采用协议的白名单检查。
通过修改IP或者域名,攻击者可以指定访问的目标,IP既可以是127.0.0.1也可以是其它内网的IP,通过它结合端口,可以扫描内网的服务器以及端口,了解内网的情况。针对一些内存数据库,例如:Redis,还可能发起RCE攻击。
预防方法就是:采用IP或者域名以及端口的白名单检查。
有些路径可能是指针对内网才可以访问,如果用户可以通过修改path,就可以绕过防火墙的限制,直接访问内部的服务。例如:http://test.com/admin是内部的管理界面,如果攻击者可以通过篡改访问路径并且让Server去访问这个目标,就可以访问内部的管理界面。
预防方法就是:尽量避免从外界或获取参数值作为访问路径的一部分,如果业务需要或者代码已经实现了的老的应用,需要添加输入验证,或者将参数使用加密算法或者HMAC进行保护,防止篡改。
关于参数的篡改,主要是通过HPP的方式进行攻击。例如:服务器构造一个内部请求:http://a.exmaple.com?query=[],?query的参数的值是从一个请求中获取的参数,示例代码如下:
String url = "http://a.exmaple.com?query=";
String queryValue = request.getParameter("value");
url = url + queryValue;
如果queryValue的值中含有&字符,例如:name&query=name’?or ‘1’=’,就可能将查询的请求修改为:
http://a.exmaple.com?query=name&query=name’?or ‘1’=’
就可以注入一个新的参数,既然参数也是这个请求的一部分,而且,它的注入导致了原来请求的内容的改变,其实,它也是一个篡改的请求,也可以算作SSRF的范畴。根据https://blog.csdn.net/jimmyleeee/article/details/114104274 不同的技术获取的参数是不同的,这就导致了一个请求的查询的内容被篡改。
预防方法就是:一个方法就是输入验证,保证参数值在固定的取值范围;另外一个方法就是将参数组装为URL参数的一部分时,需要进行URL编码,可以参考java.net.URLEncoder。
参考:应用安全系列之二十三:SSRF_jimmyleeee的博客-CSDN博客
|