Information Assurance |
Brent Putman |
Information AssuranceBugtraq AnalysisFormat String Vulnerability in Apache auth_ldap module |
Listings: This vulnerability concerns a remote format string attack in the auth_ldap module for the Apache web server. Apache is an open source web server and is the most commonly used web server for Unix and Linux operating systems. The auth_ldap module is a popular and commonly used extension module for Apache that allows authentication of users against a Lightweight Directory Access Protocol (LDAP) server. LDAP servers are commonly used for storing user authentication and authorization data in large enterprise environments. This vulnerability only affects the auth_ldap 1.6.0 module for version 1.3 of Apache. Apache version 2.0 has been available for several years and bundles a rewritten version of auth_ldap which is apparently not vulnerable to the problem described below. However, many sites still use Apache 1.3 and auth_ldap, and it also continues to be bundled with many vendor products such as Oracle.
The general problem is that of an attack against the format string of the
The auth_ldap vulnerability occurs because of an improper use of an Apache server logging function auth_ldap.c: void auth_ldap_log_reason(request_rec *r, const char *fmt, ...) { va_list args; char buf[MAX_STRING_LEN]; va_start(args, fmt); ap_vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); #if APACHE_RELEASE < 1030000 log_reason(buf, r->uri, r); #else ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r, buf); #endif }The format string in the call to ap_log_rerror (variable buf above) contains string data that is potentially supplied directly by the user. ap_log_error() in turn calls a couple of functions which must process the variable arguments of the format string:
Apache http_log.c API_EXPORT_NONSTD(void) ap_log_rerror(const char *file, int line, int level, const request_rec *r, const char *fmt, ...) { va_list args; va_start(args, fmt); log_error_core(file, line, level, r->server, r, fmt, args); va_end(args); va_start(args,fmt); if (((level & APLOG_LEVELMASK) <= APLOG_WARNING) && (ap_table_get(r->notes, "error-notes") == NULL)) { ap_table_setn(r->notes, "error-notes", ap_escape_html(r->pool, ap_pvsprintf(r->pool, fmt, args))); } va_end(args); }For example, log_error_core() calls ap_vsnprint() to produce a formatted string buffer:
static void log_error_core(const char *file, int line, int level, const server_rec *s, const request_rec *r, const char *fmt, va_list args) { (..... SNIP .......) #ifndef AP_UNSAFE_ERROR_LOG_UNESCAPED if (ap_vsnprintf(scratch, sizeof(scratch) - len, fmt, args)) { len += ap_escape_errorlog_item(errstr + len, scratch, sizeof(errstr) - len); } #else len += ap_vsnprintf(errstr + len, sizeof(errstr) - len, fmt, args); #endif (..... SNIP .......) }In turn ap_vsnprintf() must process the variable number of format specifiers, and it is here that extraneous format specifiers may be exploited.
There are several possible vectors of attack which allow a malicious remote user to choose or influence the content of the format string, such as the web URL that is being accessed. These correspond to different places in the module where various pieces of information are logged during request processing. The most obvious and direct way to influence the format string is via the username sent by the user, which is logged by the module here: auth_ldap_log_reason(r, "LDAP search for %s failed: LDAP error: %s; URI %s", filtbuf, ldap_err2string(result), r->uri);In this case the username supplied by the user for doing HTTP Basic authentication would be included in the filtbuf variable above, e.g. "uid=username" . By specifying a specially-crafted username, a format string attack against the logging function is possible. This potentially allows a remote user to run code with the same permissions as the Apache server httpd process.
The problem could have been prevented by not allowing the user-determined string to be used directly as the format string by the BAD: printf(userinput_buffer) vs. GOOD: printf("%s", userinput_buffer)The auth_ldap v1.6.1 module patch to fix this vulnerability was a simple change to the ap_log_rerror() call, adding a fixed format string with a single %s string format specifier:
ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r, "%s", buf); Another workaround or fix to the vulnerability would be to upgrade the server to Apache 2.0 or 2.2. The version of the auth_ldap module included with those versions is not vulnerable to this problem. Format string attack vulnerabilities can generally be found and avoided by static analysis tools such as Flawfinder. It is usually easy for such tools to flag whether the format string used is a constant string or a variable buffer. |