checksec
2026/5/29工具工具ELFchecksec大约 4 分钟
checksec
链接
是什么
checksec 用来查看 ELF 程序开启了哪些安全保护。
Pwn 题拿到二进制后,第一步通常就是:
checksec ./vuln它能帮助判断利用路线,例如:
- NX 开启:不能直接执行栈上 shellcode,考虑 ROP
- Canary 开启:不能直接覆盖返回地址,先泄露或绕过 Canary
- PIE 开启:程序地址随机化,需要泄露程序基址
- RELRO 开启:GOT 改写是否可行
安装与配置
Kali/Ubuntu 常见环境:
sudo apt update
sudo apt install checksec如果使用 pwntools,也可以:
pwn checksec ./vulnpwndbg 中也常有:
checksec基本用法
查看单个文件
checksec ./vuln使用 pwntools
pwn checksec ./vuln在 Python 脚本里查看
from pwn import *
elf = ELF("./vuln")
print(elf.checksec())输出解读
输出示例
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
RUNPATH: b'./'各字段含义
Arch: 架构
- amd64-64-little: x86_64 小端序
- i386-32-little: x86 32位 小端序
- arm-32-little: ARM 32位
RELRO: 重定位只读保护
- No RELRO: 无保护
- Partial RELRO: GOT 可写
- Full RELRO: GOT 只读
Stack: 栈保护
- No canary: 无栈保护
- Canary found: 有栈保护
NX: 数据执行保护
- NX disabled: 栈可执行(可用 shellcode)
- NX enabled: 栈不可执行
PIE: 地址随机化
- No PIE: 地址固定
- PIE enabled: 地址随机化
RUNPATH: 运行时库搜索路径保护机制详解
NX (No-eXecute)
开启:
- 栈、堆等数据段不可执行
- 不能直接跳转到栈上执行 shellcode
- 需要使用 ROP、ret2libc 等技术
关闭:
- 栈可执行
- 可以直接注入 shellcode
- 但要注意输入限制和坏字符Stack Canary
开启:
- 函数返回前检查 canary 值
- 直接覆盖返回地址会触发检测
- 需要泄露 canary 或寻找其他利用方式
关闭:
- 可以直接覆盖返回地址
- 标准栈溢出利用
绕过方法:
- 泄露 canary 值
- 格式化字符串泄露
- 覆盖 canary 不影响的部分
- 利用 fork 保持 canary 不变PIE (Position Independent Executable)
开启:
- 程序基址随机化
- 每次运行地址不同
- 需要泄露程序地址
关闭:
- 程序基址固定
- 通常从 0x400000 开始(64位)
- 可以直接使用程序中的地址
绕过方法:
- 泄露程序地址
- 利用相对偏移
- 格式化字符串泄露RELRO
No RELRO:
- GOT 表可读可写
- 可以覆盖 GOT 表
Partial RELRO:
- GOT 表可读可写
- 可以覆盖 GOT 表
- 常见配置
Full RELRO:
- GOT 表只读
- 不能覆盖 GOT 表
- 需要其他利用方式
绕过方法:
- 使用 ROP
- 使用 ret2libc
- 利用其他可写内存CTF常用技巧
根据保护判断路线
No Canary + No PIE + NX enabled:
常见 ret2text / ret2libc / ROP
Canary enabled:
先找泄露点,或寻找不覆盖 canary 的利用方式
PIE enabled:
需要泄露程序地址或通过相对偏移构造
Full RELRO:
GOT 基本不可改,考虑泄露、ROP、hook、IO 结构等路线
NX disabled:
可以考虑 shellcode,但仍要看输入过滤和可执行区域不要只看 checksec
checksec 只告诉你保护状态,不告诉你漏洞点。正确流程是:
checksec -> 运行观察 -> 逆向找输入点 -> 崩溃验证 -> 构造利用链组合分析
场景1: No Canary + No PIE + NX + Partial RELRO
→ ret2text / ROP / GOT 覆写
场景2: Canary + PIE + NX + Full RELRO
→ 泄露 canary + 泄露地址 + ROP
场景3: No NX + No PIE
→ shellcode 注入
场景4: 全部开启
→ 需要多个泄露点,复杂利用链checksec + file 组合
checksec ./vuln
file ./vulnfile 告诉你架构、链接方式、是否 stripped。
Python 中使用
from pwn import *
elf = ELF("./vuln")
libc = ELF("./libc.so.6")
# 打印保护状态
print(elf.checksec())
# 获取基址
print(hex(elf.address))
# 获取符号地址
print(hex(elf.symbols["main"]))
print(hex(elf.got["puts"]))
print(hex(elf.plt["puts"]))常见问题
checksec 显示 PIE 开启,但地址看起来固定
可能你看到的是文件偏移,不是运行时地址。运行时基址仍会变化。
Full RELRO 是不是不能利用
不是。Full RELRO 主要限制 GOT 改写,不影响栈溢出、ROP、格式化字符串泄露、堆利用等其他路线。
NX 关闭是不是一定用 shellcode
不一定。shellcode 只是选择之一,如果题目已有 system、win、ROP 条件,也可以走更短路径。
32 位和 64 位区别
64 位:
- 参数通过寄存器传递: rdi, rsi, rdx, rcx, r8, r9
- 地址 8 字节
- 程序基址通常 0x400000
32 位:
- 参数通过栈传递
- 地址 4 字节
- 程序基址通常 0x8048000stripped 和 not stripped
not stripped:
- 保留符号信息
- 函数名可见
- 逆向更容易
stripped:
- 去除符号信息
- 函数名不可见
- 需要逆向分析关联
- 栈、返回地址与控制流
- Canary与绕过
- ROP基础
- ELF、PLT、GOT与libc
- GDB+pwndbg
- pwntools