106471 2003-07-02  21:54  /148 rader/ Michal Zalewski <lcamtuf@ghettot.org>
Importerad: 2003-07-02  21:54  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <5391>
Ärende: Red Hat 9: free tickets
------------------------------------------------------------

[ This is not strictly a new vulnerability - but a description of
  a flaw that can be combined with any of the minor vulnerabilities
  that pop up once a week to turn them into a major vulnerability.
  I will leave it up to the moderators of BUGTRAQ and VulnWatch to
  approve or reject it... ]

The reason for this post is that largely under-appreciated file
creation vulnerabilities can now get a higher profile, I think. Below
are some hopefully interesting thoughts on turning almost any O_CREAT
w/o O_EXCL in a world-writable directory - or similar issues, you
name it - into an instant, generic root compromise scenario on modern
Linux boxes (primarily Red Hat and derivates)...

Until recently, you could basically exercise three possible active
attack vectors against such a /tmp vulnerability - none of which is
particularly tempting in terms of privilege escalation:

  1) Denial of Service:

     Just create an appropriate symlink to create /etc/nologin,
     truncate /lib/libc.so.6 or do something of a similar nature once
     followed by a broken application. This is possible in almost all
     cases when a vulnerable application is run by a privileged user.
     Fortunately or unfortunately, there's very little benefit for the
     attacker in this scenario.

  2) Contents manipulation:

     Attack the application itself by securing a write access to the
     soon-to-be-accessed temporary file (it's usually enough to
     create it in advance). Then stuff its temporary file with some
     unexpected data. This could be successful only if the
     application uses file contents in some interesting way later
     on. While there are some nice examples (for example, older
     versions of GCC), this is seldom a feasible scenario, and is
     very application-specific.

  3) Contents redirection:

     If you can control the data written by the application to a
     temporary file, you could use a symlink to force writing to a
     file like /etc/ld.so.preload, /etc/passwd,
     ~/.ssh/authorized_keys or such. In most cases, however, races
     occur in boot scripts, cron scripts, non-suid applications run
     by privileged users, etc - and the attacker can exercise very
     little control over the contents of such a file.

As far as I know, there was no neat and generic way to exploit an
insecure /tmp file creation alone - well, until now.

Starting release 9, Red Hat ships and uses pam_timestamp_check.so
module (accompanied by /sbin/pam_timestamp_check setuid helper), a
part of the new pam-0.75 (Pluggable Authentication Modules)
package. PAM is a generic centralized authentication and session
management component that is also shipped by an increasing number of
other distributions, so it is reasonable that the code is about to
propagate to other distros.

The module mentioned implements a credential caching functionality,
very closely inspired on a tty ticketing system used in sudo. Most
sudo users are familiar with the fact they are not prompted for
password if a subsequent sudo session is opened shortly after a
previous one on the same terminal - and this is exactly what
pam_timestamp_check tries to implement for other services.

The system used in sudo is somewhat naive and does have its problems, but
the impact caused by an eventual ticket stealing attack is fairly minimal
- the user has to be trusted and listed in /etc/sudoers in the first
place, and the credentials that are cached are for his own account
(sudo users enter their own password, as opposed to root's).

The way Red Hat deployed this mechanism is badly broken, since they
use it to cache root credentials for access to critical components of
the system, and there are no restrictions as to who can use those
components. While in sudo, stealing or spoofing a ticket is worth
exactly as much as knowing the password for the account you already
have access to, and the account has to be trusted, in Red Hat, it is
worth root's password almost all the time, and any user can use
it. As such, there should me much more caution exercised with such a
mechanism. But there is not, causing an obvious exposure.

The way the module (and sudo) works, in essence, is that it gets
current pseudo-terminal name A (which can be trivially spoofed, but
this is of no relevance at the moment), current user name B, and the
user for which credentials are cached, C (usually root for Red Hat
applications, user himself for sudo). Then the code checks for
/var/run/sudo/B/A:C (or /var/run/sudo/B/A if B == C), and if the file
is recent, the module returns success, and enables the user to skip
the usual password authentication.

The mechanism is used in Red Hat to make it easier for users to
perform administrative tasks without having to switch to root via su
or sudo, granted they know the admin password. There is a number of
management applications that can be invoked via a single setuid
PAM-enabled wrapper, /usr/sbin/userhelper, that all have
pam_timestamp_check.so included in their PAM configs. From quite
harmless ones, such as redhat-config-mouse, to pretty much instant
root scenarios once the mechanism is compromised
- say, redhat-config-rootpassword, redhat-install-packages,
up2date-config, redhat-config-services, etc.

A noble concept indeed, but there is a nasty issue - since there's no
check for file origin, it should be more than obvious that suddenly,
any insecure file creation problem in an application used by a
superuser (or from privileged scripts, such as boot rc files,
crontabs, etc), it is possible to spoof a ticket in /var/run and
bypass root password prompt and other checks, and perform
administrative tasks, easily modifying system config, installing
custom components (say, a rootshell), etc. All this by crafting a
single symlink that is later opened with O_CREAT with no O_EXCL or
O_NOFOLLOW.

The simplest workaround for all concerned users is to first remove all
occurrences of pam_timestamp_check.so from /etc/pam.d, and replace
/sbin/pam_timestamp_check standalone helper, if possible. Perhaps
reconsider the necessity of having /usr/sbin/userhelper mechanism
implemented at all.

For Red Hat, my suggestion is to verify ticket contents. Say, have a
host-wide random key K, and put user_name, expire_time, MD5(K +
user_name
+ expire_time) in every ticket. The check code would verify the MD5
signature to make sure the origin of the ticket is sane, and the
originating application performed a specific operation on a not
publicly readable key.

On a side note, the per-terminal ticketing in pam_timestamp_check the
way it is has absolutely no significance and adds no protection,
since the A element of the path can be easily manipulated. Just an
example (there are other possible ways of accomplishing this):

    ln `tty` /tmp/tty1
    /usr/sbin/userhelper -w -t redhat-install-packages </tmp/tty1

As such, those tickets effectively become per-user, and an attacker
who compromised the account can snatch a ticket granted to the
legitimate user who already authenticated. Consider dropping the
honor tty system and granting per-user tickets to avoid giving users
a false sense of security.

I mailed pam_timestamp_check maintainer at Red Hat (Nalin Dahyabhai)
about a week ago, but never heard back from him. Since this is not an
issue alone, I decided to post the information here.

-- 
------------------------- bash$ :(){ :|:&};: --
 Michal Zalewski * [http://lcamtuf.coredump.cx]
    Did you know that clones never use mirrors?
--------------------------- 2003-07-02 11:07 --
(106471) /Michal Zalewski <lcamtuf@ghettot.org>/(Ombruten)
Kommentar i text 106474 av Carlos Villegas <villegas@math.gatech.edu>
106474 2003-07-02  23:48  /15 rader/ Carlos Villegas <villegas@math.gatech.edu>
Importerad: 2003-07-02  23:48  av Brevbäraren
Extern mottagare: Michal Zalewski <lcamtuf@ghettot.org>
Mottagare: Bugtraq (import) <5393>
Kommentar till text 106471 av Michal Zalewski <lcamtuf@ghettot.org>
Ärende: Re: Red Hat 9: free tickets
------------------------------------------------------------

This way of attack seems useless to me. This is also used on RH 8.0
systems, and for both 8.0 and 9 systems:

drwx------    4 root     root         4096 Jun 27 08:43 /var/run/sudo

Which means that if the packages are properly built (and will make
sure  that this directory gets this permissions if it existed before
the rpm is installed), this attack will gain you nothing, since you
need to be root to exploit it. If you can get root access to make
this attack possible, then you might as well launch a shell instead.

Carlos
(106474) /Carlos Villegas <villegas@math.gatech.edu>/(Ombruten)
106473 2003-07-02  23:48  /42 rader/ Michal Zalewski <lcamtuf@coredump.cx>
Importerad: 2003-07-02  23:48  av Brevbäraren
Extern mottagare: Carlos Villegas <villegas@math.gatech.edu>
Mottagare: Bugtraq (import) <5392>
Ärende: Re: Red Hat 9: free tickets
------------------------------------------------------------
On Wed, 2 Jul 2003, Carlos Villegas wrote:

> This way of attack seems useless to me. This is also used on RH 8.0
> systems, and for both 8.0 and 9 systems:
>
> drwx------    4 root     root         4096 Jun 27 08:43 /var/run/sudo
>
> Which means that if the packages are properly built (and will make sure
> that this directory gets this permissions if it existed before the
> rpm is installed), this attack will gain you nothing, since you need
> to be root to exploit it.

You have missed a point.

Please look at any vulnerability archives on the net, there is one to
several insecure file creation reports every week in applications
that either are run as root, or are invoked from boot scripts, or
from cron jobs. In most of those cases, it is possible to create a
dangling symlink and then exploit this problem to create a file in a
location the attacker have chosen, with permissions of the victim
(root).

Those vulnerabilities are generally considered a lesser threat, as
there seemed to be no practical method to easily gain root privileges
just by creating a file when no control over its contents can be
exercised (again, most cases). There is less interest in finding and
fixing those problems, and administrators are not that quick about
addressing them.

Thanks to pam_timestamp_check[.so] and the way it is used in Red Hat,
it is now possible to gain root in a generic way in those scenarios.

That's all. I could post it along with results of a quick grep and a
bunch of programs that do create files this way, but I believe it
would only confuse the reader. I think it's pam_timestamp_check that
should be fixed, because it makes it needlessly trivial to exploit
this vector.

-- 
------------------------- bash$ :(){ :|:&};: --
 Michal Zalewski * [http://lcamtuf.coredump.cx]
    Did you know that clones never use mirrors?
--------------------------- 2003-07-02 23:06 --
(106473) /Michal Zalewski <lcamtuf@coredump.cx>/(Ombruten)
107198 2003-07-04  18:39  /86 rader/ Spybreak <spybreak@hysteria.sk>
Importerad: 2003-07-04  18:39  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <5412>
Ärende: Generic way to exploit an insecure /tmp file creation - Red Hat 7,8,9  (Re: Red Hat 9: free tickets)
------------------------------------------------------------

On Wed, 2 Jul 2003, Michal Zalewski wrote:

> As far as I know, there was no neat and generic way to exploit an
> insecure /tmp file creation alone - well, until now.

Hello Michal and BugTraq,


there already has been a generic way to exploit O_CREAT w/o O_EXCL
in a world-writable directory issues, especially on Red Hat boxes.

My method exploits the Logwatch utility, what is a perl script
used for monitoring logfiles. Logwatch is a part of the Red Hat
distribution since releases 7.x , run daily by the cron daemon.
But the method is still usable on any system that runs Logwatch.

When I found the Logwatch tempdir vulnerability (BID-4374) in march
2002, I looked for a way to exploit this bug to get a root shell.
Basically we had the possibility to create or overwrite any file on
the filesystem, but with content we couldn't control much.

While I knew of possible attack vectors, they were not very
interesting in this case. Another audit run through the Logwatch code
showed that the problem is solved by Logwatch itself.

What Logwatch basically does, is feeding the logfiles through filter
scripts and emailing the results to a designated user (root by
default).  But the whole issue is in the way how it is done.

Here is the guilty code snippet from the latest Logwatch version -
4.3.2 (http://www.logwatch.org) :


if (opendir (LOGDIR,$BaseDir . "scripts/logfiles/" . $LogFile)) {
   foreach (sort readdir(LOGDIR)) {
      unless ( -d $BaseDir . "scripts/logfiles/$LogFile/$_") {
         $FilterText .= ("| $BaseDir" . "scripts/logfiles/$LogFile/$_");
      }
   }
   closedir (LOGDIR);
}
if ($FileText) {
   my $Command = $FileText . $FilterText . ">" . $TempDir . $LogFile;
   if ($Config{'debug'}>4) {
      print "\nPreprocessing LogFile: " . $LogFile . "\n" . $Command ."\n";
   }
   `/bin/cat $Command`;
}


Simply put, Logwatch has its filter scripts located in the
/etc/log.d/scripts/logfiles/* directories, and when some logfile is
parsed, Logwatch takes all filenames from the corresponding subdirectory
and constructs a command line including the filenames with pipes
between them and passes the command line to the shell.

It means if we create a file with a name of the form \`command\` in
one of these directories, the command gets executed with root privs,
when Logwatch is run by the cron daemon. And it doesn't matter, what
the  content of the created file is. What does matter is the filename.

So if we have some buggy privileged software that insecurely writes
into  e.g. /tmp/trash, the only thing we may need to do is something
like this:

ln -s /etc/log.d/scripts/logfiles/xferlog/'`cd etc;chmod 666 passwd`'
/tmp/trash

and wait for Logwatch to be run by cron.

While this is not a Logwatch bug by itself, because the filter-script
directories are writable only by root, it is a very helpful _flaw_
once we have an above mentioned insecure file creation issue in 
some privileged code, and provides an easy root access.
   
This method was already used to exploit e.g. vulnerabilities BID-4374
BID-5708, BID-5602.
       
    
Cheers,
Spybreak
(107198) /Spybreak <spybreak@hysteria.sk>/(Ombruten)
107411 2003-07-09  21:55  /53 rader/ Stephen Samuel <samuel@bcgreen.com>
Importerad: 2003-07-09  21:55  av Brevbäraren
Extern mottagare: Spybreak <spybreak@hysteria.sk>
Extern mottagare: vuln-dev@securityfocus.com
Extern mottagare: bugtraq@securityfocus.com
Mottagare: Bugtraq (import) <5495>
Ärende: Re: Generic way to exploit an insecure /tmp file creation - Red Hat 7,8,9  (Re: Red Hat 9: free tickets)
------------------------------------------------------------
I actually *would* describe the bug below as a logwatch bug.
If you have a uid=0 program calling shell scripts from
data like filenames, those filenames should be sanitized.
It would be easy enough to scan the filename for unexpected
characters and refuse to use them on that basis.

something as simple as:

if ($command =~ /[^\w]){
	carp "Unexpected filename: [[$LogFile]]. Not used\n"
}else{
     	`/bin/cat $Command`;
};

I believe that PERL actually has a pragma that you can set that
should cause it to complain about cases like this. (sorry --
don't have my book here with me).

Spybreak wrote:
> On Wed, 2 Jul 2003, Michal Zalewski wrote:
>>As far as I know, there was no neat and generic way to exploit an
>>insecure /tmp file creation alone - well, until now.
....
> What Logwatch basically does, is feeding the logfiles through filter
> scripts and emailing the results to a designated user (root by default).
> But the whole issue is in the way how it is done.
....
> if ($FileText) {
>    my $Command = $FileText . $FilterText . ">" . $TempDir . $LogFile;
>    if ($Config{'debug'}>4) {
>       print "\nPreprocessing LogFile: " . $LogFile . "\n" . $Command ."\n";
>    }
>    `/bin/cat $Command`;
> }
> 
....
> It means if we create a file with a name of the form \`command\`
> in one of these directories, the command gets executed with root privs,
> when Logwatch is run by the cron daemon. And it doesn't matter, what the 
> content of the created file is. What does matter is the filename.
.....
> While this is not a Logwatch bug by itself, because the filter-script
> directories are writable only by root, it is a very helpful _flaw_
> once we have an above mentioned insecure file creation issue in 
> some privileged code, and provides an easy root access.

-- 
Stephen Samuel +1(604)876-0426                samuel@bcgreen.com
		   http://www.bcgreen.com/~samuel/
    Powerful committed communication. Transformation touching
        the jewel within each person and bring it to life.
(107411) /Stephen Samuel <samuel@bcgreen.com>/------
107595 2003-07-12  23:23  /50 rader/ Jon Hart <warchild@spoofed.org>
Importerad: 2003-07-12  23:23  av Brevbäraren
Extern mottagare: Stephen Samuel <samuel@bcgreen.com>
Mottagare: Bugtraq (import) <5522>
Ärende: Re: Red Hat 9: free tickets
------------------------------------------------------------
On Sun, Jul 06, 2003 at 12:30:34PM -0700, Stephen Samuel wrote:
> The way it works is:
> 
> ln -s /var/run/sudo/mylogin/0:root /tmp/likely_tmp_name
> 
> Then you wait for or cause some setuid progrem to attempt to
> (insecurely) write to /tmp/likely_tmp_name .   When that happens,
> /var/run/sudo/mylogin/0:root is created, and pam_timestamp_check
> now allows you to run any helper application as if you'd
> typed in the root password...
> 
>  Since these helper applicaitons tend to allow all sorts
> of nasty work (like creating a uid=0 user), you've now got a
> *serious* security violation on your hands.
> 
> The face that /var/run/sudo is rwx root only is no protection
> because the open is doen by an suid-root program, and the symlink
> in /tmp can be created by anybody.
> 
> Proof of concept:
> 
> as youreslf:
> ln -s /var/run/sudo/$USER/unknown:root /tmp/oops
> 
> as root:
> touch /tmp/oops
> 
> as yourself: open the system-settings/users&groups utility from
> the desktop menu.
> 
> You can now create an account with uid=0
> 
> Now ANY exploit that can cause a setuid/root program to create
> an arbitrary file (regardless of content) can be used to create
> an arbitrary root user.
> 
> Finding such an exploit is left as an exercise for the user.

Actually, I'm not sure this entirely true.  Well, it is, but there is
another important condition that must be met for this (or similar)
attacks to work properly -- /var/run/sudo/$USER/ must exist.  This
means that the user must have previously sudo'd at lease once and
/var/run/sudo/$USER/ will have been created.

I'm sure there are ways to work around this, but in my experiments,
/var/run/sudo/$USER/ must exist if you hope to exploit something like
this with the predictable file name creation + symlink trick.

-jon
(107595) /Jon Hart <warchild@spoofed.org>/(Ombruten)