白话二进制漏洞攻击方式第二部分
字数 1357 2025-08-06 08:35:32
二进制漏洞攻击方式详解(第二部分)
0x00 前言
本文是二进制漏洞攻击方式系列的第二部分,将深入探讨权限机制、异常处理以及相关的攻击与防御技术。
0x01 权限与异常处理基础
内核与用户态
- 内核:操作系统的核心,完全控制系统资源(处理器、内存、芯片等)
- 用户态:常规应用程序运行的内存空间
- 特权环:计算机系统采用的分层权限模型(通常4个环)
- 环0:最高权限(内核)
- 环3:最低权限(用户应用程序)
特权转换
- 系统调用(syscall):用户态程序访问特权功能的桥梁
- 异常:当程序尝试越权访问或执行非法操作时触发
- 示例:算术异常(除零)、访问违例等
结构化异常处理(SEH)
- 作用:处理程序运行时的异常情况
- 层次结构:
- 程序自定义的异常处理(如try-catch块)
- 操作系统提供的默认异常处理
- 异常处理流程:
- 异常首先由程序自身的处理程序捕获
- 若未处理,则交由操作系统处理
- 若仍无法处理,程序崩溃
0x02 防御机制:Stack Canaries
原理
- 位置:在局部变量和返回地址之间插入随机值
- 检查时机:函数返回前验证Canary值是否被修改
- 命名来源:类比煤矿中的金丝雀预警机制
工作方式
- 函数开始时在栈上放置随机Canary值
- 函数返回前检查该值
- 若值被修改,立即终止程序
局限性
- 可通过信息泄露绕过(如格式字符串漏洞)
- 仅防御简单的栈溢出攻击
0x03 攻击技术:格式字符串漏洞
格式字符串基础
- printf函数:
printf("格式", 变量) - 常见格式说明符:
%s:字符串%i:整数%x:十六进制值%n:写入已打印字符数到指定地址
漏洞成因
当用户输入直接作为printf的第一个参数时,攻击者可控制格式字符串:
char inputvar[100];
readuserinput(inputvar); // 用户可控输入
printf(inputvar); // 漏洞点:直接使用用户输入作为格式字符串
攻击方式
-
信息泄露:
- 使用
%x泄露栈内容 - 通过多次
%x可获取敏感信息(如Canary值、返回地址)
- 使用
-
任意写:
- 使用
%n向指定地址写入数据 - 可覆盖返回地址或函数指针
- 使用
攻击示例
用户输入: "AAAA%x%x%x"
输出: AAAA41414141[栈内容1][栈内容2]...
用户输入: "[addr]%n"
效果: 向addr地址写入已打印字符数
0x04 攻击技术:SEH Overwrites
原理
- 目标:覆盖结构化异常处理指针
- 步骤:
- 通过溢出覆盖SEH指针
- 触发异常使程序跳转到恶意payload
类比说明
类似保险欺诈:
- 攻击者覆盖合法的"处理程序"(保险条款)
- 触发"异常"(事故)
- 执行恶意代码(获取赔偿)
利用条件
- 能覆盖栈上的SEH结构
- 能触发可控异常
0x05 防御机制:DEP/NX
数据执行保护(Data Execution Prevention)
- 原理:标记内存页为不可执行
- 实现:
- Windows: DEP
- Linux: NX(No-eXecute)位
W^X策略
- 含义:内存页不能同时可写和可执行
- 理想情况:所有内存遵循此策略
- 现实限制:
- 部分合法代码需要动态生成(如JIT编译)
- 兼容性考虑
保护效果
- 阻止栈/堆上的代码执行
- 迫使攻击者使用代码复用技术(如ROP)
总结
本部分详细讲解了:
- 权限分离机制(内核/用户态,特权环)
- 异常处理流程及SEH结构
- Stack Canaries防御原理与局限
- 格式字符串漏洞的成因与利用
- SEH覆盖攻击技术
- DEP/NX防御机制
这些知识构成了二进制安全的基础,理解这些概念对于分析更复杂的漏洞和防御机制至关重要。