I reported the following vulnerability to AUSCERT, but they weren''t interested. People on this list might be, though! GNU tar is lazy about file creation modes and file owners when unpacking a tar file. Because GNU tar defaults to creating files owned by the userid running tar when the username is not found on your system, it can be possible to inadvertantly create setuid root programs. Let me give you an example: On machine A, as user "fred" (uid doesn''t matter), use gtar to create a tar file of the directory ~/files. Inside the subdirectory, place a copy of /bin/bash and, as fred, make the program setuid fred (the mode 4755 works well). Set the tar file to someone on machine B where the user "fred" does not exist and have them unpack the directory somewhere. Since "fred" does not exist on machine B and gtar is being run as root, you have created a world-executable setuid-root shell. I stumbled on this when using a `tar | rsh tar'' pipeline to transfer a bunch of home directories from one machine to another. I thought all users on the source machine existed on the destination, but this was not the case. Furthermore, for all files owned by the users not on both machines, they were created with ownership to root . . including some setuid programs which were now setuid root! It''s very, very easy to get caught out by this. I''d like to see GNU tar strip the setuid bit off files it has to revert the ownership for due to an unknown original owner. Ben. -- Ben Elliston <bje@air.net.au>
-- [ From: Paul-Joseph de Werk * EMC.Ver #3.2 ] --> Date: Saturday, 25-Jan-97 09:37 AM > From: linux-security@redhat.com \ Internet: (linux-security@redhat.com) > To: bugtraq@netspace.org \ Internet: (bugtraq@netspace.org) > To: linux-security@redhat.com \ Internet: (linux-security@redhat.com) > Subject: [linux-security] GNU tar vulnerability > > I reported the following vulnerability to AUSCERT, but they weren''t > interested. People on this list might be, though! > > GNU tar is lazy about file creation modes and file owners when unpacking > a tar file. Because GNU tar defaults to creating files owned by the > userid running tar when the username is not found on your system, it can > be possible to inadvertantly create setuid root programs.[[...snip...]]> It''s very, very easy to get caught out by this. I''d like to see GNU tar > strip the setuid bit off files it has to revert the ownership for due to > an unknown original owner.I''d prefer to see GNU tar add an option that basically says "I trust any setuid/setgid flags in this tar, keep them." If the option isn''t specified when de-tarring then it should strip the flags for safety. -- #include <stddiscl.h> | Quote: Paul-Joseph de Werk, BSCS | Sr. Systems Programmer | Every accomplishment MCI Telecommunications Corporation | starts with the decision State Government and University Markets | to try. mailto:Paul.deWerk@MCI.Com | pdewerk@campus.mci.net | --Unknown http://www.campus.mci.net/~pdewerk/ |
Martinez ; Sylvain - BSc Mod Comp
1997-Feb-03 12:14 UTC
Re: [linux-security] GNU tar vulnerability
On Sat, 25 Jan 1997, Ben Elliston wrote:> to create a tar file of the directory ~/files. Inside the > subdirectory, place a copy of /bin/bash and, as fred, make > the program setuid fred (the mode 4755 works well). > > Set the tar file to someone on machine B where the user "fred" > does not exist and have them unpack the directory somewhere. > Since "fred" does not exist on machine B and gtar is being > run as root, you have created a world-executable setuid-root > shell.Well, I''ve tried on Linux and HPUX, and when you do : tar xvf file.tar all the files have got the ID of the user who have done the tar command. Do I miss something ? Anyway, it seems to be normal, you can''t put your home linux root shell on a disk and then after mount the disk on an other Linux system as a normal user and run your root shell ... Best regards, Sylvain. ---LINUX---LINUX---LINUX---LINUX---LINUX---LINUX---LINUX---LINUX--- MARTINEZ Sylvain BSc in Computer Science (University of Teesside, UK) Passion: Cryptography and Network Security r903633@tees.ac.uk http://www.asi.fr/~martinez
> Well, I''ve tried on Linux and HPUX, and when you do : tar xvf file.tar > all the files have got the ID of the user who have done the tar command.run tar as root? don''t use the -p flag> Anyway, it seems to be normal, you can''t put your home linux root shell on > a disk and then after mount the disk on an other Linux system as a > normal user and run your root shell ...you would let users mount remote file systems? with the suid flag switched on in /etc/fstab? god.... [Mod: Lets consider this topic closed as it is clearly a case of misconfigured system -- alex] *-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-*-=-* Wim Vandeputte --So pound the nails in tight--
> > [Mod: Lets consider this topic closed as it is clearly a case of > misconfigured system -- alex]I''m sorry but it is not a case of a misconfigured system at all, the original complaint is valid and should not be dissmissed at all. In my opinion, GNU tar is broken, it SHOULD be creating the file with the UID/GID of the original file but it is not. (see my other post to this). Try it yourself if you don''t believe me: create a new user, call it foo. Create a suid(foo) file (/bin/bash is as good a choice as any) and create a tar file of that suid binary. remove the user foo and untar the file in /tmp -- check to see that the file is now suid(root). It *should* have been suid(uid-of-foo). To really see this as the bug that it is, do the same as above but don''t create the user first, you will then see the proper behaviour. GNU Tar gets this wrong and it is a concern. cheers, kinch [mod: I was going to write this blurb myself, but you beat me to it.... One more note: Gnu tar here does something unexpected. You may keep shouting "USER ERROR", but unix tries to be as consistent as it can, to keep surprises to a minimum. That''s what this is about. Suppose you have a system full of students. One student needs to be moved to another system. suppose you do this: m1:/home # tar cf - stud1 | rsh m2 "cd /home;tar xvf -" m1:/home # grep ^stud1: /etc/passwd | rsh m2 "cat >> /etc/passwd" You should have done this the other way around. Did you expect to give "root" away with this? No. At least I didn''t. This resulted in the users''s account having "root" as the owner, which allows him just limited access to his account. The user will come back asking for: m2:/home # chmod -R stud1 stud1 But all setuid-stud1 files were suddenly setuid-root.... You''ve unknowingly given "root" access away..... Not good. -- REW]
There is some debate as to whether this is a bug or not, in my view it is and so I supply a patch for those that want to fix it. Discussion: GNU tar extends the standard tar format to include names for owner and group AS WELL AS UID/GID values in the header. The intent is to be able to restore files under the correct user name when run by root. The problem is that the names take precedence over the uid/gid EVEN IF they are nonexistent on the system extracting the files. So, when root goes to extract a file with names used in the header and those names are not found, those files get owned by root and not by the uid/gid of the underlying file. This problem is compounded when the file in the archive is setuid, the extracted file becomes a setuid(root) file which is surely not what is expected. Rather than try to determine when to remove the setuid bit and when not to, I decided that the Right Answer is to honour the UID/GID pair in the header if the names used in the header is a nonexistent user/group. [mod: about 5 people reported the same without taking the trouble to write the patch. Good work Dave! -- REW] --- tar-1.11.8/src/list.c.orig 1997/02/05 21:10:10 1.1 +++ tar-1.11.8/src/list.c 1997/02/05 21:43:51 @@ -414,6 +414,9 @@ decode_header (register union record *header, register struct stat *st, int *stdp, int wantug) { + int saveuid; + int savegid; + st->st_mode = from_oct (8, header->header.mode); st->st_mode &= 07777; st->st_mtime = from_oct (1 + 12, header->header.mtime); @@ -435,13 +438,22 @@ st->st_uid = from_oct (8, header->header.uid); st->st_gid = from_oct (8, header->header.gid); #else + /* + * if there is a name saved and it produces a non-root uid from + * finduid(), use that value otherwise fall back to using the + * uid from the header. This saves tar from making inappropriate + * setuid(root) files from nonexistent users + */ + st->st_uid (*header->header.uname - ? finduid (header->header.uname) + ? saveuid=finduid (header->header.uname) + ? saveuid : from_oct (8, header->header.uid) : from_oct (8, header->header.uid)); st->st_gid (*header->header.gname - ? findgid (header->header.gname) + ? savegid=findgid (header->header.gname) + ? savegid : from_oct (8, header->header.gid) : from_oct (8, header->header.gid)); #endif }
| > > GNU tar is lazy about file creation modes and file owners when | > > unpacking a tar file. | On Sat, 25 Jan 1997, der Mouse wrote: | > | > Whaaaaat? [...] Hello, Mike. I''m just remembering your voice, and am really *hearing* you when I read that :-) :-). | > If GNU tar, by default, uses a private header format that contains | > string names instead of the numeric UID and GID info a standard tar | > header block holds, IMO that is a crippling bug, because it will | > render it uninteroperable. Oh, it is not a private format. It is roughly POSIX. GNU tar already supports old V7 format, a few BSD idiosyncrasies, and an obsolete draft of POSIX ustar format. Maintainers (before me) added extensions to that draft format, in such a way that it is now incompatible with the more recent POSIX ustar format, and put GNU tar in a difficult position as for its evolution. I''m trying to correct that. I now have to support all previous formats while reading archives, including a few different ways for implementing long file names, and some new format I''m trying to devise for accommodate GNU extensions, in a way which is more respectful of latest POSIX extension mechanisms. Yet, a bit uncomfortably, I''m under pressure to use some extra free space at the end of the current (comparatively new) POSIX header, so files will usually not need any extra header block for the cases which are most common in GNU and elsewhere. However, the exact ways are not completely decided, and I would surely be happy to have a lot of feedback and opinions before they crystallise. GNU tar has an option to generate old (V7) headers, this option will be kept. By default right now, it generates obsolete-POSIX GNU-augmented headers -- not wonderful for interchange, I agree, yet real problems seem to be infrequent in practice. My current goal is to generate latest-POSIX headers by default, with some extra values in the last few undefined bytes of the POSIX block, and to generate extension blocks for less usual GNU specialities (like volume labels, multi-volume resuming, and such strangeties). There will also be an option to force stricter POSIX conformance, and so, to disallow most GNU extensions. | I''ve found that GNU tar will create files owned by uids/gids not in | /etc/passwd...but it seems to only do so when I don''t necessarily | need it to. I often see this happen when untaring new sources into | /usr/local/src/. POSIX headers have both numeric and symbolic identification for owners and groups. If symbolic identification succeeds at extraction time, it may imply ignoring the stored numeric identification, so effectively changing from the numeric value stored into the archive. Only a few days after the release of GNU tar 1.11.8, I made some cleanup in this area: there was a long lasting bug by which restored files were all owned by root if using an incomplete /etc/passwd or /etc/group file. They now use the stored numeric identification if the symbolic identification is not successful. (All this either as root, or as user with the -p option on systems allowing users to give away their files --- in which case special bits are duly reset --- hoping I remember correctly.) I also added an option for GNU tar to merely ignore all symbolic identification. | When restoring a full backup to a blank disk, I''ve found that if the | /etc/passwd isn''t restored first, all user files (and nearly everything | else) will end up owned by root. Many GNU tar users considered this to be a bug and reported it as such. As I implied earlier, this should be corrected in the next real release. It has already corrected in pretest releases for quite a while by now. If you have any further comment on these matters, be sure they reach me, either by mailing directly to the address in my signature (or Reply-To: field), to <tar-bugs@gnu.ai.mit.edu> or to <tar-forum@iro.umontreal.ca>. I''m not on the security lists to which this reply is being sent. =09=09=09Thanks for your collaboration, everybody. [mod: I hope this wraps it up. -- REW] -- Fran=E7ois Pinard ``Vivement GNU!'''' pinard@iro.umontreal.ca Support Programming Freedom, join our League! Ask lpf@lpf.org for info!