Lucene search

K
packetstormEric SesterhennPACKETSTORM:141367
HistoryMar 01, 2017 - 12:00 a.m.

X.org Privilege Escalation / Use-After-Free / Weak Entropy

2017-03-0100:00:00
Eric Sesterhenn
packetstormsecurity.com
53

0.002 Low

EPSS

Percentile

51.7%

`  
X41 D-Sec GmbH Security Advisory: X41-2017-001  
  
Multiple Vulnerabilities in X.org  
=================================  
  
Overview  
--------  
Vendor: X.org/Freedesktop.org  
Vendor URL: https://www.x.org/wiki/  
Credit: X41 D-Sec GmbH, Eric Sesterhenn  
Advisory-URL: https://www.x41-dsec.de/lab/advisories/x41-2017-001-xorg/  
Status: Public  
  
  
Timing attack against MIT Cookie  
================================  
Vulnerability Type: Other  
Affected Products: Xorg Server  
Attack Type: Local  
Impact: Escalation of Privileges   
Severity Rating: low  
Confirmed Affected Version: 1.19.0 and lower  
Confirmed Patched Version: -  
Vector: local  
CVE: CVE-2017-2624  
CVSS Score: 5.9  
CVSS Vector: CVSS:3.0/AV:L/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N  
  
  
Summary and Impact  
------------------  
The xorg-server uses memcmp() to check the received MIT cookie against a  
series of valid cookies. If the cookie is correct, it is allowed to  
attach to the Xorg session:  
  
XID  
MitCheckCookie(unsigned short data_length,  
const char *data, ClientPtr client, const char **reason)  
{  
struct auth *auth;  
  
for (auth = mit_auth; auth; auth = auth->next) {  
if (data_length == auth->len &&  
memcmp(data, auth->data, (int) data_length) == 0)  
return auth->id;  
}  
*reason = "Invalid MIT-MAGIC-COOKIE-1 key";  
return (XID) -1;  
}  
  
Since most memcmp() implementations return after an invalid byte is  
seen, this causes a time difference between a valid and invalid byte,  
which in theory could allow an efficient brute force attack[1].  
  
Analysis  
--------  
X41 was not able to measure a significant difference using the optimised  
memcmp() version of a standard Linux system, but for a naive  
implementation consisting of a loop comparing the bytes. Since timing  
attacks against memcmp() have been successful in the past [2] and fixed  
elsewhere [3][4] X41 would consider this an issue. If this would be  
exploited, it would allow a local attacker to run code in the Xorg  
session of another user.  
  
In order to prevent this, MIT-COOKIES should be removed or a memcmp()  
similar to timingsafe_memcmp()[5] used. Other projects (e.g. openssl)  
use timing safe memcmp() implementations to compare cookies retrieved  
via the network[6].  
  
Workaround  
----------  
  
None  
  
References  
----------  
  
[1]  
https://cryptocoding.net/index.php/Coding_rules#Compare_secret_strings_in_constant_time  
[2]  
http://de.slideshare.net/cisoplatform7/defcon-22paulmcmillanattackingtheiotusingtimingattac  
[3] http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf  
[4] https://bugs.ruby-lang.org/issues/10098  
[5]  
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libc/string/timingsafe_memcmp.c  
[6] https://github.com/openssl/openssl/blob/master/ssl/t1_lib.c#L1249  
  
  
  
  
  
Potential Use after Free in Xorg Server  
=======================================  
Vulnerability Type: Other  
Affected Products: Xorg Server  
Attack Type: Local  
Impact: -   
Severity Rating: none  
Confirmed Affected Version: 1.19.0 and lower  
Confirmed Patched Version:  
Vector: local  
CVE: -  
CVSS Score: -  
CVSS Vector: -  
  
Summary and Impact  
------------------  
  
In XDM is a (currently non security) issue, regarding a potential use  
after free.  
  
The ToID() function in os/auth.c is not used anywhere, just defined in  
the struct and filled by the protocols, but there are no users.  
  
AuthToIDFunc ToID; /* convert cookie to ID */  
  
X41 noticed that, XdmToID() frees the cookie argument in case it can  
resolve the ID or on failure, but not if it can't allocate memory for plain:  
  
XdmToID(unsigned short cookie_length, char *cookie)  
{  
XdmAuthorizationPtr auth;  
XdmClientAuthPtr client;  
unsigned char *plain;  
  
plain = malloc(cookie_length);  
if (!plain)  
return (XID) -1;  
for (auth = xdmAuth; auth; auth = auth->next) {  
XdmcpUnwrap((unsigned char *) cookie, (unsigned char *) &auth->key,  
plain, cookie_length);  
if ((client =  
XdmAuthorizationValidate(plain, cookie_length, &auth->rho,  
NULL,  
NULL)) != NULL) {  
free(client);  
free(cookie);  
free(plain);  
return auth->id;  
}  
}  
free(cookie);  
free(plain);  
return (XID) -1;  
}  
  
The same return value is given, whether no memory could be allocated or  
it just failed to lookup the ID, so the caller cannot distinguish  
whether this memory is freed or not, which might lead to double-free or  
memory leaks. The other ToID functions do not free this parameter.  
  
  
Weak entropy usage for session keys in libxdm  
=============================================  
Vulnerability Type: Other  
Affected Products: libXdmcp  
Attack Type: Local  
Impact: Escalation of Privileges   
Severity Rating: medium  
Confirmed Affected Version: 1.1.2 and lower  
Confirmed Patched Version:  
Vector: local  
CVE: CVE-2017-2625  
CVSS Score: 7.1  
CVSS Vector: CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N  
  
  
Summary and Impact  
------------------  
  
To further explore the auth mechanism libXdmcp-1.1.2 was checked as well.  
  
XDM uses weak entropy to generate the session keys on non BSD systems:  
  
void  
XdmcpGenerateKey (XdmAuthKeyPtr key)  
{  
#ifndef HAVE_ARC4RANDOM_BUF  
long lowbits, highbits;  
  
srandom ((int)getpid() ^ time((Time_t *)0));  
lowbits = random ();  
highbits = random ();  
getbits (lowbits, key->data);  
getbits (highbits, key->data + 4);  
#else  
arc4random_buf(key->data, 8);  
#endif  
}  
  
On multi user systems it might possible to check the PID of the process  
and how long it is running to get an estimate of these values, which  
could allow an attacker to attach to the session of a different user.  
Several checked Linux distributions (debian testing, archlinux and  
Ubuntu) did not link against libbsd at the time this was found.  
  
Workaround  
----------  
  
Compile against libbsd  
  
  
Weak Entropy Usage in Session Keys in libICE  
============================================  
Vulnerability Type: Other  
Affected Products: libICE  
Attack Type: Local  
Impact: Escalation of Privileges   
Severity Rating: medium  
Confirmed Affected Version: 1.0.9 and lower  
Confirmed Patched Version:  
Vector: local  
CVE: CVE-2017-2626  
CVSS Score: 7.1  
CVSS Vector: CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N  
  
Summary and Impact  
------------------  
  
libICE depends on arc4random() as well to generate the session cookies,  
thereby falling back to the same weak mechanism as libXdmcp:  
  
IceGenerateMagicCookie (  
int len  
)  
{  
char *auth;  
#ifndef HAVE_ARC4RANDOM_BUF  
long ldata[2];  
int seed;  
int value;  
int i;  
#endif  
  
if ((auth = malloc (len + 1)) == NULL)  
return (NULL);  
  
#ifdef HAVE_ARC4RANDOM_BUF  
arc4random_buf(auth, len);  
#else  
#ifdef ITIMER_REAL  
{  
struct timeval now;  
X_GETTIMEOFDAY (&now);  
ldata[0] = now.tv_sec;  
ldata[1] = now.tv_usec;  
}  
#else  
{  
long time ();  
ldata[0] = time ((long *) 0);  
ldata[1] = getpid ();  
}  
#endif  
seed = (ldata[0]) + (ldata[1] << 16);  
srand (seed);  
for (i = 0; i < len; i++)  
{  
value = rand ();  
auth[i] = value & 0xff;  
}  
#endif  
auth[len] = '\0';  
return (auth);  
}  
  
For this issue a PoC is available which takes 2-3 seconds to retrieve  
the key:  
  
https://www.x41-dsec.de/lab/sources/icetest.c  
  
Workaround  
----------  
  
Compile against libbsd  
  
  
Weak Entropy Usage in xorg server  
=================================  
Vulnerability Type: Other  
Affected Products: Xorg Server  
Attack Type: Local  
Impact: Unknown   
Severity Rating: unclear  
Confirmed Affected Version: 1.19.0 and lower  
Confirmed Patched Version:  
Vector: local  
CVE: -  
CVSS Score: -  
CVSS Vector: -  
  
Summary and Impact  
------------------  
  
When looking at other places that use entropy, X41 also noticed  
os/auth.c and hw/xwin/winauth.c providing GenerateRandomData()  
  
void  
GenerateRandomData(int len, char *buf)  
{  
int fd;  
  
fd = open("/dev/urandom", O_RDONLY);  
read(fd, buf, len);  
close(fd);  
}  
  
When the call to open or read fails, the contents of buf might be  
undefined. This should be handled more gracefully, it might fail in  
chrooted environments (unlikely) or when file descriptors are exhausted.  
Newer Linux Kernels provide getrandom() to protect against this and  
OpenBSD provides getentropy().  
  
This security impact of these functions has not been further inspected.  
  
  
  
About X41 D-Sec GmbH  
--------------------  
X41 D-Sec GmbH is an expert provider for application security services.  
Having extensive industry experience and expertise in the area of  
information security, a strong core security team of world class  
security experts enables X41 to perform premium security services.  
  
Fields of expertise in the area of application security are security  
centric code reviews, binary reverse engineering and vulnerability  
discovery. Custom research and a IT security consulting and support  
services are core competencies of X41.  
  
  
  
Timeline  
--------  
2017-01-17 to Report to [email protected]  
01-23  
2017-02-10 CVE Request at [email protected]  
2017-02-13 CVE IDs assigned  
2017-02-16 Information of [email protected]  
2017-02-20 Patch for CVE-2017-2624 provided by Matthieu Herrb  
2017-02-28 Advisory release  
  
--   
X41 D-SEC GmbH, Dennewartstr. 25-27, D-52068 Aachen  
T: +49 241 9809418-0, Fax: -9  
Unternehmenssitz: Aachen, Amtsgericht Aachen: HRB19989  
GeschA$?ftsfA1/4hrer: Markus Vervier  
  
  
  
  
  
  
  
`