4 - TRIPLE ENCODING
1 - INTRODUCTION
Encoding is one of the techniques used to evade AntiVirus (AV) and Intrusion Detection Systems (IDS) when writing shellcodes. The goal of this exercise is to apply a three phase encoding process to a well-known program, demonstrating that with the appropiate decoder the functionality of the program remains, whereas the pattern of the shellcode is severely changed. Overlaying three different techniques the resulting shellcode can be distorted in a better way than applying just one technique.
2 - TRIPLE ENCODING / DECODING STEP BY STEP
- First of all, let's take a shellcode to be encoded / decoded. The well-known execve-stack.nasm is an easy program whose effect is to spwan a shell:
- Once compiled, linked and tested, a shellcode can be extracted from execve-stack.nasm:
- This shellcode will be encoded using three different techniques, one after the other. For that purpose a Python script is used:
i) the original shellcode is ROL-ed byte by byte twice. For this purpose this function is used:
rol = lambda val, r_bits, max_bits: \
(val << r_bits%max_bits) & (2**max_bits-1) | \
((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
http://www.falatic.com/index.php/108/python-and-bitwise-rotation
ROL bitwise operator rotates a number to the left . As used at the Python script:
y = rol (x, 2, 8) <-- accepts x (byte) as input (8 bytes) and rotates it twice to the left.
ii) bytes resultant from last step are complemented with NOT operator: z = ~y
iii) a number is added to each one othe the bytes, 7 in this case: t = z + 7
- Once the Python script is executed, the result is a new shellcode that is the consequence of applying three consecutive encoding techniques:
- Now, a decoder program A4.nasm is created. The decoding process must be done in reverse order than the encoding:
i) 7 is substracted to each one of the bytes: sub byte [esi],0x07
ii) Bytes are complemented with NOT operator: not byte [esi]
iii) Bytes are ROR-ed twice: ror byte [esi], 0x2
- The whole program A4.nasm:
- A4.nasm is compiled and linked:
- There are no null opcodes:
3 - TESTING
- To create a testing program a shellcode is extracted from A4.nasm:
- The shellcode is applied to ShellcodeTest.c:
- Compiling ShellcodeTest.c:
- Executing ShellcodeTest.c the test is successful, because a shell is spawn, as expected:
4 - ANALYZING WITH GDB
- gdb is launched for ShellcodeTest:
- A breakpoint is set where the shellcode is located:
- Running the program:
- Disassembling, "call" instruction for the shellcode is detected:
- A second breakpoint is set, just before "call" instruction:
- The execution of the program continues:
- Disassembling, instructions from the original program execve-stack.nasm are detected, confirming that the decoding process has been successful:
- Starting again gdb and executing the whole program the shellcode is spawn, as expected: