pwndbg checksec 命令:在 GDB/LLDB 会话中快速检测二进制安全防护属性
2026/9/15 23:54:51 网站建设 项目流程

pwndbg checksec 命令:在 GDB/LLDB 会话中快速检测二进制安全防护属性

【免费下载链接】pwndbgExploit Development and Reverse Engineering with GDB & LLDB Made Easy项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg

导读

checksec是 pwndbg 提供的一条实用命令,用于在调试会话内直接输出当前目标二进制(或用户指定文件)的安全防护属性,包括 RELRO、栈金丝雀(Stack Canary)、NX、PIE 以及基于 CET 的 SHSTK/IBT 等关键信息。它以 pwntools 的ELF.checksec()为基础实现,能够复用 pwndbg 的颜色主题输出结果。读完本文,你将掌握checksec的完整用法、输出字段含义,以及它在 pwndbg 源码中的实现原理,并能将它与内核加固检查命令kchecksec配合使用。

命令概览与定位

checksec命令属于 pwndbg 命令体系中的MISC(杂项)类别,对应的说明文档位于 docs/commands/misc/checksec.md,命令入口实现在 pwndbg/commands/checksec.py。

在 pwndbg 的 命令索引 中,它的定位是:

checksec- Prints out the binary security settings usingchecksec

一句话概括:当你在调试一个二进制程序时,输入checksec即可在不退出调试器、不借助外部工具的情况下,立刻看到该文件开启了哪些安全机制——这是漏洞利用(Exploit Development)阶段评估攻击面、判断防护强度的常用前置步骤。

语法与参数

命令的完整语法如下:

usage: checksec [-h] [-f FILE]
短参数长参数说明
-h--help显示帮助信息并退出
-f--file指定要运行checksec检查的文件

两种典型用法:

  • 不带参数:检查当前正在调试的程序(GDB 中已加载的目标文件);
  • -f FILE:显式指定任意一个 ELF 文件进行检查,即使该文件当前并未被调试。

从源码看,参数解析由 pwndbg/commands/checksec.py 中的argparse定义:

parser = argparse.ArgumentParser( description="Prints out the binary security settings using `checksec`.", ) parser.add_argument("-f", "--file", type=str, help="Specify the file to run `checksec` on.")

典型输出与字段解读

在调试会话中执行checksec,例如针对/usr/bin/bash,输出形如:

pwndbg> checksec File: /usr/bin/bash Arch: amd64 RELRO: Full RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled SHSTK: Enabled IBT: Enabled

逐字段解读如下:

字段含义说明
File被检查文件的路径未指定-f时为当前调试目标
Arch目标架构amd64i386aarch64
RELRO重定位表只读可能为Full RELROPartial RELRONo RELRO,决定 GOT 表能否被改写
Stack栈金丝雀Canary found表示存在栈保护,No canary found表示可尝试栈溢出
NX不可执行栈NX enabled表示栈页不可执行,限制 shellcode 直接入栈执行
PIE地址随机化PIE enabled表示基址随机化开启,需要配合泄漏绕过
SHSTKShadow Stack(影子栈)CET 特性,返回地址被额外保护,可有效对抗 ROP 中改写返回地址的手法
IBTIndirect Branch Tracking(间接分支跟踪)CET 特性,校验间接跳转目标,限制 ret2plt / 跳板类利用

其中SHSTKIBT属于 Intel CET(Control-flow Enforcement Technology)的两大支柱,在较新工具链编译的二进制上会以Enabled形式出现。攻击者视角下,SHSTK/IBT 开启意味着经典 ROP 链的构造条件大幅收紧,需要在利用设计中专门规避。

实战:两种调用方式

方式一:检查当前调试目标(默认行为)

在 GDB/LLDB 中启动任意程序后直接执行:

pwndbg> checksec

命令会自动确定“当前被调试的可执行文件”。根据 pwndbg/commands/checksec.py 的实现:

@pwndbg.commands.OnlyWithFile def checksec(file: str) -> None: local_path = file or pwndbg.aglib.file.get_proc_exe_file() print(pwndbg.wrappers.checksec.get_raw_out(local_path))
  • 若用户传入-f FILElocal_path取用户指定路径;
  • 否则调用pwndbg.aglib.file.get_proc_exe_file()(见 pwndbg/aglib/file.py),它返回“调试目标文件的本地路径”,从而实现对 GDB 加载目标的自动解析。

方式二:显式指定文件

调试过程中想顺带分析另一个二进制(例如漏洞利用要打的目标版本、或崩溃样本),无需重新加载:

pwndbg> checksec -f /path/to/other/binary

这在对比“当前调试程序”与“待攻击目标”防护差异时非常实用。

无文件加载时的行为

checksec@pwndbg.commands.OnlyWithFile装饰器(定义于 pwndbg/commands/init.py)约束:只有当前会话能够确定目标文件时才执行。当没有加载任何文件时,它会拒绝执行并给出错误提示:

  • 在 QEMU 调试场景下报错:Could not determine the target binary on QEMU.
  • 其他场景下报错:There is no file loaded.

这意味着该命令依赖调试器上下文中存在可解析的 ELF 目标,不能在“空会话”下凭空工作。

源码级原理:与 pwntools 的集成

checksec的输出并非 pwndbg 自行实现,而是基于 pwntools 的pwnlib.elf.ELF.checksec()生成。核心逻辑集中在 pwndbg/wrappers/checksec.py:

def get_raw_out(local_path: str) -> str: elf = ELF(local_path) output = "File:".ljust(10) + elf.path + "\n" output += "Arch:".ljust(10) + elf.arch + "\n" with monkeypatch_pwnlib_term_text(): output += elf.checksec() return output

几个实现细节值得注意:

  1. 列对齐的“魔数 10”File:Arch:两行使用ljust(10)对齐,源码注释明确指出10是 pwntoolself.checksec()内部用于对齐输出的魔数,二者必须保持一致,否则输出会错位。若将来 pwntools 变更对齐宽度,此处的10也需要同步更新。

  2. 颜色输出接管(monkeypatch):pwntools 默认使用自己的pwnlib.term.text配色(红/绿/黄)来标记各防护状态。pwndbg 通过monkeypatch_pwnlib_term_text()上下文管理器,把这些颜色函数临时替换为 pwndbg 自己的配色体系(见 pwndbg/color/message.py 的error/success/warn),从而让checksec的输出与 pwndbg 整体主题风格统一:

    pwnlib.term.text.red = message.error pwnlib.term.text.green = message.success pwnlib.term.text.yellow = message.warn

    离开上下文后立即del恢复,避免污染 pwntools 全局状态。这是一个典型的“第三方库输出风格适配”模式,也提示读者:此处与 pwntools 内部实现强耦合,升级 pwntools 时需要关注兼容性。

  3. 日志静默:模块顶部通过pwnlib.elf.elf.log._logger.disabled = True关闭 pwntools 的日志输出,避免其调试信息混入 pwndbg 的命令结果。

此外,该包装模块还提供了两个独立的判断函数:

  • relro_status(local_path):将 pwntools 的elf.relro取值("Full"/"Partial"/None)映射为人类可读的Full RELRO/Partial RELRO/No RELRO
  • pie_status(local_path):根据elf.pie返回PIE enabledNo PIE

这两个函数可被 pwndbg 其他模块复用,作为独立的防护状态查询接口。

延伸:内核加固检查kchecksec

pwndbg 还提供了一条同族命令kchecksec(文档见 docs/commands/kernel/kchecksec.md,实现见 pwndbg/commands/kchecksec.py),用于检查 Linux 内核的加固配置,而非单个二进制。它需要满足OnlyWhenQemuKernel(QEMU 内核调试环境)与OnlyWhenPagingEnabled两个前提,逐项读取内核 Kconfig 配置并对照一组加固期望值输出。

其检查项覆盖面很广,包括:

  • 栈溢出保护:STACKPROTECTORSTACKPROTECTOR_STRONGSHADOW_CALL_STACK
  • 可写可执行(RWX):STRICT_KERNEL_RWXSTRICT_MODULE_RWXDEBUG_WX
  • ASLR:RANDOMIZE_BASERANDOMIZE_KSTACK_OFFSET_DEFAULT等;
  • 内存分配加固:SLAB_FREELIST_HARDENEDSLAB_FREELIST_RANDOMKFENCE
  • CFI:CFI_CLANG
  • 访问控制:SECURITY_YAMA、SELinux 相关选项;
  • 以及FORTIFY_SOURCEHARDENED_USERCOPYRANDSTRUCT_FULLSTRICT_DEVMEM等数十项杂项加固。

且针对不同架构附加专属检查项:x86 系(i386/x86-64)额外检查X86_SMAPIA32_EMULATIONX86_X32aarch64则检查ARM64_PANARM64_EPANARM64_PTR_AUTHARM64_BTIARM64_MTE等。该命令已有自动化测试覆盖,见 tests/library/qemu_system/tests/test_commands_kernel.py 中的test_command_kchecksec

两者定位互补:checksec面向用户态二进制的安全属性,kchecksec面向内核映像的加固配置,在涉及内核漏洞利用、沙箱逃逸等场景时尤其值得联合使用。

小结

  • checksec在调试器内直接输出目标 ELF 的 RELRO、Canary、NX、PIE、SHSTK、IBT 等防护状态,零切换成本;
  • 默认自动识别当前调试文件,也可用-f FILE指定任意文件;
  • 实现上以 pwntoolsELF.checksec()为引擎,由 pwndbg/wrappers/checksec.py 完成对齐、配色接管与日志静默;
  • 无文件加载或 QEMU 环境下命令会被OnlyWithFile装饰器拦截并提示;
  • 配合kchecksec可从“用户态二进制”与“内核配置”两个层面完成安全评估。

【免费下载链接】pwndbgExploit Development and Reverse Engineering with GDB & LLDB Made Easy项目地址: https://gitcode.com/GitHub_Trending/pw/pwndbg

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询