Menu

#87 Global-buffer-overflow on optipng

v1.0 (example)
open
None
5
2023-11-04
2023-09-17
zengyx
No

Global-buffer-overflow on optipng

For a detailed graphic description of this vulnerability, please see: https://github.com/Frank-Z7/z-vulnerabilities/blob/main/optipng-heap-buffer-overflow1/optipng-heap-buffer-overflow1.md

Description

We found a global-buffer-overflow on OptiPNG.

Running optipng with the "-zm 3-zc 1-zw 256-snip-out" configuration options enabled raises a global-buffer-overflow bug, which could allow a remote attacker to conduct a denial-of-service attack or other unspecified effect on a crafted file.

It should be noted that optipng (version 0.7.7) downloaded through apt-get can also trigger this vulnerability, which may endanger the system security of Debian users.

It should be noted that CVE-2017-16938 also found the global-buffer-overflow bug in the old version of OptiPNG (version 0.7.6), but the bug we found this time is different from CVE-2017-16938. In CVE-2017-16938, there is a global-buffer-overflow bug in the global variable 'stack'(defined in 'gifread.c:401:16',version 0.7.6) and the global variable 'oldcode'(defined in 'gifread.c:398:27',version 0.7.6). The global-buffer-overflow bug we discovered this time is caused by global variable 'buffer' (defined in 'gifread.c:334:26', version 0.7.7).

Version

OptiPNG version 0.7.7.

This is the latest version of http://optipng.sourceforge.net/

root@38ad1e4b9d16:/test2/optipng-0.7.7/src/optipng# /test2/optipng-0.7.7/src/optipng/optipng --version
OptiPNG version 0.7.7
Copyright (C) 2001-2017 Cosmin Truta and the Contributing Authors.

This program is open-source software. See LICENSE for more details.

Portions of this software are based in part on the work of:
  Jean-loup Gailly and Mark Adler (zlib)
  Glenn Randers-Pehrson and the PNG Development Group (libpng)
  Miyasaka Masaru (BMP support)
  David Koblas (GIF support)

Using libpng version 1.6.34 and zlib version 1.2.11-optipng

Reference

OptiPNG Official website: http://optipng.sourceforge.net/

Source Code Download: https://sourceforge.net/projects/optipng/files/OptiPNG/optipng-0.7.7/optipng-0.7.7.tar.gz/download?use_mirror=udomain&download=

Actual Behavior

global-buffer-overflow

PoC

POCoptipng:https://github.com/Frank-Z7/z-vulnerabilitys/blob/main/POCoptipng

Reproduction

#First,install Aflplusplus to use ASAN and other vulnerability analysis functions
git clone https://github.com/AFLplusplus/AFLplusplus
cd AFLplusplus
apt install build-essential libtool-bin python3-dev automake flex bison libglib2.0-dev libpixman-1-dev clang python3-setuptools llvm
make
make install

#Then download the latest optipng source code (version0.7.7) from https://sourceforge.net/projects/optipng/files/OptiPNG/optipng-0.7.7/optipng-0.7.7.tar.gz/download?use_mirror=udomain&download=
tar -xvf optipng-0.7.7.tar.gz
cd optipng-0.7.7

#Next, we compile optipng
export CC=afl-clang-fast
export CXX=afl-clang-fast++
./configure
AFL_USE_ASAN=1  make

#Finally, we run optipng with the PoC file under specific configuration options.
src/optipng/optipng -o4 POCoptipng -zm 3 -zc 1 -zw 256 -snip -out optipngtest.png

ASAN Log

=================================================================
==1681804==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000e73918 at pc 0x00000054f5ce bp 0x7fffffffa350 sp 0x7fffffffa348
READ of size 1 at 0x000000e73918 thread T0
    #0 0x54f5cd  (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x54f5cd)
    #1 0x54d98f  (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x54d98f)
    #2 0x54c8cc  (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x54c8cc)
    #3 0x4def39  (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x4def39)
    #4 0x4dac27  (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x4dac27)
    #5 0x4cb8c4  (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x4cb8c4)
    #6 0x4c8cbd  (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x4c8cbd)
    #7 0x4c85bc  (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x4c85bc)
    #8 0x4c6966  (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x4c6966)
    #9 0x7ffff7c52082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #10 0x41c52d  (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x41c52d)

0x000000e73918 is located 0 bytes to the right of global variable 'buffer' defined in 'gifread.c:334:26' (0xe73800) of size 280
SUMMARY: AddressSanitizer: global-buffer-overflow (/afltest/optipng/optipng-0.7.7/src/optipng/optipng+0x54f5cd)
Shadow bytes around the buggy address:
  0x0000801c66d0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x0000801c66e0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x0000801c66f0: 00 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9
  0x0000801c6700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000801c6710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0000801c6720: 00 00 00[f9]f9 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
  0x0000801c6730: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 01 f9 f9 f9
  0x0000801c6740: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
  0x0000801c6750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000801c6760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0000801c6770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==1681804==ABORTING

Location

global variable 'buffer' defined in 'gifread.c:334:26'.

Environment

ubuntu:20.04
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)
clang version 10.0.0-4ubuntu1
afl-cc++4.09

Credit

Zeng Yunxiang (Huazhong University of Science and Technology)

1 Attachments

Discussion

  • zengyx

    zengyx - 2023-09-22

    configuration options:"-zm 3 -zc 1 -zw 256 -snip -out"

     
  • Sebastian Pipping

    @zengyx is there a patch for this?

     
    • Thomas Hurst

      Thomas Hurst - 2023-10-30

      A simple fix that just adds a bounds check: https://gist.github.com/Freaky/0effd5f4bd3895f256329289bc45897e

      The "configuration options" appear completely meaningless, you don't need any particular flags to trigger this.

       

      Last edit: Thomas Hurst 2023-10-30
  • Cosmin Truta

    Cosmin Truta - 2023-11-03
    • assigned_to: Cosmin Truta
     
  • Cosmin Truta

    Cosmin Truta - 2023-11-03

    Thank you, Thomas, for the fix that you proposed. It is straightforward, and it solves the problem.

    I want to publish a new release (v0.7.8), with an overhaul of the GIF reader, which was originally forked and then heavily modified, eons ago, from the same original code by David Koblas. Among other programs that are based on the same old code, the most notable one is gif2png. Interestingly enough, that program is unaffected by this POC test case, but that's because of the differences in the handling of bogus data outside of the LZW-compressed stream, which makes the LZW-compressed stream different.

    I'm still thinking whether to catch up with gif2png's own modifications of the GIF reader, or better yet, whether to "steal" that one entirely. But before I do that, I need to align the differences between OptiPNG and gif2png in how they handle the external bogus data.

     
    • Sebastian Pipping

      Hi Cosmin, would you recommend Thomas' patch for application as-is in Linux distros before the is a release 0.7.8? I think distros would want to patch before 0.7.8 unless it's only a few days away. Is there anything making sure that "curbit + code_size" cannot overflow btw? Best!

       
  • Cosmin Truta

    Cosmin Truta - 2023-11-03

    I just did what I should have done days ago: ship version 0.7.8 with Thomas' fix as-is. And then, should a follow-up fix turn out to be necessary, I'll do it in the next release.

    Sebastian wrote:

    Is there anything making sure that "curbit + code_size" cannot overflow btw?

    I don't know the answer to this question, which is why I wanted to investigate the other LZW implementations out there, and to understand exactly why they are robust in a way that this one inside OptiPNG isn't.

    I uploaded the fresh archives to SourceForge, and I will send an announcement as well, in a few minutes. Even if this bug may be considered fixed, I will leave this discussion open until I'm ready to say with certainty what has truly been happening with those LZW codes.

     
    • Sebastian Pipping

      Thanks, Cosmin! OptiPNG is at 0.7.8 in Gentoo now.

       

Log in to post a comment.

MongoDB Logo MongoDB