二进制安全
0day2
01 基础知识
02 栈溢出原理和利用
03 shellcode 开发
其它
某固件提取资产网络指纹数据
利用异常的思路
x64 shellcode 内存加载器
本文档使用 MrDoc 发布
-
+
首页
01 基础知识
## 漏洞概述 - 漏洞分类: 1. **功能性逻辑缺陷(bug)**:影响软件的正常功能,例如,执行结果错误、图标显示错误等。 2. **安全性逻辑缺陷(漏洞)**:通常情况下不影响软件的正常功能,但被攻击者成功利用后,有可能引起软件去执行额外的恶意代码。常见的漏洞包括软件中的缓冲区溢出漏洞、网站中的跨站脚本漏洞(XSS)、 SQL 注入漏洞等。 - 普遍采用的漏洞挖掘方法是 **Fuzz**,这实际是一种“灰”盒测试。 - 漏洞的公布: 1. **CVE** 2. **CNVD** ## 二进制文件概述 - PE文件格式:[PE 文件结构图](https://crackmes.cn/doc/19/) - 常见的数据节 ``` .text 由编译器产生,存放着二进制的机器代码,也是我们反汇编和调试的对象。 .data 初始化的数据块,如宏定义、全局变量、静态变量等。 .idata 可执行文件所使用的动态链接库等外来函数与文件的信息。 .rsrc 存放程序的资源,如图标、菜单等。 ``` - 物理内存: - 物理内存比较复杂,需要进入 Windows 内核级别 ring0 才能看到。通常,在用户模式下,我们用调试器看到的内存地址都是**虚拟内存**。 ![](/media/202404/2024-04-28_145814_6083110.31510135972930087.png) - PE 文件与虚拟内存之间的映射: - 静态反汇编工具看到的 PE 文件中某条指令的位置是相对于磁盘文件而言的,即所谓的**文件偏移**,我们可能还需要知道这条指令在内存中所处的位置,即虚拟**内存地址(VA)**。 - 基本概念: 1. **文件偏移地址(File Offset)** 数据在 PE 文件中的地址叫文件偏移地址,是文件在磁盘上存放时相对于文件开头的偏移。 2. **装载基址(Image Base)** PE 装入内存时的基地址。默认情况下, EXE 文件在内存中的基地址是 0x00400000, DLL 文件是 0x10000000。这些位置可以通过修改编译选项更改。 3. **虚拟内存地址(Virtual Address, VA)** PE 文件中的指令被装入内存后的地址。 4. **相对虚拟地址(Relative Virtual Address, RVA)** 相对虚拟地址是内存地址相对于映射基址的偏移量。 重点关注:`VA= Image Base+ RVA` - 文件与内存映射关系: ![](/media/202404/2024-04-28_150506_8471040.7178686102667872.png) - 为什么 RVE 和文件偏移会有区别: - 这些差异是由于文件数据的存放单位与内存数据存放单位不同而造成的: 1. PE 文件中的数据按照磁盘数据标准存放,以 0x200 字节为基本单位进行组织。当一个数据节(section)不足 0x200 字节时,不足的地方将被 0x00 填充;当一个数据节超过 0x200 字节时,下一个 0x200 块将分配给这个节使用。因此 PE 数据节的大小永远是 0x200 的整数倍。 2. 当代码装入内存后,将按照内存数据标准存放,并以 0x1000 字节为基本单位进行组织。类似的,不足将被补全,若超出将分配下一个 0x1000 为其所用。因此,内存中的节总是0x1000 的整数倍。 - 实际上是在 PE 头中定义了: ![](/media/202404/2024-04-28_151009_9912730.4687587848973723.png) - 下面举例说明 | 节 | RVA | 文件偏移量 | | :---: | :---: | :---: | | .text | 0x00001000 | 0x0400 | | .rdata | 0x00007000 | 0x6200 | | .data | 0x00009000 | 0x7400 | | .rsrc | 0x0002D000 | 0x7800 | - 我们把这种由存储单位差异引起的节基址差称做**节偏移**,在上例中:(**这个概念千万别和文件偏移混淆!!!!!**) ``` .text 节偏移=0x1000-0x400=0xc00 .rdata 节偏移=0x7000-0x6200=0xE00 .data 节偏移=0x9000-0x7400=0x1C00 .rsrc 节偏移=0x2D000-0x7800=0x25800 ``` - `有重要计算公式如下:` ``` 文件偏移地址 = 虚拟内存地址(VA) − 装载基址(Image Base) - 节的RVA + 节的文件地址 = 虚拟内存地址(VA) − 装载基址(Image Base) - (节的RVA - 节的文件地址) = 虚拟内存地址(VA) − 装载基址(Image Base) − 节偏移 = RVA -节偏移 ``` ## 常用工具 - OD - WinDbg - IDA - 二进制编辑器(Winhex,010editor等) - VMWare - PE 分析工具(DIE,PEInfo等) ## Crack 小实验 ```c #include <stdio.h> #define PASSWORD "1234567" int verify_password (char *password) { int authenticated; authenticated=strcmp(password,PASSWORD); return authenticated; } main() { int valid_flag=0; char password[1024]; while(1) { printf("please input password: "); scanf("%s",password); valid_flag = verify_password(password); if(valid_flag) { printf("incorrect password!\n\n"); } else { printf("Congratulation! You have passed the verification!\n"); break; } } } ``` - 编译结果下载[【附件】crackme.rar](/media/attachment/2024/04/crackme.rar),尝试修改研究。书中给了三种修改方法(IDA 静态修改,OD 动态分析,010 editor 修改),建议都尝试一遍。 - 给个提示:文件修改的话,使用 PE 文件分析工具找到节的虚拟地址和文件地址计算节偏移,然后进一步计算指令的位置: ![](/media/202404/2024-04-28_154034_1263140.6153703415675748.png) ``` 文件偏移地址 = 虚拟内存地址( VA)- 装载基址( Image Base)- 节偏移 = 0x0040106E-0x00400000-(0x00001000-0x00001000) = 0x106E ``` - 解体方法:修改如下跳转为 jmp 即可 ![](/media/202404/2024-04-28_153015_3155650.09211297805863305.png) ![](/media/202404/2024-04-28_153028_3482020.74566950905833.png)
别卷了
2024年4月28日 15:56
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码