CVE-2020-25291-金山WPS Office远程堆损坏漏洞

发布于 2021-09-23  322 次阅读


WPS Office由位于珠海的中国软件开发商金山软件开发,是一款面向微软Windows、macOS、Linux、iOS、Android的办公套件。WPS办公室由三个主要组件组成:WPS编写器、WPS演示文稿和WPS电子表格。个人基本版可以免费使用。WPS软件存在远程执行代码的漏洞,这是在分析特制的Office文件时对内存中的对象处理不当造成的。成功利用此漏洞的攻击者可以在当前用户的上下文中运行任意代码。失败可能导致拒绝服务。易受攻击的产品WPS Office,影响版本11.2.0.9453。

漏洞分析

在WPS Office中用于图像格式解析的Qt模块中发现堆损坏。嵌入WPS office的特制图像文件可能会触发此漏洞。当打开特制的文档文件时,将触发访问冲突。EDX是指向数组的指针,而EAX是指向数组的索引。

0:000> g

(c50.b4): Access violation - code c0000005 (first chance)

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=000000c0 ebx=006f1c48 ecx=cd2aefbc edx=cd2c6f80 esi=2ed7ae18 edi=0000001c

eip=6ba13321 esp=006f1b44 ebp=006f1b44 iopl=0 nv up ei pl nz na po nc

cs=0023ss=002bds=002bes=002bfs=0053gs=002b efl=00210202

QtCore4!QMatrix::dy+0x48a8:

6ba13321 8b448210mov eax,dword ptr [edx+eax*4+10h] ds:002b:cd2c7290=????????

崩溃是如何触发的?让我们看一下PNG标头格式。

00029E30FF 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44ÿ‰PNG........IHD

00029E4052 00 00 02 80 00 00 01 C6 04 03 00 00 00 16 0AR...€...Æ.......

00029E5027 FC 00 00 00 04 67 41 4D 41 00 00 B1 88 95 98'ü....gAMA..±ˆ•˜

00029E60F4 A6 00 00 00 30 50 4C 54 45 00 00 00 80 00 00ô¦...0PLTE...€..

00029E7000 80 00 80 80 00 00 00 80 80 00 80 00 80 80 80.€.€€...€€.€.€€€

00029E8080 80 C0 C0 C0 FF 00 00 00 FF 00 FF FF 00 00 00€€ÀÀÀÿ...ÿ.ÿÿ...

00029E90FF FF 00 FF 00 FF FF FF FF FF 7B 1F B1 C4 00 00ÿÿ.ÿ.ÿÿÿÿÿ{.±Ä..

从偏移量0x29E31开始-0x29E34是PNG文件格式的签名标头。PNG头文件的结构:

PNG signature --> IHDR --> gAMA --> PLTE --> pHYs --> IDAT --> IEND

在这种情况下,当WPS Office Suite中使用的QtCore库解析PLTE结构并触发堆损坏时,该漏洞存在于Word文档中嵌入的PNG文件中。在偏移量0x29E82到0x29E85处,调色板的解析失败,这触发了堆中的内存损坏。崩溃触发前的堆栈跟踪:

00 00ee1790 6b8143ef QtCore4!path_gradient_span_gen::path_gradient_span_gen+0x6a71

01 00ee17f0 6b814259 QtCore4!QBrush::setMatrix+0x234

02 00ee58d4 6b8249a4 QtCore4!QBrush::setMatrix+0x9e

03 00ee58ec 6b80cc84 QtCore4!QImage::rect+0x22b

04 00ee5908 6b857ccc QtCore4!QTransform::inverted+0xec8

05 00ee629c 6b81c55b QtCore4!QSvgFillStyle::setFillOpacity+0x1b59

06 00ee6480 6b896844 QtCore4!QPainter::drawPixmap+0x1c98

07 00ee6574 6d1e0fbd QtCore4!QPainter::drawImage+0x325

08 00ee6594 6d0dd155 kso!GdiDrawHoriLineIAlt+0x11a1a

在QtCore4解析嵌入的图像之前,我们可以看到来自KSO模块的最后一个调用,试图处理图像kso!GdiDrawHoriLineIAlt .用IDA Pro分解应用分析异常功能。的最终崩溃路径如下(WinDBG结果):

QtCore4!QMatrix::dy+0x48a8:

6ba13321 8b448210mov eax,dword ptr [edx+eax*4+10h] ds:002b:cd2c7290=????????

在IDA Pro中打开时,我们可以试试按以下方式反汇编该函数:

.text:67353315 pushebp

.text:67353316 mov ebp, esp

.text:67353318 movzx eax, byte ptr [ecx+edx]; crash here

.text:6735331C mov ecx, [ebp+arg_0]

.text:6735331F mov edx, [ecx]

.text:67353321 mov eax, [edx+eax*4+10h]

.text:67353325 mov ecx, eax

使用崩溃转储中的信息,我们知道应用程序在0x67353321 (mobile eax,[edx+eax * 4+10h])触发了访问冲突。我们可以看到,EAX寄存器由0xc0值控制。因此,从这里,我们可以根据导致异常的指令对寄存器的状态做出一些假设。需要注意的是,在异常发生之前,我们可以看到包含在ECX(0xc0)中的值被写入由以下指令定义的任何位置


公交车司机终于在众人的指责中将座位让给了老太太