logo资料库

深入浅出MS06-040(看雪网络版).pdf

第1页 / 共33页
第2页 / 共33页
第3页 / 共33页
第4页 / 共33页
第5页 / 共33页
第6页 / 共33页
第7页 / 共33页
第8页 / 共33页
资料共33页,剩余部分请下载后查看
前言
1 浅出篇
1.1 逆向,永恒的主题
1.2 IDA,迷宫的地图
1.3 OLLYDBG,庖丁解牛
1.4 shellcode DIY
2 深入篇
2.1 初识,RPC的玄机
2.2 Hacking,远程攻击
2.3 踏雪无痕,寄存器状态的恢复
3 展望篇
3.1 魔波,蠕虫现身!
3.2 补丁,无洞可钻?
附件清单
解读西方 诠释失败 敬请关注:《0day 安全:软件漏洞分析与利用》《加密与解密 3》 敬请关注 2008 年“看雪”新书 《0day 安全:软件漏洞分析与利用》 failwest 《加密与解密第 3 版》 kanxue 电子工业出版社 看雪论坛倾力打造
解读西方 诠释失败 敬请关注:《0day 安全:软件漏洞分析与利用》《加密与解密 3》 声明 本文曾发表于《黑客防线》2006 年第 10 期。看雪论坛为作者授权的唯一发布网站。 之用,转载请注明作者及引用看雪论坛相应 链接。 形 式 用 于 任 何 赢 利 目 的 的 组 织 、 机 构 与 培 训。 本文谨用于漏洞分析技术爱好者学习研究 本文不得在作者未经许可的情况下以任何
解读西方 诠释失败 敬请关注:《0day 安全:软件漏洞分析与利用》《加密与解密 3》 深入浅出 MS06-040 ——To be the apostrophe which changed "Impossible" into "I'm possible" ! failwest 目录 1.1 1.2 1.3 1.4 前言.................................................................................................................................................... 4 1 浅出篇........................................................................................................................................ 5 逆向,永恒的主题...................................................................................................... 5 IDA,迷宫的地图........................................................................................................ 6 OLLYDBG,庖丁解牛 .............................................................................................. 10 shellcode DIY........................................................................................................... 13 2 深入篇...................................................................................................................................... 21 初识,RPC的玄机 .................................................................................................... 21 Hacking,远程攻击 ................................................................................................... 24 踏雪无痕,寄存器状态的恢复................................................................................ 25 3 展望篇...................................................................................................................................... 28 魔波,蠕虫现身!.................................................................................................... 28 补丁,无洞可钻?.................................................................................................... 29 附件清单.......................................................................................................................................... 32 2.1 2.2 2.3 3.1 3.2
解读西方 诠释失败 敬请关注:《0day 安全:软件漏洞分析与利用》《加密与解密 3》 前言 时至今日,网上已有颇多 MS06-040 的文章,其中不乏精辟之作。与其相比,本文突显业 余,技术上无法超越,徒逞口舌之快。然而对于普通的学生和技术爱好者来说,离漏洞挖掘和利 用的路还是相当遥远的。回想自己当年拜读安焦和绿盟的文章时那种纵使滔滔的仰慕之情也无法 掩盖的抓狂的感觉,我决定还是基础一点,把给导师的漏洞分析报告写成了这么一篇实验教 程:) 本文适合有一定计算机基础,初步了解溢出攻击原理,稍微了解逆向技术的朋友阅读。如果 您根据本文的指导亲手完成了全部的 7 节实验内容,相信您对栈溢出的掌握和漏洞利用的认识一 定会到一个更高的 level。 文章组织如下: 第一章主要讨论 MS06-040 的溢出原理和本地溢出实验。其中:1.1 中介绍了本地溢出实验 的环境要求和 MS06-040 的一些基础知识;1.2 中结合反汇编代码对漏洞进行静态分析;1.3 中 结合动态调试进一步了解漏洞函数调用时的栈空间状态;1.4 中则手把手的教你制作自己的 shellcode,并完成对 MS06-040 的本地溢出实验。 第二章主要讨论 MS06-040 的远程利用实验。2.1 中介绍了 RPC 调用的一些基础知识,这 也是远程利用 RPC 系列漏洞的基础,有相关的分布式计算编程经验的朋友可以跳过这一节;2.2 中实现远程攻击;2.3 中进一步讨论从 shellcode 返回到正常程序时,寄存器状态恢复的问题,在 这一节中,我们将结束本文中的实验部分。 第三章在完成实验的基础上,做了一些展望。3.1 中简介了利用 MS06-040 传播的蠕虫病毒 魔鬼波以及学术界对蠕虫研究的概况;3.2 中结合从安全焦点技术峰会上听到的业界动向和自己 研究工作的体会,谈了一下我个人对漏洞挖掘这个领域的研究前景和研究价值的一些看法。 本文实验中涉及的所有细节均可重现,使用的源代码都已经过详细的注释附于附录之中。所 有代码都已调试通过,个别依赖于机器和操作系统版本的函数地址已在文章中特别指出,并指明 了计算方法。 如果您发现文章中的分析或代码有不妥之处,欢迎来信与我讨论MS06-040 及其他安全问 题。( failwest@gmail.com ) 好了,现在让我们立刻去体会把“Impossible”变成“I’m possible”的那一撇是怎么画进 WINDOWS 里的吧。
解读西方 诠释失败 敬请关注:《0day 安全:软件漏洞分析与利用》《加密与解密 3》 1 浅出篇 ——欲善其事,先利其器 思考许久,为了让更多的人能够享受到实验的乐趣,我还是决定用一些篇幅来介绍几个在本 章的实验中涉及到的逆向工具。没有工具的 hacker 如同没有枪的战士,欲善其事,先利其器! 1.1 逆向,永恒的主题 MS06-040 打破了 RPC 系列安全问题许久的寂静,魔波的出现恰好戏剧性的给即将上市的 vistal 安全体系做了免费广告。 勿庸置疑,这是一个被犇人们玩了很久的 0day,发现漏洞的犇人肯定不会浮躁到写个蠕虫 出来炫耀的。从技术角度看,真正应该引起关注的应该是漏洞而不是蠕虫。在学习的过程中找不 到第一手的漏洞资料一直困扰着我,想想在漆黑的夜里肯定还有无数和我经历类似,满腔热情但 却无从下手的做着黑客梦的朋友,我决定详细的分析下这个漏洞。 不巧由于参加安焦的 X’Con 峰会耽误了一个星期,一圈玩回来,网上已经满是 MS06-040 的 exploits 版本和介绍,几乎家喻户晓了。但我想,如果能够亲手分析调试一遍,走一下漏洞利 用的全部流程,不管是安全工作者还是学习黑客技术的发烧友,肯定都会受益匪浅的。 微软 POST 出的漏洞信息是没有技术细节的,一般都是几句简短的类似“XXXX 可能存在 允许远程代码执行的漏洞”之类的话。光靠这些是没有办法利用,渗透,入侵,控制的。详细技 术资料其实是很难搜到的,因为那都是安全专家和 hacker 们辛苦的研究成果,当然今天讨论的 MS06-040 除外。要想第一时间研究和利用漏洞,你需要查出漏洞对应的补丁号,追查这个补丁 patch 了哪几个系统文件的哪几个部分,然后进行逆向分析。IDA 就有类似用途的比较 BIN 文件 差异的插件。 下面我们来关注 MS06-040。这个漏洞指的是 windows 系统的 DLL 文件 netapi32.dll 中的几 个导出函数在字符串复制时有边界检查的缺陷。本文的实验和分析都基于 WIN2000 SP4 版本的 操作系统,它也是这个漏洞危害最严重的操作系统版本。 要 获 得 这 个 DLL 文 件 才 有 的 玩 。 在 WIN2000 SP4 中 , Netapi32.dll 位 于 系 统 目 录 c:\winnt\system32 下,大小为 309008 字节。如果你的系统已经打过补丁,则该文件会被补丁替 换 , 大 小 为 309520 字 节 , 原 先 的 漏 洞 DLL 会 备 份 到 系 统 目 录 下 的 c:\winnt\$NtUninstallKB921883$ 里。不管是从别人机器上拷贝还是在卸载目录下寻找,要完成 本章的实验,都需要得到这个 DLL 文件。当然为了方便您的研究和实验调试,我为您在本文的 附加资料中提供了这个 DLL。 让我们来初步认识一下这个 DLL。用诸如 LordPE、PETools 之类的 PE 工具查看下导出表, 有 317 个导出函数,很多都是我们耳熟能详的调用。要想看看这个 DLL 应用有多广泛的话,可
解读西方 诠释失败 敬请关注:《0day 安全:软件漏洞分析与利用》《加密与解密 3》 Netapi32.dll 库中第 303 个导出函数 NetpwPathCanonicalize()用于格式化网络路径字符 以用大名鼎鼎的 sysinternals 出品的 Process Explorer 查一下当前加载了这个库的进程,你会发现 什么 svchost、 service、winlogin,、lsass 之类的只要有网络操作的进程都会使用这个库。 MS06-040 实际上包含了 Netapi32.dll 中几个有溢出问题的函数,本文实验以目前讨论最多的 NetpwPathCanonicalize()函数的溢出为例进行阐述。 串, 它需要 6 个参数: 参数 1:指向一个 UNICODE 字串的指针,用于生成路径字串的第二个部分 参数 2:指向一个 buffer 的指针,用于接收格式化后的路径字串 参数 3:指向一个数字的指针,标明参数 2 所指 buffer 的大小 参数 4:指向一个 UNICODE 字串的指针,用于生成路径字串的第一个部分 参数 5:指针,在漏洞利用中不起作用 参数 6:标志位,必需为 0 这个函数大体功能是把参数 4 所指的字串(以后简称 4 号串)连接上’/’作为路径分割,再连 上参数 1 所指字串(后简称 1 号串),并将生成的这个新串拷回参数 2 所指的 buffer,也就是返 回给 2 号 buffer 如下形式的字串: 4 号串 + ‘/’ + 1 号串 这个函数在格式化字符串时的函数调用 CanonicalizePathName()使用 WCSCPY()进行字符 串拷贝时,边界检查有缺陷,可以被构造栈溢出。 关于 NetpwPathCanonicalize()函数的细节资料是很难找到的,MSDN 上没有任何介绍,甚至 在 GOOGLE 上也只是在 srvsvc 的接口定义文件 IDL 里看到了函数声明。在这种情况下要利用这 个函数只有靠自己逆向分析了。上面这些说明就是我用 IDA 把它反汇编后分析、总结出来的, 在本小节中提前摆出来是为了让您在阅读后面这节的汇编代码时提前有一个全局观。如果哪些朋 友发现有不对的地方,请不吝指正。 一定要坚信,求人不如靠自己。不管你是 cracker 还是 hacker,不管你做外挂、做脱壳、做 病毒分析、还是做 exploit 的开发人员,要获得第一手资料都离不开逆向技术。就算微软公布源 码,逆向技术仍然是安全领域里永恒不变的主题。 1.2 IDA,迷宫的地图 在大体了解了漏洞的位置之后,我们需要进行调试,需要获得具体的栈空间信息以及漏洞被 触发时的寄存器信息。进入一个 PE 文件就好像置身一个错综复杂的迷宫,光靠动态调试器的分 析是远远不够的。IDA 强大的静态分析和标注功能则是这个迷宫的地图,他能为你的调试导 航。用 IDA 能迅速定位代码,我用的是 IDA pro 5.0 版本,里边甚至还对函数内部提供了流程图 的生成。
解读西方 诠释失败 敬请关注:《0day 安全:软件漏洞分析与利用》《加密与解密 3》 IDA 5.0 一般默认有 9 个标签窗口,依次是 PE 文件对应的 16 进制 IDA View-A Hex View-A Exports Imports Names Functions Strings Structures Enums 反汇编代码窗口 导出函数列表 导入函数列表 命名列表 函数名列表 字符串列表 结构体列表 枚举列表 下面我们就用 IDA 来看看这个神秘的 NetpwPathCanonicalize()函数到底干什么用的。安装好 了后,把我们的问题 DLL 直接丢进 IDA,忽悠忽悠几下,它就分析出结构明确质量上乘的汇编 代码了。这里要庆幸的是我们研究的是微软的系统 API 文件,用 C 语言编写并且没有任何加壳 之类的保护,所以得到的结果如此优美,几乎所有的函数都自动标注好了。 我们直接去 Exports 窗口在最后几行找到我们需要分析的 NetpwPathCanonicalize,双击就跳 到了这个导出函数对应的代码部分,按下空格键汇编代码将以流程图的形式显示出来,给阅读者 一个全局的把握。 指南针介绍到此为止,后面的分析就要靠人肉了。这个函数并不复杂,可以看到生成新串的 过程实际是在 CanonicalizePathName()内完成(.text:7517F856 call sub_7517FC68)。这个函数 使用局部变量,在栈内开空间暂存新串,这块空间可被溢出。 具体说来,NetpwPathCanonicalize()在调用 CanonicalizePathName()前的动作包括: (ERROR_INVALID_NAME),引起程序退出 5.验证接收 buffer 的大小是否为 0,否则退出 6.调用 CanonicalizePathName()函数 …… ============================ S U B R O U T I N E ============================= 7517FC68 int __stdcall sub_ CanonicalizePathName (wchar_t *,wchar_t *,wchar_t *,int,int) 7517FC68 push ebp 7517FC69 mov ebp, esp 7517FC6B sub 7517FC71 push ebx 1.判断第 6 个参数是否为 0,不为 0 则退出 2.判断第 5 个参数所指值是否为 0,为 0 则进行一次 NetpwPathType 的验证调用 3.判断第 4 个参数所指值是否为 0,若不为 0 则将所指字串放入 NetpwPathType 进行验证。 4.在这次验证中,如果 4 号串 unicode 长度超过 0x103(字节长度为 0x206),则返回 0x7B CanonicalizePathName()为实际发生溢出的函数,下面用 IDA 重点看一下这个函数: esp, 414h //开辟栈内空间,用于暂存生成的字符串
解读西方 诠释失败 敬请关注:《0day 安全:软件漏洞分析与利用》《加密与解密 3》 esi, esi [ebp+arg_0], esi //判断4号串地址是否为空 //4号串地址 //栈中暂存串起址 loc_7517FD3E //若越界则退出程序 7517FC72 push esi 7517FC73 xor 7517FC75 push edi 7517FC76 cmp 7517FC79 mov edi, ds:__imp_wcslen 7517FC7F mov ebx, 411h short loc_7517FCED 7517FC84 jz //压入4号串 7517FC86 push [ebp+arg_0] //计算4号串的unicode长度,注意为字节长度的一 edi ; __imp_wcslen 7517FC89 call //半,这是导致边界检查被突破的根本原因,即 //用UNICODE检查边界,而栈空间是按字节开的 7517FC8B mov esi, eax 7517FC8D pop ecx esi, esi 7517FC8E test 7517FC90 jz short loc_7517FCF4 7517FC92 cmp esi, ebx 7517FC94 ja 7517FC9A push [ebp+arg_0] 7517FC9D lea eax, [ebp+var_414] 7517FCA3 push eax 7517FCA4 call ds:__imp_wcscpy //将4号串拷入栈中暂存串。虽然前面的边界 7517FCAA mov ax, [ebp+esi*2+var_416] //取出此刻暂存串(4号串)的最后两个字节,检 7517FCB2 pop ecx 7517FCB3 cmp ax, 5Ch //0x5C=92=ASCII(\) 7517FCB7 pop ecx 7517FCB8 jz 7517FCBA cmp ax, 2Fh //0x2F=47=ASCII(/) short loc_7517FCD5 7517FCBE jz eax, [ebp+var_414] 7517FCC0 lea 7517FCC6 push offset asc_751717B8 7517FCCB push eax 7517FCCC call ds:__imp_wcscat //把斜杠的unicode连接到栈中暂存串的末尾 7517FCD2 pop ecx 7517FCD3 inc 7517FCD4 pop ecx 7517FCD5 mov eax, [ebp+arg_4] //检查有缺陷,似乎实际可以传入的4号串可以达 //到0x822字节,但是4号串在传入本函数前被 //NetpwPathType()提前检查过,按照前面的分析 //知道,四号串的长度不能超过0x206字节,所以 //光靠这里的检查缺陷还不足以通过4号串制造溢 //出 //取出1号串,类似的检查1号串的首字符是否是 //斜杠或反斜杠 esi //把斜杠的长度计入暂存串 //压入斜杠的unicode short loc_7517FCD5 //查是否是斜杠
分享到:
收藏