Bugzilla – Bug 917760
VUL-0: CVE-2015-1315: unzip: DOS, possible RCE by out-of-bounds write
Last modified: 2015-02-18 08:34:26 UTC
Date: Fri, 13 Feb 2015 00:02:14 +0100 From: William Robinet <william.robinet@conostix.com> Here is a crash file [0] for Info-ZIP unzip. I tested it on Ubuntu 14.04.1 LTS amd64 with unzip-6.0-9ubuntu1.2. $ unzip -l crash.zip Archive: crash.zip Segmentation fault (core dumped) $ echo $? 139 $ unzip crash.zip Archive: crash.zip Segmentation fault (core dumped) $ echo $? 139 The problem comes from the "unix/unix.c:charset_to_intern()" function from the "06-unzip60-alt-iconv-utf8" patch (cfr relevant excerpt at [1]). Arbitrary code execution is most probably possible. It's just a matter of time in order to get a working exploit. Here are the details. Please refer to the code of the "unix/unix.c:charset_to_intern()" function in [1]. The problem is triggered during string conversion from CP866 to UTF-8: (gdb) p local_charset $2 = 0x7ffff755330c "UTF-8" (gdb) p from_charset $3 = 0x62bda0 <OEM_CP> "CP866" The "string" variable is allocated at: fileio.c:2207 G.filename_full = malloc(fnbufsiz); Size of the allocation is defined by fileio.c:2201 extent fnbufsiz = FILNAMSIZ; and unzpriv.h:1198 #define FILNAMSIZ PATH_MAX Finally "string" has a maximum size of: (gdb) p PATH_MAX $1 = 4096 The "buf" variable is used as the destination buffer for the result of the string conversion of the "string" variable by the "iconv" function at unix/unix.c:1948. "buf" is allocated with a size of twice (+1) the actual size of the string referenced by the "string" variable at unix/unix.c:1942. Finally, after conversion, the actual string referenced by "buf" is copied to "string" at unix/unix.c:1950. The problem is that, in some case and after conversion, the actual size of the string referenced by "buf" can be larger that the maximum size of the "string" buffer (4096). This leads to a heap-based buffer overflow. Here is an example gdb session (unzip has been recompiled with -g -ggdb3). RIP control can be easily achieved. As an example, with the attached crash.zip file, RIP is set to 0x414141 (just before crashing). The 0x414141 value can be changed at offset 0x1599 in the crash.zip file. $ gdb -q unzip Reading symbols from unzip...done. (gdb) b unix/unix.c:1950 Breakpoint 1 at 0x41ef32: file unix/unix.c, line 1950. (gdb) r -l crash.zip Starting program: /usr/bin/unzip -l crash.zip Archive: crash.zip Length Date Time Name --------- ---------- ----- ---- Breakpoint 1, charset_to_intern (string=0x71c120 <G+983872> '\313' <repeats 199 times>, <incomplete sequence \313>..., from_charset=0x62bda0 <OEM_CP> "CP866") at unix/unix.c:1950 1950 strncpy(string, buf, buflen); (gdb) p strlen(string) $1 = 2714 (gdb) p strlen(buf) $2 = 4395 (gdb) n 1953 free(buf); (gdb) p strlen(string) $4 = 4395 <--------------- Overflow has occurred (gdb) p strlen(buf) $5 = 4395 (gdb) b *0x414141 <-------- Let's break at the selected arbitrary address Breakpoint 2 at 0x414141: file process.c, line 1364. (gdb) c
so this "Enter" should not have send the bug report ... ========== Continuing. Breakpoint 2, 0x0000000000414141 in find_ecrec64 (searchlen=1423209390) at process.c:1364 1364 Info(slide, 0x401, ((char *)slide, (gdb) info reg rax 0x1e 30 rbx 0x20 32 rcx 0x0 0 rdx 0x1e 30 rsi 0x70bee0 7388896 rdi 0x62bde0 6471136 rbp 0x7fffffffe430 0x7fffffffe430 rsp 0x7fffffffe2a8 0x7fffffffe2a8 r8 0x7ffff7972840 140737347266624 r9 0x2 2 r10 0x7ffff7bb9760 140737349654368 r11 0x0 0 r12 0x414141 4276545 r13 0x2d 45 r14 0x2d 45 r15 0x0 0 rip 0x414141 0x414141 <find_ecrec64+2537> <-- RIP was redirected to the arbitrary address 0x414141 eflags 0x202 [ IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 (gdb) At this point, getting arbitrary code execution is just a matter of time. The locale config of my test systems is en_US.UTF-8 . [0] Attachment: crash.zip (SHA256: d79d6612ffabe7906f0afdf7293de819950623ffc2004fa501f874a42547d7d8) [1] Attachment: 06-unzip60-alt-iconv-utf8.excerpt (SHA256: 7043a3cd71618085281400ed1ae576964ae5067e7a28cf664510ab20f9ef055e)
Created attachment 623175 [details] Crasher
CRD: 2015-02-17 Crasher doesn't work on openSUSE 13.2. I checked SLE 12 and we don't have the patch that introduces the vulnerability, so we're probably not vulnerable. Please check older versions and close this bug if we're not vulnerable.
bugbot adjusting priority
Introduced in 6.1, doesn't affect us.
public