在这篇博文中,我将向您展示一种更好的方法来利用ASP.NET Web窗体应用程序中的非根相对路径覆盖问题。这是一个低风险漏洞,可用于将资源(如样式表)甚至动态JavaScript注入受影响的网页。
介绍
很长一段时间以来,我们很多人都知道路径信息以及.Net,php或java等几种Web应用技术的能力,这些技术可以通过使用斜杠(“/”)或半波段在文件扩展名后接受参数-colon(“;”)字符。这是创建自定义restful应用程序的有用功能。在Java的情况下,它通常可以在URL中的分号字符后接受会话令牌(当jsessionid不在cookie中时 - 不好的做法)。
在输出中包含其URL但未正确编码(假设它是安全的)或编码不正确的网页可能容易受到跨站点脚本问题的影响(例如http://www.exploit-db.com/exploits/31865/ )。但是,这不是本博文的主题,因为它与相对路径无关!
我们中的许多人都知道相对路径可能导致Web应用程序的功能问题,尤其是在使用URL重写规则或restful URL时。例如,我们可以通过在URL中添加或更改参数来不时地看到带有混乱图像和样式表的损坏页面。但是,在Gareth Heyes阐明并发表以下有用的博客文章之前,我不知道如何以任何方式利用这个问题:http://www.thespanner.co.uk/2014/03/21/rpo /
在那之后,我错误地认为这种攻击只会在IE的旧版本中有用,直到James Kettle在PortSwigger的博客中发布以下有用的帖子:https://portswigger.net/blog/detecting-and-exploiting-path-relative-stylesheet-import-prssi-vulnerabilities
如果您尚未阅读,强烈建议您阅读此博客文章。特别是“利用技巧”一节引起了我的注意!谁知道?它也可能抓住你的;-)
RPO和ASP.NET应用程序
非根相对路径的使用在ASP.NET Web窗体应用程序中很常见,我将在本博文中专注于此类应用程序。为了添加具有非根相对路径的样式表和JavaScript文件,可以将以下代码添加到ASP.NET页面(.aspx或其主页面):
<head runat="server">
<link href="~/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="<%=Page.ResolveClientUrl("~/js.js")%>"></script>
</head>
您可以在测试环境中使用以下易受攻击的“.aspx”页面(VB.NET):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!-- Author: Soroush Dalili (@irsdl) - https://Soroush.SecProject.com/blog/ -->
<head runat="server">
<link href="~/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="<%=Page.ResolveClientUrl("~/js.js")%>"></script>
</head>
<%
Dim input: input = Request("input")
if input <> "" then session("input") = input
%>
<body>
<form runat="server">
<div class="page" id="page">Just an example. Your input goes here: "<%=Server.HtmlEncode(session("input"))%>"</div>
<div class="DotNetVersion">.Net Framework version: "<%=Environment.Version%>"</div>
</form>
<script>
var pageColor = '';
var pageObj = document.getElementById('page');
var textColor;
if (pageObj.currentStyle){
textColor = pageObj.currentStyle.color;
}else if (window.getComputedStyle){
textColor = document.defaultView.getComputedStyle(pageObj, null).getPropertyValue("color");
}
if(textColor=="red" || textColor=="rgb(255, 0, 0)"){
pageColor = 'red';
}
</script>
</body>
</html>
此页面使用旧的doctype,可以在RPO攻击中简单地利用它。正如PortSwigger博客文章中所述,可以在以下网站找到可以以Quirks模式打开网站的文档类型列表:https://hsivonen.fi/doctype/#handling有时甚至可以强制使用网页使用IE在Quirks模式下打开的页面(请参阅PortSwigger的博客文章了解要求)。
此ASPX页面已保存在以下URL(.Net Framework 2)中:http://sdl.me/demo/RPO/test.aspx?input = test
由于此页面对“输入”参数进行HTML编码,因此无法利用跨站点脚本问题。有时在真正的ASP.NET应用程序中,保护可能是因为请求验证模块。
上面的ASP.NET页面在浏览器中显示以下HTML代码:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<!-- Author: Soroush Dalili (@irsdl) - https://Soroush.SecProject.com/blog/ -->
<head><link href="../../style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="../../js.js"></script>
<title>
</title></head>
<body>
<form name="ctl01" method="post" action="test.aspx?input=test" id="ctl01">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTQ3MDQ5NDcxMmRkL+8De/6ibnWrmbVRn1YZfKdyQoI=" />
</div>
<div>
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="EBB86DB2" />
</div>
<div class="page" id="page">Just an example. Your input goes here: "test"</div>
<div class="DotNetVersion">.Net Framework version: "2.0.50727.4253"</div>
</form>
<script>
var pageColor = '';
var pageObj = document.getElementById('page');
var textColor;
if (pageObj.currentStyle){
textColor = pageObj.currentStyle.color;
}else if (window.getComputedStyle){
textColor = document.defaultView.getComputedStyle(pageObj, null).getPropertyValue("color");
}
if(textColor=="red" || textColor=="rgb(255, 0, 0)"){
pageColor = 'red';
}
</script>
</body>
</html>
.NET将“〜”运算符解析为当前应用程序的根(在IIS中)。因此,当页面位于子目录中时,您可能会看到“../”模式。
注意:如果网页位于目录中但在非根相对路径中不包含“../”模式(不以协议或“/”字符开头),则目录名称显示应用程序IIS上安装的名称(实际上是该Web应用程序的根目录)。
.Net Framework 4解决了与.Net Framework 2略有不同的“〜”运算符,这就是出现混乱的时候!
在我们的示例页面中,当我们在“.aspx”扩展名后面有其他文件夹时,.Net Framework 4会向“style.css”路径添加更多“../”。换句话说,通过在.Net Framework 4中打开“/test.aspx/1111/2222/3333”页面,“style.css”路径有3个额外的“../”,如下所示:
不幸的是,我没有.Net Framework 4的Web服务器,但我们可以使用我们的本地IIS服务器来重现该问题。
.Net Framework 4的这种行为中和了正常的RPO攻击,因为页面无法再将自身加载为样式表。但是,.Net Framework 2中的易受攻击的页面可以使用Gareth Heyes或PortSwigger博客文章中描述的相同开发方法来利用:
http://sdl.me/demo/RPO/test.aspx/1111/2222/?input=%0C}}}}]]]]]*/ {} *{color:red;}
注意: “%0A”,“%0C”或“%0D”应该用于转义双引号或单引号字符。此外,如果有任何打开的“{”或“[”字符以及“/ *”,攻击将不起作用。因此,在CSS注入向量之前使用了“%0C}}}}]]]]] * /”字符串,以确保可以将其余字符串作为有效样式加载以使页面变为红色。“import”方法也可以用作CSS注入的另一个向量。
注意:如果使用.Net Framework 4,则此PoC代码将不起作用,如上所述。
ASP.NET页面的通用解决方案:
当“.aspx”扩展名后面的目录名为空时,.Net Framework 4不会在路径中添加额外的“../”!因此,可以在.Net Framework 2和4中同时使用以下简单的解决方案:
http://sdl.me/demo/RPO/test.aspx////////////?input=%0C}}}}]]]]]*/ {} *{color:red;}
使用另一个文件覆盖:
在诸如IIS之类的Web服务器中的RPO,其理解路径“%2F ..%2F”中的编码目录遍历模式,也可以被利用来指向同一网站上的其他文件(支持路径信息)。
下面显示了一个示例,其中“anotherpage.css.aspx”用于替换样式表:
</pre>
http://sdl.me/demo/RPO/anotherpage.css.aspx/%2f..%2f..%2f..%2fdemo/RPO/test.aspx
<pre>
在IIS中,“%2F”(URL编码版本的“/”)也可以替换为“%5C”(URL编码版本的“”)。
注意:此方法类似于我以前用于在JavaScript中利用location.pathname的方法(https://soroush.secproject.com/blog/2013/09/simple-security-tip-window-location-window-location -pathname灿事业开重定向消息发布/)。
注意:如果路径中的IIS上有应用程序,则此方法只能在此应用程序路径中使用(不是来自网站的根目录)。以下是一个示例:
</pre>
http://example.com/ApplicationName/page2.aspx/%2f..%2fpage1.aspx
<pre>
注意:使用其他动态页面可能有助于攻击者在特殊情况下注入其他资源,甚至是JavaScript文件。
.NET Framework 4表单的操作:
.NET Framework 4的这个功能在很长一段时间内都为人所知,但我永远无法以任何有用的方式利用它。然而,有些人可能会发现这个鼓舞人心的发现一些安全问题,请不要忘记更新我,因为我真的很感兴趣!
在URL的QueryString部分之前的最后一个正斜杠或反斜杠(“/”或“”)字符之后的任何内容都被用作没有URL编码的表单操作(双引号和单引号字符具有HTML编码)。例如,打开“example.aspx / 1.aspx / 2.aspx?test = test”将在页面中创建以下HTML表单:
我无法使用它来利用RPO,因为控制字符(例如“%0A”,“%0C”或“%0D”)将被默认的IIS设置和“<> *%&:?等字符阻止“并且双重转义被默认的ASP.NET设置(requestPathInvalidCharacters)阻止。在这种情况下,通过使用“import”来利用CSS注入更为可行,但正斜杠或反斜杠字符的使用存在限制(当您开始自己开发时会看到它)。
大多数ASP.NET页面也不使用.Net表单的“action”属性,否则我们可能会通过将其链接到开放重定向或反映的跨站点脚本问题来利用它(绕过浏览器的反XSS)保护)。
最后,我不应忘记感谢Dean McCarten(@ 2bitwannabe),他为我提供了Visual Studio 2013中的一个示例,该示例在样式表中使用了相对路径。这个.Net示例代码和最近的渗透测试项目鼓励我写这篇博文。