Lucene search

K
talosTalos IntelligenceTALOS-2015-0065
HistoryOct 21, 2015 - 12:00 a.m.

Network Time Protocol Password Length Memory Corruption Vulnerability

2015-10-2100:00:00
Talos Intelligence
www.talosintelligence.com
13

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

6.5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:S/C:P/I:P/A:P

0.008 Low

EPSS

Percentile

82.0%

Talos Vulnerability Report

TALOS-2015-0065

Network Time Protocol Password Length Memory Corruption Vulnerability

October 21, 2015
CVE Number

CVE-2015-7854

Description

A potential buffer overflow vulnerability exists in the password management functionality of ntp. A specially crafted key file could cause a buffer overflow potentially resulting in memory being modified. An attacker could provide a malicious password to trigger this vulnerability.

Tested Versions

ntp 4.2.8p2

Product URLs

<http://www.ntp.org>

Details

The function MD5auth_setkey() is called in three places: - line 179 in authreadkeys.c - line 202 in authreadkeys.c - line 32 in authusekey.c

void MD5auth_setkey(keyid_t keyno, int keytype, const u_char *key, size_t len)

The function takes 4 arguments, the keyno, keytype, key and len. If a keyno doesn’t exist, then a new key will be allocated based on len. If keyno does exist, the new key will be copied over the old key, using the new length as a size for the strlcpy or memcpy function. The 2 calls in authreadkeys.c have size checks (20 and 32 bytes respectively):

178		if (len &lt;= 20) {	/* Bug 2537 */
				MD5auth_setkey(keyno, keytype, (u_char *)token, len);
			} else {
				char	hex[] = "0123456789abcdef";
				u_char	temp;
				char	*ptr;
				size_t	jlim;

	186			jlim = min(len, 2 * sizeof(keystr));
				…
	202			MD5auth_setkey(keyno, keytype, keystr, jlim / 2);

In the code above, keystr is a 32 byte unsigned character array.

The one in authusekey does not have size checks:

28	len = strlen((const char *)str);
	if (0 == len)
		return 0;

32	MD5auth_setkey(keyno, keytype, str, len);

However it is called twice from the functions sendrequest and passwd in ntpd.c (lines 895 and 1785) and ntpq.c (lines 1217 and 2453). The code to call authusekey is identical in both files. Both functions retrieve the key via a call to getpass which requires console access and only use it for the info_auth_keyid. Below is the code from ntpd.c for the functions sendrequest and passwd respectively:

889	if (!authistrusted(info_auth_keyid)) {
			pass = getpass_keytype(info_auth_keytype);
			if ('\0' == pass[0]) {
				fprintf(stderr, "Invalid password\n");
				return 1;
			}
			authusekey(info_auth_keyid, info_auth_keytype,
				   (u_char *)pass);
			authtrust(info_auth_keyid, 1);
	898	}

	1776	if (pcmd-&gt;nargs &gt;= 1)
			pass = pcmd-&gt;argval[0].string;
		else {
			pass = getpass_keytype(info_auth_keytype);
			if ('\0' == *pass) {
				fprintf(fp, "Password unchanged\n");
				return;
			}
		}
		authusekey(info_auth_keyid, info_auth_keytype, (u_char *)pass);
	1786	authtrust(info_auth_keyid, 1);

Below is the vulnerable code in the MD5auth_setkey function:

530	/*
		 * See if we already have the key.  If so just stick in the
		 * new value.
		 */
		bucket = &key_hash[KEYHASH(keyno)];
		for (sk = *bucket; sk != NULL; sk = sk-&gt;hlink) {
			if (keyno == sk-&gt;keyid) {
				sk-&gt;type = (u_short)keytype;
				secretsize = len;
				sk-&gt;secretsize = (u_short)secretsize;
	#ifndef DISABLE_BUG1243_FIX
				memcpy(sk-&gt;secret, key, secretsize);
	#else
				strlcpy((char *)sk-&gt;secret, (const char *)key,
					secretsize);
	#endif

If a key is set to 20 bytes and later replaced by a key that is 32 bytes or larger, no extra size checks will be performed, the key will simply be copied over the old key, potentially resulting in a heap-based buffer overflow. This allows an attacker to first provide a shorter key and then a longer one. This can be exploited either through the console using the getpass functionality or via the remote configuration facility: specifying a password file where a specific key is set to a short password and then replacing it with one up to 32 bytes in length, causing a buffer overflow.

Credit

Yves Younan and Aleksander Nikolich of Cisco Talos


Vulnerability Reports Next Report

TALOS-2015-0069

Previous Report

TALOS-2015-0064

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

6.5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

SINGLE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:S/C:P/I:P/A:P

0.008 Low

EPSS

Percentile

82.0%