CLD-284 Details

Other IDs this deficiency may be known by:

CVE ID CVE-2018-1000035 (nvd) (mitre) (debian) (archlinux) (red hat) (suse) (ubuntu)
Other ID(s)

Basic Information:

Affected Package(s) unzip
Deficiency Type SECURITY
Date Created 2018-02-08 15:53:19
Date Last Modified 2018-02-16 10:15:35

Version Specific Information:

Cucumber 1.0 i686 partially fixed in unzip-6.0-i686-3
Cucumber 1.0 x86_64 partially fixed in unzip-6.0-x86_64-3

Cucumber 1.1 i686 partially fixed in unzip-6.0-i686-3
Cucumber 1.1 x86_64 partially fixed in unzip-6.0-x86_64-3

Details:

=================================== Overview ===================================

Heap-based buffer overflow in password protected ZIP archives (CVE-2018-1000035)
InfoZip's UnZip suffers from a heap-based buffer overflow when uncompressing
password protected ZIP archives. An attacker can exploit this vulnerability
to overwrite heap chunks to get arbitrary code execution on the target system

================================ Initial Report ================================

From http://www.openwall.com/lists/oss-security/2018/02/08/1:

Vulnerability overview/description:
-----------------------------------
1) Heap-based buffer overflow in password protected ZIP archives (CVE-2018-1000035)

InfoZip's UnZip suffers from a heap-based buffer overflow when uncompressing
password protected ZIP archives. An attacker can exploit this vulnerability
to overwrite heap chunks to get arbitrary code execution on the target system.

For newer builds the risk for this vulnerability is partially mitigated
because modern compilers automatically replace unsafe functions with length
checking variants of the same function (for example sprintf gets replaced
by sprintf_chk). This is done by the compiler at locations were the length
of the destination buffer can be calculated.

Nevertheless, it must be mentioned that UnZip is used on many systems
including older systems or on exotic architectures on which this protection
is not in place. Moreover, pre-compiled binaries which can be found on the
internet lack the protection because the last major release of InfoZip's
UnZip was in 2009 and compilers didn't enable this protection per default at
that time. The required compiler flags are also not set in the Makefile of
UnZip. Compiled applications are therefore only protected if the used compiler
has this protection enabled per default which is only the case with modern
compilers.

To trigger this vulnerability (and the following) it's enough to uncompress
a manipulated ZIP archive. Any of the following invocations can be used to
trigger and abuse the vulnerabilities:

> unzip malicious.zip
> unzip -p malicious.zip
> unzip -t malicious.zip

Proof of concept:
-----------------
1) Heap-based buffer overflow in password protected ZIP archives (CVE-2018-1000035)

Unzipping a malicious archive results in the following output:
(On Ubuntu 16.04 with UnZip 6.0 which was installed via aptitude install unzip)

*** buffer overflow detected ***: unzip terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x*****)[0x************]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x**)[0x************]
/lib/x86_64-linux-gnu/libc.so.6(+0x*****)[0x************]
/lib/x86_64-linux-gnu/libc.so.6(+0x*****)[0x************]
/lib/x86_64-linux-gnu/libc.so.6(_IO_default_xsputn+0x**)[0x************]
/lib/x86_64-linux-gnu/libc.so.6(_IO_vfprintf+0x**)[0x************]
/lib/x86_64-linux-gnu/libc.so.6(__vsprintf_chk+0x**)[0x************]
/lib/x86_64-linux-gnu/libc.so.6(__sprintf_chk+0x**)[0x************]
unzip[0x40c02b]
unzip[0x4049ac]
unzip[0x40762c]
unzip[0x409b60]
unzip[0x411175]
unzip[0x411bdf]
unzip[0x404191]

Function names can be mapped to the backtrace by compiling the application
with debug symbols:

(gdb) backtrace
#0  0x000000000040c706 in UzpPassword ()
#1  0x00000000004043ce in decrypt ()
#2  0x000000000040731c in extract_or_test_entrylist ()
#3  0x00000000004094af in extract_or_test_files ()
#4  0x00000000004149a5 in do_seekable ()
#5  0x000000000041540f in process_zipfiles ()
#6  0x0000000000403921 in unzip ()

The vulnerability resides inside the UzpPassword function in the following
code snippet (file ./fileio.c):

[1591]	if ((prompt = (char *)malloc(2*FILNAMSIZ + 15)) != (char *)NULL) {
[1592]		sprintf(prompt, LoadFarString(PasswPrompt),
[1593]					FnFilter1(zfn), FnFilter2(efn));
...
[1595]	}					
					
The allocation at line 1591 allocates a fixed size buffer and then writes into
it at line 1592. It writes the following format string (PasswPrompt) into
the buffer: "[%s] %s password: "

This string has a length of 15 including the null-termination which explains
the +15 in the allocation. The developer allocated 2*FILENAMESIZ which
corresponds to 2 * PATH_MAX for the two format strings (zfn and efn).
zfn is the archive filename and can therefore not exceed PATH_MAX.
efn is the current processed filename inside the ZIP archive which should
typically be smaller than PATH_MAX for normal files. However, since an
attacker can manipulate the archive file the name can arbitrarily be chosen
which leads to a heap-based buffer overflow.

As already mentioned, modern compilers replace unsafe functions with
safe alternatives as a defense in depth mechanism.
This feature is called BOSC (Built-in object size checking) and is part
of the FORTIFY_SOURCE=2 protection.
The following link shows the source code (and vulnerability) inside
the Ubuntu package:
http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/unzip/trusty-updates/view/head:/fileio.c#L1593

By checking the installed compiled binary the following code can be seen:
(UnZip 6.0 from Ubuntu 16.04)

0x40bfc6:    mov    edi,0x200f
0x40bfcb:    mov    r13,r8
0x40bfce:    mov    QWORD PTR [rsp+0x8],r9
0x40bfd3:    call   0x401d30 
...
0x40c01a:    mov    edx,0x200f
0x40c01f:    mov    esi,0x1
0x40c024:    xor    eax,eax
0x40c026:    call   0x401f40 <__sprintf_chk@...>

The code allocates 0x200f (=4096*2 + 15) bytes but the unsafe sprintf
function was replaced with the length-checking sprintf_chk() function
which receives as argument the size of the buffer (0x200f at address
0x40c01a). The risk is therefore mitigated on Ubuntu (and other modern
operating systems), at least with the currently used compiler default flags.

However, many pre-compiled UnZip binaries can be found on the internet
which are not compiled with this protection.
For example, the following three links are the first links which can be
found when searching for InfoZip UnZIP on the internet and which contain
unprotected binaries:
http://gnuwin32.sourceforge.net/packages/unzip.htm
https://oss.oracle.com/el4/unzip/unzip.tar
http://www.willus.com/archive/zip64/

============================ Additional Information ============================

The full analysis and report is at
http://www.openwall.com/lists/oss-security/2018/02/08/1.

================================= Our Analysis =================================

----- Affected Products -----
Unzip 6.0 is vulnerable to this vulnerability. This includes unzip as originally
packaged in Cucumber Linux 1.0 and 1.1.

----- Scope and Impact of this Vulnerability -----
This vulnerability can allow an attacker to execute arbitrary code when the
user extracts a a specially crafted password protected zip file.

----- Fix for this Vulnerability -----
This vulnerability has been fixed in unzip 6.10c23; however, this version also
introduces new vulnerabilities that have not been fixed (namely
CVE-2018-1000034). Unfortunately, no patch has been released for the 6.0
version of unzip.

Alternatively, this vulnerability can reportedly be mitigated against by
compiling unzip with the -D_FORTIFY_SOURCE=2 CFLAG. This causes the compiler to
replace unsafe functions (i.e. sprintf) with their safe equivalents (i.e.
sprintf_chk), which mitigates the impact of this vulnerability to a denial of
service.

================================= Our Solution =================================

We have rebuilt unzip with the -D_FORTIFY_SOURCE=2 CFLAG, which partially fixes
this vulnerability: it prevents aribitrary code execution but still allows for
a denial of service.