您现在的位置是:首页 > 编程 > 

记一次蓝队—反钓鱼的策略研究

2025-07-26 08:44:06
记一次蓝队—反钓鱼的策略研究 原文首发在:先知社区 一·前言鄙人最近在某某中寻到了一个不知道谁的后门,心血来潮写下此文,以此提供一些蓝队简易反钓鱼的策略ps.(下篇文章就写红队如何高概率钓鱼,期待一下)本文所用环境:VS2022二·总思路通过对IP查,特殊文件名,文件编译器,启动项的检查,选出第一批可疑进程,再对其筛选,最终以弹窗的形式呈现三·流量方面1.获取所有进程的IP连接:代码语言:j

记一次蓝队—反钓鱼的策略研究

原文首发在:先知社区

一·前言

鄙人最近在某某中寻到了一个不知道谁的后门,心血来潮写下此文,以此提供一些蓝队简易反钓鱼的策略

ps.(下篇文章就写红队如何高概率钓鱼,期待一下)

本文所用环境:VS2022

二·总思路

通过对IP查,特殊文件名,文件编译器,启动项的检查,选出第一批可疑进程,再对其筛选,最终以弹窗的形式呈现

三·流量方面

1.获取所有进程的IP连接:

代码语言:javascript代码运行次数:0运行复制
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <winsock2.h>
#include <iphlpapi.h>
#include <windows.h>
#include <tlhelp2.h>
#include <psapi.h>
#include <ws2tcpip.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_2.lib")
#pragma comment(lib, "user2.lib")
#pragma comment(lib, "advapi2.lib") // For UAC check and elevation

// Function to get the process name given its PID
std::wstring getProcessame(DWORD pid) {
    wchar_t processame[MAX_PATH] = L"<未知>";
    HADLE hProcess = OpenProcess(PROCESS_QUERY_IFORMATIO | PROCESS_VM_READ, FALSE, pid);
    if (hProcess != ULL) {
        HMODULE hMod;
        DWORD cbeeded;
        if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbeeded)) {
            GetModuleBaseameW(hProcess, hMod, processame, sizeof(processame) / sizeof(wchar_t));
        }
        CloseHandle(hProcess);
    }
    return std::wstring(processame);
}

// Function to get the process path given its PID
std::wstring getProcessPath(DWORD pid) {
    wchar_t processPath[MAX_PATH] = L"<未知>";
    HADLE hProcess = OpenProcess(PROCESS_QUERY_IFORMATIO | PROCESS_VM_READ, FALSE, pid);
    if (hProcess != ULL) {
        GetModuleFileameExW(hProcess, ULL, processPath, sizeof(processPath) / sizeof(wchar_t));
        CloseHandle(hProcess);
    }
    return std::wstring(processPath);
}

// Function to enumerate all network connecti
void enumerateConnecti() {
    PMIB_TCPTABLE2 tcpTable;
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    tcpTable = (MIB_TCPTABLE2*)malloc(sizeof(MIB_TCPTABLE2));
    if (tcpTable == ULL) {
        std::cerr << "分配内存时出错" << std::endl;
        return;
    }

    dwSize = sizeof(MIB_TCPTABLE2);

    if ((dwRetVal = GetTcpTable2(tcpTable, &dwSize, TRUE)) == ERROR_ISUFFICIET_BUFFER) {
        free(tcpTable);
        tcpTable = (MIB_TCPTABLE2*)malloc(dwSize);
        if (tcpTable == ULL) {
            std::cerr << "分配内存时出错" << std::endl;
            return;
        }
    }

    if ((dwRetVal = GetTcpTable2(tcpTable, &dwSize, TRUE)) == O_ERROR) {
        char ipStringBuffer[IET_ADDRSTRLE];
        std::wstring output;
        for (int i = 0; i < (int)tcpTable->dwumEntries; i++) {
            inet_ntop(AF_IET, &tcpTable->table[i].dwRemoteAddr, ipStringBuffer, IET_ADDRSTRLE);
            std::string remoteIp(ipStringBuffer);

            DWORD pid = tcpTable->table[i].dwOwningPid;
            std::wstring processame = getProcessame(pid);
            std::wstring processPath = getProcessPath(pid);

            output += L"程序名称: " + processame + L"\n连接的IP: " + std::wstring(remoteIp.begin(), ()) +
                L"\n程序路径: " + processPath + L"\n---------------------------------\n";
        }

        // Show the output in a message box
        if (!()) {
            MessageBoxW(ULL, _str(), L"IP 和进程监控", MB_OK);
        }
        else {
            MessageBoxW(ULL, L"未到任何连接信息。", L"IP 和进程监控", MB_OK);
        }
    }
    else {
        std::cerr << "GetTcpTable2 调用失败,错误代码: " << dwRetVal << std::endl;
    }

    if (tcpTable != ULL) {
        free(tcpTable);
        tcpTable = ULL;
    }
}

// Function to check if the program is running as administrator
bool isRunningAsAdmin() {
    BOOL fIsRunAsAdmin = FALSE;
    PSID pAdministratorsGroup = ULL;

    SID_IDETIFIER_AUTHORITY tAuthority = SECURITY_T_AUTHORITY;
    if (AllocateAndInitializeSid(&tAuthority, 2,
        SECURITY_BUILTI_DOMAI_RID,
        DOMAI_ALIAS_RID_ADMIS,
        0, 0, 0, 0, 0, 0,
        &pAdministratorsGroup))
    {
        if (!CheckTokenMembership(ULL, pAdministratorsGroup, &fIsRunAsAdmin)) {
            fIsRunAsAdmin = FALSE;
        }
        FreeSid(pAdministratorsGroup);
    }

    return fIsRunAsAdmin;
}

// Function to restart the program with UAC elevation
void runAsAdmin() {
    wchar_t szPath[MAX_PATH];
    if (GetModuleFileameW(ULL, szPath, ARRAYSIZE(szPath))) {
        SHELLEXECUTEIFOW sei = { sizeof(sei) };
        sei.lpVerb = L"runas";
        sei.lpFile = szPath;
        sei.hwnd = ULL;
         = SW_ORMAL;

        if (!ShellExecuteExW(&sei)) {
            DWORD dwError = GetLastError();
            if (dwError == ERROR_CACELLED) {
                MessageBoxW(ULL, L"用户拒绝了权限提升请求。", L"错误", MB_OK);
            }
        }
        else {
            ExitProcess(0); // Terminate the current process since it's being restarted with elevation
        }
    }
}

int main() {
    // Step 1: Check for administrator privileges
    if (!isRunningAsAdmin()) {
        MessageBoxW(ULL, L"尝试以管理员权限运行...", L"提示", MB_OK);
        runAsAdmin();
        return 0;
    }

    // Step 2: Enumerate all connecti
    enumerateConnecti();

    return 0;
}

功能解释:

头文件和库的导入部分
代码语言:javascript代码运行次数:0运行复制
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <winsock2.h>
#include <iphlpapi.h>
#include <windows.h>
#include <tlhelp2.h>
#include <psapi.h>
#include <ws2tcpip.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_2.lib")
#pragma comment(lib, "user2.lib")
#pragma comment(lib, "advapi2.lib") // For UAC check and elevation
功能说明:
  • 头文件:
    • iostream,fstream: 用于输入输出流操作。
    • string,vector: 提供字符串处理和动态数组的支持。
    • winsock2.h: 提供 Windows 套接字(网络编程)接口。
    • iphlpapi.h: 包含与 IP 地址和网络接口相关的 API。
    • windows.h: Windows API 的通用头文件,提供多种核心功能。
    • tlhelp2.h: 提供与进程、线程快照相关的 API。
    • psapi.h: 用于获取进程相关信息(如模块和内存使用情况)。
    • ws2tcpip.h: 提供对 IPv6、地址转换和其他网络功能的支持。
  • 库链接:
    • iphlpapi.lib: 提供 IP 助手 API 的支持。
    • ws2_2.lib: 提供套接字编程所需的基础支持。
    • user2.lib: 提供与 GUI 和用户界面交互相关的 API。
    • advapi2.lib: 提供与权限提升(如 UAC 检查)相关的 API。

获取进程名称的函数
代码语言:javascript代码运行次数:0运行复制
std::wstring getProcessame(DWORD pid) {
    wchar_t processame[MAX_PATH] = L"<未知>";
    HADLE hProcess = OpenProcess(PROCESS_QUERY_IFORMATIO | PROCESS_VM_READ, FALSE, pid);
    if (hProcess != ULL) {
        HMODULE hMod;
        DWORD cbeeded;
        if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbeeded)) {
            GetModuleBaseameW(hProcess, hMod, processame, sizeof(processame) / sizeof(wchar_t));
        }
        CloseHandle(hProcess);
    }
    return std::wstring(processame);
}
功能说明:
  • 输入:
    • pid: 进程的 PID(Process ID)。
  • 输出:
    • 该 PID 对应的进程名称。
  • 详细逻辑:
    • PROCESS_QUERY_IFORMATIO: 允许查询进程信息。
    • PROCESS_VM_READ: 允许读取进程的虚拟内存。
    1. 调用OpenProcess打开目标进程句柄,权限为PROCESS_QUERY_IFORMATIO | PROCESS_VM_READ
    2. 使用EnumProcessModules获取进程的第一个模块句柄(通常是主程序)。
    3. 调用GetModuleBaseameW获取该模块(即程序)的名称。
    4. 若无法获取,返回默认值<未知>
    5. 关闭进程句柄以释放资源。

获取进程路径的函数
代码语言:javascript代码运行次数:0运行复制
std::wstring getProcessPath(DWORD pid) {
    wchar_t processPath[MAX_PATH] = L"<未知>";
    HADLE hProcess = OpenProcess(PROCESS_QUERY_IFORMATIO | PROCESS_VM_READ, FALSE, pid);
    if (hProcess != ULL) {
        GetModuleFileameExW(hProcess, ULL, processPath, sizeof(processPath) / sizeof(wchar_t));
        CloseHandle(hProcess);
    }
    return std::wstring(processPath);
}
功能说明:
  • 输入:
    • pid: 进程的 PID(Process ID)。
  • 输出:
    • 该 PID 对应的可执行文件完整路径。
  • 详细逻辑:
    • 与获取进程名称类似,但这里使用GetModuleFileameExW,返回的是可执行文件的完整路径(包括磁盘路径)。
    • 如果进程无法访问,返回默认值<未知>

枚举所有网络连接的函数
代码语言:javascript代码运行次数:0运行复制
void enumerateConnecti() {
    PMIB_TCPTABLE2 tcpTable;
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    tcpTable = (MIB_TCPTABLE2*)malloc(sizeof(MIB_TCPTABLE2));
    if (tcpTable == ULL) {
        std::cerr << "分配内存时出错" << std::endl;
        return;
    }
功能说明:
  • 步骤 1:分配空间
    • 调用mallocMIB_TCPTABLE2分配内存,用于存储 TCP 连接表。
代码语言:javascript代码运行次数:0运行复制
cpp复制代码
    if ((dwRetVal = GetTcpTable2(tcpTable, &dwSize, TRUE)) == ERROR_ISUFFICIET_BUFFER) {
        free(tcpTable);
        tcpTable = (MIB_TCPTABLE2*)malloc(dwSize);
        if (tcpTable == ULL) {
            std::cerr << "分配内存时出错" << std::endl;
            return;
        }
    }
  • 步骤 2:获取 TCP 连接表
    • 使用GetTcpTable2获取当前的 TCP 连接表。
    • 如果内存不足,重新分配足够的空间。
代码语言:javascript代码运行次数:0运行复制
cpp复制代码
    if ((dwRetVal = GetTcpTable2(tcpTable, &dwSize, TRUE)) == O_ERROR) {
        char ipStringBuffer[IET_ADDRSTRLE];
        std::wstring output;
        for (int i = 0; i < (int)tcpTable->dwumEntries; i++) {
            inet_ntop(AF_IET, &tcpTable->table[i].dwRemoteAddr, ipStringBuffer, IET_ADDRSTRLE);
            std::string remoteIp(ipStringBuffer);

            DWORD pid = tcpTable->table[i].dwOwningPid;
            std::wstring processame = getProcessame(pid);
            std::wstring processPath = getProcessPath(pid);

            output += L"程序名称: " + processame + L"\n连接的IP: " + std::wstring(remoteIp.begin(), ()) +
                L"\n程序路径: " + processPath + L"\n---------------------------------\n";
        }
  • 步骤 :解析每个连接
    1. 遍历tcpTable->table中的每个 TCP 连接项。
    2. 使用inet_ntop将二进制的远程 IP 地址转换为字符串形式。
    3. 调用getProcessamegetProcessPath获取连接对应进程的名称和路径。
    4. 将结果拼接到output中。
代码语言:javascript代码运行次数:0运行复制
cpp复制代码
        if (!()) {
            MessageBoxW(ULL, _str(), L"IP 和进程监控", MB_OK);
        }
        else {
            MessageBoxW(ULL, L"未到任何连接信息。", L"IP 和进程监控", MB_OK);
        }
    }
  • 步骤 4:输出结果
    • 如果存在连接信息,将结果显示在消息框中。
    • 如果没有任何连接,显示提示信息。
代码语言:javascript代码运行次数:0运行复制
cpp复制代码
    if (tcpTable != ULL) {
        free(tcpTable);
        tcpTable = ULL;
    }
  • 步骤 5:释放资源
    • 释放之前分配的内存,避免内存泄漏。

检查程序是否以管理员权限运行
代码语言:javascript代码运行次数:0运行复制
bool isRunningAsAdmin() {
    BOOL fIsRunAsAdmin = FALSE;
    PSID pAdministratorsGroup = ULL;

    SID_IDETIFIER_AUTHORITY tAuthority = SECURITY_T_AUTHORITY;
    if (AllocateAndInitializeSid(&tAuthority, 2,
        SECURITY_BUILTI_DOMAI_RID,
        DOMAI_ALIAS_RID_ADMIS,
        0, 0, 0, 0, 0, 0,
        &pAdministratorsGroup))
    {
        if (!CheckTokenMembership(ULL, pAdministratorsGroup, &fIsRunAsAdmin)) {
            fIsRunAsAdmin = FALSE;
        }
        FreeSid(pAdministratorsGroup);
    }

    return fIsRunAsAdmin;
}
功能说明:
  • 通过CheckTokenMembership检查当前用户是否属于管理员组。
  • 如果属于管理员组,返回true;否则返回false

请求权限提升
代码语言:javascript代码运行次数:0运行复制
void runAsAdmin() {
    wchar_t szPath[MAX_PATH];
    if (GetModuleFileameW(ULL, szPath, ARRAYSIZE(szPath))) {
        SHELLEXECUTEIFOW sei = { sizeof(sei) };
        sei.lpVerb = L"runas";
        sei.lpFile = szPath;
        sei.hwnd = ULL;
         = SW_ORMAL;

        if (!ShellExecuteExW(&sei)) {
            DWORD dwError = GetLastError();
            if (dwError == ERROR_CACELLED) {
                MessageBoxW(ULL, L"用户拒绝了权限提升请求。", L"错误", MB_OK);
            }
        }
        else {
            ExitProcess(0);
        }
    }
}
功能说明:
  • 如果程序未以管理员权限运行,调用ShellExecuteExW重新启动程序,并请求权限提升。

主函数
代码语言:javascript代码运行次数:0运行复制
int main() {
    if (!isRunningAsAdmin()) {
        MessageBoxW(ULL, L"尝试以管理员权限运行...", L"提示", MB_OK);
        runAsAdmin();
        return 0;
    }

    enumerateConnecti();

    return 0;
}
功能说明:
  1. 检查程序是否以管理员权限运行。
  2. 如果未以管理员权限运行,尝试权限提升。
  3. 如果权限足够,则调用enumerateConnecti列出所有网络连接。

2.过筛-192,127,0等

code:

代码语言:javascript代码运行次数:0运行复制
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <winsock2.h>
#include <iphlpapi.h>
#include <windows.h>
#include <tlhelp2.h>
#include <psapi.h>
#include <ws2tcpip.h>

#define _CRT_SECURE_O_WARIGS

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_2.lib")
#pragma comment(lib, "user2.lib")
#pragma comment(lib, "advapi2.lib") // For UAC check and elevation

// Function to check if an IP is public (exclude private/internal IPs)
bool isPublicIP(ct std::string& ip) {
    // Split IP into 4 octets
    unsigned int octet1, octet2, octet, octet4;

    if (sscanf_s(_str(), "%u.%u.%u.%u", &octet1, &octet2, &octet, &octet4) != 4) {
        return false; // Invalid IP format
    }
    // Exclude private IP ranges
    if ((octet1 == 10) ||  // 10.0.0.0/8
        (octet1 == 127) || // 127.0.0.0/8 (loopback)
        (octet1 == 192 && octet2 == 168) || // 192.168.0.0/16
        (octet1 == 172 && (octet2 >= 16 && octet2 <= 1)) || // 172.16.0.0/12
        (octet1 == 0) ||  // 0.0.0.0 (invalid address)
        (octet1 == 169 && octet2 == 254)) { // 169.254.0.0/16 (APIPA)
        return false;
    }

    return true; // Public IP
}

// Function to get the process name given its PID
std::wstring getProcessame(DWORD pid) {
    wchar_t processame[MAX_PATH] = L"<未知>";
    HADLE hProcess = OpenProcess(PROCESS_QUERY_IFORMATIO | PROCESS_VM_READ, FALSE, pid);
    if (hProcess != ULL) {
        HMODULE hMod;
        DWORD cbeeded;
        if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbeeded)) {
            GetModuleBaseameW(hProcess, hMod, processame, sizeof(processame) / sizeof(wchar_t));
        }
        CloseHandle(hProcess);
    }
    return std::wstring(processame);
}

// Function to get the process path given its PID
std::wstring getProcessPath(DWORD pid) {
    wchar_t processPath[MAX_PATH] = L"<未知>";
    HADLE hProcess = OpenProcess(PROCESS_QUERY_IFORMATIO | PROCESS_VM_READ, FALSE, pid);
    if (hProcess != ULL) {
        GetModuleFileameExW(hProcess, ULL, processPath, sizeof(processPath) / sizeof(wchar_t));
        CloseHandle(hProcess);
    }
    return std::wstring(processPath);
}

// Function to enumerate all network connecti
void enumerateConnecti() {
    PMIB_TCPTABLE2 tcpTable;
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    tcpTable = (MIB_TCPTABLE2*)malloc(sizeof(MIB_TCPTABLE2));
    if (tcpTable == ULL) {
        std::cerr << "分配内存时出错" << std::endl;
        return;
    }

    dwSize = sizeof(MIB_TCPTABLE2);

    if ((dwRetVal = GetTcpTable2(tcpTable, &dwSize, TRUE)) == ERROR_ISUFFICIET_BUFFER) {
        free(tcpTable);
        tcpTable = (MIB_TCPTABLE2*)malloc(dwSize);
        if (tcpTable == ULL) {
            std::cerr << "分配内存时出错" << std::endl;
            return;
        }
    }

    if ((dwRetVal = GetTcpTable2(tcpTable, &dwSize, TRUE)) == O_ERROR) {
        char ipStringBuffer[IET_ADDRSTRLE];
        std::wstring output;
        for (int i = 0; i < (int)tcpTable->dwumEntries; i++) {
            inet_ntop(AF_IET, &tcpTable->table[i].dwRemoteAddr, ipStringBuffer, IET_ADDRSTRLE);
            std::string remoteIp(ipStringBuffer);

            // Filter out private/internal IPs
            if (!isPublicIP(remoteIp)) {
                continue; // Skip internal/private IPs
            }

            DWORD pid = tcpTable->table[i].dwOwningPid;
            std::wstring processame = getProcessame(pid);
            std::wstring processPath = getProcessPath(pid);

            output += L"程序名称: " + processame + L"\n连接的IP: " + std::wstring(remoteIp.begin(), ()) +
                L"\n程序路径: " + processPath + L"\n---------------------------------\n";
        }

        // Show the output in a message box
        if (!()) {
            MessageBoxW(ULL, _str(), L"IP 和进程监控", MB_OK);
        }
        else {
            MessageBoxW(ULL, L"未到任何有效的公网连接信息。", L"IP 和进程监控", MB_OK);
        }
    }
    else {
        std::cerr << "GetTcpTable2 调用失败,错误代码: " << dwRetVal << std::endl;
    }

    if (tcpTable != ULL) {
        free(tcpTable);
        tcpTable = ULL;
    }
}

// Function to check if the program is running as administrator
bool isRunningAsAdmin() {
    BOOL fIsRunAsAdmin = FALSE;
    PSID pAdministratorsGroup = ULL;

    SID_IDETIFIER_AUTHORITY tAuthority = SECURITY_T_AUTHORITY;
    if (AllocateAndInitializeSid(&tAuthority, 2,
        SECURITY_BUILTI_DOMAI_RID,
        DOMAI_ALIAS_RID_ADMIS,
        0, 0, 0, 0, 0, 0,
        &pAdministratorsGroup))
    {
        if (!CheckTokenMembership(ULL, pAdministratorsGroup, &fIsRunAsAdmin)) {
            fIsRunAsAdmin = FALSE;
        }
        FreeSid(pAdministratorsGroup);
    }

    return fIsRunAsAdmin;
}

// Function to restart the program with UAC elevation
void runAsAdmin() {
    wchar_t szPath[MAX_PATH];
    if (GetModuleFileameW(ULL, szPath, ARRAYSIZE(szPath))) {
        SHELLEXECUTEIFOW sei = { sizeof(sei) };
        sei.lpVerb = L"runas";
        sei.lpFile = szPath;
        sei.hwnd = ULL;
         = SW_ORMAL;

        if (!ShellExecuteExW(&sei)) {
            DWORD dwError = GetLastError();
            if (dwError == ERROR_CACELLED) {
                MessageBoxW(ULL, L"用户拒绝了权限提升请求。", L"错误", MB_OK);
            }
        }
        else {
            ExitProcess(0); // Terminate the current process since it's being restarted with elevation
        }
    }
}

int main() {
    // Step 1: Check for administrator privileges
    if (!isRunningAsAdmin()) {
        MessageBoxW(ULL, L"尝试以管理员权限运行...", L"提示", MB_OK);
        runAsAdmin();
        return 0;
    }

    // Step 2: Enumerate all connecti
    enumerateConnecti();

    return 0;
}
  1. 新增**isPublicIP**函数
    • 对 IP 地址进行解析,筛选出公网 IP。
    • 剔除内网范围(如127.0.0.0/8192.168.0.0/16172.16.0.0/12等)。
  2. **enumerateConnecti**函数中调用**isPublicIP**
    • 遍历每个 TCP 连接时,使用isPublicIP检查远程 IP 地址,剔除内网 IP 和无效地址。
四·启动方面

1.启动目录及任务启动

代码语言:javascript代码运行次数:0运行复制
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
#include <shlobj.h>
#include <tlhelp2.h>

#pragma comment(lib, "shell2.lib")

std::vector<std::wstring> getFilesInDirectory(ct std::wstring& directoryPath) {
    std::vector<std::wstring> filePaths;
    WI2_FID_DATA findFileData;
    HADLE hFind = FindFirstFile((directoryPath + L"\\*").c_str(), &findFileData);

    if (hFind == IVALID_HADLE_VALUE) {
        return filePaths;
    }

    do {
        ct std::wstring fileOrDirame = ;
        if (fileOrDirame != L"." && fileOrDirame != L"..") {
            ct std::wstring fullPath = directoryPath + L"\\" + fileOrDirame;
            if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
                filePaths.push_back(fullPath);
            }
        }
    } while (FindextFile(hFind, &findFileData) != 0);

    FindClose(hFind);
    return filePaths;
}

void showMessage(ct std::wstring& message) {
    MessageBoxW(ULL, _str(), L"启动项检查", MB_OK | MB_ICOIFORMATIO);
}

void checkStartupDirectories() {
    wchar_t* userame = nullptr;
    size_t len = 0;
    _wdupenv_s(&userame, &len, L"USERAME");

    // 定义常见的启动目录
    std::wstring startupDirectories[] = {
        L"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
        L"C:\\Users\\" + std::wstring(userame) + L"\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
        L"C:\\Users\\" + std::wstring(userame) + L"\\AppData\\Local\\Microsoft\\Windows\\Startup",
        L"C:\\Users\\" + std::wstring(userame) + L"\\AppData\\Roaming\\Microsoft\\Windows\\Startup"
    };

    free(userame);  // 释放分配的内存

    std::wstring message = L"";

    for (ct auto& directory : startupDirectories) {
        std::vector<std::wstring> files = getFilesInDirectory(directory);

        if (!()) {
            message += L"在目录 " + directory + L" 中到以下启动项:\n";
            for (ct auto& file : files) {
                message += L"  - " + file + L"\n";
            }
            message += L"\n";
        }
    }

    if (!()) {
        showMessage(L"以下是各启动目录中的文件:\n" + message);
    } else {
        showMessage(L"未检测到各启动目录中的启动项文件。");
    }
}

void checkTaskSchedulerStartupItems() {
    // 定义任务计划程序路径的查询命令
    std::wstring command = L"schtasks /query /fo LIST /v";
    std::wstring result = L"";

    FILE* pipe = _wpopen(_str(), L"r");
    if (!pipe) {
        showMessage(L"无法执行任务计划程序查询命令!");
        return;
    }

    wchar_t buffer[1024];
    while (fgetws(buffer, sizeof(buffer) / sizeof(wchar_t), pipe) != ULL) {
        result += buffer;
    }
    _pclose(pipe);

    if (!()) {
        showMessage(L"任务计划启动项内容:\n" + result);
    } else {
        showMessage(L"未检测到任务计划中的启动项。");
    }
}

int main() {
    checkStartupDirectories();
    checkTaskSchedulerStartupItems();
    return 0;
}
(1)getFilesInDirectory()- 扫描目录中的文件
代码语言:javascript代码运行次数:0运行复制
std::vector<std::wstring> getFilesInDirectory(ct std::wstring& directoryPath) {
    std::vector<std::wstring> filePaths;
    WI2_FID_DATA findFileData;
    HADLE hFind = FindFirstFile((directoryPath + L"\\*").c_str(), &findFileData);

    if (hFind == IVALID_HADLE_VALUE) {
        return filePaths;
    }

    do {
        ct std::wstring fileOrDirame = ;
        if (fileOrDirame != L"." && fileOrDirame != L"..") {
            ct std::wstring fullPath = directoryPath + L"\\" + fileOrDirame;
            if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
                filePaths.push_back(fullPath);
            }
        }
    } while (FindextFile(hFind, &findFileData) != 0);

    FindClose(hFind);
    return filePaths;
}
  • 作用:获取指定目录中的所有文件路径。
  • 逻辑
    1. 调用FindFirstFile()FindextFile()遍历目录。
    2. 忽略...(表示当前目录和父目录)。
    3. 只将非目录的文件路径加入结果列表。
  • 返回值:包含文件路径的std::vector
(2)checkStartupDirectories()- 检查常见启动目录
代码语言:javascript代码运行次数:0运行复制
void checkStartupDirectories() {
    wchar_t* userame = nullptr;
    size_t len = 0;
    _wdupenv_s(&userame, &len, L"USERAME");

    // 定义常见的启动目录
    std::wstring startupDirectories[] = {
        L"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
        L"C:\\Users\\" + std::wstring(userame) + L"\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
        L"C:\\Users\\" + std::wstring(userame) + L"\\AppData\\Local\\Microsoft\\Windows\\Startup",
        L"C:\\Users\\" + std::wstring(userame) + L"\\AppData\\Roaming\\Microsoft\\Windows\\Startup"
    };

    free(userame);  // 释放分配的内存

    std::wstring message = L"";

    for (ct auto& directory : startupDirectories) {
        std::vector<std::wstring> files = getFilesInDirectory(directory);

        if (!()) {
            message += L"在目录 " + directory + L" 中到以下启动项:\n";
            for (ct auto& file : files) {
                message += L"  - " + file + L"\n";
            }
            message += L"\n";
        }
    }

    if (!()) {
        showMessage(L"以下是各启动目录中的文件:\n" + message);
    } else {
        showMessage(L"未检测到各启动目录中的启动项文件。");
    }
}
  • 作用:扫描系统中几个常见启动目录,列出其中的文件。
  • 步骤
    • 调用getFilesInDirectory()检查目录中的文件。
    • 如果存在文件,将其路径记录到消息内容中。
    • 公共启动目录:C:\ProgramData\...
    • 当前用户的启动目录:C:\Users\[USERAME]\AppData\...
    1. 获取当前用户名(用于构造用户相关的目录路径)。
    2. 定义常见的启动目录路径数组,包括:
    3. 遍历每个目录:
    4. 弹窗显示结果。
  • 功能覆盖
    • 扫描所有用户级别和全局级别的启动目录。

()checkTaskSchedulerStartupItems()- 检查任务计划中的启动项
代码语言:javascript代码运行次数:0运行复制
void checkTaskSchedulerStartupItems() {
    // 定义任务计划程序路径的查询命令
    std::wstring command = L"schtasks /query /fo LIST /v";
    std::wstring result = L"";

    FILE* pipe = _wpopen(_str(), L"r");
    if (!pipe) {
        showMessage(L"无法执行任务计划程序查询命令!");
        return;
    }

    wchar_t buffer[1024];
    while (fgetws(buffer, sizeof(buffer) / sizeof(wchar_t), pipe) != ULL) {
        result += buffer;
    }
    _pclose(pipe);

    if (!()) {
        showMessage(L"任务计划启动项内容:\n" + result);
    } else {
        showMessage(L"未检测到任务计划中的启动项。");
    }
}
  • 作用:通过命令行工具schtasks获取任务计划中定义的启动项。
  • 步骤
    • /query:查询任务计划。
    • /fo LIST:输出为列表格式。
    • /v:显示详细信息。
    1. 定义命令:schtasks /query /fo LIST /v
    2. 使用_wpopen()打开命令行管道,执行命令。
    3. 读取命令输出,将其存储为字符串。
    4. 如果有输出,弹窗显示任务计划项的内容;否则提示没有启动项。

五·加上签名过滤代码语言:javascript代码运行次数:0运行复制
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
#include <tlhelp2.h>
#include <psapi.h>
#include <wintrust.h>
#include <softpub.h>
#include <winreg.h>
#include <iphlpapi.h>
#include <sddl.h>
#include <fstream>
#include <chrono>
#include <thread>
#include <Lmc.h>
#include <ShlObj.h>
#include <ctime>
#include <regex>

#pragma comment(lib, "user2.lib")
#pragma comment(lib, "advapi2.lib")
#pragma comment(lib, "wintrust.lib")
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "shell2.lib")


std::vector<std::wstring> getFilesInDirectory(ct std::wstring& directoryPath) {
    std::vector<std::wstring> filePaths;
    WI2_FID_DATA findFileData;
    HADLE hFind = FindFirstFile((directoryPath + L"\\*").c_str(), &findFileData);

    if (hFind == IVALID_HADLE_VALUE) {
        return filePaths;
    }

    do {
        ct std::wstring fileOrDirame = ;
        if (fileOrDirame != L"." && fileOrDirame != L"..") {
            ct std::wstring fullPath = directoryPath + L"\\" + fileOrDirame;
            if (!(findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
                filePaths.push_back(fullPath);
            }
        }
    } while (FindextFile(hFind, &findFileData) != 0);

    FindClose(hFind);
    return filePaths;
}

bool isRunningAsAdmin() {
    BOOL isAdmin = FALSE;
    PSID adminGroup = ULL;
    SID_IDETIFIER_AUTHORITY tAuthority = SECURITY_T_AUTHORITY;

    if (AllocateAndInitializeSid(&tAuthority, 2, SECURITY_BUILTI_DOMAI_RID,
        DOMAI_ALIAS_RID_ADMIS, 0, 0, 0, 0, 0, 0, &adminGroup)) {
        CheckTokenMembership(ULL, adminGroup, &isAdmin);
        FreeSid(adminGroup);
    }

    return isAdmin;
}

void restartAsAdmin() {
    wchar_t szPath[MAX_PATH];
    if (GetModuleFileame(ULL, szPath, ARRAYSIZE(szPath))) {
        SHELLEXECUTEIFO sei = { sizeof(sei) };
        sei.lpVerb = L"runas";
        sei.lpFile = szPath;
        sei.hwnd = ULL;
         = SW_ORMAL;

        if (!ShellExecuteEx(&sei)) {
            std::cerr << "请求管理员权限失败。" << std::endl;
            exit(EXIT_FAILURE);
        }
        exit(EXIT_SUCCESS);
    }
}

std::wstring getProcessame(DWORD pid) {
    wchar_t processame[MAX_PATH] = L"<未知>";
    HADLE hProcess = OpenProcess(PROCESS_QUERY_IFORMATIO | PROCESS_VM_READ, FALSE, pid);
    if (hProcess != ULL) {
        HMODULE hMod;
        DWORD cbeeded;
        if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbeeded)) {
            GetModuleBaseameW(hProcess, hMod, processame, sizeof(processame) / sizeof(wchar_t));
        }
        CloseHandle(hProcess);
    }
    return std::wstring(processame);
}

std::wstring getProcessPath(DWORD pid) {
    wchar_t processPath[MAX_PATH] = L"<未知>";
    HADLE hProcess = OpenProcess(PROCESS_QUERY_IFORMATIO | PROCESS_VM_READ, FALSE, pid);
    if (hProcess != ULL) {
        GetModuleFileameExW(hProcess, ULL, processPath, sizeof(processPath) / sizeof(wchar_t));
        CloseHandle(hProcess);
    }
    return std::wstring(processPath);
}

bool isSystemProcess(HADLE hProcess) {
    HADLE hToken = ULL;
    if (!OpenProcessToken(hProcess, TOKE_QUERY, &hToken)) {
        return false;
    }

    DWORD dwSize = 0;
    GetTokenInformation(hToken, TokenUser, ULL, 0, &dwSize);
    PTOKE_USER pTokenUser = (PTOKE_USER)malloc(dwSize);
    if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize)) {
        free(pTokenUser);
        CloseHandle(hToken);
        return false;
    }

    WCHAR szame[MAX_PATH];
    WCHAR szDomain[MAX_PATH];
    DWORD dwameSize = MAX_PATH;
    DWORD dwDomainSize = MAX_PATH;
    SID_AME_USE sidType;

    if (LookupAccountSidW(ULL, pTokenUser->User.Sid, szame, &dwameSize, szDomain, &dwDomainSize, &sidType)) {
        if (wcscmp(szame, L"SYSTEM") == 0) {
            free(pTokenUser);
            CloseHandle(hToken);
            return true;
        }
    }

    free(pTokenUser);
    CloseHandle(hToken);
    return false;
}

std::vector<std::wstring> getExternalIPs(DWORD pid) {
    std::vector<std::wstring> externalIPs;

    PMIB_TCPTABLE2 tcpTable;
    DWORD dwSize = 0;

    GetTcpTable2(ULL, &dwSize, TRUE);
    tcpTable = (PMIB_TCPTABLE2)malloc(dwSize);

    if (GetTcpTable2(tcpTable, &dwSize, TRUE) == O_ERROR) {
        for (DWORD i = 0; i < tcpTable->dwumEntries; i++) {
            if (tcpTable->table[i].dwOwningPid == pid) {
                DWORD ipAddr = tcpTable->table[i].dwRemoteAddr;
                BYTE* ipBytes = (BYTE*)&ipAddr;

                std::wstring ipString = std::to_wstring(ipBytes[0]) + L"." +
                    std::to_wstring(ipBytes[1]) + L"." +
                    std::to_wstring(ipBytes[2]) + L"." +
                    std::to_wstring(ipBytes[]);

                if (!(ipBytes[0] == 192 && ipBytes[1] == 168) &&
                    !(ipBytes[0] == 127 && ipBytes[1] == 0) &&
                    !(ipAddr == 0)) {
                    externalIPs.push_back(ipString);
                }
            }
        }
    }

    free(tcpTable);
    return externalIPs;
}

enum ProcessSignatureStatus {
    SIGED_AD_TRUSTED,
    SIGED_BUT_OT_TRUSTED,
    OT_SIGED
};

ProcessSignatureStatus checkProcessSignature(ct std::wstring& processPath) {
    WITRUST_FILE_IFO fileInfo = { 0 };
     = sizeof(fileInfo);
    fileInfo.pcwszFilePath = _str();

    WITRUST_DATA winTrustData = { 0 };
     = sizeof(winTrustData);
    winTrustData.dwUIChoice = WTD_UI_OE;
    winTrustData.fdwRevocationChecks = WTD_REVOKE_OE;
    winTrustData.dwUnionChoice = WTD_CHOICE_FILE;
    winTrustData.dwStateAction = WTD_STATEACTIO_VERIFY;
    winTrustData.pFile = &fileInfo;

    GUID policyGUID = WITRUST_ACTIO_GEERIC_VERIFY_V2;

    LOG status = WinVerifyTrust(ULL, &policyGUID, &winTrustData);

    winTrustData.dwStateAction = WTD_STATEACTIO_CLOSE;
    WinVerifyTrust(ULL, &policyGUID, &winTrustData);

    if (status == ERROR_SUCCESS) {
        return SIGED_AD_TRUSTED;
    }
    else if (status == TRUST_E_OSIGATURE) {
        return OT_SIGED;
    }
    else {
        return SIGED_BUT_OT_TRUSTED;
    }
}

bool detectTrojanBehavior(DWORD pid, ct std::wstring& processPath) {
    bool hasSuspiciousBehavior = false;

    std::vector<std::wstring> sensitiveDirs = { L"C:\\Windows\\System2", L"C:\\Users" };
    for (ct auto& dir : sensitiveDirs) {
        if (processPath.find(dir) != std::wstring::npos) {
            hasSuspiciousBehavior = true;
            break;
        }
    }

    if (isSystemProcess(OpenProcess(PROCESS_QUERY_IFORMATIO, FALSE, pid))) {
        hasSuspiciousBehavior = true;
    }

    HADLE hProcessSnap;
    PROCESSETRY2 pe2;
    pe2.dwSize = sizeof(PROCESSETRY2);
    hProcessSnap = CreateToolhelp2Snapshot(TH2CS_SAPPROCESS, 0);
    if (hProcessSnap != IVALID_HADLE_VALUE) {
        if (Process2First(hProcessSnap, &pe2)) {
            do {
                if ( != pid) {
                    hasSuspiciousBehavior = true;
                    break;
                }
            } while (Process2ext(hProcessSnap, &pe2));
        }
        CloseHandle(hProcessSnap);
    }

    return hasSuspiciousBehavior;
}

bool isHighRiskProcess(ct std::wstring& processame, ct std::wstring& processPath) {
    std::vector<std::wstring> keywords = { L"PC", L"财务", L"CW", L"2024", L"202", L"工资", L"报表", L"调整" };
    std::wregex extensionPattern(L".*\\.(com|exe|bat)", std::regex_ctants::icase);

    for (ct auto& keyword : keywords) {
        if (processame.find(keyword) != std::wstring::npos && std::regex_match(processPath, extensionPattern)) {
            return true;
        }
    }
    return false;
}

bool isProcessInAutostart(ct std::wstring& processPath) {
    HKEY hKey;
    LPCWSTR runKeys[] = {
        L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
        L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
        L"SOFTWARE\\Wow642ode\\Microsoft\\Windows\\CurrentVersion\\Run",
                L"SOFTWARE\\Wow642ode\\Microsoft\\Windows\\CurrentVersion\\RunOnce",
        L"SYSTEM\\CurrentControlSet\\Services"
    };

    for (int i = 0; i < sizeof(runKeys) / sizeof(runKeys[0]); i++) {
        if (RegOpenKeyEx(HKEY_LOCAL_MACHIE, runKeys[i], 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
            DWORD index = 0;
            wchar_t valueame[MAX_PATH];
            wchar_t data[MAX_PATH];
            DWORD valueameSize = MAX_PATH;
            DWORD dataSize = sizeof(data);

            while (RegEnumValue(hKey, index, valueame, &valueameSize, ULL, ULL, (LPBYTE)data, &dataSize) == ERROR_SUCCESS) {
                std::wstring dataStr(data);
                if (dataStr.find(processPath) != std::wstring::npos) {
                    RegCloseKey(hKey);
                    return true;
                }
                index++;
                valueameSize = MAX_PATH;
                dataSize = sizeof(data);
            }

            RegCloseKey(hKey);
        }
    }

    return false;
}

void showMessage(ct std::wstring& message) {
    MessageBoxW(ULL, _str(), L"高危进程监控", MB_OK | MB_ICOIFORMATIO);
}
void checkStartupDirectoriesForUnsignedFiles() {
    wchar_t* userame = nullptr;
    size_t len = 0;
    _wdupenv_s(&userame, &len, L"USERAME");

    std::wstring startupDirectories[] = {
        L"C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup",
        L"C:\\Users\\" + std::wstring(userame) + L"\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup"
    };

    free(userame);  // 记得释放内存

    std::wstring message = L"";

    for (ct auto& directory : startupDirectories) {
        std::vector<std::wstring> files = getFilesInDirectory(directory);

        for (ct auto& file : files) {
            if (checkProcessSignature(file) == OT_SIGED) {
                message += L"无签名文件: " + file + L"\n";
            }
        }
    }

    if (!()) {
        showMessage(L"检测到启动目录中存在以下无签名文件:\n" + message);
    }
    else {
        showMessage(L"未检测到启动目录中存在无签名文件。");
    }
}

void monitorProcesses() {
    HADLE hProcessSnap;
    PROCESSETRY2 pe2;
    pe2.dwSize = sizeof(PROCESSETRY2);

    hProcessSnap = CreateToolhelp2Snapshot(TH2CS_SAPPROCESS, 0);
    if (hProcessSnap == IVALID_HADLE_VALUE) {
        std::cerr << "创建进程快照失败。" << std::endl;
        return;
    }

    if (!Process2First(hProcessSnap, &pe2)) {
        std::cerr << "获取第一个进程失败。" << std::endl;
        CloseHandle(hProcessSnap);
        return;
    }

    std::wstring message = L"";

    do {
        DWORD pid = ;
        if (pid == 0) continue;

        HADLE hProcess = OpenProcess(PROCESS_QUERY_IFORMATIO | PROCESS_VM_READ, FALSE, pid);
        if (hProcess == ULL) continue;

        std::wstring processPath = getProcessPath(pid);

        if (processPath.find(L"C:\\Windows") != std::wstring::npos) {
            CloseHandle(hProcess);
            continue;
        }

        std::wstring processame = getProcessame(pid);
        bool isHighRisk = isHighRiskProcess(processame, processPath);
        ProcessSignatureStatus signatureStatus = checkProcessSignature(processPath);

        if (signatureStatus == SIGED_AD_TRUSTED) {
            CloseHandle(hProcess);
            continue;  // If the process is signed and trusted, skip it
        }

        std::vector<std::wstring> externalIPs = getExternalIPs(pid);
        if (()) {
            CloseHandle(hProcess);
            continue;  // If there are no external IP connecti, skip the process
        }

        bool hasSuspiciousBehavior = detectTrojanBehavior(pid, processPath);
        bool inAutostart = isProcessInAutostart(processPath);

        CloseHandle(hProcess);

        std::wstring processInfo;
        if (isHighRisk) {
            processInfo = L"名称伪造高危进程: " + processame + L" (PID: " + std::to_wstring(pid) + L")\n路径: " + processPath + L"\n";
        }
        else if (signatureStatus == SIGED_BUT_OT_TRUSTED) {
            processInfo = L"签名伪造高危进程: " + processame + L" (PID: " + std::to_wstring(pid) + L")\n路径: " + processPath + L"\n";
        }
        else if (signatureStatus == OT_SIGED) {
            processInfo = L"无签名高危进程: " + processame + L" (PID: " + std::to_wstring(pid) + L")\n路径: " + processPath + L"\n";
        }
        else {
            processInfo = L"进程: " + processame + L" (PID: " + std::to_wstring(pid) + L")\n路径: " + processPath + L"\n";
        }

        processInfo += L"  - 检测到外部IP连接:\n";
        for (ct auto& ip : externalIPs) {
            processInfo += L"    " + ip + L"\n";
        }
        if (hasSuspiciousBehavior) {
            processInfo += L"  - 检测到异常行为\n";
        }

        if (inAutostart) {
            processInfo += L"  - 已加启动\n";
        }
        else {
            processInfo += L"  - 未发现自启动\n";
        }

        message += processInfo + L"\n";

    } while (Process2ext(hProcessSnap, &pe2));

    CloseHandle(hProcessSnap);

    if (!()) {
        showMessage(message);
    }
    else {
        showMessage(L"未检测到可疑进程。");
    }
}

int main() {
    if (!isRunningAsAdmin()) {
        restartAsAdmin();
    }

    monitorProcesses();
    checkStartupDirectoriesForUnsignedFiles();

    return 0;
}

#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格

本文地址:http://www.dnpztj.cn/biancheng/1218304.html

相关标签:无
上传时间: 2025-07-25 10:29:33
留言与评论(共有 14 条评论)
本站网友 海南二手房
4分钟前 发表
cerr << "创建进程快照失败
本站网友 中文大学
28分钟前 发表
wstring(processame); } std
本站网友 养老金替代率
24分钟前 发表
processame
本站网友 房屋出租信息发布
21分钟前 发表
本站网友 上海男科医院哪个最好
6分钟前 发表
wstring& message) { MessageBoxW(ULL
本站网友 电子请帖
3分钟前 发表
本站网友 应急救援
24分钟前 发表
SIGED_BUT_OT_TRUSTED
本站网友 94网
4分钟前 发表
L"C
本站网友 西安市人才交流中心
2分钟前 发表
to_wstring(ipBytes[]); if (!(ipBytes[0] == 192 && ipBytes[1] == 168) && !(ipBytes[0] == 127 && ipBytes[1] == 0) && !(ipAddr == 0)) { externalIPs.push_back(ipString); } } } } free(tcpTable); return externalIPs; } enum ProcessSignatureStatus { SIGED_AD_TRUSTED
本站网友 邢天溯
9分钟前 发表
&dwSize
本站网友 房地产报
21分钟前 发表
本站网友 伏特加酒多少度
24分钟前 发表
"); } } int main() { if (!isRunningAsAdmin()) { restartAsAdmin(); } monitorProcesses(); checkStartupDirectoriesForUnsignedFiles(); return 0; }
本站网友 chinapub
24分钟前 发表
L"SYSTEM") == 0) { free(pTokenUser); CloseHandle(hToken); return true; } } free(pTokenUser); CloseHandle(hToken); return false; } std