|
----- Original Message ----- From: "Timo Sirainen" <tss@iki.fi> To: <bugtraq@securityfocus.com> Sent: Monday, December 09, 2002 11:25 AM Subject: Cyrus SASL library buffer overflows > These overflows are found at least in version 2.1.9, none of them are > present in 1.5.28. 2.1.10 was just released which fixed the problems. > > Note that besides the Cyrus project itself, the SASL library is also used > by Postfix-TLS patch, OpenLDAP and probably some other servers. > > Problem 1 > --------- > > Insufficient buffer length checking in user name canonicalization may allow > attacker to execute arbitrary code on servers using Cyrus SASL library. > Client side library also has the bug but since the user name is asked from > the local user, there's probably not many applications that care about it, > except maybe webmails and the like. This overflow only happens if default > realm is set. > > Exploiting may not be too easy though, since you can only write > "@default.realm.name" to limited space in heap past the buffer, depending > on how long user name is allowed. With postfix this is around 2048 BASE64 > encoded bytes (around 1500 bytes) by default. Postfix uses $myhostname as > default realm name. > > We can overflow two different buffers at the end of sasl_conn_t structure: > > char user_buf[CANON_BUF_SIZE+1], authid_buf[CANON_BUF_SIZE+1]; > > sasl_conn_t is malloc()ed, so the most obvious exploit could happen with > modifying malloc headers. Since we can use only few specific characters, > the possibility to exploit is very system dependant. > > Problem 2 > --------- > > LDAP authentication with saslauthd doesn't allocate enough memory when it > needs to escape characters '*', '(', ')', '\' and '\0' in username and > realm. This should be easily exploited with glibc's malloc implementation. > > Problem 3 > --------- > > Log writer might not have allocated memory for the trailing \0 in > message. Probably hard to exploit, although you can affect the logging > data with at least anonymous authentication. > > patch > ----- > > If you need for some reason. > > diff -ru cyrus-sasl-2.1.9-old/lib/canonusr.c cyrus-sasl-2.1.9/lib/canonusr.c > --- cyrus-sasl-2.1.9-old/lib/canonusr.c 2002-09-16 21:37:20.000000000 +0300 > +++ cyrus-sasl-2.1.9/lib/canonusr.c 2002-12-05 06:18:36.000000000 +0200 > @@ -306,6 +306,7 @@ > /* Now copy! (FIXME: check for SASL_BUFOVER?) */ > memcpy(out_user, begin_u, MIN(ulen, out_umax)); > if(sconn && u_apprealm) { > + if(ulen >= out_umax) return SASL_BUFOVER; > out_user[ulen] = '@'; > memcpy(&(out_user[ulen+1]), sconn->user_realm, > MIN(u_apprealm-1, out_umax-ulen-1)); > diff -ru cyrus-sasl-2.1.9-old/saslauthd/lak.c cyrus-sasl-2.1.9/saslauthd/lak.c > --- cyrus-sasl-2.1.9-old/saslauthd/lak.c 2002-08-01 22:58:24.000000000 +0300 > +++ cyrus-sasl-2.1.9/saslauthd/lak.c 2002-12-05 07:43:34.000000000 +0200 > @@ -279,7 +279,7 @@ > char *buf; > char *end, *ptr, *temp; > > - buf = malloc(strlen(s) * 2 + 1); > + buf = malloc(strlen(s) * 3 + 1); > if (buf == NULL) { > return LAK_NOMEM; > } > @@ -358,7 +358,8 @@ > if( *buf == '%' ) percents++; > } > > - buf=malloc(strlen(lak->conf->filter) + (percents * maxparamlength) +1); > + buf=malloc(strlen(lak->conf->filter) + > + (percents * maxparamlength * 3) + 1); > if(buf == NULL) { > syslog(LOG_ERR|LOG_AUTH, "Cannot allocate memory"); > return LAK_NOMEM; > diff -ru cyrus-sasl-2.1.9-old/lib/common.c cyrus-sasl-2.1.9/lib/common.c > --- cyrus-sasl-2.1.9-old/lib/common.c 2002-09-19 01:07:54.000000000 +0300 > +++ cyrus-sasl-2.1.9/lib/common.c 2002-12-05 08:11:49.000000000 +0200 > @@ -1326,6 +1326,8 @@ > } > } > > + result = _buf_alloc(&out, &alloclen, outlen+1); > + if (result != SASL_OK) goto done; > out[outlen]=0; /* put 0 at end */ > > va_end(ap); >