CESA-2007-005 - rev 2
[See all my vulnerabilities at
http://scary.beasts.org/security]
[Blog if you want to subscribe to new findings is at
http://scarybeastsecurity.blogspot.com/]
JDK image parsing library vulnerabilities (more ICC parsing)
Programs affected: JDK 1.6.0u3 and others.
Fixed version: JDK 1.6.0u5.
Reported date: October 2007.
Vendor advisory:
http://sunsolve.sun.com/search/document.do?assetkey=1-66-233325-1
Severity: Possible remote compromise of systems which use the vulnerable
JDK APIs to parse images.
JDK comes with an image parsing API based around the
javax.imagio.ImageIO
class. A slightly sloppy demo program to
exercise this API would be:
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import java.util.Iterator;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.ByteArrayInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
import javax.imageio.stream.ImageInputStream;
public class ImgReader {
public static void main(String[] args) throws Exception {
InputStream is = new FileInputStream(args[0]);
ImageInputStream iis = new MemoryCacheImageInputStream(is);
Iterator it = ImageIO.getImageReaders(iis);
ImageReader reader = it.next();
reader.setInput(iis);
int width = reader.getWidth(0);
}
}
This program takes the first command line argument as an image filename to
put through the JDK image parsing API.
Of course, most Java image parsing will be safe from the usual gamut of
buffer overflows, integer overflows, subtle memory corruptions, etc. Most, but
not all. The JPEG and BMP parsers support embedded ICC profiles (to do with
colour correction), and the ICC profile parser is actually backed by native
code.
Flaw 1 - DoS due to heap buffer out-of-bounds write with para-type curves
Demo JPG:
http://scary.beasts.org/misc/jdk/evilicc.jpg. It causes a crash of the JVM. The crash is caused by writing out-of-bounds
to a heap buffer. It is not immediately clear how controllable the data written
past the heap is, so this may be just a DoS. However, a DoS still represents
a serious problem in a server-side context.
The code flaw would seem quite unfortunate: 4096 bytes are allocated in a
buffer, which is then treated as being capable of fitting 4096 uint16 values.
It seems that any ICC profile containing a parametric-type curve should crash
out the JVM.
There seem to be a few genuine reports of what could be this issue in the
wild:
http://www.google.com/search?hl=en&q=sun.awt.color.CMM.cmmCombineTransforms&btnG=Google+Search
Flaw 2 - heap-based buffer overflow parsing curv-type curves
Demo JPG:
http://scary.beasts.org/misc/jdk/evilicc2.jpg.
This, on my machine, causes a crash due to an out-of-bounds heap write.
The code flaw is an integer overflow in SpCurveToPublic:
Limit = SpGetUInt32 (Buf);
...
UInt16Ptr = (KpUInt16_t *)SpMalloc (Limit * (KpInt32_t)sizeof (*UInt16Ptr));
...
for (Index = 0; Index < Limit; Index++)
*UInt16Ptr++ = SpGetUInt16 (Buf);
...
Comments
- The native code affected looks to be a library that is likely to be reused
in other commercial projects. You might want to run the evil JPEGs through
other ICC parsing packages.
- The heap overflow triggered in flaw 2) is somewhat wild in that it is
going to hit an unmapped page eventually.
However, JDK installs a
SEGV handler which usually crashes a second time (in a more controllable way),
making the condition much more interesting.
-
Lots of other ICC content parsing would seem to have integer overflows / buffer
overflow combinations, but it's not clear if these code paths can be reached
during a standard JDK JPEG parse.
Credits
- Google - this flaw was discovered in Google's time. I'm with Google's
Security Team, and we're always recruiting talented security individuals.
Mail me.
-
Christof Kaleschke and Markus Dorfer from lokalisten.de, for providing the
image analyzed in flaw 1) and leading to research ending in flaw 2).
CESA-2007-005 - rev 2
Chris Evans
scarybeasts@gmail.com