Security
Two glibc vulnerabilities
Tavis Ormandy has been busy of late, poking around in the guts of GNU libc. Out of that have come two separate local privilege escalations that exploit an obscure corner (the dynamic linker auditing API) of glibc, while the exploits themselves use—abuse—some Linux features that many probably aren't aware of. These vulnerabilities and exploits provide good examples of the way that security researchers look at code and systems—a way of looking that more developers would do well to emulate.
The runtime library auditing API is a way for developers to intercept the actions of the dynamic linker to see the steps that it is taking while searching for .so files and resolving symbols from them. When a program is executed with the LD_AUDIT environment variable pointing to one or more shared libraries, the linker will make callbacks into functions in those libraries for various events that happen in the linking process. There are various events specified in the rtld-audit man page, including searching for an object, opening an object, binding to a symbol, and so on. It seems like a useful facility, but one that is likely not in the toolbox of many Linux developers.
The simpler of the two problems that Ormandy found was that setuid programs will open whatever arbitrary library a user specifies in LD_AUDIT, as long as that library lives on the trusted library path. The more well-known LD_PRELOAD environment variable, which preloads the specified libraries before the linker searches for others, is specifically prohibited from operating on setuid programs unless the library is on the trusted path and has the setuid bit set. Exploiting ping (or some other setuid program) with LD_PRELOAD would be trivial—a user-provided library could remap any call ping made to anything the attacker wanted—so it was an obvious restriction. LD_AUDIT using non-setuid libraries was evidently not so obvious.
The problem with allowing user-provided libraries to be used for auditing setuid programs is not anywhere in the auditing API, but is instead inherent in the way the runtime linker processes libraries. When the library is opened with dlopen() to determine whether the auditing callback symbols are present, any library initialization routines must be run. So, an exploit is done by finding a vulnerable system library (it must be on the trusted path) that was not written with setuid execution in mind (and thus does not have that bit set in the filesystem).
In his description of the flaw, Ormandy gives an example of using the libpcprofile.so library, which writes an output file to the path specified by the PCPROFILE_OUTPUT environment variable. Using ping for its setuid nature, he sets LD_AUDIT to the library, points PCPROFILE_OUTPUT where he wants, and ping ends up putting a user-writable file in /etc/cron.d. The details will vary depending on the distribution, but most will be vulnerable to the flaw. There is nothing particularly special about libpcprofile.so, as Ormandy describes ways to find other vulnerable system libraries, which are likely to be numerous—those libraries weren't meant to be used by privileged programs.
The other vulnerability is more difficult to exploit, but stems from a similar laxness in LD_AUDIT handling. In the Linux executable file format, ELF, library search paths can be specified in the executable itself using DT_RPATH or DT_RUNPATH tags. Those tags can contain a $ORIGIN value, which is replaced with location of the executable in the filesystem. That way, a library used by a single executable can be located in a program-specific location rather than in the system library directories.
The ELF specification recommends that $ORIGIN be disallowed for setuid executables, but glibc ignores that recommendation. Ormandy doesn't really see a problem with that:
Unfortunately, the $ORIGIN substitution code was reused in the LD_AUDIT path. There was seemingly an attempt to restrict the use of $ORIGIN in LD_AUDIT for privileged programs, but it was insufficient. $ORIGIN will be expanded if it is the only entry in LD_AUDIT. Since $ORIGIN expands to the directory that contained the program, it isn't necessarily obvious that there is anything there to exploit. But, there are known ways to exploit this kind of situation.
If the directory that contains the executable can be replaced with an exploit library object between the time $ORIGIN is expanded and when the value is used, the library will be loaded and the attacker can do what they like. It is essentially a race condition, but one that can be reliably won by the attacker. Ormandy's example basically pauses the execution of a ping that has been hardlinked into an attacker-controlled directory after the expansion of $ORIGIN has been done. He then removes the directory and its contents, and puts a library that has exploit code in its initialization function in the place of the directory.
That particular exploit mechanism is fairly modern, using relatively recent Linux kernel features, but there are others. Ormandy describes several other ways to exploit the flaw, with differing requirements (e.g. a C compiler or winning an easily winnable race) that might serve different attack strategies. While both are local privilege escalations, they very well might be used in conjunction with a web application or other flaw to turn them into a remote root vulnerability.
Both of these vulnerabilities are quite serious for systems that allow untrusted users to log in. Their impact on other systems depends on whether there are other vulnerable, network-facing programs. While it is a bit ironic that it was an audit of LD_AUDIT behavior that found these bugs, it seems clear that there isn't enough of that kind of auditing being done for Linux systems. It's always a bit worrisome to think of how many of these kinds of flaws are still lingering out there.
Brief items
A Firefox zero-day vulnerability
The Mozilla Security Blog warns of a new Firefox vulnerability which is already being exploited. "Users who visited an infected site could have been affected by the malware through the vulnerability. The trojan was initially reported as live on the Nobel Peace Prize site, and that specific site is now being blocked by Firefox's built-in malware protection. However, the exploit code could still be live on other websites." Disabling JavaScript (or running NoScript) will block exploit attempts.
New vulnerabilities
festival: code execution
| Package(s): | festival | CVE #(s): | CVE-2010-3996 | ||||||||||||||||
| Created: | October 22, 2010 | Updated: | December 9, 2013 | ||||||||||||||||
| Description: | From the openSUSE advisory:
festival_server uses an unsafe LD_LIBRARY_PATH. Local users could exploit that to execute code as another user if that user runs festival_server. | ||||||||||||||||||
| Alerts: |
| ||||||||||||||||||
glibc: privilege escalation
| Package(s): | glibc | CVE #(s): | CVE-2010-3847 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Created: | October 21, 2010 | Updated: | April 15, 2011 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description: | From the Red Hat advisory: It was discovered that the glibc dynamic linker/loader did not handle the $ORIGIN dynamic string token set in the LD_AUDIT environment variable securely. A local attacker with write access to a file system containing setuid or setgid binaries could use this flaw to escalate their privileges. (CVE-2010-3847) For a detailed look, see Tavis Ormandy's report. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Alerts: |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
glibc: privilege escalation
| Package(s): | glibc | CVE #(s): | CVE-2010-3856 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Created: | October 22, 2010 | Updated: | January 12, 2011 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description: | From the Debian advisory:
Ben Hawkes and Tavis Ormandy discovered that the dynamic loader in GNU libc allows local users to gain root privileges using a crafted LD_AUDIT environment variable. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Alerts: |
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
libsmi: arbitrary code execution
| Package(s): | libsmi | CVE #(s): | CVE-2010-2891 | ||||||||||||||||||||||||||||||||||||
| Created: | October 22, 2010 | Updated: | December 16, 2013 | ||||||||||||||||||||||||||||||||||||
| Description: | From the Mandriva advisory:
A buffer overflow was discovered in libsmi when long OID was given in numerical form. This could lead to arbitrary code execution. | ||||||||||||||||||||||||||||||||||||||
| Alerts: |
| ||||||||||||||||||||||||||||||||||||||
pidgin: denial of service
| Package(s): | pidgin | CVE #(s): | CVE-2010-3711 | ||||||||||||||||||||||||||||||||||||||||||||
| Created: | October 21, 2010 | Updated: | March 14, 2011 | ||||||||||||||||||||||||||||||||||||||||||||
| Description: | From the Red Hat advisory: Multiple NULL pointer dereference flaws were found in the way Pidgin handled Base64 decoding. A remote attacker could use these flaws to crash Pidgin if the target Pidgin user was using the Yahoo! Messenger Protocol, MSN, MySpace, or Extensible Messaging and Presence Protocol (XMPP) protocol plug-ins, or using the Microsoft NT LAN Manager (NTLM) protocol for authentication. (CVE-2010-3711) | ||||||||||||||||||||||||||||||||||||||||||||||
| Alerts: |
| ||||||||||||||||||||||||||||||||||||||||||||||
tuxguitar: code execution
| Package(s): | tuxguitar | CVE #(s): | CVE-2010-3385 | ||||||||
| Created: | October 21, 2010 | Updated: | October 27, 2010 | ||||||||
| Description: | From the Red Hat bugzilla entry: Raphael Geissert conducted a review of various packages in Debian and found that tuxguitar contained a script that could be abused by an attacker to execute arbitrary code [1]. The vulnerability is due to an insecure change to LD_LIBRARY_PATH, and environment variable used by ld.so(8) to look for libraries in directories other than the standard paths. When there is an empty item in the colon-separated list of directories in LD_LIBRARY_PATH, ld.so(8) treats it as a '.' (current working directory). If the given script is executed from a directory where a local attacker could write files, there is a chance for exploitation. | ||||||||||
| Alerts: |
| ||||||||||
Page editor: Jake Edge
Next page:
Kernel development>>
