<<< Date Index >>>     <<< Thread Index >>>

Re: gzip TOCTOU file-permissions vulnerability



On Tue, Apr 12, 2005 at 01:47:01PM +0200, Martin Pitt wrote:
[SNIP]
> > Vulnerability
> > ==============
> > 
> > If a malicious local user has write access to a directory in which a
> > target user is using gzip to extract or compress a file to then a
> > TOCTOU bug can be exploited to change the permission of any file
> > belonging to that user.
[SNIP]
> I tried this with gzip 1.3.5 and cannot reproduce this; when
> gunzip'ing a file, the output file is _always_ created with 0600
> permissions first, and chmod'ed to the original permission after
> decompression finished. 

Let's pretend the target user's user name is targetuser, they have a
home directory with permissions drwxr-xr-x, and in their home
directory they have a file My_Financial_Accounts with permissions
-rw------- that the attacker wants to access.  The attacker has write
access to the directory in which the user is unzipping files.

Basically, after this code is executed:

>         /* Create the output file */
>         remove_ofname = 1;
>         ofd = OPEN(ofname, flags, RW_USER);
>         if (ofd == -1) {
>             progerror(ofname);
>             close(ifd);
>             return ERROR;
>         }

The attacker runs the equivalent of the following shell commands:

  unlink $file
  link ~targetuser/My_Financial_Accounts $file

We use $file as the name of the file which gzip is going to write.
These commands must complete before the writing of the file is
finished, so the attacker would choose to do this while gzip was
unzipping a file that he knew to be large.  He also knows that the
file will have permissions 0644 when done (maybe because he creeated
the gzip archive, or at least has previous knowledge of it).  The
original file is deleted, and replaced with a hard link to
My_Financial_Accounts, the target file.  It has owner targetuser, and
permissions 0600, same as My_Financial_Accounts.  

After the file is finished being written, the program calls chmod to
change the permissions to 0644.  Now attacker can read $file, which
happens to be a hard link to My_Financial_Accounts.

The attacker could potentially distract the target user long enough to
make a copy of the file and then switch it quickly to the real file
(by re-linking it to his own copy of the gzipped file, in order to
avoid having to write the whole file again) before the target user
notices.  Of course, if the target user sees that the ownership of the
file is the attacker and not himself, that might raise a flag...  But
that's a detail that may be easily overlooked, especially if the user
is fairly new to Unix and naive about Unix permissions.  Other forms
of deception may be possible, and of course the attacker could just
rm the file to avoid being detected.  The attacker could, for example,
do all of this while standing right infront of the target user, logged
into the system remotely via wireless palm device, the target user all
the while unaware of what he was doing.

The open() call is at fault here.  If instead of being called with a
mode of RW_USER, it is called with the final intended access mode,
there is no need to later call chmod(), and the problem is averted.

I think it's important to note that the directory need not be
world writable to effect this attack.  The attacker and target user
might be part of the same programming team, or what have you, and be
working in a directory that's group-writable by their Unix group...
Such directories arguably should still have the sticky bit set; but
it's easy to overlook that detail, AND the group may not WANT the bit
set because of how the directory is used and/or their work process.


-- 
Derek D. Martin
http://www.pizzashack.org/
GPG Key ID: 0x81CFE75D


Attachment: pgpndoSGDg04q.pgp
Description: PGP signature