课程简介

我在之前的课程中讨论过W32Dasm这款软件中的漏洞分析与利用的方法,由于使用该软件的人群毕竟是小众群体,因此该漏洞的危害相对来说还是比较小的。但是如果漏洞出现在Windows系统中,那么情况就会很不一样了。毕竟Windows统治了全球九成以上的计算机操作系统,因此如果该系统中出现了漏洞,而这个漏洞又被别有用心者所利用,那么就必然会出现数以亿计的受害者。
课程介绍
  • 实验环境:
  • 操作机: Windows XP
  • 实验工具:
Tools
Path
IDA Pro
C:\Tools\Ida61
Dependency Walker
C:\Tools\ Depends
  • 实验文件:
  • Netapi32.dll
利用IDA Pro静态分析漏洞出现的原因。
实验步骤
第一步 下载实验文件
请访问http://tools.ichunqiu.com/5db600f6下载实验文件。
小i提示:
  • 在本次实验中,请注意实验工具、实验文件存放路径,不同的文件路径可能会出现不一样的实验结果。
  • 在实验环境中无法连接互联网,请使用您本地的网络环境。
快速查找实验工具
  • 打开桌面 Everything 搜索工具,输入实验工具名称,右击选择“打开路径”,跳转实验工具所在位置。
  • 以查找BURP为例为大家演示。
第二步 MS06-040漏洞基本信息
其实,微软的安全技术中心所公布的漏洞是所有安全工作者和黑客们最为感兴趣的地方。每当微软发布一个补丁,修复了一个漏洞,总会有许多的攻击者通宵达旦地去研究这些补丁都修补了哪些漏洞,并写出漏洞利用程序。因为在补丁刚刚发布的一段时间内并非所有用户都能及时修复,所以这种新公布的漏洞会很有利用价值。对于这些攻击者而言,虽说他们的行为很不光彩,但是他们这种去挖掘漏洞的毅力,还是值得钦佩的。毕竟微软的漏洞公告,仅仅给出了一个大概的方向,而漏洞的具体细节,比如漏洞出现在哪个函数,该如何利用这个漏洞等等细节,是根本就没有透露的。这就和之前我们讨论的W32Dasm的漏洞报告很不一样,后者已经具体到了一个特定的函数,因此我们只要找到究竟是哪个位置的函数出现了问题即可。而通过微软的漏洞报告,我们一般至多只能够知道漏洞出现在哪一个动态链接库中,具体到究竟是该动态链接库中的哪一个函数,就需要我们自己去寻找了。由于动态链接库中可能包含有众多的导出函数,所以很多时候定位漏洞出现的位置就如同大海捞针,是需要极大的耐心甚至还包含有运气成分的。 依据微软的漏洞报告,我们知道出现问题的是Netapi32.dll这个动态链接库:
在该动态链接库中有一个名为NetpwPathCanonicalize()的导出函数:
这个函数存在着缓冲区溢出的缺陷,也正是我们重点关注的对象。
第三步 静态分析漏洞出现的原因
既然已经知道了出现漏洞的函数,那么下一步可以使用IDA Pro来分析一下漏洞出现的原因。事实上,在NetpwPathCanonicalize()函数中有一个名为sub_7517FC68的函数,出现溢出隐患的正是在这个函数内部:
下面就是对这个函数反汇编代码的分析:
.text:7517FC68 ; Attributes: bp-based frame
.text:7517FC68 ; int __stdcall sub_7517FC68(wchar_t *Source, wchar_t *Str, int, int, int)
.text:7517FC68 sub_7517FC68 proc near ; CODE XREF: NetpwPathCanonicalize+74p
.text:7517FC68 var_416 = word ptr -416h
.text:7517FC68 Dest = word ptr -414h
.text:7517FC68 Source = dword ptr 8
.text:7517FC68 Str = dword ptr 0Ch
.text:7517FC68 arg_8 = dword ptr 10h
.text:7517FC68 arg_C = dword ptr 14h
.text:7517FC68 arg_10 = dword ptr 18h
; 本函数中一共有五个参数和两个局部变量
.text:7517FC68 push ebp
.text:7517FC69 mov ebp, esp
.text:7517FC6B sub esp, 414h
; 开辟0x414字节大小的空间,用于存放生成的字符串
.text:7517FC71 push ebx
.text:7517FC72 push esi
.text:7517FC73 xor esi, esi
.text:7517FC75 push edi
.text:7517FC76 cmp [ebp+Source], esi
; 验证参数Source是否为0
.text:7517FC79 mov edi, ds:__imp_wcslen
.text:7517FC7F mov ebx, 411h
; 在本函数中,ebx的值不变,恒为0x411,用于检查是否越界
.text:7517FC84 jz short loc_7517FCED
; 依据上面的Source与0的比较结果来判定是否跳转
.text:7517FC86 push [ebp+Source] ; Str
.text:7517FC89 call edi ; __imp_wcslen
; 计算参数Source的长度,注意这里是Unicode形式的长度
.text:7517FC8B mov esi, eax
; esi保存的是参数Source的Unicode形式的长度
.text:7517FC8D pop ecx
.text:7517FC8E test esi, esi
.text:7517FC90 jz short loc_7517FCF4
; 验证参数Source的长度是否为0
.text:7517FC92 cmp esi, ebx
; 验证参数Source的长度是否大于0x411
.text:7517FC94 ja loc_7517FD3E
; 如果大于,则退出程序
.text:7517FC9A push [ebp+Source] ; Source
.text:7517FC9D lea eax, [ebp+Dest]
.text:7517FCA3 push eax ; Dest
.text:7517FCA4 call ds:__imp_wcscpy
; 将参数Source字符串拷贝到新分配的空间中。需要注意的是,这里开辟的是0x414字节的空间,
; 但是上述代码检测的却是宽字符,宽字符的0x411相当于0x822字节的空间。看似这是可以
; 利用的漏洞,但是在本函数调用之前,程序已经使用了NetpwPathType()函数用于检测参
; 数Source的长度,使其不能超过0x206个字节,因此这里是不能被当做漏洞利用的。
.text:7517FCAA mov ax, [ebp+esi*2+var_416]
; 取出字符,检查是否为斜杠
.text:7517FCB2 pop ecx
.text:7517FCB3 cmp ax, 5Ch ; 0x5C表示的是“\”
.text:7517FCB7 pop ecx
.text:7517FCB8 jz short loc_7517FCD5
.text:7517FCBA cmp ax, 2Fh ; 0x2F表示的是“/”
.text:7517FCBE jz short loc_7517FCD5
.text:7517FCC0 lea eax, [ebp+Dest]
.text:7517FCC6 push offset asc_751717B8 ; "\\"
.text:7517FCCB push eax ; Dest
.text:7517FCCC call ds:__imp_wcscat
; 将斜杠与字符串进行连接
.text:7517FCD2 pop ecx
.text:7517FCD3 inc esi
; 由于加入了斜杠,所以字符串的长度增加1
.text:7517FCD4 pop ecx
.text:7517FCD5
.text:7517FCD5 loc_7517FCD5: ; CODE XREF: sub_7517FC68+50j
.text:7517FCD5 ; sub_7517FC68+56j
.text:7517FCD5 mov eax, [ebp+Str]
.text:7517FCD8 mov ax, [eax]
.text:7517FCDB cmp ax, 5Ch ; 0x5C表示的是“\”
.text:7517FCDF jz short loc_7517FCE7
.text:7517FCE1 cmp ax, 2Fh ; 0x2F表示的是“/”
.text:7517FCE5 jnz short loc_7517FCF4
.text:7517FCE7
.text:7517FCE7 loc_7517FCE7: ; CODE XREF: sub_7517FC68+77j
.text:7517FCE7 add [ebp+Str], 2
.text:7517FCEB jmp short loc_7517FCF4
.text:7517FCED ; ------------------------------------------------------------
.text:7517FCED loc_7517FCED: ; CODE XREF: sub_7517FC68+1Cj
.text:7517FCED mov [ebp+Dest], si
.text:7517FCF4
.text:7517FCF4 loc_7517FCF4: ; CODE XREF: sub_7517FC68+28j
.text:7517FCF4 ; sub_7517FC68+7Dj ...
.text:7517FCF4 push [ebp+Str] ; Str
.text:7517FCF7 call edi ; __imp_wcslen
; 计算参数Str的长度,注意这里是Unicode形式的长度
.text:7517FCF9 add eax, esi
; 这里计算的是加上了斜杠的参数Source与Str长度的总和,该长度保存在eax中
.text:7517FCFB pop ecx
.text:7517FCFC cmp eax, ebx
.text:7517FCFE ja short loc_7517FD3E
; 对连接后的字符串长度进行检查,经过之前的分析可以知道,仅仅依靠参数Source是不能够
; 实现漏洞的利用的,因为它的长度被限定在了0x206个字节,但是程序并没有对参数Str的
; 长度进行足够的限定,利用这一点就可以实现漏洞的利用。
.text:7517FD00 push [ebp+Str] ; Source
.text:7517FD03 lea eax, [ebp+Dest]
.text:7517FD09 push eax ; Dest
.text:7517FD0A call ds:__imp_wcscat
; 字符串连接,将参数Str连接到缓冲区中,也正是这个函数,导致了缓冲区的溢出
.text:7517FD10 pop ecx
.text:7517FD11 lea eax, [ebp+Dest]
.text:7517FD17 pop ecx
.text:7517FD18 push eax
.text:7517FD19 call sub_7518AE95
.text:7517FD1E lea eax, [ebp+Dest]
.text:7517FD24 push eax ; Str
.text:7517FD25 call sub_7518AEB3
.text:7517FD2A test eax, eax
.text:7517FD2C jnz short loc_7517FD43
.text:7517FD2E lea eax, [ebp+Dest]
.text:7517FD34 push eax
.text:7517FD35 call sub_7518AFE2
.text:7517FD3A test eax, eax
.text:7517FD3C jnz short loc_7517FD43
.text:7517FD3E
.text:7517FD3E loc_7517FD3E: ; CODE XREF: sub_7517FC68+2Cj
.text:7517FD3E ; sub_7517FC68+96j
.text:7517FD3E push 7Bh
.text:7517FD40 pop eax
.text:7517FD41 jmp short loc_7517FD7A
.text:7517FD43 ; ------------------------------------------------------------
.text:7517FD43 loc_7517FD43: ; CODE XREF: sub_7517FC68+C4j
.text:7517FD43 ; sub_7517FC68+D4j
.text:7517FD43 lea eax, [ebp+Dest]
.text:7517FD49 push eax ; Str
.text:7517FD4A call edi ; __imp_wcslen
.text:7517FD4C lea eax, [eax+eax+2]
.text:7517FD50 pop ecx
.text:7517FD51 cmp eax, [ebp+arg_C]
.text:7517FD54 jbe short loc_7517FD66
.text:7517FD56 mov ecx, [ebp+arg_10]
.text:7517FD59 test ecx, ecx
.text:7517FD5B jz short loc_7517FD5F
.text:7517FD5D mov [ecx], eax
.text:7517FD5F
.text:7517FD5F loc_7517FD5F: ; CODE XREF: sub_7517FC68+F3j
.text:7517FD5F mov eax, 84Bh
.text:7517FD64 jmp short loc_7517FD7A
.text:7517FD66 ; ------------------------------------------------------------
.text:7517FD66 loc_7517FD66: ; CODE XREF: sub_7517FC68+ECj
.text:7517FD66 lea eax, [ebp+Dest]
.text:7517FD6C push eax ; Source
.text:7517FD6D push [ebp+arg_8] ; Dest
.text:7517FD70 call ds:__imp_wcscpy
.text:7517FD76 pop ecx
.text:7517FD77 xor eax, eax
.text:7517FD79 pop ecx
.text:7517FD7A
.text:7517FD7A loc_7517FD7A: ; CODE XREF: sub_7517FC68+D9j
.text:7517FD7A ; sub_7517FC68+FCj
.text:7517FD7A pop edi
.text:7517FD7B pop esi
.text:7517FD7C pop ebx
.text:7517FD7D leave
.text:7517FD7E retn 14h
.text:7517FD7E sub_7517FC68 endp
.text:7517FD7E
如上所述,程序对字符串的长度限定是unicode的0x411个字符,也就是0x822个字节,而程序仅仅分配了0x414个字节的空间,于是就出现了缓冲区溢出的隐患。 对于函数sub_7517FC68而言,它有两个参数是需要我们特别留意的,一个是Source,另一个是Str。由于前者已经被限定了长度,最多只能0x206个字节,所以我们只能拿后者做文章。那么这两个参数在NetpwPathCanonicalize()函数中是什么形态呢?经过分析可知,Str这个参数正是NetpwPathCanonicalize()函数的第一个参数,而Source则是第四个参数:
也就是说,我们可以构造一个程序,让它加载Netapi32.dll这个动态链接库,并调用其中的NetpwPathCanonicalize()函数,精心构造这个函数的第一和第四个参数的内容,那么就可以实现漏洞的利用了。
第四步 函数NetpwPathCanonicalize()说明
其实经过上述分析,我们就可以知道NetpwPathCanonicalize()函数的大概功能了。其实关于这个函数,微软是没有给我们任何介绍的,现在对于这个函数功能的讲解,都是前辈们通过类似于我们上述的逆向分析而总结出来的。由此可见,逆向工程确实是计算机领域中最富挑战性的工作之一。 函数NetpwPathCanonicalize()用于格式化网络路径字符串,其定义如下:
void NetpwPathCanonicalize(
_in_ dword Str, // +8h
_out_ dword lpWideCharStr, // +0Ch
_in_ dword arg_8, // +10h
_in_ dword Source, // +14h
_in_out_ dword arg_10, // +18h
_in_ dword arg_14 // +1Ch
);
参数说明:
Str:指向Unicode字串的指针,用于生成路径字串的第二部分。
lpWideCharStr:指向buffer的指针,用于接收格式化后的字符串。
arg_8:表明lpWideCharStr的大小
Source:指向Unicode字串的指针,用于生成路径字串的第一部分。
arg_10:指向long的指针。
arg_14:标志位,一般为0。
函数的功能是把Source指的字符串,加上‘\’,再加上Str指的字符串,放在lpWideCharStr的buffer里。即
Source + ‘\’ + Str => lpWideCharStr[arg_8]
第五步 小结
经过上述一系列的分析,我们已经弄清楚了漏洞出现的原因以及利用方法。那么对于这个漏洞的实际利用,我会在下一次的讲解中,结合动态调试,编程实现。
 

MS06-040漏洞研究(上)【转载】的更多相关文章

  1. Winamp栈溢出漏洞研究【转载】

    课程简介 Winamp是一款非常经典的音乐播放软件,它于上世纪九十年代后期问世.与现在音乐播放软件行业百家争鸣的情况不同,当时可以说Winamp就是听音乐的唯一选择了,相信那个时代的电脑玩家是深有体会 ...

  2. MS17-010 漏洞研究——免考课题 20155104 赵文昊

    免考实验与研究--MS17-010漏洞研究 研究内容 ·MS17-010漏洞的来源 ·MS17-010漏洞的攻击实例 ·MS17-010漏洞原理分析 ·MS17-010代码分析 写在前面:这次对一个漏 ...

  3. fastjson反序列化漏洞研究(上)

    前言 最近护网期间,又听说fastjson传出“0day”,但网上并没有预警,在github上fastjson库中也有人提问关于fastjson反序列化漏洞的详情.也有人说是可能出现了新的绕过方式.不 ...

  4. MS06-040漏洞研究(下)【转载】

    课程简介 经过前两次的分析,我们已经对Netapi32.dll文件中所包含的漏洞成功地实现了利用.在系统未打补丁之前,这确实是一个非常严重的漏洞,那么打了补丁之后,这个动态链接库是不是就安全了呢?答案 ...

  5. MS06-040漏洞研究(中)【转载】

    课程简介 经过上次的分析,我们已经知道了MS06-040漏洞的本质,那么这次我们就通过编程实现漏洞的利用. 课程介绍 实验环境: 操作机: Windows XP 实验工具: Tools Path ID ...

  6. Fastjson反序列化漏洞研究

    0x01 Brief Description java处理JSON数据有三个比较流行的类库,gson(google维护).jackson.以及今天的主角fastjson,fastjson是阿里巴巴一个 ...

  7. 盗墓笔记—阿里旺旺ActiveX控件imageMan.dll栈溢出漏洞研究

    本文作者:i春秋作家——cq5f7a075d 也许现在还研究Activex就是挖坟,但是呢,笔者是摸金校尉,挖坟,呸!盗墓是笔者的本职工作. 额,不扯了,本次研究的是阿里旺旺ActiveX控件imag ...

  8. Android浮窗权限研究(转载)

    这篇博客主要介绍的是 Android 主流各种机型和各种版本的悬浮窗权限适配,但是由于碎片化的问题,所以在适配方面也无法做到完全的主流机型适配,这个需要大家的一起努力,这个博客的名字永远都是一个将来时 ...

  9. 缓冲区溢出分析第09课:MS06-040漏洞研究——深入挖掘

    前言 经过前两次的分析,我们已经对Netapi32.dll文件中所包含的漏洞成功地实现了利用.在系统未打补丁之前,这确实是一个非常严重的漏洞,那么打了补丁之后,这个动态链接库是不是就安全了呢?答案是否 ...

随机推荐

  1. MySQL基础知识:创建MySQL数据库和表

    虚构一个微型在线书店的数据库和数据,作为后续MySQL脚本的执行源,方便后续MySQL和SQL的练习. 在虚构这个库的过程中,主要涉及的是如何使用命令行管理 MySQL数据库对象:数据库.表.索引.外 ...

  2. Learn Python the Hard Way,ex37-2

    本练习为复习python的符号和关键字 数据类型有:True False None Strings numbers floats lists dict tuple set ""&q ...

  3. FreeBSD 宣布 2020 年第 4 季度状态报告

    FreeBSD 宣布 2020 年第 4 季度状态报告● 继续努力从 FreeBSD 基本系统中移除 GPL 协议的软件,以实现 FreeBSD 项目基本目标.● Linux 二进制兼容层的 Linu ...

  4. WPF 基础 - Window 启动动画

    <Window ... WindowStyle="None" AllowsTransparency="True" RenderTransformOrigi ...

  5. Java volatile关键字详解

    Java volatile关键字详解 volatile是java中的一个关键字,用于修饰变量.被此关键修饰的变量可以禁止对此变量操作的指令进行重排,还有保持内存的可见性. 简言之它的作用就是: 禁止指 ...

  6. TensorFlow2.0使用方法

    TensorFlow2.0 1 使用技巧 更新到最新版本: pip install --upgrade tensorflow pip install --upgrade tensorflow-gpu ...

  7. 新的颜色对比度算法-感知对比度算法APCA

    目录 对比度 在控制台查看 插件或网站 感知对比度算法(APCA) APCA Math 原理 js 实现的 SAPC 最后 灵感的源泉来源于不断的接受新鲜事物. Chrome 89 新功能一览,性能提 ...

  8. Java并发编程之基础理论

    内存模型   主内存.工作内存与Java堆.栈.方法区并不是同一个层次的内存划分 勉强对应起来 从定义来看,主内存对应Java堆中对象实例数据部分,工作内存对应虚拟机栈中部分区域 从更低层次来说,主内 ...

  9. golang 性能调优分析工具 pprof(下)

    golang 性能调优分析工具 pprof(上)篇, 这是下篇. 四.net/http/pprof 4.1 代码例子 1 go version go1.13.9 把上面的程序例子稍微改动下,命名为 d ...

  10. Spring Boot 轻量替代框架 Solon 1.3.15 发布

    Solon 是一个微型的Java开发框架.项目从2018年启动以来,参考过大量前人作品:历时两年,4000多次的commit:内核保持0.1m的身材,超高的跑分,良好的使用体验.支持:RPC.REST ...