SLAE32 - Assignment 6

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

Student ID: PA-15072

All associated code can be found here:

Polymorphic Shellcodes

Assignment 6 required students to take three shellcodes from shellstorm and create polymorphic versions of them.


  • Take up 3 shellcodes from Shell-Storm and create polymorphic versions of them to beat pattern matching
  • The polymorphic versions cannot be larger 150% of the existing shellcode

Shellcode 1:

The first shellcode I chose for this assignment was a shellcode which adds a value to an /etc/hosts file, available here

I like the idea here, as it's a little out of the normal shellcode tactic. It's not 'covert' but it certainly isn't just spawning /bin/bash :shrug The original shellcode is 77 bytes, so it's not huge, especially considering the size is going to be based on the value you add to the hosts file.

The original shellcode can be found here:
Note that the file also contains my shellcode as I used that file's shellcode wrapper to test my own out when making sure everything worked. 

My shellcode can be found here:
Note that each area marked with 'Mod' are different, but equivalent instructions.

The original shellcode sits at 77-bytes, my modifications only added three bytes, but the core of the shellcode has been rewritten. I was even able to add some cool math in the '_write' function, which adds the length of the value added to hosts (in this case, dec 20) to dl, then subtracts the difference to obtain the correct syscall value. The sub instruction needs to be changed if the host value is, just to the difference between len - X = 6.

Shellcode 2:

My second choice for shellcodes was one intended to disable ASLR by rewriting the contents of /proc/sys/kernel/randomize_va_space. Again, this piqued my interest due to it not being quite as 'common'. The original shellcode came in at 83 bytes, mine's a bit bulkier coming in at 91 bytes, but it's core is completely different. It may not be the most efficient, but I thought the changes were pretty clever, every section except exit() has been pretty heavily modified.

The original shellcode can be found here:
For this one, I was again able to do a lot of fun math, multiple areas were able to have the imul and mul mnemonics used in place of simply mov'ing values into registers. I was also able to address registers by their high and low byte counterparts in order to manipulate the values within and get the same results as the original shellcode. I had a lot of fun with this one, although making it 'different' enough for me to be satisfied with the result was challenging. 

Shellcode 3:

Lastly, I decided to try my hand at taking an optimized shellcode and seeing if I could modify it enough for me to feel as though I actually DID something to it, without inflating it's size too much. I was pleasantly surprised that my modifications actually kept it the same size, 28 bytes, but I changed the majority of what was actually able to be modified. There's not a whole lot that can be done with the //bin/sh portion without absolutely mangling things, so I left that as is.

The original shellcode can be found here:
I started out by just xor'ing all the registers I'd be using, rather than xor'ing one and using mov's on them. I replaced some mov's with push, pop and ended up reclaiming a lost byte with the xchg, inc, for the sys_exit call.

I've had a lot of fun with these tasks, but so far four and six have been the most fun. These two required a lot of creativity, which is something that really allows us to flex our capabilities and learn new techniques. I was pretty proud of the little byte manipulations I managed to plug in here and there. Perhaps simplistic, but isn't that the name of the game?

That's it for assignment six.

Popular posts from this blog

06 - How to maybe not be so bad at fuzzing, Part 2

07 - Just Another OSCE Review

02x01 - How to maybe not be as bad at fuzzing unknown binary protocols as you were before reading this