恶意 IIS 扩展悄悄地打开服务器的持久性后门
攻击者越来越多地利用 Internet Information Services (IIS) 扩展作为服务器的隐蔽后门,这些后门隐藏在目标环境中的深处,并为攻击者提供持久的持久性机制。虽然之前已经发表了关于特定事件和变体的研究,但对攻击者如何利用 IIS 平台作为后门知之甚少。
在针对服务器的攻击中,恶意 IIS 扩展不太常见,攻击者通常仅使用脚本 Web shell 作为第一阶段有效负载。与脚本 Web shell 相比,这导致恶意 IIS 扩展的检测率相对较低。IIS 后门也更难检测,因为它们大多与目标应用程序使用的合法模块位于同一目录中,并且它们遵循与干净模块相同的代码结构。在大多数情况下,实际的后门逻辑是最小的,如果不更广泛地了解合法的 IIS 扩展的工作原理,就不能将其视为恶意逻辑,这也使得确定感染源变得困难。
通常,攻击者首先利用托管应用程序中的关键漏洞进行初始访问,然后再将脚本 Web Shell 作为第一阶段有效负载。在稍后的时间点,攻击者会安装 IIS 后门程序,以提供对服务器的高度隐蔽和持久的访问。正如我们在 2022 年 1 月至 5 月期间针对 Exchange 服务器的活动以及我们之前对自定义 IIS 后门ScriptModule.dll和App_Web_logoimagehandler.ashx.b6031896.dll的研究中所观察到的那样,攻击者还可以安装自定义的 IIS 模块以满足其目的。向目标应用程序注册后,后门程序可以监视传入和传出请求并执行其他任务,例如在用户向 Web 应用程序进行身份验证时在后台运行远程命令或转储凭据。
由于我们预计攻击者将继续越来越多地利用 IIS 后门,因此事件响应者必须了解这些攻击如何运作的基础知识,以成功识别和防御它们。组织可以使用 Microsoft 365 Defender 进一步提高其防御能力,其保护功能来自此类研究以及我们对服务器攻击和入侵的独特可见性。Microsoft 365 Defender 具有威胁和漏洞管理以及防病毒功能等关键保护功能,为组织提供了一个全面的解决方案,可跨域协调保护,包括电子邮件、标识、云和终结点。
在这篇博客文章中,我们将详细介绍 IIS 扩展的工作原理,并深入了解攻击者如何利用它们作为后门。我们还分享了我们在过去一年中对 IIS 威胁形势的一些观察,以帮助防御者识别和防范这种威胁,并为更大的安全社区做好准备,以应对任何日益复杂的情况。更具体地说,该博客涵盖以下主题:
了解 IIS 扩展
IIS 是一个灵活的通用 Web 服务器,多年来一直是 Windows 平台的核心部分。作为一个易于管理、模块化和可扩展的平台,用于托管网站、服务和应用程序,IIS 为众多组织提供关键业务逻辑。IIS 的模块化架构允许用户根据自己的需要扩展和自定义 Web 服务器。这些扩展可以采用本机 (C/C++) 和托管 (C#、VB.NET) 代码结构的形式,后者是我们这篇博文的重点。扩展可以进一步归类为模块和处理程序。
IIS 管道是由 ASP.NET 运行时启动的一系列可扩展对象,用于处理请求。IIS 模块和处理程序是 .NET 组件,用作管道中扩展性的主要点。每个请求都由多个 IIS 模块处理,然后由单个 IIS 处理程序处理。与一组构建基块一样,添加模块和处理程序是为了为目标应用程序提供所需的功能。此外,可以将处理程序配置为响应请求中的特定属性,例如 URL、文件扩展名和 HTTP 方法。例如,Aspnet_isapi.dll 是用于常见.aspx扩展的预配置 IIS 处理程序。
创建自定义托管 IIS 模块
若要创建托管 IIS 模块,代码必须实现 IHttpModule 接口。IHttpModule 接口有两个具有以下签名的方法:Init() 和 Dispose()。
图 1.IIS 模块框架
在 Init() 中,该模块可以与请求管道中可用的任意数量的 HTTP 事件同步,此处按顺序列出:
BeginRequest
AuthenticateRequest
授权请求
ResolveRequestCache
AcquireRequestState
PreRequestHandler执行
PostRequestHandler执行
ReleaseRequestState
UpdateRequestCache
EndRequest
PreSendRequestHeaders
PreSendRequestContent
然后,新创建的扩展应该与目标应用程序映射,以完成注册。通常,有几种方法可用于映射托管模块以达到合法目的。另一方面,我们观察到攻击者在攻击过程中使用以下技术注册恶意IIS扩展:
向全局程序集缓存(GAC)注册PowerShell API:每个具有公共语言缓存(Common Language Cache,简称GAC)的设备都托管一个称为全局程序集缓存(GAC)的设备级缓存。GAC存储专门指定为由设备上的多个应用程序共享的程序集。GacInstall()是一个PowerShell API,用于将模块添加到全局缓存中。安装后,该模块在路径%windir%\Microsoft.NET\assembly下可用,并使用append.exe映射到IIS(w3wp.exe)。
图2.使用GAC PowerShell API的攻击程序命令
使用appcmd.exe注册:Appcmd. exe是用于管理IIS的单一命令行工具。所有关键方面,如添加或删除模块和处理程序,都可以使用该实用程序执行。在这种情况下,攻击者将恶意扩展放在目标应用程序的/bin文件夹中,并使用add module命令对其进行映射。
图3.攻击者命令使用app.exe
使用gacutil.exe注册:Gacutil.exe是VisualStudio附带的. NETGAC实用程序。该工具允许用户查看和操作GAC的内容,包括使用-I选项安装新模块。
图4.使用gacutil.exe的攻击程序命令
使用web.config注册:将模块放入应用程序的/bin文件夹后,攻击者还可以编辑目标应用程序的web.config或全局配置文件applicationHost.config,以注册模块。
图5.恶意 web.config 条目
成功注册后,该模块在 IIS 管理器应用程序中可见。
图6.列表中可见的已安装模块
使用自定义 IIS 后门的攻击流
在 2022 年 1 月至 5 月期间,我们的 IIS 相关检测发现了针对 Microsoft Exchange 服务器的有趣活动。通过 ProxyShell 漏洞,在路径 %ExchangeInstallPath%\FrontEnd\HttpProxy\owa\auth\ 中删除了 Web shell。
经过一段时间的侦查、转储凭据和建立远程访问方法后,攻击者在文件夹 C:\inetpub\wwwroot\bin\ 中安装了一个名为 FinanceSvcModel.dll 的自定义 IIS 后门。后门具有执行 Exchange 管理操作的内置功能,例如枚举已安装的邮箱帐户和导出邮箱以进行外泄,如下所述。
命令运行
PowerShDLL 工具包是一个开源项目,用于在不调用powershell.exe的情况下运行 PowerShell,用于运行远程命令。攻击者避免在 Exchange 应用程序池 (MSExchangeOWAAppPool) 的上下文中调用常见的 LIVING off-the-land 二进制文件 (LOLBins),例如 cmd.exe 或 powershell.exe,以逃避相关的检测逻辑。
图7.使用 PowerShDLL 运行远程命令
凭据访问
攻击者启用了 WDigest 注册表设置,迫使系统使用 WDigest 协议进行身份验证,从而导致lsass.exe在内存中保留用户明文密码的副本。此更改允许攻击者窃取实际密码,而不仅仅是哈希值。后来,运行 Mimikatz 来转储本地凭据并执行 DCSYNC 攻击。
图8.Mimikatz 用法
远程访问
攻击者使用了 plink.exe,一种类似于 SSH 的命令行连接工具。该工具允许攻击者绕过网络限制,通过隧道 RDP 流量远程访问服务器。
图 9.绕过网络限制
外泄
攻击者通过发送带有 cookie EX_TOKEN的构建的 POST 请求来调用 IIS 后门。该模块提取 cookie 值,并使用提供的筛选器启动邮箱导出请求。
图 10.攻击者生成的 POST 请求
该值解码为:ep,06/21/2022,06/21/2022,C:\Windows\Web,Administrator,其中 ep 是启动邮箱导出请求的命令,筛选器确定开始和结束日期,后跟导出路径。最后一个命令具有以下语法:
图 11.攻击者生成的邮箱导出请求
图 12.邮箱导出代码段
下表详细介绍了在后门程序中找到的所有命令:
IIS 后门的类型
回顾过去一年中观察到的恶意托管 (.NET) IIS 扩展,我们根据各种因素(例如相似的功能和源)对这些扩展进行了分组,如下面各节所述。
基于 Web shell 的变体
像 China Chopper 这样的 Web shell 已被广泛用于许多针对性攻击。多年来,随着中国斩波器的使用量增加,检测量也在增加。因此,攻击者发展并添加了这些 Web Shell 的基于 IIS 模块的版本,这些 Web Shell 保持相同的功能。该模块使用与脚本版本中用于运行代码的相同 eval() 技术。虽然大多数防病毒解决方案都会检测单行 Web Shell,例如 < %@page language=js%><%eval(request.item(<password>),“unsafe”);%>,但在 IIS 模块中嵌入相同的代码会生成较低的检测率。
在模块版本中,攻击者发起的 POST 请求包含代码以及参数 z1 和 z2 中的参数,就像基于脚本的版本一样。
图 13.中国斩波器IIS模块 - 版本1
图 14.攻击者生成的 POST 数据 – 版本 1
在另一个版本中,该模块在 DLL 中硬编码了后门逻辑,并且仅等待参数 z1 和 z2。参数 kfaero 的命令公开为“A-Q”的顺序字母。
图 15.中国斩波器IIS模块–版本2
与脚本版本一样,IIS 模块具有类似的功能,例如列出和创建目录、下载和上传文件、使用 SQL 适配器运行查询以及运行命令。若要运行命令,攻击者发起的 POST 请求包含命令“M”以及参数。
图 16.攻击者生成的 POST 数据示例 – 版本 2
蚂蚁剑是另一种流行的网络外壳,广泛用于各种针对性攻击。在野外观察到受 Web Shell 代码启发的自定义 IIS 模块,其中包括类似的体系结构和功能。这些恶意模块有趣的新功能包括无文件执行 C# 代码和通过 TCP 套接字连接进行远程访问。
图 17.Antsword IIS 模块代码片段
根据请求,模块可以采用两种代码路径之一。如果是 /server-status,则从自定义标头 Lhposzrp 中的值启动套接字连接。
对于任何其他 URL,该模块遵循 China Chopper 风格的命令架构,范围从“A”到“R”。附加的“R”命令允许攻击者以反射方式运行 C# 代码。
图 18.命令“R”以反射方式调用代码
开源变体
关于为 IIS 创建后门的 GitHub 项目已经有一段时间了。虽然主要是为了教育红队社区而共享的,但威胁行为者也对这些项目产生了兴趣并取消了代码。以攻击者主动利用的公共项目为例,原始代码包括以下功能:
In this case, the in-the-wild variants change the cookie names, keeping the rest of the code intact:
图19.来自开源项目的代码(左)和攻击者使用的代码(右)的横向比较
在向后门提供 whoami 命令时,生成的 cookie 具有以下格式:
Cookie:BDUSS=P6zUsk/1xJyW4PPufWsx5w==
后门使用包装在 base64 中的 AES 加密 blob 进行响应。解码后的输出采用以下格式:
图 20.来自服务器的解码响应
IIS 处理程序
如前所述,IIS 处理程序具有与请求管道中的模块相同的可见性。可以将处理程序配置为响应某些扩展或请求。若要创建托管 IIS 处理程序,代码必须实现 IHttpHandler 接口。IHttpHandler 接口具有一个方法和一个具有以下签名的属性:
图 21.IIS 处理程序框架
可以通过直接编辑 web.config 文件或使用 appcmd 实用工具来注册处理程序。处理程序配置采用一些重要字段,例如 path(指定处理程序应响应的 URL 或扩展名)和 verb(指定 HTTP 请求类型)。在下面的示例中,处理程序仅响应以 .gif 扩展名结尾的图像请求:
图 22.恶意 web.config 条目
成功安装后,该处理程序在 IIS 管理器应用程序中可见:
图 23.列表中可见的已安装处理程序
分析的大多数处理程序都相对简单,仅包括运行命令的功能:
图 24.IIS 处理程序通过 cmd.exe 运行命令
有趣的是,响应 Content-Type 设置为 image/gif 或 image/jpeg,这在浏览图像 URL 时显示默认图像,输出隐藏在 <pre> 标记中。造成这种情况的一个可能原因可能是绕过网络检查,因为图像文件通常被认为是非恶意的,并且会根据扩展名进行过滤和识别。
凭据窃取程序
此模块子集监视传出请求中的登录模式,并以加密格式转储提取的凭据。被盗的凭据允许攻击者在环境中保持持久性,即使检测到主后门也是如此。
这些模块监视特定请求以确定登录活动,例如 OWA 应用程序的 /auth.owa 默认 URL。在检查请求时,模块会将凭据转储到 .dat 文件中。内容使用硬编码值的 XOR 进行加密,并使用 base64 编码包装。下图描绘了解码后的示例输出:
图 25.解密条目示例
图 26.查找 OWA 登录 URL 的后门程序
在另一个变体中,该模块查找用于传递不同 ASP.Net 应用程序中使用的凭据的常见占位符变量。转储的凭据经过 AES 加密,并使用 Base64 编码包装,位于 %programdata%\log.txt 中。
图 27.后门查找常见凭据占位符变量
图 28.解密条目示例
改进对服务器入侵的防御
由于我们预计会观察到更多使用 IIS 后门的攻击,因此组织必须确保遵循安全实践来帮助保护其服务器。
应用最新的安全更新
识别并修复影响服务器的漏洞或错误配置。部署最新的安全更新,尤其是针对 Exchange 等服务器组件,一旦它们可用。使用 Microsoft Defender 漏洞管理定期审核这些服务器是否存在漏洞、错误配置和可疑活动。
保持防病毒和其他保护处于启用状态
使用 Windows 防病毒软件和其他安全解决方案(如防火墙保护和 MFA)保护服务器至关重要。在 Microsoft Defender 防病毒中启用云提供的保护和自动示例提交,以使用人工智能和机器学习快速识别和阻止新的和未知的威胁。使用攻击面减少规则自动阻止凭据盗窃和 PsExec 和 Windows Management Instrumentation (WMI) 的可疑使用等行为。开启防篡改功能,防止攻击者停止安全服务。
如果您担心这些安全控制会影响性能或中断操作,请与 IT 专业人员联系,以帮助确定这些设置的真正影响。安全团队和 IT 专业人员应协作应用缓解措施和适当的设置。
查看敏感角色和组
查看高特权组,例如管理员、远程桌面用户和企业管理员。攻击者将帐户添加到这些组中以在服务器上站稳脚跟。定期检查这些组是否有可疑的添加或删除。若要识别特定于 Exchange 的异常情况,请使用 Exchange PowerShell 中的 Get-ManagementRoleAssignment cmdlet 查看敏感角色(如邮箱导入导出和组织管理)中的用户列表。
限制访问
践行最小特权原则,保持良好的凭证卫生。避免使用域范围的管理员级服务帐户。强制实施强随机、实时本地管理员密码并启用 MFA。使用 Microsoft Defender for Identity 的本地管理员密码解决方案 (LAPS) 等工具。
Place access control list restrictions on virtual directories in IIS. Also, remove the presence of on-premises Exchange servers when only used for recipient management in Exchange Hybrid environments.
Prioritize alerts
服务器入侵的独特模式有助于检测恶意行为,并通知安全运营团队快速响应入侵的初始阶段。注意并立即调查指示服务器上可疑活动的警报。在探索阶段(攻击者在获得访问权限后花费数天时间探索环境)捕获攻击是关键。确定与net.exe cmd.exe等进程相关的警报的优先级,这些警报通常来自w3wp.exe。
检查配置文件和 bin 文件夹
定期检查目标应用程序的 web.config 和 ApplicationHost.config,以识别任何可疑的添加项,例如图像文件的处理程序 - 如果不是完全恶意的,它本身就是可疑的。此外,定期扫描已安装的路径,例如应用程序的 bin 目录和默认 GAC 位置。还建议使用 appcmd.exe 或 gacutil.exe 实用程序定期检查已安装模块的列表。
Hardik Suri
Microsoft 365 Defender研究团队
附录
Microsoft Defender 防病毒将这些威胁和相关行为检测为以下恶意软件:
后门:MSIL/SuspIISModule.G!gen
后门:MSIL/SuspIISModule.H!gen
后门:MSIL/SuspIISModule.K!gen
后门:MSIL/OWAStealer.B
后门:MSIL/OWAStealer.C
行为:Win32/SuspGacInstall.B
终结点检测和响应 (EDR)
可疑的 IIS AppCmd 用法
搜寻查询
若要查找与可疑 IIS 模块注册相关的恶意活动,请运行以下查询:
可疑的 IIS 模块注册
DeviceProcessEvents
| where ProcessCommandLine has “appcmd.exe add module”
| where InitiatingProcessParentFileName == “w3wp.exe”
DeviceProcessEvents
| where InitiatingProcessFileName == “powershell.exe”
|where ProcessCommandLine has ” system.enterpriseservices.internal.publish”
| where InitiatingProcessParentFileName == “w3wp.exe”
DeviceProcessEvents
|where ProcessCommandLine has ” \\gacutil.exe /I”
| where InitiatingProcessParentFileName == “w3wp.exe”