[UNIX] Linux 'util-linux' chfn Local Root Vulnerability
From: support@securiteam.comDate: 07/30/02
- Previous message: support@securiteam.com: "[UNIX] Easy Homepage Creator Vulnerability"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
From: support@securiteam.com To: list@securiteam.com Date: Tue, 30 Jul 2002 08:16:10 +0200 (CEST)
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
When was the last time you checked your server's security?
How about a monthly report?
http://www.AutomatedScanning.com - Know that you're safe.
- - - - - - - - -
Linux 'util-linux' chfn Local Root Vulnerability
------------------------------------------------------------------------
SUMMARY
A locally exploitable vulnerability is present in the util-linux package
shipped with Red Hat Linux and numerous other Linux distributions.
DETAILS
Affected Systems:
Red Hat Linux 7.3 and previous; potentially many other distributions up to
date that use util-linux to provide chfn and chsh utilities. Please refer
to the CERT vulnerability note for more information.
Systems that ship chfn within the shadow-utils package (for example SuSE)
are not vulnerable.
Details:
The vulnerability is present within the shared code of the util-linux
package. For the purpose of this discussion, we use the setuid application
'chfn' as an attack vector. We used the "Fenris" utility, available at
<http://razor.bindview.com/tools/fenris>
http://razor.bindview.com/tools/fenris, to analyze the issue.
The purpose of the 'chfn' utility is to allow users to modify personal
information stored within the system-wide password file, /etc/passwd. In
order to modify this file, this application must be installed setuid root.
It is a part of the base installation of most Linux systems.
Under certain commonly met conditions (see "Mitigating Factors"), a
carefully crafted attack sequence can be performed to exploit a complex
file locking and modification race present in this utility, and, as a
result, alter /etc/passwd to escalate privileges in the system.
Password file locking and modification code can be found in util-linux
within the login-utils/setpwnam.c file. The general logic used for this
process is as follows:
1. /etc/ptmptmp file is opened with O_WRONLY|O_CREAT, 0644 perms
2. The file is linked to /etc/ptmp, exit on failure
3. /etc/ptmptmp is removed
Later, the descriptor obtained in step 1 is used for writing to construct
the new /etc/passwd contents. This is done line by line, by calling the
fputs() routine. When the new file is ready, three more steps are taken:
4. /etc/passwd.OLD is removed
5. /etc/passwd is linked to /etc/passwd.OLD
6. /etc/ptmp is renamed to /etc/passwd
At first sight, this logic is not flawed. There is no O_EXCL in step 1,
but step 2 works as an accurate exclusive locking mechanism, and prevents
other instances of this application from making any writes until the
procedure is completed (step 6). In addition, step 3 ensures that no
process will work on the hardlink of /etc/passwd after the procedure is
completed. This, while is not a standard way of handling file locking on
Linux, is an adequate protection against race conditions. The only concern
is that if chfn, chsh, or any other process that uses /etc/ptmp is
terminated abnormally (e.g. never exits because of a system crash or is
killed with SIGKILL), the lock has to be removed manually in order for
applications that rely on this signaling method to work properly. This
includes utilities such as chsh, chfn, useradd, userdel, adduser, vipw,
and other software. Most of seasoned Linux administrators have had to
remove this lock file at least once, and many utilities offer help
troubleshooting this issue - for example, adduser refuses to run when
/etc/ptmp is present and terminates with the following message:
# adduser
vipw lockfile (/etc/ptmp) is present!
This is exactly what causes the problem. Because this dangling lock file
makes it impossible to perform regular user management tasks, it is
trivial to force the administrator to remove it. This is a risk if chfn is
stopped (by SIGSTOP) between steps 2 and 3 - which can be done. There is a
very small window of opportunity here, but it is possible to fit into it.
Later, the application can be resumed with SIGCONT.
Note that there is no easy way to diagnose who created /etc/ptmp and for
what reason they created it. The file is owned by root and has no
additional information whatsoever. The attack relies on small windows of
opportunity, making one-shot attempts not feasible on certain systems, it
is reasonable to expect that if the attacker repeatedly runs chfn or chsh
just to create dangling lock files several times a day - and to make user
management and maintenance tasks repeatedly fail because of this lockfile
- the administrator will most likely add "rm -f /etc/ptmp" or equivalent
to his crontab, instead of putting much more effort into tracing the
problem that cannot be easily diagnosed using standard Linux tools - there
is no log entry associated with successful authentication for chfn
service, ownership of the file is set to root, the file is empty.
As soon as this or a similar counter-measure is deployed, trial-and-error
attacks become much simpler. None of the above administrative tasks is to
be viewed as requiring social engineering. Such tasks are a part of
standard system maintenance and operations, and it is safe to assume that
almost all system administrators will follow this or a similar procedure
to address the problem.
Once the attacker has a stopped chfn process in between steps 2 and 3, and
the /etc/ptmp file has been removed, he can easily execute another
instance of chfn. It will open the already existing /etc/ptmptmp (this
file is not considered a lock by any software, and most likely will not be
deleted). The second instance runs and step 2 succeeds because there is no
lock file present. The file is then written. As soon as /etc/ptmp has the
projected size (or /etc/passwd.OLD appears), the instance should be killed
to avoid renaming to /etc/passwd (this is a timing concern for this
attack, and we will address it later).
The First instance of chfn is still holding an open descriptor to
/etc/ptmptmp, which later became /etc/ptmp - and, if we send SIGCONT to
this process, will be renamed to /etc/passwd. Step 3 will fall through
because there is no error checking, and new information will be written
into a descriptor that will de facto become /etc/passwd.
Copying the file should go smoothly up to the point where the attacker's
account information is stored. Let's analyze what is going to happen past
this point if the second instance of chfn was called with significantly
longer GECOS parameters than first (minimum GECOS length set by chfn is
zero, maximum is 260 characters). Keep in mind that there is no call to
ftruncate() before fclose(), so the new file would have a "tail"
consisting of the last characters of the longer version of /etc/passwd. If
'Write 1' is the first write to file, or the write made by the second
instance of chfn, 'Write 1 is the second write (first instance), and '|'
represents a record separator (newline), then:
Write 1: user 1 | user 2 | ATTACKER LONG | user 3 | user 4 |
Write 2: user 1 | user 2 | ATTACKER | user 3 | user 4 |
------------------------------------------------------------
Result: user 1 | user 2 | ATTACKER | user 3 | user 4 |r 4 |
As a result, /etc/passwd has now a new line at the end, a "leftover" part
from last username. This, itself, can be considered an annoyance, but is
hardly a full-blown security issue. However, something makes this problem
more serious - that is, GNU libc.
As we mentioned earlier, records are being written to wannabe /etc/passwd
line-by-line, using fputs(). It is important to realize that the text-file
functions such as fputs() are buffered - that is, lines are being actually
written to disk in chunks, when internal cache is full. Until this point,
the OS's idea of the file and the process's idea of the file are not
synchronized. Cache block size, by default, is four kilobytes. This means
that if the password file has more than four kilobytes (which is very
often true on systems where local attacks are performed, see "Mitigating
Factors"), and the attacker's account is not in the last cached that is
going to be written before fclose(), it should be possible to "cut" the
file on four kilobytes boundary by killing the first chfn process as soon
as /etc/passwd has the desired contents:
<--- attacker's account 4 kB boundary
|
Write 1: ...ser1:x:640:640:Foo Bar:/bin/bash\nuser2:x:641:641:Foo...
Write 2: ...user1:x:640:640:Foo Bar:/bin/bash\nuser2: ***CUT***
--------------------------------------------------------------------
Result: ...\nuser2::641:641:Foo...
Note that both the data written in "Write 1" and in "Write 2" can be
padded within a 260 byte range, which is typically much more than a
typical /etc/passwd line length, so it is possible to pad the record
exactly in the way described above - which happens to erase the password
for user2. All it takes is to determine the appropriate initial padding,
then invoke the first chfn with one more character in GECOS than in the
second chfn.
It is also possible to create root accounts or other privileged access
accounts that effectively lead to privilege escalation (kmem, mail, etc).
A root account with no password can be generated in two steps, first
truncate the UID ending with '0' to the last digit, and the second step is
to remove the password as described above. Note that even if there is no
account with UID 0 anywhere close to the 4 kB boundary, data can be moved
over much longer distance by several subsequent attack cycles where the
first instance is called with the maximum length GECOS field, and the
second with minimum.
The question of timing required for trimming is essential in evaluating
the feasibility of this attack - but, fortunately for the attacker, timing
is on his side. First, the copying procedure is essentially slow, being
done in a read-compare-write cycle. Then, the results are cached so the
output appears in larger chunks, but less frequently, giving the attacker
plenty of CPU cycles. Finally, the passwd file is world-readable, which
gives the attacker a tremendous advantage - it can be easily monitored
e.g. by mapping a single byte at the boundary to the memory space of the
exploit. Additionally, for files that consist of more than one segment
past the attacker's account, the problem of careful timing needed to avoid
renaming /etc/ptmp to /etc/passwd becomes less of an issue, because the
process can be killed before reaching the end of the file, just after the
desired boundary is modified.
Mitigating factors:
In order to successfully exploit the vulnerability and perform privilege
escalation, the following additional requirements have to be met:
1. There is a need for a minimal administrator interaction that falls into
the category of standard system maintenance and operations.
2. The password file, /etc/passwd, must be over 4 kilobytes. This
requirement is typically satisfied on systems with approximately 50
accounts or more - that is, on a vast majority of systems that where
unprivileged accounts are being compromised / used by malicious attackers.
3. Assume that /etc/passwd is divided into 4 kB chunks. The attacker's
account record in this file must NOT be located in the last chunk. That
is, if /etc/passwd has 9 kB and we have three chunks, 4 kB, 4 kB and 1 kB,
and attacker's account must be located within the first or second chunk
and cannot be located further than 8th kilobyte of the file.
Other mitigating factors are similar to ones for other local
vulnerabilities in setuid binaries.
Workaround / Fix:
The fast workaround is to remove setuid flags from /usr/bin/chfn and
/usr/bin/chsh. A more appropriate fix is to patch the sources as follows:
--- util-linux-2.11n-old/login-utils/setpwnam.c Mon Jul 31 08:50:39 2000
+++ util-linux-2.11n/login-utils/setpwnam.c Wed Jun 12 21:37:12 2002
@@ -98,7 +98,8 @@
/* sanity check */
for (x = 0; x < 3; x++) {
if (x > 0) sleep(1);
- fd = open(PTMPTMP_FILE, O_WRONLY|O_CREAT, 0644);
+ // Never share the temporary file.
+ fd = open(PTMPTMP_FILE, O_WRONLY|O_CREAT|O_EXCL, 0644);
if (fd == -1) {
umask(oldumask);
return -1;
Systems Affected:
Vendor - Status - Date Updated
3Com - Unknown - 10-Jul-2002
Alcatel - Not Vulnerable - 24-Jul-2002
Apple Computer Inc. - Unknown - 10-Jul-2002
AT&T - Unknown - 28-Jun-2002
BSDI - Unknown - 10-Jul-2002
Caldera - Vulnerable - 11-Jul-2002
Cisco Systems Inc. - Unknown - 28-Jun-2002
Compaq Computer Corporation - Unknown - 10-Jul-2002
Computer Associates - Unknown - 10-Jul-2002
Cray Inc. - Not Vulnerable - 10-Jul-2002
Data General - Unknown - 10-Jul-2002
Debian - Not Vulnerable - 27-Jun-2002
Engarde - Unknown - 10-Jul-2002
F5 Networks - Unknown - 28-Jun-2002
FreeBSD - Unknown - 10-Jul-2002
Fujitsu - Unknown - 28-Jun-2002
Hewlett-Packard Company - Unknown - 27-Jun-2002
IBM - Not Vulnerable - 17-Jul-2002
Intel - Unknown - 28-Jun-2002
Juniper Networks - Unknown - 28-Jun-2002
Lachman - Unknown - 10-Jul-2002
Lotus Development Corporation - Not Vulnerable - 11-Jul-2002
Lucent - Unknown - 27-Jun-2002
MandrakeSoft - Unknown - 28-Jun-2002
Microsoft Corporation - Not Vulnerable - 12-Jul-2002
Multinet - Unknown - 10-Jul-2002
NEC Corporation - Unknown - 28-Jun-2002
NetBSD - Not Vulnerable - 12-Jul-2002
Network Appliance - Unknown - 28-Jun-2002
Nortel Networks - Unknown - 10-Jul-2002
OpenBSD - Unknown - 28-Jun-2002
Oracle - Unknown - 28-Jun-2002
Red Hat Inc. - Vulnerable - 10-Jul-2002
Sequent - Unknown - 28-Jun-2002
SGI - Unknown - 10-Jul-2002
Sony Corporation - Unknown - 28-Jun-2002
Sun Microsystems Inc. - Vulnerable - 17-Jul-2002
SuSE Inc. - Not Vulnerable - 15-Jul-2002
Unisphere Networks - Unknown - 28-Jun-2002
Unisys - Unknown - 10-Jul-2002
Wind River Systems Inc. - Unknown - 10-Jul-2002
Xerox - Unknown - 28-Jun-2002
(An updated version is available through:
<http://www.kb.cert.org/vuls/id/405955>
http://www.kb.cert.org/vuls/id/405955)
ADDITIONAL INFORMATION
The information has been provided by <mailto:lcamtuf@coredump.cx> Michal
Zalewski.
========================================
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com
====================
====================
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
- Previous message: support@securiteam.com: "[UNIX] Easy Homepage Creator Vulnerability"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
- RAZOR advisory: Linux util-linux chfn local root vulnerability
... CERT vulnerability note: http://www.kb.cert.org/vuls/id/405955 ... package shipped
with Red Hat Linux and numerous other Linux ... up to date that use util-linux to provide
chfn and chsh utilities. ... application 'chfn' as an attack vector. ...
(Bugtraq) - [VulnWatch] RAZOR advisory: Linux util-linux chfn local root vulnerability
... CERT vulnerability note: http://www.kb.cert.org/vuls/id/405955 ... package shipped
with Red Hat Linux and numerous other Linux ... up to date that use util-linux to provide
chfn and chsh utilities. ... application 'chfn' as an attack vector. ...
(VulnWatch) - RE: vBulletin Security Vulnerability
... Subject: vBulletin Security Vulnerability ... *** Status: Unknown Signature
... Contacting the board developers and explaining the vulnerability ... (Vuln-Dev) - RE: vBulletin Security Vulnerability
... Subject: vBulletin Security Vulnerability ... *** Status: Unknown Signature
... Contacting the board developers and explaining the vulnerability ... (Bugtraq) - Re: Help - e-mail attack
... > My domain, wormhole.com, is under attack for the past four days by parties ...
They are flooding me with messages addressed to random names @ ... > trying to process
these thousands of unknown users. ... Your system doesn't accept mail for unknown users,
... (comp.mail.sendmail)