This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert
Student-ID: SLAE-1154
This one details the use of an encoding scheme to encode the shellcode with and decode it subsequently on runtime, which is rather handy to evade anti-virus engines.
I’ve decided to use YEnc (draft 1.3). YEnc is used to encode binary data to be transmitted by email or newsgroups and uses the complete 8-bit character set, thus making its output only 1-2% larger than the original.
Basically, the encoding process consists of for any given character, increment its ASCII value by 42, modulo 256. Next, if the resulting character is a forbidden one (0x00, 0x0a, 0x0d and 0x3d), output the escape 0x3d character and increment the previous resulting character by 64, modulo 256.
The encoder does not strictly follow the draft, since it will not use the header, trailer and the CRC32 checksum.
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 |
|
1 2 3 4 |
|
The resulting shellcode is using the FPU fldz and fstenv instructions to get the absolute address of the shellcode. Due to the decoding process having to discard the escape characters, it is also pushing the final decoded characters to the stack instead of the data section, where it would imply having to overwrite the escape characters:
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 |
|
As usual, the configure script in the base directory can be used to tweak the code. In this case, the new -s command-line option should point to the shellcode to encode:
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 71 72 73 74 75 |
|
Debugging with gdb(1) shows that the absolute address of the shellcode is correctly retrieved, since the address of the last FPU instruction is 0x08048084, thus putting the encoded shellcode 4 bytes below in 0x08048088:
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 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
|
Given the above, the shellcode is being correctly decoded on the stack. Executing it yields a bind shell:
1 2 3 4 5 6 7 8 |
|