使用Burp Suite测试ASP.NET无Cookie会话的渗透技巧

本文详细介绍了如何利用Burp Suite处理ASP.NET无Cookie会话的渗透测试挑战,包括双代理配置、匹配替换规则设置以及会话宏的使用,有效解决会话令牌导致的站点地图混乱问题。

使用Burp Suite测试ASP.NET无Cookie会话

Carrie Roberts & Brian King //
注意: 本博文中引用的技术和工具可能已过时,不适用于当前情况。然而,这篇博文仍可作为学习机会,并可能更新或集成到现代工具和技术中。

我们最近测试了一个使用ASP.NET无Cookie会话的Web应用程序。这意味着会话令牌是URL的一部分,如下例所示:
http://www.blackhillsinfosec.com/(S(hd73kdjf780sndyfn23elomzqd5ghwa))/login.html
在这种情况下,会话令牌的形式为(S(LongRandomToken)),其中LongRandomToken是一个长随机生成的字母数字字符串,取代了会话Cookie。

这种实现在使用Burp Suite测试时会导致站点地图混乱,因为变化的令牌使应用程序看起来有无限的内容路径。例如,一个只有一个登录页面的站点地图会因为变化的令牌值而显示为多个不同的路径,如下所示。

因多个令牌导致的混乱站点地图

在测试过程中,我们希望有一个“干净”的站点地图,基本上忽略所有令牌值,并将它们映射为好像不存在。此外,我们希望Burp Suite的爬虫和扫描工具继续工作。因此,我们想出了以下技巧,请继续阅读…

解决方案:

使用两个Burp实例。

  • 浏览器使用Burp1作为代理。
  • Burp1使用Burp2作为代理。
  • 在Burp1中创建一个匹配/替换规则,将有问题的令牌从请求URL中提取出来,并将其作为URL参数附加到URL的末尾。
  • 在Burp2中创建一个匹配/替换规则,从末尾抓取参数并将其放回。
  • 当您想查看漂亮的站点地图时,使用Burp1。
  • 当您想查看未经篡改的请求时,使用Burp2。
    Burp1监听默认端口8080,我们将Burp2配置为监听端口8090。

Burp2监听端口8090

然后,我们将Burp1配置为使用Burp2作为上游代理。

现在,Web应用程序连接到Burp1,Burp1连接到Burp2,Burp2连接到我们正在测试的ASP.NET服务器。

代理配置

以下是所需的匹配和替换规则。
Burp1匹配/替换规则:
匹配:(.*)/(S\(.*?\)\))/([^ ]*)(.*)
替换:$1/$3\?zzzz=$2$4

这将令牌从URL路径中拉出,并将其作为zzzz参数附加到URL的末尾。不用担心是否已经有URL参数,您只是添加了另一个问号,我们将在发送到Web服务器之前在Burp2代理中撤销此操作。

Burp2匹配/替换规则:
匹配:(\w* /)(.*)\?zzzz=([^ ]*)(.*)
替换:$1$3/$2$4

这有效并创建了一个干净的站点地图,但是…
这仅影响通过Burp代理的内容。如果您使用爬虫、扫描器或其他工具,这些规则不适用。对于第二个问题,我们将使用Burp的宏和会话工具。如果参数有名称,宏就足够了。但由于它显示为没有名称的裸值,我们需要再次使用上游Burp实例。

转到“选项”>“会话”,并向下滚动到“宏”部分以添加一个。您可以从代理历史记录中提取请求,或者现在发送这些请求并捕获它们。您需要一组创建新会话的必要请求——登录步骤。

对于每个需要的URL,配置项目,以便Burp发送正确的输入(例如用户名和密码)并注意响应中的正确内容。通常,您希望它更新Cookie jar,这就足够了。但在这里,没有会话Cookie,我们想要的东西甚至没有名称。

我们配置了第一个项目,以便发送一个没有令牌的请求,这导致服务器返回HTTP 302到一个确实有令牌的URL。我们配置Burp从HTTP 302响应中提取令牌。由于实际令牌没有名称,我们编造了一个新名称,该名称在任何地方都未使用。

接下来,我们手动将该参数添加到第二个请求的查询字符串中——只需在GET字符串的末尾键入“&aaaa=asdf”。然后,我们需要配置该第二个URL,以便将我们的“asdf”替换为在第一个请求的响应中找到的任何内容。

单击“测试宏”按钮以确保Burp正在提取正确的值并将其放在正确的位置。在第二个项目中查找“派生参数”。在我们的测试中,无法避免它被URL编码。这在这里没问题,因为我们无论如何都会在上游代理中更改它。如果我们只捕获内部括号之间的部分,会更干净。

在上游代理中,配置一个匹配和替换规则,以将URL重写为应用程序期望的形式。

该规则将类似以下内容:
GET /(S(3gmt4o45krcb0bfbzvh2ud55))/Pages/default.aspx?locId=1&aaaa=%28S%28awtsga551hn1bb550xmy2n2i%29%29 HTTP/1.1
转换为类似以下内容:
/(S(awtsga551hn1bb550xmy2n2i))/Pages/default.aspx?locId=1 HTTP/1.1

但这有一个问题——它是短暂的。在这个应用程序中没有任何实际称为“aaaa”的参数,更不用说在我们需要它的地方了。如果这是一个正常的命名参数,我们不需要编造临时参数名称,也不需要上游代理来重写URL。

这在使用时还会导致一些额外的流量,并且可能会稍微污染站点地图。但对于一次针对一个功能的有针对性扫描,它肯定比必须重新探索站点并在一个不间断的会话上运行扫描要好。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计