Windows中的父进程欺骗技术实现

Windows中的父进程欺骗技术实现

点击上方蓝字关注我们

SPRING HAS ARRIVED

Windows中的父进程欺骗技术实现


Windows中的父进程欺骗技术实现

摘要

Windows中的父进程欺骗技术实现

进程ID(PID)欺骗通常是恶意软件使用的一种隐蔽技术, 其希望以一个由系统上的合法程序创建的进程来执行其恶意意图。在操作系统中, 运行的每个程序都被赋予一个称为进程ID的唯一标识号, 这个PID能够帮助操作系统在系统级别监控每个程序状态, 而PID欺骗就是修改或伪装正常进程的PID, 使恶意程序以合法进程的身份运行。


Windows中的父进程欺骗技术实现

PID欺骗的目的

Windows中的父进程欺骗技术实现

恶意软件通过PID欺骗,可能会有机会实现以下功能:

  • 规避检测:恶意软件通过修改自身PID为合法PID后, 相当于实现了身份变换, 可以绕过安全软件的检测。

  • 绕过访问控制:可以将PID欺骗看作伪造了一个VIP通行证来获取对受限区域的访问权限, 通过伪装成具有合法PID的另一个进程, 可以程序可以欺骗系统的访问控制, 突破系统限制。

  • 隐藏恶意活动:PID欺骗使恶意程序可以伪装其行为,使系统管理员和安全分析人员更难以发现任何可疑行为。通过表现得像另一个无害进程, 它可以执行其恶意行为而不会引起任何警告。

  • 保持持久性:恶意程序通常在被害系统中需要保持持久性, 以确保长期访问和控制, 通过伪装成合法进程, 其可以根深牢固的潜伏在系统中, 使其变得更难以被发现和删除。

  • 促进多阶段攻击:在复杂的网络攻击中, 通常涉及多个阶段, 每个阶段由不同的组件或程序执行。PID欺骗有助于掩盖这些组件的活动, 使对手很难追踪攻击源头。


Windows中的父进程欺骗技术实现

PID欺骗概念实现

Windows中的父进程欺骗技术实现

以下是使用C++实现的PID欺骗的概念验证代码:

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

// 通过进程名获取PID
DWORD GetProcessIdByName(const wchar_t* processName) {
    PROCESSENTRY32W pe32;
    HANDLE hSnapshot;
    DWORD pid = 0;

    // 运行时获取进程在内存中的快照
    hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hSnapshot == INVALID_HANDLE_VALUE) {
        std::cerr << "Error: CreateToolhelp32Snapshot failed (" << GetLastError() << ")n";
        return 0;
    }

    pe32.dwSize = sizeof(PROCESSENTRY32W);

    if (Process32FirstW(hSnapshot, &pe32)) {
        do { // 迭代获取所需的进程
            if (wcscmp(pe32.szExeFile, processName) == 0) { // 将可执行文件名称与进程名称进行匹配
                pid = pe32.th32ProcessID; // Retriving Its PID
                break;
            }
        } while (Process32NextW(hSnapshot, &pe32));
    }

    CloseHandle(hSnapshot);
    return pid;
}

int main(void) {
    std::wcout << L"Enter the process name: "; // 获取进程名
    std::wstring targetProcessName;
    std::getline(std::wcin, targetProcessName);

    DWORD targetProcessId = GetProcessIdByName(targetProcessName.c_str());

    if (targetProcessId == 0) {
        std::cerr << "Error: Process '" << &targetProcessName << "' not foundn";
        return 1;
    }

    PROCESS_INFORMATION pi;
    STARTUPINFOW si = { sizeof(si) };

    si.cb = sizeof(STARTUPINFOW);
    si.dwFlags = STARTF_USESTDHANDLES; // 使用标准句柄
    si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

    // 指定记事本可执行文件的完整路径
    std::wstring notepadPath = L"C:\Windows\System32\notepad.exe";

    // 使用指定的父进程创建一个新的进程(记事本)
    if (!CreateProcessW(nullptr, const_cast<LPWSTR>(notepadPath.c_str()), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi)) {
        std::cerr << "Error: CreateProcess failed (" << GetLastError() << ")n";
        return 1;
    }

    std::wcout << L"Notepad process created successfully with PID: " << pi.dwProcessId << std::endl;
    system("pause"); // Holding Console Window

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    
    return 0;
}

在上面的概念验证代码中,实现了以下几个部分功能:

1.通过名称获取进程ID

GetProcessIdByName函数使用Windows工具帮助函数(CreateToolhelp32Snapshot、Process32FirstW、Process32NextW)按名称搜索进程。它接受一个表示进程名称的宽字符字符串,并返回找到的进程ID(PID)。

2.创建新进程

主函数需要一个进程名称。然后调用GetProcessIdByName()来获取指定进程的PID。使用CreateProcessW()创建提供程序的新进程以检索其PID。STARTUPINFOW结构(si)初始化为sizeof(STARTUPINFOW),并指示使用标准句柄的标志。这是保存所提供进程的PID的主要结构。CreateProcessW()使用提供的参数启动指定进程(在本例中为notepad.exe)。如果成功,则返回非零值,并使用有关新创建进程的信息填充PROCESS_INFORMATION结构(pi)。

3.标准句柄

标准句柄(hStdInput、hStdOutput、hStdError)用于指定新进程的输入、输出和错误流。它们设置在传递给CreateProcessW的STARTUPINFOW结构中。默认情况下,这些句柄设置为当前进程的标准句柄。

4.句柄继承

在此代码中,CreateProcessW()的bInheritHandles参数设置为FALSE。这表示新进程不应继承当前进程的句柄,确保它不使用相同的错误和输出流。

5.错误处理

使用标准错误输出(std::cerr)和Windows错误函数(GetLastError)实现错误处理。Windows API函数返回的错误代码用于提供有关失败的诊断信息。


Windows中的父进程欺骗技术实现

程序验证

Windows中的父进程欺骗技术实现

以下是程序运行后的效果:

Windows中的父进程欺骗技术实现

首先输入了进程名:explorer.exe, 之后通过程序获取该进程的PID, 通过该PID作为父进程创建了一个子进程5696, 该子进程指向的二进制程序路径为:C:WindowsSystem32notepad.exe

原文始发于微信公众号(二进制空间安全):Windows中的父进程欺骗技术实现

版权声明:admin 发表于 2024年3月29日 上午9:30。
转载请注明:Windows中的父进程欺骗技术实现 | CTF导航

相关文章