Shellcode动态分析
字数 1612 2025-09-01 11:25:53

Shellcode动态分析实战教学文档

1. 二进制文件初步分析

1.1 文件基本信息分析

首先使用file命令查看二进制文件的基本信息:

ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=..., for GNU/Linux 3.2.0, stripped

关键信息:

  • ELF: Linux系统下最常见的可执行文件格式
  • 64-bit: x86-64架构
  • LSB: 小端字节序
  • pie executable: 位置无关可执行文件,加载时可随机分配内存地址

1.2 安全机制检查

使用checksec检查文件的安全保护机制:

RELRO:    Full RELRO
Stack:    Canary found
NX:       NX enabled
PIE:      PIE enabled

安全机制说明:

  • RELRO(Relocation Read-Only): 重定位表只读保护
  • Stack Canary: 栈溢出检测机制
  • NX(No-eXecute): 不可执行内存保护
  • PIE(Position-Independent Executable): 位置无关可执行文件

2. 静态分析

2.1 字符串分析

使用strings命令查找可能的明文IP和端口信息:

strings binary_file

2.2 IDA Pro静态分析

  1. 将文件拖入IDA Pro,自动识别架构
  2. 查看导入表,寻找网络相关函数(如connect等)
  3. 分析main函数流程

关键发现:

  • IP地址不是明文存储
  • 通过memcpy将数据复制到内存中
  • 需要动态调试获取实际IP和端口信息

3. 动态调试分析

3.1 GDB调试准备

  1. 启动GDB:
gdb ./binary_file
  1. 查看文件入口点:
info files
  1. 在入口点设置断点:
b *0x1240
  1. 运行程序:
run

3.2 调试过程

  1. 删除初始断点(如果需要):
del 1
  1. 使用ni(next instruction)步过指令:
ni
  1. 重复执行直到看到main函数地址(可连续按回车)

  2. 使用si(step into)步入main函数:

si
  1. 在main函数地址设置断点(例如0x55555555540a):
b *0x55555555540a
  1. 继续执行到断点:
c
  1. 使用n(next)重复执行直到看到call rax指令

  2. 进入call rax

si

3.3 关键数据获取

  1. 继续执行直到看到syscall指令
  2. 观察寄存器中的值,特别是:
    • 连接相关的系统调用(如connect)
    • IP地址和端口信息(通常以16进制形式存储)

4. 数据转换与分析

4.1 IP地址转换

从调试中获取的16进制IP地址需要转换为点分十进制格式:

例如:0x0100007F -> 127.0.0.1

转换方法:

  1. 将16进制值转换为小端序
  2. 每8位(2个16进制数字)转换为一个十进制数

4.2 端口号转换

端口号通常以网络字节序(大端)存储:

例如:0x1F90 -> 8080

5. Shellcode分析技巧

5.1 识别Shellcode特征

  1. 观察不寻常的系统调用序列
  2. 查找网络操作相关的系统调用(socket, connect, send等)
  3. 注意加密或编码的数据区域

5.2 动态分析要点

  1. 内存转储:在关键点转储内存内容

    x/32xb $rax
    
  2. 寄存器监控:关注系统调用前的寄存器设置

    • RAX: 系统调用号
    • RDI, RSI, RDX: 参数
  3. 调用跟踪:使用backtrace查看调用栈

6. 常见挑战与解决方案

6.1 反调试技术应对

  1. 检测调试器:修改环境变量或使用catch syscall ptrace
  2. 代码混淆:结合静态和动态分析,关注实际执行路径
  3. 时间延迟:设置断点跳过无关代码

6.2 PIE处理技巧

  1. 使用GDB的pie命令:

    set stop-on-solib-events 1
    
  2. 在程序加载后获取实际地址:

    info proc mappings
    
  3. 使用相对地址设置断点

7. 工具链推荐

  1. 静态分析

    • IDA Pro
    • Ghidra
    • Radare2
  2. 动态分析

    • GDB(增强版:GEF/PEDA/Pwndbg)
    • strace/ltrace
    • Frida
  3. 辅助工具

    • checksec
    • strings
    • xxd/hexdump

8. 总结流程

  1. 初步文件分析(file, checksec, strings)
  2. 静态反汇编(IDA/Ghidra)
  3. 识别关键代码区域
  4. 动态调试验证
  5. 数据提取与转换
  6. 结果验证

通过这套方法,可以有效分析包含隐藏网络连接的Shellcode或恶意代码,提取出关键的IP和端口信息。

Shellcode动态分析实战教学文档 1. 二进制文件初步分析 1.1 文件基本信息分析 首先使用 file 命令查看二进制文件的基本信息: 关键信息: ELF : Linux系统下最常见的可执行文件格式 64-bit : x86-64架构 LSB : 小端字节序 pie executable : 位置无关可执行文件,加载时可随机分配内存地址 1.2 安全机制检查 使用 checksec 检查文件的安全保护机制: 安全机制说明: RELRO(Relocation Read-Only) : 重定位表只读保护 Stack Canary : 栈溢出检测机制 NX(No-eXecute) : 不可执行内存保护 PIE(Position-Independent Executable) : 位置无关可执行文件 2. 静态分析 2.1 字符串分析 使用 strings 命令查找可能的明文IP和端口信息: 2.2 IDA Pro静态分析 将文件拖入IDA Pro,自动识别架构 查看导入表,寻找网络相关函数(如connect等) 分析main函数流程 关键发现: IP地址不是明文存储 通过 memcpy 将数据复制到内存中 需要动态调试获取实际IP和端口信息 3. 动态调试分析 3.1 GDB调试准备 启动GDB: 查看文件入口点: 在入口点设置断点: 运行程序: 3.2 调试过程 删除初始断点(如果需要): 使用 ni (next instruction)步过指令: 重复执行直到看到main函数地址(可连续按回车) 使用 si (step into)步入main函数: 在main函数地址设置断点(例如0x55555555540a): 继续执行到断点: 使用 n (next)重复执行直到看到 call rax 指令 进入 call rax : 3.3 关键数据获取 继续执行直到看到 syscall 指令 观察寄存器中的值,特别是: 连接相关的系统调用(如connect) IP地址和端口信息(通常以16进制形式存储) 4. 数据转换与分析 4.1 IP地址转换 从调试中获取的16进制IP地址需要转换为点分十进制格式: 转换方法: 将16进制值转换为小端序 每8位(2个16进制数字)转换为一个十进制数 4.2 端口号转换 端口号通常以网络字节序(大端)存储: 5. Shellcode分析技巧 5.1 识别Shellcode特征 观察不寻常的系统调用序列 查找网络操作相关的系统调用(socket, connect, send等) 注意加密或编码的数据区域 5.2 动态分析要点 内存转储 :在关键点转储内存内容 寄存器监控 :关注系统调用前的寄存器设置 RAX: 系统调用号 RDI, RSI, RDX: 参数 调用跟踪 :使用 backtrace 查看调用栈 6. 常见挑战与解决方案 6.1 反调试技术应对 检测调试器 :修改环境变量或使用 catch syscall ptrace 代码混淆 :结合静态和动态分析,关注实际执行路径 时间延迟 :设置断点跳过无关代码 6.2 PIE处理技巧 使用GDB的 pie 命令: 在程序加载后获取实际地址: 使用相对地址设置断点 7. 工具链推荐 静态分析 : IDA Pro Ghidra Radare2 动态分析 : GDB(增强版:GEF/PEDA/Pwndbg) strace/ltrace Frida 辅助工具 : checksec strings xxd/hexdump 8. 总结流程 初步文件分析(file, checksec, strings) 静态反汇编(IDA/Ghidra) 识别关键代码区域 动态调试验证 数据提取与转换 结果验证 通过这套方法,可以有效分析包含隐藏网络连接的Shellcode或恶意代码,提取出关键的IP和端口信息。