Relative Path Overwrite(相对路径覆盖)是一种通过覆盖目标文件来利用相对URL的技术,简称RPO技术。 随着RPO(相对路径覆盖)技术在强网杯的web题中被提出,国内相继出现了不少相关的writeup。作为14年就被发现的技术,它的攻击技巧早已被拓展开,本期“安仔课堂”,ISEC实验室的老师对这项技术之前的研究成果进行了归纳,10分钟的时间,让我们跟随老师一起初探RPO攻击。 ![]() 绝对路径与相对路径的区别 一、绝对路径 ![]() 图1 二、相对路径 ![]() 图2 我们可以发现:绝对路径的URL目标地址完整,包含了协议和域名,而相对路径的URL并不指定协议或域名,而是使用现有的目的地来确定协议和域名。 如何理解相对路径 使用当前路径并查找其中的目录,如“mytest”,或使用目录遍历技术,如“../mytest”。 工作方式以下方的样式表为例: ![]() 图3 上方样式表的链接元素使用相对URL,引用“test.css”,样式表的加载取决于所在站点目录结构的位置。 例如:如果在一个名为“mytest”的目录中,那么样式表将从“mytest /Test.css”加载。使用相对URL,浏览器不知道什么是正确的路径,因此,浏览器无法访问服务器的文件系统。 RPO原理解析 一、漏洞触发条件: ①配置错误的Apache服务器或者Ngnix服务器,URL重写 ②相对路径JS、CSS样式表的调用 ③存储允许CSS注入的XSS ④可控页面 注:为方便演示,以Ngnix服务器为例 二、关于触发条件: 对于用户看到的完全相似的URL,服务器的处理方式也有所不同。 以下方样式表为例: ![]() 图4 对于默认的Apache服务器来说: “%2f”在这里并不会被解析,因为服务器不认识这个符号,因此它会认为 “..%2f1.php”是一个文件。 对于默认的Ngnix服务器来说: Ngnix会把“%2f”进行解码,转化为“../”,从而使URL如下图所示: ![]() 图5 而我们知道“../”表示的是向前跳转一个目录,因此我们最终得到的URL是: ![]() 图6 我们简单梳理一下流程: 目标URL: ![]() 图7 网页代码: ![]() 图8 浏览器将提交的URL编码解码后发给服务器使用“%2f”代替“/”,把URL写为: ![]() 图9 结果: 服务器: ![]() 图10 浏览器: ![]() 图11 页面中导入的样式表为: ![]() 图12 浏览器认为“test.css”的根目录是: “/RPO/mytest/” 而不是: “/RPO/mytest/test/” 所以“../../test.css”跳到了更高一级的目录下。 伪造一个目录“ISEC”,尝试导入一个不存在的“RPO/Isec/test.css”。 伪造: ![]() 图13 结果: 服务器: ![]() 图14 浏览器: ![]() 图15 页面中导入的样式表为: ![]() 图16 浏览器的认知中,“ISEC”和“%2fbasic”是两个不同的目录,从而导入主域下任意样式表。 三、解读触发条件: 前提: 在利用CSS选择器之前,我们需要知道它是怎么进行解析的。在CSS2规范中,明确了在某些情况下,user agents必须忽略非法样式表的一部分,这个规范定义为忽略。这意味着user agents解析非法部分时,除非明确匹配到了开始和结束,否则将予以忽略,简单的说就是解析其中格式正确完整的部分,忽略非法语法。 结论: 浏览器在解析CSS样式时,会忽略非法的部分,直到找到正确的开始才会进行解析,一直到结束停止。所以我们植入CSS代码,欺骗CSS解析器忽略之前不合法的语法内容,从而加载我们注入的CSS内容,最终页面变成渲染后的红色,如下图所示: ![]() 图17 再加入XSS的内容,我们定义了一个全局的选择器: ![]() 图18 RPO攻击还原 实例: 在infinite security上我们找到这样一个简单的实例: 在下面的页面中,它存储了XSS,满足了条件,因此,在CSS中的表达式功能将执行JavaScript。 ![]() 图19 现在通过分析源代码链接与href风格“.css”,让我们看看开发者工具或浏览器中的网络部分,我们可以通过从“url”结尾添加和去除“/”来看到RPO的行为。 通过删除“style.css”,我们得到“404”状态码响应。 ![]() 图20 通过添加“style.css”,我们获得“200OK”状态码响应。 ![]() 图21 由于Internet Explorer支持表达式,因此,为了运行这个代码,我们将在旧版本的IE中执行这个页面。当此页面加载到IE中时,IE中的CSS解析器将执行CSS部分,跳过HTML部分,执行XSS负载,最终执行XSS的payload。 ![]() 图22 RPO(相对路径覆盖)技术作为14年的攻击方式,如今依然被广泛运用,近期举办的强网杯上也出现了类似题目, 网上有很多的思路,大家可搜索下方链接以作参考。 ![]() 图23 RPO攻击扩展 最初的RPO攻击有一些(隐含的)限制: ①易受攻击的HTML和HTML加载的样式表必须是同一个文件。 ②攻击者无法操作已加载样式表URL的查询字符串参数。 因此,我们来探讨几个特殊环境下避免这些限制的技术(如上实例),主要是利用Web服务器或浏览器解释URL的差异来欺骗浏览器或服务器。 (注:不同环境版本结果有出入) 例如:点“.”、斜杠“/”、反斜杠“\”、问号“?”和分号“;”等字符及其编码的等价物在URL中具有特殊意义,服务器和浏览器可以通过交互让这些具有不同含义,这些不同的解释给了攻击者扩展RPO攻击的可能性。 一、在IIS/ASP.NET上加载另一个文件 前提条件:通过使用包含“/”的URL来遍历路径,可以欺骗浏览器将另一个文件作为样式表加载到IIS/ASP.NET上。 由Soroush Dalili发现,Poc: ![]() 图24 URL返回“/demo/rpo/test.aspx”的内容,因为“%2f”和“/”,在IIS/ASP.NET上被同等对待。 ![]() 图25 同时, 因为浏览器不将“%2f”视为路径分隔符,HTML中的链接元素(如上文所示)将从 “/demo/rpo/andivipage.css.aspx/style.css”加载样式表。样式表URL的“PATH_INFO”部分,即“/style.css”的部分在服务器端被忽略了。 这意味着上述两种限制中的第一种,即关于文件路径的限制,已经成功的被规避。 注意:这种技术对攻击者来说非常方便,因为攻击者可控内容的URL有时与包含路径相对样式表的网页不同。 二、在Safari/Firefox上加载另一个文件 Safari在路径解释方面的独特之处在于它不对URL中的编码点(和其他字符)进行解码,攻击者可以将其用于另一种文件加载攻击。 假设Safari用户访问下面的URL: ![]() 图26 Safari按照原样把URL路径发送到服务器(PHP/Apache),服务器将解析路径中的“.%2E”,并返回“/member/top.php”的内容。 假设响应包含以下脚本元素: ![]() 图27 由于Safari不对URL中的编码点进行解码,加载的JS路径将是 “/member/profile_photo.php/js/jquery.js”,这意味着服务器加载了一个不同于主HTML的文件。在本例中,Profile_Photo.php返回的图像将在浏览器上作为JavaScript执行。 至于Firefox,它的独特之处在于如何处理跟踪编码的双点。 假设Firefox用户访问下面的URL: ![]() 图28 Firefox将路径发送到服务器,但是不解析最后编码的点,服务器对它进行解析,然后返回“/members/”的内容。 假设内容下面包含一个脚本元素: ![]() 图29 当Firefox在确定JS路径留下未解决的尾随点时,加载的JS路径将是 “/member/profile_photo.php/js/jquery.js”,这将返回Profile_Photo.php的内容。 注意:在这两种攻击中,攻击者都无法像在ASP.NET上一样自由地控制加载的资源路径。,具体而言,前一种攻击要求加载资源路径以“../”开头,而后一种攻击要求HTML路径以“/”结尾。 三、在WebLogic/IE上加载另一个文件 与IIS/ASP.NET一样,WebLogic对待“%2f”和“/”是平等的,但是上述对ASP.NET的攻击并不仅仅适用于WebLogic,原因如下: ①WebLogic需要分号来添加字符串到URL的末尾; ②像“..%2F”这样的字符串是在“分号不会导致服务器遍历”之后才出现(WebLogic在第一个分号出现后完全忽略了一个字符串)。 因此,我们使用另一种方法便能成功攻击,如下图所示: ![]() 图30 这个URL将返回“/aa/Test1Servlet”的内容,因为如上所述,WebLogic只是在第一个分号之后忽略一个字符串。 假设内容包含下面的链接元素: ![]() 图31 当浏览器确定样式表URL时,原始URL中的“.%2E/”被解码为“../”,这样发送给服务器的样式表路径将是“/aaa/test2Servlet;/style.css”,而它作用于“/aaa/test2servlet”的内容。 这意味着与第一个HTML不同的HTML文件被成功加载为样式表。 攻击要求 ①“.%2E”在初始HTTP请求中按原样发送; ②它们在下一个样式表加载请求中对这些事件进行解码。 注意:这两种情况只有在IE上才能满足, 攻击URL在位置标头中提供。 ![]() 图32 换句话说,如果攻击URL是在 四、在WebLogic+Apache上加载带有查询字符串的文件 在基于Java的大型企业系统中,我们经常可以看到将Apache置于WebLogic前面的系统架构。对于这个构成,Oracle提供了一个Apache模块(mod_wl.so),它就像他们之间的反向代理。 有趣的是,在将URL路径传递给后端WebLogic之前,该模块以一种非常独特的方式规范URL路径。具体来说,它将URL路径中的“%3F”解码为“?”,这显然会混淆URL解析器,给攻击者提供机会。 ![]() 图33 假设内容包含下面的链接元素: ![]() 图34 在本例中,最终样式表从浏览器发送到Apache的路径是“/aaa/test1servlet?param={}*{color:red}/style.css”,这是因为浏览器将“%3F”视为URL路径的一部分。因此,在确定最终样式表的路径时,浏览器不会删除该部分。 如前所述,样式表中的URL由模块解码,然后发送到后端WebLogic,以便在WebLogic中将之后的部分视为查询字符串,这意味着本节开头显示的第二个限制,即查询字符串,成功地被绕过。 |
| 本文出处: https://www.toutiao.com/i6573446036700791299/ |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|