调用Windows API实现命令行工具:Sharp4Cmd
字数 1542 2025-08-22 12:22:42

Sharp4Cmd 工具详细教学文档

1. 工具概述

Sharp4Cmd 是一款基于.NET框架开发的Windows命令行交互工具,其主要特点是通过直接调用Windows API实现命令执行,不依赖系统的cmd.exe,在内网渗透测试中能够有效规避安全防护设备的检测。

2. 核心功能

  • 直接调用kernel32.dll中的CreateProcess函数执行命令
  • 通过管道机制实现父子进程间通信
  • 支持命令执行结果的实时获取
  • 可配置进程创建策略,增强隐蔽性

3. 使用方法

3.1 编译与运行

  1. 编译Sharp4Cmd项目生成Sharp4Cmd.exe
  2. 命令行执行格式:
    Sharp4Cmd.exe [command]
    
  3. 示例:
    Sharp4Cmd.exe whoami /priv
    

4. 技术原理详解

4.1 核心代码结构

程序主要由两部分组成:

  1. Main方法:程序入口,接收并处理命令行参数
  2. UnmanagedExecute类:封装Windows API调用,实现进程创建和管道通信

4.2 关键API函数

4.2.1 OpenProcess

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(
    ProcessAccessFlags processAccess,
    bool bInheritHandle,
    int processId
);
  • 功能:打开已存在的进程
  • 参数:
    • processAccess:进程访问权限标志
    • bInheritHandle:是否允许子进程继承句柄
    • processId:目标进程ID

4.2.2 InitializeProcThreadAttributeList

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool InitializeProcThreadAttributeList(
    IntPtr lpAttributeList,
    int dwAttributeCount,
    int dwFlags,
    ref IntPtr lpSize
);
  • 功能:初始化进程属性列表
  • 参数:
    • lpAttributeList:属性列表指针
    • dwAttributeCount:属性数量
    • dwFlags:保留标志,通常为0
    • lpSize:返回所需缓冲区大小

4.2.3 UpdateProcThreadAttribute

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UpdateProcThreadAttribute(
    IntPtr lpAttributeList,
    uint dwFlags,
    IntPtr Attribute,
    IntPtr lpValue,
    IntPtr cbSize,
    IntPtr lpPreviousValue,
    IntPtr lpReturnSize
);
  • 功能:更新进程属性列表
  • 重要参数:
    • Attribute:要设置的属性类型
    • lpValue:属性值指针

4.2.4 CreatePipe

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CreatePipe(
    out IntPtr hReadPipe,
    out IntPtr hWritePipe,
    ref SECURITY_ATTRIBUTES lpPipeAttributes,
    uint nSize
);
  • 功能:创建匿名管道
  • 参数:
    • hReadPipe:返回读取端句柄
    • hWritePipe:返回写入端句柄
    • lpPipeAttributes:安全属性结构
    • nSize:缓冲区大小,0表示默认

4.3 关键数据结构

4.3.1 SECURITY_ATTRIBUTES

public struct SECURITY_ATTRIBUTES {
    public int nLength;
    public IntPtr lpSecurityDescriptor;
    public bool bInheritHandle;
}
  • 功能:定义对象的安全属性
  • 成员:
    • nLength:结构体大小
    • lpSecurityDescriptor:安全描述符指针
    • bInheritHandle:句柄继承标志

4.4 核心实现流程

4.4.1 管道创建与配置

  1. 初始化安全属性结构:

    var saHandles = new SECURITY_ATTRIBUTES();
    saHandles.nLength = Marshal.SizeOf(saHandles);
    saHandles.bInheritHandle = true;
    saHandles.lpSecurityDescriptor = IntPtr.Zero;
    
  2. 创建管道:

    IntPtr hStdOutRead;
    IntPtr hStdOutWrite;
    CreatePipe(out hStdOutRead, out hStdOutWrite, ref saHandles, 0);
    SetHandleInformation(hStdOutRead, HANDLE_FLAGS.INHERIT, 0);
    

4.4.2 进程策略配置

  1. 初始化属性列表:

    var lpSize = IntPtr.Zero;
    var success = InitializeProcThreadAttributeList(IntPtr.Zero, 2, 0, ref lpSize);
    siEx.lpAttributeList = Marshal.AllocHGlobal(lpSize);
    success = InitializeProcThreadAttributeList(siEx.lpAttributeList, 2, 0, ref lpSize);
    
  2. 设置安全策略(仅允许微软签名DLL):

    IntPtr lpMitigationPolicy = Marshal.AllocHGlobal(IntPtr.Size);
    Marshal.WriteInt64(lpMitigationPolicy, 
        PROCESS_CREATION_MITIGATION_POLICY_BLOCK_NON_MICROSOFT_BINARIES_ALWAYS_ON);
    success = UpdateProcThreadAttribute(siEx.lpAttributeList, 0, 
        (IntPtr)PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, 
        lpMitigationPolicy, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero);
    

4.4.3 进程创建与数据重定向

  1. 打开父进程并更新属性:

    IntPtr parentHandle = OpenProcess(
        ProcessAccessFlags.CreateProcess | ProcessAccessFlags.DuplicateHandle, 
        false, parentProcessId);
    lpValueProc = Marshal.AllocHGlobal(IntPtr.Size);
    Marshal.WriteIntPtr(lpValueProc, parentHandle);
    success = UpdateProcThreadAttribute(siEx.lpAttributeList, 0, 
        (IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, 
        lpValueProc, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero);
    
  2. 复制句柄实现数据重定向:

    IntPtr hCurrent = System.Diagnostics.Process.GetCurrentProcess().Handle;
    IntPtr hNewParent = OpenProcess(ProcessAccessFlags.DuplicateHandle, true, parentProcessId);
    success = DuplicateHandle(hCurrent, hStdOutWrite, hNewParent, 
        ref hDupStdOutWrite, 0, true, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
    siEx.StartupInfo.hStdError = hDupStdOutWrite;
    siEx.StartupInfo.hStdOutput = hDupStdOutWrite;
    
  3. 创建新进程:

    siEx.StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    siEx.StartupInfo.wShowWindow = SW_HIDE;
    var ps = new SECURITY_ATTRIBUTES();
    var ts = new SECURITY_ATTRIBUTES();
    ps.nLength = Marshal.SizeOf(ps);
    ts.nLength = Marshal.SizeOf(ts);
    bool ret = CreateProcess(null, command, ref ps, ref ts, true, 
        EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW, 
        IntPtr.Zero, null, ref siEx, out pInfo);
    

4.4.4 输出数据读取

  1. 创建读取管道数据的流:

    SafeFileHandle safeHandle = new SafeFileHandle(hStdOutRead, false);
    var encoding = Encoding.GetEncoding(GetConsoleOutputCP());
    var reader = new StreamReader(
        new FileStream(safeHandle, FileAccess.Read, 4096, false), 
        encoding, true);
    
  2. 循环读取输出数据:

    string result = "";
    bool exit = false;
    do {
        if (WaitForSingleObject(pInfo.hProcess, 100) == 0) {
            exit = true;
        }
    
        char[] buf = null;
        int bytesRead;
        uint bytesToRead = 0;
    
        bool peekRet = PeekNamedPipe(hStdOutRead, IntPtr.Zero, IntPtr.Zero, 
            IntPtr.Zero, ref bytesToRead, IntPtr.Zero);
    
        if (peekRet == true && bytesToRead == 0) {
            if (exit == true) break;
            else continue;
        }
    
        if (bytesToRead > 4096) bytesToRead = 4096;
        buf = new char[bytesToRead];
        bytesRead = reader.Read(buf, 0, buf.Length);
    
        if (bytesRead > 0) {
            result += new string(buf);
        }
    } while (true);
    

5. 技术要点总结

  1. 进程创建机制:直接调用CreateProcess API,不依赖cmd.exe
  2. 管道通信:通过CreatePipe创建匿名管道,实现父子进程间数据传递
  3. 安全策略:配置PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY限制非微软签名DLL加载
  4. 输出重定向:使用DuplicateHandle复制句柄,将子进程输出重定向到父进程
  5. 隐蔽性设计
    • 设置CREATE_NO_WINDOW标志不显示窗口
    • 使用SW_HIDE隐藏窗口显示
    • 通过管道而非标准控制台获取输出

6. 应用场景

  1. 内网渗透测试中规避安全设备检测
  2. 需要隐蔽执行命令的红队活动
  3. 需要精细控制进程创建属性的场景
  4. 需要绕过传统命令行监控的安全测试

7. 注意事项

  1. 需要.NET框架支持
  2. 在高度受限的环境中可能无法执行
  3. 父进程ID为0时会排除系统空闲进程
  4. 输出编码依赖于控制台代码页(GetConsoleOutputCP)
Sharp4Cmd 工具详细教学文档 1. 工具概述 Sharp4Cmd 是一款基于.NET框架开发的Windows命令行交互工具,其主要特点是通过直接调用Windows API实现命令执行,不依赖系统的cmd.exe,在内网渗透测试中能够有效规避安全防护设备的检测。 2. 核心功能 直接调用kernel32.dll中的CreateProcess函数执行命令 通过管道机制实现父子进程间通信 支持命令执行结果的实时获取 可配置进程创建策略,增强隐蔽性 3. 使用方法 3.1 编译与运行 编译Sharp4Cmd项目生成Sharp4Cmd.exe 命令行执行格式: 示例: 4. 技术原理详解 4.1 核心代码结构 程序主要由两部分组成: Main方法:程序入口,接收并处理命令行参数 UnmanagedExecute类:封装Windows API调用,实现进程创建和管道通信 4.2 关键API函数 4.2.1 OpenProcess 功能:打开已存在的进程 参数: processAccess:进程访问权限标志 bInheritHandle:是否允许子进程继承句柄 processId:目标进程ID 4.2.2 InitializeProcThreadAttributeList 功能:初始化进程属性列表 参数: lpAttributeList:属性列表指针 dwAttributeCount:属性数量 dwFlags:保留标志,通常为0 lpSize:返回所需缓冲区大小 4.2.3 UpdateProcThreadAttribute 功能:更新进程属性列表 重要参数: Attribute:要设置的属性类型 lpValue:属性值指针 4.2.4 CreatePipe 功能:创建匿名管道 参数: hReadPipe:返回读取端句柄 hWritePipe:返回写入端句柄 lpPipeAttributes:安全属性结构 nSize:缓冲区大小,0表示默认 4.3 关键数据结构 4.3.1 SECURITY_ ATTRIBUTES 功能:定义对象的安全属性 成员: nLength:结构体大小 lpSecurityDescriptor:安全描述符指针 bInheritHandle:句柄继承标志 4.4 核心实现流程 4.4.1 管道创建与配置 初始化安全属性结构: 创建管道: 4.4.2 进程策略配置 初始化属性列表: 设置安全策略(仅允许微软签名DLL): 4.4.3 进程创建与数据重定向 打开父进程并更新属性: 复制句柄实现数据重定向: 创建新进程: 4.4.4 输出数据读取 创建读取管道数据的流: 循环读取输出数据: 5. 技术要点总结 进程创建机制 :直接调用CreateProcess API,不依赖cmd.exe 管道通信 :通过CreatePipe创建匿名管道,实现父子进程间数据传递 安全策略 :配置PROC_ THREAD_ ATTRIBUTE_ MITIGATION_ POLICY限制非微软签名DLL加载 输出重定向 :使用DuplicateHandle复制句柄,将子进程输出重定向到父进程 隐蔽性设计 : 设置CREATE_ NO_ WINDOW标志不显示窗口 使用SW_ HIDE隐藏窗口显示 通过管道而非标准控制台获取输出 6. 应用场景 内网渗透测试中规避安全设备检测 需要隐蔽执行命令的红队活动 需要精细控制进程创建属性的场景 需要绕过传统命令行监控的安全测试 7. 注意事项 需要.NET框架支持 在高度受限的环境中可能无法执行 父进程ID为0时会排除系统空闲进程 输出编码依赖于控制台代码页(GetConsoleOutputCP)