Subject: gzip: dir traversal bug when using "gunzip -N" Package: gzip Version: 1.3.5-9 Severity: important Tags: security patch
A directory traversal bug exists in multiple versions of gzip. When compressing a file, gzip saves its original name but not its path inside the compressed file. When using gunzip's "-N" option, the original name found inside the compressed file will be used as the name to save the decompressed file with. "gunzip -N" doesn't check if the original name inside the compressed file has any "/" characters in it. This makes it possible to create a malicious compressed file that when decompressed with "gunzip -N" will create a file at an arbitrary location in the file system, such as "/etc/nologin" or "/etc/cron.d/evil". The command "gunzip -N" prints no output during normal operation, so the user will not get any warning! The command "gunzip -Nv" prints information about what file it is creating where, but then it may be too late. The gunzip command always asks before overwriting existing files, so this bug only allows for creating new files and not overwriting old ones. This bug has some limited security implications. It allows attackers to create arbitrary files with arbitrary contents on a system, if they can get a user or a program with sufficient rights to decompress a .gz file from the attackers with "gunzip -N". At least the following gzip versions are affected: 1.2.4, 1.2.4a, 1.3.3, 1.3.4 and 1.3.5. I have attached the compressed file "dir-traversal-bug.gz" that will create a file in "/tmp" when decompressed with "gunzip -N". I have also attached a patch. // Ulf H�rnhammar -- System Information: Debian Release: 3.1 APT prefers testing APT policy: (500, 'testing') Architecture: i386 (i686) Kernel: Linux 2.6.8-2-686 Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1) Versions of packages gzip depends on: ii debianutils 2.8.4 Miscellaneous utilities specific t ii libc6 2.3.2.ds1-20 GNU C Library: Shared libraries an -- no debconf information
dir-traversal-bug.gz
Description: Binary data
--- gzip.c.old 2005-04-18 23:15:05.449840344 +0200 +++ gzip.c 2005-04-18 23:24:30.596924928 +0200 @@ -933,6 +933,10 @@ local int create_outfile() } /* Create the output file */ remove_ofname = 1; + char *baseout; + baseout = base_name(ofname); + strncpy(ofname, baseout, sizeof(ofname)); + ofname[sizeof(ofname) - 1] = '\0'; ofd = OPEN(ofname, flags, RW_USER); if (ofd == -1) { progerror(ofname);