RPO(Relative Path Overwrite)是一种基于服务器的web缓存技术和配置差异,利用服务器与浏览器对URL解析的差异,将页面中使用相对路径引入的静态资源文件解析成其他资源文件/可控内容的页面,从而使用可控的方式(js)来处理服务器的响应内容,导致XSS、信息泄漏的产生的新型攻击技术。此外,服务器与浏览器对URL解析的差异也是开放重定向漏洞的一个成因。
攻击前提
- 服务器与浏览器对URL解析的差异
- 存在相对路径的js或者css的引用
利用场景
首先需要知道的一点是浏览器对%2f是不会解析的。然后就是服务端的解析情况。
- Apache在开启
AllowEncodedSlashes这个选项时,会对URL中的%2f进行解码。(默认不开启) - nginx默认会对URL中的%2f进行解码。
url会存在以下几种模式。
普通模式
http://localhost/index.php?m=Index&a=test
那么对于传入的url为/A/B/..%2f.index.php来说,服务器端会定位到/A/index.php,而浏览器获得的相对路径为/A/B/。因此,当在/A/index.php页面中存在相对资源的引用时,本应该引入的/A/xxx.js,却引入了/A/B/xxx.js。当/A/B/目录下的资源可控时,就能造成xss等漏洞。
这样的攻击方式利用条件比较严苛,需要对静态资源可控。
pathinfo模式
PHP的path_info模式,如下面所示:
1 | http://localhost/index.php/模块/方法 |
这样的方式,存在的安全问题就是后端服务器会将拼接的不存在的路径当作一个参数,实际上会返回错误路径前正确路径的内容。
url_rewrite模式
当服务器端进行了路由美化(使用了url_rewrite的php框架,python web框架),比如REST风格的API,http://ip:port/rpo/user/id/1。其中1为id参数的值,该请求的接口实际为/rpo/user/。那么当请求为/rpo/user/id/1/test,后端会识别出<id,1>这一对参数值,然后的识别为<test,’’>,因此会返回<id,1>的内容。但是浏览器客户端会认为id是目录,从而加载了/rpo/user/id/路径下的静态资源。
浏览器在解析CSS样式时,会忽略非法的部分,直到找到正确的开始然后进行解析一直到结束。可以输入payload为CSS的XSS向量。
1 | #header {background:url(javascript:alert(‘1’));} |
实战
- 参考2018年强网杯。
参考
- 浅谈RPO攻击
- 【技术分析】RPO攻击技术浅析