初探RFD-RFD的攻击原理和应对措施

RFD全称Reflection file download,反射文件下载,一种json攻击手段。通过在URL中插入带有可执行文件的内容,一旦被点击这些可执行文件就会被下载并执行,攻击者通过控制文件的内容来达到自身攻击的目的。通过这个文件攻击者可以控制用户的计算机,可以控制浏览器设置包括那些加密的会话,还可以利用已下载的软件的漏洞。攻击者通常使用一些热门的受信任的域名来掩饰这个URL,让用户任务这是个安全的连接可以点击,以此让用户认为所有的操作都是安全的,从而使得攻击能够顺利进行。

RFD攻击想要能够进行有三个条件要满足。1.某些用户的输入能被反射到响应内容中,可以利用这一点来注入shell命令。2.站点或者是API存在漏洞使得URL能够添加额外的输入并且被接受。攻击者利用这一点把文件的扩展名设置成可执行的扩展名。3.响应会被下载并且浏览器会下载一个和2中相同文件名的文件。如果这三个条件都满足了那么就认为服务是有漏洞的。

那些可以反射到响应内容中且由用户控制的输入通常有一下这么几个:1.请求参数。如果一个网页或者API接受用户输入,那么这是一个把输入反射到响应内容中的好机会。2.错误。一个常见从错误做法是返回引起error的输入。通过篡改请求参数,即使只是反射了错误的输入也足够使得RFD能够顺利进行。3.持久化存储。在某些案例中,攻击者控制的输入是来自于应用的持久化存储,比如数据库和文件等等。在绝大多数情况下,ID参数或者URL路径是被认为是要被存储的内容的。通过这个ID构造一个URL也是能够使得RFD攻击成功进行的。4.JSONP。通过定义一个JSONP的回调内容,这可以被反射进响应内容。尽管这个方法有局限性,因为不支持特殊字符,但是对于某些RFD载体来说这是一个可利用的漏洞。

通常为了让特殊字符能够通过,会使用转义字符的方法,而不是encoding,但是这就给了RFD攻击的可能性,使得特殊字符能够被传递,而且JSON使用的括号在shell命令中也是支持的。通过特殊字符打破括号,从而完成命令的注入。

 

注入的命令以及命令分隔符

&分割命令,两个都执行

&&分割命令,只有第一个成功才执行第二个

|分割命令,只有第一个成功才继续

||分割命令,只有第一个失败才执行第二个

换行符[0x0a]类似于&

 

控制文件名

如果文件名属性缺失并且相应头中含有Content-Disposition,那么浏览器就会被强制要求根据URL确定下载文件的文件名。攻击者可以通过篡改URL中的路径部分,在域名和问题标记符号?之间的部分,设置一个恶意的扩展来下载。

不同的浏览器对于不同的content-type的处理是不同的,具体如下:

 

红色代表响应会被作为文件下载,红色的.js表示强制文件的扩展为JS。黄色sniff表示总是使用MIME-Sniffing,如果攻击者反射了不可打印的字符那么响应会被作为文件下载。黄色sniff*表示浏览器在除了明确声明了nosniff的情况外都使用MIME-Sniffing。

Content-Disposition header可以指导浏览器下载响应作为一个文件而不是被重定向。但是如果缺少filename参数属性的话就会要求浏览器根据URL为文件命名,这就给了RFD创造了条件。

对于Content-Dispostion 带有attachment但是没有filename并且结合content-type各个浏览器的表现如下:

 

缓解措施

使用精确的URL Mapping,确保攻击者无法插入额外的字符和参数。

不使用转义而是使用encoding。

为APIS设置死Content-Disposition的filename属性。

一些攻击通过借助JSONP的回调实现的,如果想避免这一点可能需要动态的回调,一个回调的白名单机制。

用户不应该直接访问API,应该所有的API调用都需要它携带一个HTTP header。

如果有可能的话使用CSRF token,这样一来攻击者就无法给受害者发送一条有效的RFD连接。

永远不要在API的错误里显示用户的输入。

如果不使用路径参数的话就取消对其的支持。

添加X-Content-Type-Options头。

攻击验证

 

构建一个如上的接口,访问http://localhost:8080/webroot/descision/?filename=sample&contents=Hello,%20World,结果显示Hello World。

访问http://localhost:8080/webroot/descision/;setup.bat?filename=sfef&e&contents=inject%20some%20commands%20here,结果只显示inject some command here,无文件下载。在setup前加上jsessionId=xxxx也是一样的结果,只有给Response手动添加ContentDisposition且filename缺省才有文件自动下载。如果不加这个header,即使设置了content-type为text/plain也是一样的结果,没有文件下载,且关闭了nosniff。

官方修复

spring中针对CVE-2015-5211是校验扩展名是否安全,如果不安全的话,直接设置ContentDisposition为attachment;filename=t.txt。并且对于jsonp 的回调加了校验,检验是否合法。还要一些其他的处理,比如给jsonp函数加了前缀,从URL中抽取filename的方法做了修改,主要是对于几个界定的字符做了修改。还有其他一些操作的判断条件做了修改。

https://github.com/spring-projects/spring-framework/commit/a95c3d820dbc4c3ae752f1b3ee22ee860b162402

针对CVE-2020-5421,Spring主要是取消了removeJsessionId的操作,其次在存储参数的键值对的时候如果有jsessionId就不做操作直接跳过。

https://github.com/spring-projects/spring-framework/commit/aec3a4c69e02d87f87258b0ab5c1d6c83f4cb44f

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷福。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值