PNG Heap Corruption Vulnerability in inflate when using zlib version 1.0.4 or older



Build Config
15 years ago
12 years ago


(Reporter: Glenn Randers-Pehrson, Assigned: tor)


Firefox Tracking Flags

(Not tracked)



(1 attachment)



15 years ago
User-Agent:       Mozilla/5.0 (Windows; U; Win95; en-US; rv:1.2.1) Gecko/20021130
Build Identifier: Mozilla/5.0 (Windows; U; Win95; en-US; rv:1.2.1) Gecko/20021130

The following security bug with IE was publicized recently.  I have been
discussing it with Mark Adler, author of zlib.  We concluded that the bug
exists in zlib version 1.0.4 and earlier and was fixed in zlib-1.0.5 on
January 3, 1998.   Mozilla would not be vulnerable to the bug unless a user
builds it with that 5-year-old version of zlib.  This is possible, though,
because some platforms still have zlib-1.0.4 installed as the system
by default.

From: ("Marc Maiffret")
Newsgroups: mailing.unix.bugtraq
Subject: PNG (Portable Network Graphics) Deflate Heap Corruption Vulnerability
Date: Thu, 12 Dec 2002 19:31:14 +0000 (UTC)
Organization: NCTU CSIE FreeBSD Server
Lines: 282
Message-ID: <atao62$107h$>
X-Trace: 1039721474 33010 (12 Dec 2002
19:31:14 GMT)
NNTP-Posting-Date: Thu, 12 Dec 2002 19:31:14 +0000 (UTC)

PNG (Portable Network Graphics) Deflate Heap Corruption Vulnerability

Release Date:
December 11, 2002

High (Code Execution)

Systems Affected:
We have specifically tested the following software and verified the
potential for exploitation:
Microsoft Internet Explorer 5.01
Microsoft Internet Explorer 5.5
Microsoft Internet Explorer 6.0

Note: We have also successfully exploited this vulnerability via the IE web
control for Microsoft Outlook.

For the purpose of completeness we have included a listing of each product
that ships with the vulnerable pngfilt.dll version 6.0.2600.0 and prior. We
obtained this list from Microsoft&#146;s DLL Help Database:

Access 2000 SR1
BackOffice 4.5
Commerce Server 2000
DirectX 6.0 SDK
DirectX 6.0 SDK
Internet Explorer 4.0
Internet Explorer 4.01 SP1
Internet Explorer 4.01 SP1
Internet Explorer 4.01 SP2
Internet Explorer 4.01 SP2
Internet Explorer 5.0
Internet Explorer 5.01
Internet Explorer 5.5
Internet Explorer 5.5 Service Pack 2
Internet Explorer 6.0
Microsoft Visual Studio .NET (2002) Enterprise Architect
Microsoft Visual Studio .NET (2002) Enterprise Architect
Microsoft Visual Studio .NET (2002) Enterprise Developer
Microsoft Visual Studio .NET (2002) Professional
Office 2000 Developer
Office 2000 SR1
Office 2000 SR1
Office XP Professional
Project 2002 Professional
Publisher 98
Publisher 98
SNA Server 4.0 SP2
SNA Server 4.0 SP2
SNA Server 4.0 SP3
SNA Server 4.0 SP3
SQL Server 7.0
SQL Server 7.0
SharePoint Portal Server
Small Business Server 2000
Small Business Server 2000
Visio 2002 Professional
Visio 2002 Standard
Visual Basic .NET Standard 2002
Visual C# .NET Standard 2002
Visual C++ .NET Standard 2002
Visual FoxPro 7.0
Visual Studio 6.0
Visual Studio 6.0
Visual Studio 6.0 SP4
Visual Studio 6.0 SP5
Windows 2000 Datacenter Server
Windows 2000 Professional
Windows 2000 Server
Windows 95 OSR 2.5
Windows 95 OSR 2.5
Windows 98
Windows 98 Second Edition
Windows Millenium Edition
Windows NT 4.0 SP5
Windows NT 4.0 SP5
Windows XP Home 2002
Windows XP Professional 2002


Twas the night before Christmas, and deep in IE
A creature was stirring, a vulnerability
MS02-066 was posted on the website with care
In hopes that Team eEye would not see it there

But the engineers weren't nestled all snug in their beds,
No, PNG images danced in their heads
And Riley at his computer, with Drew's and my backing
Had just settled down for a little PNG cracking

When rendering an image, we saw IE shatter
And with just a glance we knew what was the matter
Away into SoftICE we flew in a flash
Tore open the core dumps, and threw RFC 1951 in the trash

The bug in the thick of the poorly-written code
Caused an AV exception when the image tried to load
Then what in our wondering eyes should we see
But our data overwriting all of heap memory

With heap management structures all hijacked so quick
We knew in a moment we could exploit this $#!%
More rapid than eagles our malicious pic came --
The hardest part of this exploit was choosing its name

Derek Soeder
Software Engineer
eEye Digital Security


During a review of the PNG image format implemented in Microsoft Windows,
two separate vulnerabilities were discovered related to the interpretation
of PNG image data. The first vulnerability deals with the handling of the
IDAT header and does not appear to be of significant threat level. The
second vulnerability can be exploited to execute code when the malicious PNG
image is viewed.  Due to the complexity of each of these vulnerabilities we
have decided only to describe the latter in detail.

General Description:
A heap corruption vulnerability exists due to the way the function
inflate_fast(), within pngfilt.dll, handles certain invalid data present in
&#147;deflate&#148; data input streams in a PNG image file.  The &#147;deflate&#148; compression
specification allows for the repetition of patterns that occur in the
decompressed data. This is accomplished by specifying a pair of special
codes that tell the decompression routine how far back into the decompressed
stream the pattern occurred (distance code), and the length of the pattern
to repeat in bytes (length code).  The inflate_fast() routine does not
properly handle length codes marked in the specification as invalid, and as
a result, a pattern can be replicated over a large portion of the heap,
allowing a skilled attacker to redirect the execution of a thread into a
&#147;deflated&#148; payload embedded in the deflate datastream within the malicious
PNG image.

Technical Description:
The heap overflow described above occurs in the interpretation of a
compressed block that uses fixed Huffman codes (BTYPE = 1).  Length codes
#286 and #287, while labeled as invalid in the formal specification (RFC
1951), are not discarded by the inflation routine, and are instead treated
as zero-length codes.  However, due to the way the inflation routine is
designed (see below), the length counter is decremented prior to being
evaluated, and an integer overflow will occur.  As a result, the loop will
attempt to repeat the pattern we specify over all 4GB (0xFFFFFFFF) of
virtual address space, filling our 32KB output buffer and proceeding to
overwrite process memory until finally reaching an invalid page in memory
and producing a fault.

The problem code is presented below in assembly, and C pseudo code.

        Pattern-repetition loop in PNGFILT.DLL. version 5.0.2920.0:

        69198FAF   mov         ecx,dword ptr [ebp+8]
        69198FB2   mov         cl,byte ptr [ecx]
        69198FB4   mov         byte ptr [edi],cl
        69198FB6   inc         edi
        69198FB7   inc         dword ptr [ebp+8]
        69198FBA   dec         dword ptr [ebp+0Ch]
        69198FBD   jne         69198FAF

        Pseudo-code representation of previous assembly:

                *dest = *src;
        while (--len);

After the process heap following the 32kb output buffer has been
overwritten, numerous threads running within the Internet Explorer process
attempt to free heap blocks whose memory management structures have been
overwritten.  By supplying a carefully crafted memory management header, we
can alter any 32-bit address to which we have write access in Internet
Explorer&#146;s virtual address space.

For the sake of demonstration, we will hijack the hook for the unhandled
exception filter, overwriting the pointer to the handler with the address of
a &#147;CALL DWORD PTR [ESI+0x4C]&#148; instruction present in MSHTML.DLL.  We explain
the purpose of this particular instruction below.

One of the threads that attempts to free a heap block with a memory
management structure we now control, will cause the unhandled exception
filter hook to be overwritten and will then cause an exception to be thrown
by accessing an invalid address. This exception is thrown due to the
following code sequence within RtlAllocateHeap() in NTDLL.DLL:

        77FCB3F5   mov     [ecx], eax
        77FCB3F7   mov     [eax+4], ecx

During this operation the eax register is set to the address within
MSHTML.DLL where our &#147;call dword ptr [esi+0x4c]&#148; resides. The ecx register
is set to the address of the unhandled exception filter hook.

After the first operation overwrites our exception filter hook, the second
operation will generate an exception when it attempts to &#147;mov&#148; our exception
handler address four bytes after the address we specified in the &#147;.text&#148;
section of MSHTML.DLL. An exception is generated due to the fact that code
sections, or &#147;.text&#148; sections are loaded into a process with read-only

The exception created by this operation is unhandled. The faulting thread
will then attempt to call the unhandled exception filter. Since the address
of this function has been changed, execution will redirect to the &#147;call
dword ptr [esi+0x4c]&#148;.

When an unhandled exception occurs, the unhandled exception filter is execut
ed and receives, as an argument, an exception record. The &#147;call dword ptr
[esi+0x4c]&#148; will redirect execution to an address supplied within the
exception record. The data at this address is part of our decompressed

The repeated pattern in our decompressed stream contains the two addresses
used to overwrite the unhandled exception filter hook, along with a padding
instructions and an unconditional &#147;jmp&#148; that will direct execution up what
is essentially a jump chain formed by the pattern repetition, into the
beginning of our deflated datastream and the deflated payload of choice.

During tests in our lab we noticed that under certain circumstances, race
conditions occur that make exploitation very difficult. We developed
intermediate solutions to these by reconstructing objects in heap so that
the conflicting threads would continue long enough for our target thread to
be exploited.

Mitigating Factors:
It should be noted that due to memory management system behavior across
various Windows operating system environments, exploitation may become
extremely difficult and in some cases unreliable.

Retina® Network Security Scanner has been updated to check for this

Vendor Status:
Microsoft was contacted in August 2002. Internet Explorer Service Pack 1
eliminates this vulnerability. Internet Explorer Service Pack 1 can be
retrieved using the following URL:

Microsoft has released a security bulletin for this flaw. It is located

Drew Copley, Research Engineer, eEye Digital Security

Derek Soeder, Software Engineer, eEye Digital Security
Riley Hassell, Research Engineer, eEye Digital Security

Hacktivismo!, Paul L. S. at UTD, JBNZ, and Kasia

Copyright (c) 1998-2002 eEye Digital Security
Permission is hereby granted for the redistribution of this alert
electronically. It is not to be edited in any way without express consent of
eEye. If you wish to reprint the whole or any part of this alert in any
other medium excluding electronic medium, please e-mail for

The information within this paper may change without notice. Use of this
information constitutes acceptance for use in an AS IS condition. There are
NO warranties with regard to this information. In no event shall the author
be liable for any damages whatsoever arising out of or in connection with
the use or spread of this information. Any use of this information is at the
user's own risk.

Please send suggestions, updates, and comments to:

eEye Digital Security

Reproducible: Didn't try

Steps to Reproduce:
1. can't because the sample crasher file has not been released publicly.

Mozilla could check for the presence of zlib-1.0.4 or earlier using the
"zlib_version" macro in zlib.h, and either refuse to use it or warn the
user that using it could allow a malicious web page to eat their lunch.

Comment 1

15 years ago
Taking - patch coming up...
Assignee: asa → tor
Group: security
Ever confirmed: true


15 years ago
Component: Browser-General → Build Config

Comment 2

15 years ago
What's the zlib 1.1.3 bugzilla number?  If configure checks for that, there's no
point in checking for this.


Comment 3

15 years ago
Created attachment 109351 [details] [diff] [review]
add version checking to zlib section

Comment 4

15 years ago
Greg: mozilla proper uses zlib 1.1.4.  NSS uses 1.0.4 (filed as bug 185479).

Comment 5

15 years ago
Ah, thanks, Tor.  (For anyone else who didn't know, "NSS" is Network Security
Services, .  Probably a Good
Thing if that doesn't have a code-execution vulnerability in it...)

Comment 6

15 years ago
Is it sufficient to check at configure time?  I've had other applications
configure fine with zlib-1.1.4 and then at runtime they find zlib-1.0.4
on the system and use that.  I would feel safer if there were a check
for an acceptable zlib_version at execution time.

BTW I cannot view bug 185479 but I did file a bug with Netscape this
morning after I did a quick search for zlib_version in the Mozilla source
tree and saw a lot of instances of version 1.0.4 in the nss part of the

Comment 7

15 years ago
On unix the resulting library when building the tree version of zlib is
libmozz, so it can't pick up the system one mistakenly.  On NT it's called
zlib - not sure what the win32 library search rules will choose.

Comment 8

15 years ago
...which is only the half the problem.  randeg's comment still applies if moz
was compiled on a system with 1.0.5+ and then deployed on an older 1.0.4 system.
Just out of curiousity: 
does this mean that microsoft are using the open source zlib?
It is quite strange so obscure bug shows on 2 places.

Comment 10

15 years ago
Georgi:  yes, of course.  Microsoft has never been shy about using BSD-licensed
code written by others.  And this is a generic zlib 1.0.4 bug--any program still
using it could be compromised.  The particular danger for PNG is that the eEye
guys already created a PNG image that can trigger it in MSIE and Outlook, and
the same image almost certainly would work on Windows versions of NSS, assuming
"untrusted images" could be fed to it somehow.  (I don't know what NSS does or
how it works, so maybe that's harder than it sounds.)

But something like this might also compromise older Linux systems (for example)
if they happened to use zlib 1.0.4 for PPP compression, which I think was true
in the 2.0 days.  No doubt you recall the zlib 1.1.3 security warning earlier
this year; zlib is used by *lots* of software.


Comment 11

15 years ago
I should add that there's some evidence to suggest that an exploit of this kind
of bug has been circulating since early November.  I've gotten half a dozen
reports of PNG images that can't be deleted because they're in use by something,
usually explorer.exe (when the user has sufficient clue to find out).  There's
no guarantee this is related, but it seems like a strange coincidence.

Comment 12

15 years ago
I'm inclined to say that the problem of deploying a dynamically linked mozilla
on a 1.0.4 system is the system vendor's problem, since the entire system is
vulnerable (ppp, tar, image viewers, emacs, etc...).

Comment 13

15 years ago
Comment on attachment 109351 [details] [diff] [review]
add version checking to zlib section

I agree with tor.
Attachment #109351 - Flags: review+

Comment 14

15 years ago
Checked in.

Adding wtc to CC list in case he's not in the security group (bug 185479).
Last Resolved: 15 years ago
Resolution: --- → FIXED
Removing confidential flag for bugs fixed over a year ago
Group: security

Comment 16

14 years ago
Zlib appears two places in the tree.  The one used by imglib (modules/zlib) has
been fixed but the one used by NSS (security/nss/cmd/zlib) is still at version
1.0.4 and I suppose is still vulnerable.  See bug #131826 (which does not
mention the previously-confidential vulnerability).

Comment 17

14 years ago
Oops, the other zlib is not vulnerable because it has been patched.  See my
recent comment in bug #131826.  <grumble> Maintenance would be simpler if there
were only one zlib in the tree or at least two identical ones.</grumble>
Product: Browser → Seamonkey


12 years ago
You need to log in before you can comment on or make changes to this bug.