微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

RPO攻击方式的探究

什么是RPO?

RPO (Relative Path Overwrite)相对路径覆盖,作为一种相对新型的攻击方式,由 Gareth heyes在2014年首次提出,利用的是Nginx服务器、配置错误的Apache服务器和浏览器之间对URL解析出现的差异,并借助文件中包含的相对路径的css或者js造成跨目录读取css或者js,甚至可以将本身不是css或者js的页面当做css或者js解析,从而触发xss等进一步的攻击手段。
在什么情况下漏洞会触发

触发这个漏洞有两个基本的前提:

①Apache 配置错误导致AllowEncodedSlashes这个选项开启(对Apache来说认情况下 AllowEncodedSlashes 这个选项是关闭的),或者Nginx服务器。

②存在相对路径的js或者css的引用

对第一个前提的理解

我在RPO目录下新建了两个PHP文件apache.PHPNginx.PHP 访问成功就会分别输出Apache 和 Nginx ,还有一个空的test目录。

在这里插入图片描述


简单的测试如下:

所以没有找到。

但是Nginx不同,它能自动地把…%2f进行url解码,转化为…/ 这个符号对于服务器来说就是向前跳转一个目录,在它眼中我们请求的就是

http://localhost/RPO/test/../Nginx.PHP => http://localhost/RPO/Nginx.PHP

于是就访问到了我们RPO目录下的Nginx.PHP.
两个前提结合起来会发生什么?

①我们可以跨目录读取js

实验环境:

在这里插入图片描述


RPO 目录下创建了index.PHP f访问之后就会加载本目录下的a.js,注意这个a.js前面没有/(斜杠)代表是相对路径

文件内容如下:

    <head></head>

    <body>

        <script src=a.js></script>

    </body>

</html>

<?PHP

echo "js in test folder";

?>

与index.PHP同目录下的test文件夹中有a.js,一旦被调用就会弹出对话框

alert("Read file successfully");

我们访问 localhost/RPO/test/…%2findex.PHP

在这里插入图片描述

2018强网杯RPO攻击方式的探究

惊奇的发现本来只能读取和自己在同一目录下的a.js的index.PHP居然成功访问到了test目录下的a.js

(css也是一样的原理,不再赘述)

下面我们来分析一下上面的弹窗究竟是怎么实现的:

1.我们向服务器提交我们想请求的URL

http://localhost/RPO/test/..%2findex.PHP

2.(久经沙场,善于识破伪装的)服务器会把…%2f自动进行URL解码,所以实际上服务器端看到你请求的URL是下面的样子:

http://localhost/RPO/test/../index.PHP

3.我们知道…/ 在URL中会被理解成上一层目录,所以服务器实际上认为你访问的是下面的URL,并把index.PHP内容返回给(天真的)浏览器

http://localhost/RPO/index.PHP

4.接下来浏览器的工作就是根据URL的路径处理index.PHP中引用的使用相对地址的脚本,可是万万没想到,浏览器它并不认识…%2f(惊恐脸,说实话,估计它自己都不相信,在它天真的眼中一切都是没有伪装的,它看不破%2f的伪装),于是URL在它眼里依旧是那时(青涩的)模样:

http://localhost/RPO/test/..%2findex.PHP

5.此时无知的浏览器已经把…%2findex.PHP当成了一个文件,可它还是严格按照脚本的要求加载当前目录下的a.js文件,而对它来说现在的当前目录已变成了test,自然而然test目录下的a.js就被成功加载了。

可是利用价值在哪?

有的人可能会问了,如果要利用这个漏洞(比如说想实现xss),我们必须要让页面引入我们的攻击脚本,但是是个人都明白,真实环境中网站是人家写的,我们没法控制人家的js脚本在哪,更没法把我们想要的语句添加进人家的脚本里。

一点都没有错,于是RPO真正的利用点来了!!!!前方高能….

②我们可以将服务器返回的内容按照js脚本的方式解析

等等,你没有听错!!服务器给你什么你都能当做js,而且因为是外部引用js,按照规定我们的js代码甚至不需要标签,那岂不是美滋滋???(但是这里有一个限制,就是必须是使用的URL_WRITE的网站)

可能有些童鞋不知道什么是URL重写,为了不影响下面的分析,我简单的介绍一下。

介绍URL重写之前先介绍两个概念:

动态URL:

形如:http://www.xxx.com/news/index.asp?id=123

(伪)静态URL:

形如:http://www.123.com/news/123.html    (甚至可以是任何想要的形式)

URL重写在行业内又被形象地称为”URL路由”,就相当于是一个反向代理,你发送给服务器的URL并不会直接被解析,而是要先经过一个中转站,将静态URL重新组合成服务器熟悉的动态URL形式,再对其进行解析。那为什么要这么做呢?因为(伪)静态的URL更有利于网站的优化。

简单的演示:

现在我配置好了apache的URL_REWRITE

在这里插入图片描述

模拟攻击过程

index.PHP

<!DOCTYPE html>

<html>

    <head>RPO attack test</head>

    <body>

        <script src="3.js"></script>

    </body>

</html>

<?PHP

error_reporting(E_ALL^E_NOTICE^E_WARNING);

if($_GET['page'])

{

    $a=$_GET['page'];

    Header('Location:http://localhost/RPO/test/'."$a".'.html');

}

?>

3.html

alert(“RPO attack”);

可以看到我在index.PHP中引入了当前页面中的a.js,3.html 中写入了一个没有

现在我们访问下面的URL

在这里插入图片描述

可以看到我们成功将3.html的文件中的没有

我来给大家解释一下上面的过程:

1.你向服务器请求URL:

http://localhost/RPO/index.PHP/page/3/..%2f..%2f..%2findex.PHP

2.服务器看到的是:

http://localhost/RPO/index.PHP/page/3/../../../index.PHP

3.服务器返回index.PHP页面给浏览器

 http://localhost/RPO/index.PHP

4.浏览器加载index.PHP文件,并加载同目录下的3.js,但是浏览器看到的URL是:

http://localhost/RPO/index.PHP/page/3/..%2f..%2f..%2findex.PHP

5.浏览器认为…%2f…%2f…%2findex.PHP一个页面,自然而然加载的URL就是:

http://localhost/RPO/index.PHP/page/3/3.js

6.由于我们的请求是由

(我之前对这个东西也是糊里糊涂的,于是特地请教了出题人:由于 http://localhost/RPO/index.php/page/3/一个能够请求的页面所以其之后的3.js至少会交给/3处理,就像 http://localhost/RPO/index.php/page/3/内容会被index.PHP处理一样 然后/3返回给script标签。这就是为什么3页面会被当做js解析。)

本文转载自:https://www.freebuf.com/articles/web/166731.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐