SLAE Assignment 3: Egghunter shellcode

When 30 bytes are not enough ...

Hint: Its easier to read code on github ! 

Welcome back !

The next assignment in the SLAE course is to create an egghunter shellcode.

Wikipedia: This is another form of staged shellcode, which is used if an attacker can inject a larger shellcode into the process but cannot determine where in the process it will end up. Small egg-hunt shellcode is injected into the process at a predictable location and executed. This code then searches the process's address space for the larger shellcode (the egg) and executes it.
 
Egghunter stubs are used when there is not enough space to inject your desired ultra leet shellcode (for instance, only 30 bytes are copied on the stack from your overflow which is not enough for socket reuse shellcode :]). In that case, you can use a smaller shellcode which search the memory of the process and jump to it as well as use another memory space to store your shellcode (such as environment variables).


Preparing an egg hunt


Alright, so to create such things we need assigment blog posts from previous students to find a way to search the entire process space and compare it with a key of our choosing. The key will be used to detect where the larger shellcode resides.

Here is again the master plan:
- Jump short to a function inside the stub shellcode ;
- Pop the address pushed on the stack to get a valid address, indeed if you start searching from 0x0 up to 0xFFFFFFFF you will encounter several segfaults due to unmapped address space so we need a valid address ! ;
- Since we aim for a small stub, we will use jump to the key (instead of jump key+4, if we use a 4 bytes length key) so the key must be valid (useless) opcodes ;
- Elect a key which contains valid (useless) opcodes ;

We decided to go for key 0x50905090 (push eax, nop, push eax, nop) which is not really harmful for any upcoming larger shellcode.  "Nop sleds" (0x90909090) are kinda frequent in processes so we will avoid this key.




Coding an easter bunny process 

Now for testing purposes we need a simple shellcode, so I created a print 1234 shellcode. For this shellcode to be found by the egghunter and executed, you need of course to append the key to the start of the shellcode. It's quite simple to do manually but anyway i created a script for it if you need so.



Now wrapping it all together: we need to put the larger shellcode into a memory space of the process (such as variable definition) and execute the egghunter stub. If the hunter is working it will jump to the larger shellcode and print 1234.

Some remarks:
- We need to compile the tester program with the gcc flag -z execstack. We are not jumping or executing memory from the stack here. But this flag marks several other memory location as executable (rwx) which we use. 
- The stub will search for memory while increasing the address, it means the egg shellcode should be placed in higher memory space. Without finding it, it will segfault in the loop by reaching unmapped address.
- It quite easy to modify it to search in reverse order, i.e. in direction of lower memory address (replace inc eax by dec eax). Issue we can have here is that the stub detect the key in the stub process itself instead of the real egg. That is why we put the key as 0x50905089 and increase it by 1 in the stub instead of hardcoded 0x50905090.
 
Lets try it. First the wrapper.



Now running it.



If we debug it we see that the variable is placed in higher memory space (0x804a060 <findmecode> in gdb) and that this memory is marked rwxp due to the flag (use info proc and shell cat /proc/xxx/maps in gdb to confirm). Without the flag, this memory is marked rw-p and when we jump to it ... Segfault. Okay so, everything is fine with this compile flag. Now what about trying to run it from environment variables ? Lets remove the egg shellcode from the variable memory and put it inside environment before execution. Like this :



It's also working. Brilliant. It also means environment lives in higher memory space :]

Now its time to move on and code our first .nasm assembly encoder... See you !



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/

SLAE - xxx





Comments

Popular Posts