强网杯学到的一个新姿势。比赛之后研究了下,感觉实际情况下还是比较难利用的,不过这种攻击思路值得学习。
什么是RPO攻击
RPO(Relative Path Overwrite)相对路径覆盖,是一种新型攻击技术,最早由Gareth Heyes在其发表的文章中提出。主要是利用浏览器的一些特性和部分服务端的配置差异导致的漏洞,通过一些技巧,我们可以通过相对路径来引入其他的资源文件,以至于达成我们想要的目的。
就目前来看此攻击方法依赖于浏览器和网络服务器的反应,基于服务器的Web缓存技术和配置差异,以及服务器和客户端浏览器的解析差异,利用前端代码中加载的css/js的相对路径来加载其他文件,最终浏览器将服务器返回的不是css/js的文件当做css/js来解析,从而导致XSS,信息泄露等漏洞产生。
其实猛的一看定义,刚开始我还以为和缓存攻击差不多,其实不一样。简单来理解RPO攻击的原理,我认为就是服务端和客户端(不同模块)对url(请求内容)处理不一致导致的。这也就是上面我说的攻击思路,其实这样的攻击思路在很多web攻击中都用到,比如说二次注入,宽字节注入。
漏洞浅析
差异
这里先用绿盟文章中的案例来了解一下几个关于服务器和客户端浏览器在解析和识别上的差异性基础知识。
第一个差异化
在apache和Nginx环境下,正常情况访问如下:
然后在Apache中将/编码为%2f后,服务器无法识别url,返回404,但是在Nginx中将/编码为%2f后,服务器可以识别编码后的url,返回200:
可见不同web服务器对url的识别是不一样的。
第二个差异化
在Nginx中,编码后的url服务器可以正常识别,也就是说服务器在加载文件时会解码后找到具体文件返回返回客户端。
但是在客户端识别url时是不会解码的,正常情况下解码%2f解码后应该加载的是rpo/xxx/../x.js,最后也就是rpo/x.js文件;而这里加载的是/x.js,所以浏览器是没有解码%2f的。
实际上通过测试,客户端浏览器在加载相对路径文件时是以最后一个/为相对目录加载具体资源文件的。
我们再来了解一下pathinfo
什么是pathinfo
利用pathinfo解析URL
|
<? $test = pathinfo("http://localhost/index.php"); print_r($test); ?> |
结果
|
Array ( [dirname] => http://localhost //url的路径 [basename] => index.php //完整文件名 [extension] => php //文件名后缀 [filename] => index //文件名 ) |
在pathinfo模式下
http://localhost/index.php?m=Index&a=test 等同于 http://localhost/index.php/Index/test
—-
http://www.xxx.com/index.php/模块/方法
该模式会产生的安全问题–>http://www.jb51.net/article/102156.htm
事实上就是读不到东西会退后直到能读到东西然后解析出来,也就是把读不到的路径当成模块啥的。就好比传了个参数一样,实际加载页面是前面的。
来看下这次强网杯题目来理解
Show your mind
http://39.107.33.96:20000/index.php/view/article/111
可以看到这样的url方式应该是使用了pathinfo模式相当于
http://39.107.33.96:20000/index.php?mod=view&article=763
首先可以看到/index.php/引入了js。
然后一个功能我们可以往生成页面写入任意字符,但是这个页面有限制不能直接执行js,这时候我们就要利用RPO攻击了
首先我们在写入alert(1)
比如写到了http://39.107.33.96:20000/index.php/view/article/111 页面
接着通过构造
http://39.107.33.96:20000/index.php/view/article/111/..%2f..%2f..%2f..%2findex.php 打开网页
jq.js加载了我们构造的js
对于上面的payload实际上,服务端解析为
http://39.107.33.96:20000/index.php/view/article/111/../../../../index.php
所以实际上渲染了index.php页面,而页面中jq是通过相对路径引用的 static/js/jquery.min.js
因为差异性,我们浏览器客户端去找js路径是无法解析%2f的
就把..%2f..%2f..%2f..%2findex.php这当成一个文件,
找jq文件路径就成了http://39.107.33.96:20000/index.php/view/article/111/static/js/jquery.min.js
读到static那,因为找不到就又不读了,所以就直接加载了http://39.107.33.96:20000/index.php/view/article/111/的内容
所以我们的jquery.min.js内容成了alert(1)
对于实际场景中的利用:个人感觉还是比较难利用的,也就是说首先网站有可控输出点,然后未声明<!DOCTYPE html>,(声明了就是标准模式(strict mod),未声明就是怪异模式,就是浏览器使用自己的方式解析网页代码。),使用相对引用方式,有的还得配合pathinfo。如果使用{}*{xss:expression(open(alert(1)))}/`也只能在IE6,7成功。当然还有加载Scriptlet方式,不过也有同域限制。
参考:
http://www.jb51.net/article/102156.htm
http://blog.nsfocus.net/rpo-attack/
近期评论