
本书是一本介绍二进制分析相关工具及其应用的图书,共分为五大部分,内容涵盖了ELF 二进制代码的生成、Linux 环境下分析二进制文件的相关工具、静态的二进制代码分析、动态的二进制代码分析、Intel Pin 的架构及工具的制作、污点分析技术及实现、约束求解原理与应用、符号执行技术及应用、模糊测试技术及实现、常见的系统攻击及系统对软件的常见保护措施、常见的软件漏洞的检测等。
系统安全涉及的范围比较广,从身份验证到数据加密,从防火墙到入侵检测系统,从内核安全到应用软件安全,从CPU 安全到内存安全和文件安全,从虚拟机到信任和能力系统等,都是系统安全的研究范畴。 本书仅从二进制代码安全性的角度介绍与Linux 系统安全相关的内容。 二进制代码安全性分析是逆向工程中的一种技术,通过对可执行的机器代码(二进制代码)来分析应用程序的相关信息,有助于从业人员,尤其是信息安全界的工作人员更好地分析软件中可能存在的漏洞、病毒和脆弱性,从而找到相应的解决方案。 本书主要介绍二进制代码安全性分析的相关工具及其应用,以可执行文件的生成、信息的收集与脆弱性分析、漏洞的利用,以及系统的安全保护措施为主线,主要的内容包括二进制代码的生成、Linux 系统下二进制代码信息收集的相关工具、静态的二进制代码分析、二进制代码脆弱性评估、二进制代码漏洞利用。上述内容涵盖了Linux 系统下分析二进制代码的常见工具、Intel Pin 架构及工具的制作、污点分析技术及实现、约束求解原理及应用、符号执行技术及应用、模糊测试技术及应用、常见的软件漏洞的检测方法、漏洞利用方法及系统对软件的常见保护措施等。 本书内容是作者讲授“系统安全原理与实践”课程的部分讲义。作者在讲授该课程的过程中发现,学生的理论知识和技术原理掌握得比较好,但要将理论知识和技术原理付诸实践还有一定的困难。大家往往没有抓手,即使有了抓手,也不知道如何解决在形成和运行最终代码的过程中碰到的各种各样问题。针对这种情况,本书穿插了作者亲自实践过的软件源码,并对源码的关键部分进行了说明。这些源码是和具体的技术原理对应的,相信通过本书的学习,能够加深读者对理论知识和技术原理的理解与掌握,为成为一名高水平的信息安全从业人员打下坚实的基础。 本书适合具有一定Linux 系统知识,以及C 语言和汇编语言编程基础的信息安全专业人员阅读。本书的部分内容涉及CTF(Capture The Flag,夺旗赛)的逆向和漏洞挖掘,对于想参与CTF 的同学也有一定的参考价值。 信息安全的技术发展日新月异,新的方法和工具在不断涌现,而作者水平及所了解的情况有限,因此书中难免有不少欠妥乃至错误之处,恳请广大读者和专家批评指正。 作者 2023 年5 月于红果园
第1 章概述................................ ........................................1 1.1 Linux 系统安全........................ .......................................1 1.2 代码安全.........................·..........................................1 1.3 什么是二进制代码安全性分析......................................................2 1.4 二进制代码安全性分析的重要性...................................................2 1.5 二进制代码安全性分析的主要步骤.................................................2 1.6 软件错误、漏洞以及利用...........................................................2 1.6.1 软件错误.....................................................................2 1.6.2 软件漏洞.....................................................................3 1.6.3 漏洞利用.....................................................................3 1.6.4 二进制代码利用.............................................................4 第2 章二进制代码生成...............................................................5 2.1 二进制代码的生成过程.............................................................5 2.1.1 编译预处理阶段.............................................................6 2.1.2 编译阶段.....................................................................6 2.1.3 汇编阶段.....................................................................6 2.1.4 链接阶段.....................................................................8 2.1.5 gcc 的常用选项..............................................................11 2.1.6 ld 的常用选项...............................................................17 2.1.7 gcc 的常用环境变量.........................................................21 2.1.8 二进制代码的生成举例......................................................21 2.2 ELF 文件格式.................·...........................................26 2.2.1 ELF文件的两种视图.......................................................27 2.2.2 ELF 文件的头...............................................................27 2.2.3 可执行文件的主要节........................................................29 2.2.4 位置无关代码................................................................33 2.2.5 ELF 文件的头...............................................................42 2.2.6 ELF 文件的主要段..........................................................43 2.3 程序的装载与调度执行.............................................................47 2.3.1 可执行文件的装载...........................................................47 2.3.2 可执行文件调度运行的过程................................................48 2.3.3 进程的虚拟地址空间及其访问..............................................49 第3 章二进制代码信息的收集.......................................................54 3.1 nm ...........................................................................54 3.2 ldd ..........................·........................................54 3.3 strings ..........................·.............................................55 3.4 ELF 文件分析工具LIEF ...........................................................55 3.4.1 安装..........................................................................55 3.4.2 基于LIEF 对.got.plt 表的攻击举例........................................55 3.4.3 基于LIEF 将可执行文件转变为共享库文件...............................59 3.5 ps ............................. .............................................61 3.6 strace ....................................................................61 3.7 ltrace ....................................................................62 3.8 ROPgadget..........................·..................................62 3.9 objdump...............................................................63 3.10 readelf..............................................................65 3.11 GDB ...................................................................66 3.11.1 GDB 的初始化脚本文件...................................................66 3.11.2 GDB 的常用命令..........................................................66 3.11.3 GDB 的常用命令示例.....................................................67 3.11.4 GDB 命令的运行..........................................................79 3.11.5 GDB 命令的扩充..........................................................82 3.11.6 PEDA 基本使用...........................................................92 3.12 Pwntools ...........................................................97 3.12.1 Pwntools 的安装...........................................................97 3.12.2 通过上下文设置目标平台..................................................98 3.12.3 本地进程对象的创建.......................................................98 3.12.4 远程进程对象的创建.......................................................99 3.12.5 ELF 模块...................................................................99 3.12.6 search 方法................................................................·100 3.12.7 cyclic 命令的功能.........................................................·101 3.12.8 核心文件..................................................................·102 3.12.9 数据转换..................................................................·104 3.12.10 struct 模块...............................................................·105 3.12.11 shellcraft 模块...........................................................·106 3.12.12 ROP 模块................................................................·108 3.12.13 GDB 模块................................................................·112 3.12.14 DynELF 模块............................................................·113 3.12.15 基于标准输入/输出的数据交互.........................................·116 3.12.16 基于命名管道的数据交互...............................................·118 3.12.17 脚本文件和被测目标程序的交互........................................·125 3.12.18 基于Python 脚本文件的Pwntools 应用举例..........................·125 3.13 LibcSearcher ...........................................................·127 第4 章静态二进制代码分析.........................................................·130 4.1 基于IDAPro 的静态分析..........................................................·130 4.1.1 IDC 脚本文件..............................................................·130 4.1.2 IDAPython 脚本文件......................................................·138 4.1.3 IDAPython 脚本文件示例.................................................·140 4.1.4 IDAPro 插件的编写........................................................·142 4.2 基于Radare2 的静态分析.........................................................·148 4.2.1 r2 的常用命令..............................................................·148 4.2.2 r2 常用命令示例...........................................................·150 4.2.3 r2 对JSON 格式数据的处理..............................................·156 4.2.4 基于r2pipe 的脚本文件编写..............................................·159 4.2.5 基于r2pipe 的脚本文件执行..............................................·163 第5 章二进制代码脆弱性评估......................................................·164 5.1 常见二进制代码脆弱性............................................................·164 5.1.1 栈溢出的原理...............................................................·165 5.1.2 堆溢出的原理...............................................................·165 5.2 基于系统工具对代码脆弱性的评估................................................·184 5.2.1 基于Clang Static Analyzer 的安全检测..................................·184 5.2.2 Linux 系统下堆安全的增强措施...........................................·187 5.3 基于Intel Pin 的代码脆弱性评估.................................................·192 5.3.1 插桩模式....................................................................·193 5.3.2 插桩粒度....................................................................·202 5.3.3 Intel Pintools 的编写......................................................·204 5.3.4 分析代码的过滤............................................................·215 5.3.5 Pintools 的生成............................................................·220 5.3.6 Pintools 的测试............................................................·224 5.3.7 Pintools 应用示例:缓冲区溢出的检测...................................·225 5.4 基于符号执行的代码脆弱性评估..................................................·234 5.4.1 符号执行的原理............................................................·234 5.4.2 符号执行的优、缺点.......................................................·239 5.4.3 基于Angr 的二进制代码分析.............................................·239 5.5 基于污点分析的代码脆弱性评估..................................................·281 5.5.1 污点分析原理...............................................................·282 5.5.2 污点分析的分类............................................................·283 5.5.3 污点分析相关概念..........................................................·284 5.5.4 基于Clang 静态分析仪的污点分析应用..................................·286 5.5.5 基于Pin 的动态污点分析..................................................·287 5.6 基于模糊测试的代码脆弱性评估..................................................·297 5.6.1 模糊测试的方式............................................................·298 5.6.2 内存模糊测试...............................................................·299 5.6.3 libFuzzer....................................................................·313 第6 章二进制代码漏洞利用.........................................................·320 6.1 二进制代码加固技术及其gcc 编译选项...........................................·320 6.1.1 二进制代码保护措施的查看...............................................·321 6.1.2 去掉可执行文件中的符号的方法..........................................·322 6.1.3 Linux 中的NX 机制.......................................................·322 6.1.4 Canary 栈保护.............................................................·323 6.1.5 RELRO 机制...............................................................·327 6.1.6 地址空间布局随机化.......................................................·329 6.1.7 PIE 保护机制..............................................................·333 6.1.8 绕过PIE 保护机制的方法.................................................·335 6.1.9 RPATH 和RUNPATH ....................................................·341 6.1.10 RPATH 存在的安全问题.................................................·342 6.1.11 FORTIFY 保护机制......................................................·343 6.1.12 ASCII-Armor 地址映射保护机制........................................·350 6.1.13 二进制代码保护技术比较.................................................·352 6.2 缓冲区溢出漏洞的利用............................................................·353 6.2.1 ret2shellcode ...............................................................·366 6.2.2 ret2Libc 攻击...............................................................·383 6.2.3 ret2plt ......................................................................·391 6.2.4 .got 表覆盖技术............................................................·402 6.2.5 ROP 攻击..................................................................·410 6.2.6 被测目标程序的代码被执行多次的多阶段攻击...........................·438 6.2.7 被测目标程序的代码被执行一次的多阶段攻击...........................·455 6.3 基于Angr 的缓冲区溢出漏洞自动利用...........................................·464 6.3.1 任意读......................................................................·464 6.3.2 任意写......................................................................·468 6.3.3 任意跳转....................................................................·475 附录A 数据对齐问题...........................·.................................·479 附录B 函数调用约定..............................................................·485 附录C 栈帧原理................................................................·497 附录D 32 位系统与64 位系统中程序的区别....................................·507 附录E 共享库链接的路径问题.......................................................·510 附录F 在多模块中使用ld 手动链接生成可执行文件...........................·514 附录G 在C++ 程序中调用C 函数的问题......................................·518 附录H Linux 死机的处理............................................................·522 附录I Python 文件默认的开头注释格式........................................·523