深入解析WinSxS:HelloJackHunter与DLL劫持技术揭秘

本文深入探讨Windows并行组件存储(WinSxS)机制与DLL劫持技术,详细介绍HelloJackHunter工具的实现原理,涵盖WinSxS目录结构分析、DLL搜索顺序劫持方法,以及自动化检测工具的开发与应用场景。

Side-by-Side与HelloJackHunter:揭开WinSxS的神秘面纱

这篇关于Windows并行加载的文章深入探讨了我于2023年底在圣诞节和新年之间的空闲时间进行的研究。众所周知,动态链接库侧加载/DLL劫持并不是新技术,Windows并行组件存储也不是。然而,从对抗性技术角度来看,侧加载对于建立初始访问、持久化、权限提升或在环境中执行都非常有用。

我在阅读了John Carroll关于ExpLoading的精彩文章后开始了这项研究,这是一种从当前目录劫持搜索顺序的技术。当时,我也在研究WinSxS,因为有人在博客文章中提到了它,但该博客缺乏任何概念验证代码,这让我开始了自己的探索之旅。因此,很多工具和这篇博客文章应运而生。

侧加载/劫持基础

动态链接库搜索顺序劫持,通常简称为DLL劫持,通过外部DLL利用应用程序的执行流程。通过劫持用于加载合法内容的搜索顺序,可以强制应用程序加载恶意DLL。

当易受攻击的应用程序设置为以提升的权限运行时,加载到其中的任何恶意DLL都会继承这些提升的权限,从而实现权限提升。应用程序的行为通常不会受到干扰,因为恶意DLL被设计为无缝加载它们替换的合法DLL,或者在DLL路径未明确定义的情况下。

什么是WinSxS?

WinSxS代表"Windows并行组件存储",是位于C:\Windows\WinSxS的目录,Windows在其中存储安装操作系统所需的文件以及这些文件的备份或不同版本。在Windows环境中有许多子文件夹和几乎所有二进制文件的副本,这使其成为利用的成熟目标。

WinSxS在处理更新方面起着关键作用。当您安装更新时,系统文件的新版本会添加到该文件夹中。这确保应用程序的最新版本可用,有助于整体系统安全性和性能。

将两者结合

既然我们对WinSxS和DLL劫持有了更多了解,那么将两者结合起来形成自动化识别和狩猎工作流程如何?典型的工作流程如下:

  • 在WinSxS中查找二进制文件
  • 映射从$currentdir调用的DLL
  • 运行HelloJackHunter并在for循环中指向DLL

映射可用二进制文件

有许多方法可以查找二进制文件。只需在资源管理器中搜索*.exe就会给出GUI列表,或者使用类似everything.exe的工具可以让您复制和导出路径,或者简单地使用PowerShell:

1
GCI -Path C:\Windows\WinSxS -Recurse -Filter *.exe | Select -First 20 | Select Name, FullName, @{l='FileVersion';e={[System.Version]($_.VersionInfo.FileVersion)}} | Group Name | ForEach-Object { $_.Group | Sort-Object -Property FileVersion -Descending | Select-Object -First 1 }

我们可以稍微修改上面的代码,仅将路径存储到对象中:

1
2
3
4
5
6
$LatestBinaries = GCI -Path C:\Windows\WinSxS -Recurse -Filter *.exe | 
    Select -First 20 | 
    Select Name, FullName, @{l='FileVersion';e={[System.Version]($_.VersionInfo.FileVersion)}} | 
    Group Name | 
    ForEach-Object { $_.Group | Sort-Object -Property FileVersion -Descending | Select-Object -First 1 } |
    Select-Object -ExpandProperty FullName

HelloJackHunter - 自动化识别

自动化总是好的,可以让狩猎生活更轻松:今天我编写并发布了一个工具:HelloJackHunter,这是对HijackHunter的文字游戏。该工具扫描可用的DLL并利用dumpbin.exe提取导出的函数,将每个函数与示例消息框关联起来。这种映射有助于枚举可以利用的函数。此外,它支持各种函数钩子和执行方法。

作为高级概念验证,可以使用以下代码证明DLL劫持:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <windows.h>
#include <iostream>

BOOL APIENTRY DllMain(HMODULE hModule,
                      DWORD  ul_reason_for_call,
                      LPVOID lpReserved)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        std::cout << "DLL loaded by a process.\n";
        break;
    case DLL_THREAD_ATTACH:
        std::cout << "A thread is created in the current process.\n";
        break;
    case DLL_THREAD_DETACH:
        std::cout << "A thread is exiting cleanly.\n";
        break;
    case DLL_PROCESS_DETACH:
        std::cout << "DLL unloaded from a process.\n";
        break;
    }
    return TRUE;
}

已知易受攻击的二进制文件

从我对WinSxS的研究中,我发现了四个持续易受攻击的二进制文件和其他几个,但最容易演示的如下表所示:

二进制名称 路径 DLL名称/路径
ngentask.exe C:\Windows\WinSxS\amd64_netfx4-ngentask_exe_b03f5f7f11d50a3a_4.0.15912.0_none_d5e7146d665097c0\ngentask.exe mscorsvc.dll
explorer.exe C:\Windows\WinSxS\amd64_microsoft-windows-explorer_31bf3856ad364e35_10.0.22621.3235_none_31b295f9f540d278\explorer.exe cscapi.dll
aspnet_wp.exe C:\Windows\WinSxS\amd64_netfx4-aspnet_wp_exe_b03f5f7f11d50a3a_4.0.15912.0_none_107a08446d17dcf2\aspnet_wp.exe webengine.dll, webengine4.dll
aspnet_regiis.exe c:\Windows\WinSxS\amd64_netfx4-aspnet_regiis_exe_b03f5f7f11d50a3a_4.0.15912.0_none_833013222f03235e\aspnet_regiis.exe webengine4.dll

检测此活动

研究很有趣,但如何检测这种活动?我编写了一个简单的Yara规则来检测从C:\Windows\WinSxS外部加载DLL的WinSxS二进制文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
rule WinSxS_Outside_DLL_Loading
{
    meta:
        description = "Detect binaries loading DLLs from outside the C:\\Windows\\WinSxS directory"
        author = "ZephrFish"
        reference = "Internal Analysis"
        date = "2024-05-12"

    strings:
        $suspect_path = /LoadLibrary(Ex)?\s*\(.*[^\WinSxS\\][A-Za-z]:\\.*\.dll.*/ nocase wide ascii

    condition:
        $suspect_path
}
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计