You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

采用UAC绕过技术提权的进程能否溯源至触发程序?

UAC绕过技术的进程溯源分析

问题背景

我通过ICMLuaUtil COM接口这一UAC绕过技术成功提权二进制程序(如cmd.exe),现需确认能否将提权后的程序溯源至初始触发提权的“触发程序”。若该技术无法留下溯源痕迹,我还想了解fodhelper等知名UAC绕过方法是否支持此类溯源。

进程溯源程序代码

#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#include <string>
#include <algorithm>

// Function to get the process path by process ID
const char* GetProcessPathById(DWORD processId) {
    static char processPath[MAX_PATH];
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
    if (hProcess == NULL)
        return "Unknown";

    if (GetModuleFileNameExA(hProcess, NULL, processPath, sizeof(processPath))) {
        // Convert to lowercase
        std::transform(processPath, processPath + strlen(processPath), processPath, ::tolower);
        CloseHandle(hProcess);
        return processPath;
    }

    CloseHandle(hProcess);
    return "Unknown";
}

// Function to get the parent process ID of a given process ID
DWORD GetParentProcessId(DWORD pid) {
    DWORD ppid = (DWORD)-1;
    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (h == INVALID_HANDLE_VALUE)
        return (DWORD)-1;

    PROCESSENTRY32 pe = { 0 };
    pe.dwSize = sizeof(PROCESSENTRY32);

    if (Process32First(h, &pe)) {
        do {
            if (pe.th32ProcessID == pid) {
                ppid = pe.th32ParentProcessID;
                break;
            }
        } while (Process32Next(h, &pe));
    }

    CloseHandle(h);
    return ppid;
}

int main(int argc, char* argv[]) {
    DWORD targetPid;

    // Check if a process ID was provided as a command-line argument
    if (argc > 1) {
        targetPid = std::stoul(argv[1]); // Convert the argument to DWORD
    } else {
        targetPid = GetCurrentProcessId(); // Use the current process ID if none provided
    }

    DWORD currentPid = targetPid;

    std::cout << "Process Ancestry for PID: " << targetPid << std::endl;

    while (currentPid != (DWORD)-1) {
        const char* processPath = GetProcessPathById(currentPid);
        std::cout << "Process ID: " << currentPid << " - Path: " << processPath << std::endl;

        DWORD parentPid = GetParentProcessId(currentPid);
        if (parentPid == currentPid) {
            break; // Avoid an infinite loop in case of a self-referencing process
        }
        currentPid = parentPid;
    }

    system("pause");
    return 0;
}

提权后的溯源输出

Process Ancestry for PID: 17244
Process ID: 17244 - Path: (the exe path)
Process ID: 7924 - Path: c:\windows\syswow64\dllhost.exe
Process ID: 520 - Path: Unknown
Process ID: 888 - Path: Unknown
Process ID: 760 - Path: Unknown
Process ID: 616 - Path: Unknown

用户疑问

我推测PID为616的进程父进程是系统进程,因此无法溯源至触发程序,是否正确?


分析与结论

  1. ICMLuaUtil COM接口提权的溯源情况

    • 从输出的进程链来看,提权后的程序父进程是dllhost.exe,后续显示"Unknown"的PID(520/888/760/616),是因为你的程序没有足够权限读取系统核心进程信息。这些未知PID对应的大概率是smss.exe(会话管理器)、csrss.exe或wininit.exe这类系统启动级进程,它们的最终父进程是System进程(PID 4)。
    • ICMLuaUtil提权的核心是调用系统合法的高权限COM服务(由dllhost.exe托管)启动目标程序,这个过程中初始触发程序与提权进程的直接关联被切断——dllhost.exe由系统服务管理器启动,而非触发程序直接创建,因此常规父PID溯源无法关联到初始触发程序。
  2. fodhelper等知名UAC绕过方法的溯源情况

    • fodhelper的UAC绕过通常是篡改注册表项,让这个受信任的Windows内置程序加载恶意代码或启动恶意程序。此时进程链为fodhelper.exe → 恶意程序,而fodhelper.exe的父进程多为explorer.exe或系统服务进程,同样与初始触发程序没有直接父进程关联——因为fodhelper是系统根据注册表触发启动的,而非触发程序直接创建。
    • 部分UAC绕过可能留下间接痕迹,比如注册表操作日志、ETW进程创建事件,但这些不属于常规父PID溯源范畴,需要借助Event Viewer、Process Monitor等系统审计工具才能捕捉。
  3. 结论
    你的推测完全正确:PID 616的父进程大概率是System这类系统核心进程,常规父PID溯源确实无法关联到初始触发程序;包括fodhelper在内的多数常见UAC绕过技术,都会切断提权进程与触发程序的直接父进程关联,常规手段无法直接追踪,需要依赖系统审计日志等底层信息。


内容的提问来源于stack exchange,提问作者Uladzimir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 17:35:25