最近在学习堆的溢出原理,但是查了网上和书上的一些讲解,总是感觉缺少一些关键点。所以理解起来总是有点晕,经过努力的调试分析后,总结了下面的更为详细的堆溢出原理。如果不准确的地方,希望大佬可以提醒一哈~

1.堆的结构:

struct _LIST_ENTRY{DWORD Flink;DWORD Blink;
}
//空闲堆头结构
struct _HEAP_FREE_ENTRY{union{struct{union{struct {WORD Size;BYTE Flags;BYTE SmallTagIndex;}DWORD SubSegmentCode;}WORD PreviousSize;union{BYTE SegmentOffset;BYTE LFHFlags;}BYTE UnusedBytes;};struct{union{struct {WORD FunctionIndex;WORD ContextValue;};DWORD InterceptorValue;};WORD UnusedBytesLength;BYTE EntryOffset;BYTE ExtendedBlockSignature;};struct{DWORD Code1;WORD  Code2;BYTE  Code3;BYTE  Code4;};ULONGLONG AgregateCode;};_LIST_ENTRY FreeList;
}//已使用堆的头结构
struct _HEAP_ENTRY{//这个结构只比_HEAP_FREE_ENTRY少了一个FreeList;
}
//上面的结构不是百分百正确的,这些都是通过WinDbg调试猜的。

下面这个是winDbg中的数据结构截图。

这两个结构仅仅就差了个FreeList

2.堆溢出原理

当堆溢出发生时,可能会将后面的堆结构全部覆盖掉。而后面的堆有可能是个使用过的_HEAP_ENTRY,也有可能是一个空闲堆_HEAP_FREE_ENTRY。

如果当后面是一个空闲堆时,就可以将_HEAP_FREE_ENTRY最后的FreeList结构覆盖成自己想要的数据。而FreeList是一个_LIST_ENTRY结构。这个结构中有两个成员,分别是Flink和Blink。分别表示的是上一个空闲堆和下一个空闲堆。

那么关键来了,当你调用HeapFree释放刚刚使用的堆时,就会触发一种机制,就是将释放的堆与后面的空闲堆相合并。但此时后面的空闲堆已经被你污染覆盖了。而在合并的过程中,他会修改空闲堆Blink和Flink所指向的空闲堆中的FreeList,以便让前后的空闲堆衔接在一起(因为空闲堆就是一个双向链表,当某一个节点发生改变时,你就要需要把前面的节点指针和后面的节点指针都重新做一遍调整,也就是重新连接双链表节点)。

这个机制就直接导致了堆溢出利用的可能性。因为不管是什么溢出,我们最终的目的都是控制EIP,就是覆盖栈中的返回地址。而到现在,可能还有人没有意识到问题的严重性,那么继续。

假设:需要释放的堆为A,后面被覆盖污染的空闲堆为B。

此时被污染覆盖的空闲堆B中的Flink/Blink已经是我们可以随意修改的地址。那么当释放的堆A和污染空闲堆B进行合并时,会变成一个更大的空闲堆C,那么此时空闲堆C的首地址就会发生改变,所以需要重新连接空闲堆链表。想要重新连接,就需要找到上一个空闲堆,然后并将其中的Blink修改为合并后空闲堆C的首地址。可能已经有人感觉到一丝丝的不寻常了,继续。

因为合并后的空闲堆C中的Flink和Blink是我们可以随意修改的。这就导致上一个空闲堆是我们可以随便指定的。而系统根本不知道我们会指向那里,他依旧会傻傻的去修改所指向地方的Blink。假如此时我们将空闲堆C中的Flink地址覆盖成栈地址。那么他就会把栈当成上一个空闲堆。然后去栈中寻找Blink的位置,并将其修改为空闲堆C的首地址。虽然我们的堆A已经释放了,但里面的数据还在啊,系统可不会勤快的置空呢。而空闲堆C的首地址,其实就是堆A的首地址。因为A和B合并时,其实就是把B叠在了A的屁股后面。

释放了一个有用堆。然后他会和后面的空闲堆合并在一起。而且空闲堆首地址也改变了。

而A中是有我们自己的数据的。这样就可以将栈中的数据覆盖成我们自己的数据,甚至长度算好了也可以覆盖栈中的返回地址。

OK,这就是堆的溢出原理啦。如果有错误的地方,希望大家指正。

漏洞学习笔记——堆溢出原理相关推荐

  1. C语言学习笔记——堆区空间申请(一)

    C语言学习笔记 堆区空间申请(一) 栈区变量分析 所有程序/软件的运行,都是由操作系统统一调配的,操作系统是程序的运行环境 运行中的多个程序之间,内存是不交叉的 程序结束后,操作系统还要释放其使用的资 ...

  2. 【pwn学习】堆溢出(三)- Unlink和UAF

    前置学习 [pwn学习]堆溢出(一) [pwn学习]堆溢出(二)- First Fit 文章目录 什么是Unlink? Unlink如何利用? 加入错误检查 什么是Use-After-free? 例题 ...

  3. APP安全漏洞学习笔记

    APP安全漏洞学习笔记 本文首先明确了APP安全的目标,然后对常见的APP漏洞进行了整理分析,并研究学习了APK的静态分析与动态分析技术,最后介绍了安卓的渗透测试技术和常见的安全评估工具.附录处整理了 ...

  4. 华为HCIA-datacom 学习笔记11——AAA原理与配置

    华为HCIA-datacom 学习笔记11--AAA原理与配置 AAA原理与配置 1.AAA概述 认证(authentication):验证用户是否获得访问权,确定哪些用户可以访问网络 授权(auth ...

  5. TI CC1101学习笔记:工作原理简单入门

    众所周知,在IOT的市场应用中,从通信协议细分的话,有SUB-1G,2.4G,3G, 4G,以及最新推出的5G,虽然5G通信协议已经在崭露头角,但是不同的通信协议在不同的应用领域之中还是占据着一定的重 ...

  6. 【pwn学习】堆溢出(一)

    文章目录 什么是堆溢出 基本示例 堆分配函数 堆填充长度 堆攻击总结 学习这部分之前,如果对堆的基础还不甚了解可以参考一下下面的学习笔记 Linux堆管理基础知识(一) Linux堆管理基础知识(二) ...

  7. Hacking Team Flash 0day漏洞学习笔记

    周日的夜晚,与囧桑下载下来Hacking Team之前爆出的flash 0day漏洞,怀着紧张激动的心情,在自己的机子上做了实验,经测试,在我的虚拟机(一个sp3的XP,貌似没装Flash)上根本跑不 ...

  8. CVE-2020-15999:Chrome FreeType 字体库堆溢出原理分析

     聚焦源代码安全,网罗国内外最新资讯! 漏洞简介 Google发布公告,旧版本的 chrome 浏览器的 FreeType字体库中存在堆溢出,被利用可能导致 RCE(远程代码执行). 安全专家建议用户 ...

  9. Sqlite学习笔记(四)SQLite-WAL原理(转)

    Sqlite学习笔记(三)&&WAL性能测试中列出了几种典型场景下WAL的性能数据,了解到WAL确实有性能优势,这篇文章将会详细分析WAL的原理,做到知其然,更要知其所以然. WAL是 ...

最新文章

  1. poj3259(SPFA算法)
  2. 爬虫--pyquery使用
  3. C#指针使用学习总结
  4. 关于GC.Collect在不同机器上表现不一致问题
  5. 交通银行签约第四范式,建设全行级统一AI能力平台
  6. 创建一个dynamics 365 CRM online plugin (四) - PreValidation
  7. git stash命令的用法
  8. c++string替换指定位置字符_Lua 字符串
  9. 【渝粤教育】国家开放大学2018年秋季 1137t医院管理 参考试题
  10. 当我们群嘲假博士时,不要忘了真博士们的艰辛
  11. 景驰科技与联通实现全国首个5G网络下L4级无人驾驶应用
  12. C#预处理器指令【转】
  13. Windows的cmd中如何关闭端口
  14. SVN报错The working copy needs to be upgraded
  15. 也许你不知道:越自我,越自由!
  16. iOS16 中的 3 种新字体宽度样式
  17. JAVA毕业设计vue健康餐饮管理系统设计与实现计算机源码+lw文档+系统+调试部署+数据库
  18. 【报告分享】 2020年中国汽车用户消费洞察白皮-懂车帝巨量算数(附下载)
  19. ERP系统在元器件贸易企业中的应用
  20. 我的世界服务器没有显示物品ID,我的世界物品ID不显示怎么办

热门文章

  1. 《Head First Java》
  2. 只有高中学历的我是怎样加入谷歌的?
  3. 安卓day25快速入门 目录结构 清单 DDMS adb 危险权限 发短信 点击事件 安卓版本...
  4. Android快速入门
  5. 字母排列问题 (20分)
  6. 操作列表(创建、遍历、统计、解析、切片、复制)
  7. pythonic风格_【Python进阶】Pythonic风格整理
  8. pythonic_pythonic方式
  9. 智能车竞赛技术报告 | 节能信标组 - 安徽工业大学 - 摸鱼大队
  10. 新款车型亮相,零跑汽车带来了新的一面