Now Mario meets Luigi….or what’s a bind without a reverse shellcode?

I’ve spend some extra time again to reduce the shellcode size and make it fully register aware, so that this shellcode could handle every exploit-scenario. It’s therefore currently at a size of 74 bytes, which should make it one of the smallest Linux-based Shell Reverse TCP shellcode over at shell-storm!

There also two (#1, #2) shellcodes made by Geyslan G. Bem, which are even smaller in size – good job! He added a small register-polluting piece of code to make sure that the shellcode runs in any circumstances:

Now onto my small piece of cake, which doesn’t need this ūüôā

Assignment #2: Shell Reverse TCP Shellcode

The second assignment in the SecurityTube Linux Assembly Expert exam is about creating a shellcode, which:

  • Reverse connects to a configured IP and port
  • Executes a shell on successful connection
  • is easily configureably (in regards to the IP and port)
Shell Reverse TCP PoC

In comparison to assignment #1, I’ve slightly modified the proof of concept code, which is now able to¬†connect back to an IP address (in this case 127.0.0.1) on port 1337:

Assembly prepation

As shown in the C source code, you need to translate the following calls into Assembly language:

  1. Create a socket
  2. Connect to a specified IP and port
  3. Redirect stdin, stdout and stderr via dup2
  4. Execute some more magic

Looks like this will save some more bytes in comparison to assignment #1 ūüôā

Create a socket

This is pretty much the same like in assignment #1, except¬†a slightly different register layout, which I have chosen. I’m using EDX for the protocol argument instead of ESI – this is just for keeping the overall count of used registers as small as possible, so you have less things to cleanup ;-):

In the end, the socket file descriptor is again saved into EDX using a one-byte XCHG. If you’re interested in a deep-analysis of this part, have a look at my previous article.

Connect to a specified IP and port

OK, that’s the new and interesting part. First you need the standard socketcall-syscall in AL¬†again:

I’ll skip the connect() syscall-setup (EBX) for a moment, because my register-layout¬†is a bit optimized for this part. Don’t worry – I’ll come back to this part soon!

First let’s have a look at the connect() arguments, these are the same as for the bind() call. Again the most interesting argument is the sockaddr struct:

As you’d like to connect back to an ip address / port combination, you need to place these arguments at this point. First of all (remember: reverse order!):¬†sin_addr.¬†The ip address is in network byte order, and is therefore reversed PUSHed onto the stack. Each octet is represented by one byte without the dots:

Same for the port:

Small side-note: The whole shellcode is 0x00-free as long as the ip address and port are! Therefore this shellcode connects back to the localhost via 127.1.1.1!

EBX contains 0x1 at this point due to the socket_type PUSH during the socket() call, so incrementing EBX does the next job (the sin_family argument), which needs to be 0x2, smoothly:

Now, save the pointer to this sockaddr struct to ECX:

Last but not least: You need the connect function call in EBX, which is 0x3 according to /usr/include/linux/net.h:

Thankfully EBX already contains 0x2 due to the sin_family PUSH…just one INC to rule’em all ūüėČ :

Redirect stdin, stdout and stderr via dup2

Now, this part should look very familiar to you. But the register layout is a bit different:

linux_x86_shell_reverse_tcp-1

You need to redirect stdin(0), stdout(1) and stderr(2) to have some output in your reverse shell. In assignment #1 you had a perfectly fitting stack, which held all needed values. As I am using a decrementing counter again, ECX has to be set to¬†0x2, but it’s not on the stack somewhere.¬†So the simple solution (3 bytes) looks like the following:

ECX is now ready for the loop, just saving the socket file descriptor to EBX as you need it there during the dup2-syscall:

Followed by the same looping-fun like in assignment #1:

Finally all 3 outputs are redirected!

Execute some more magic

This is nearly the same like last time, but again with a small change: You need to PUSH the terminating NULL for the /bin//sh string seperately onto the stack, because there isn’t already one to use:

DONE.

Complete shellcode

Here’s the complete and commented shellcode:

Test the shellcode

Same commandline-fu:

Same template, different opcodes:

Same compilation-fu:

But amazing different magic! Start a netcat-listener on port 1337:

linux_x86_shell_reverse_tcp-2

Fire up the shellcode:

linux_x86_shell_reverse_tcp-3

And finally type in some crazy tux-fu in your reverse-shell:

linux_x86_shell_reverse_tcp-4

You may also verify the different syscalls using strace: linux_x86_shell_reverse_tcp-5

IP-Address and Port Configuration

I love Python for many reasons! Just to mention one: things are done quickly!

Let’s test this script in a real-world environment! Using the ip as the first, and the port as the second argument, echoes back the new shellcode, which is ready to use:

linux_x86_shell_reverse_tcp-6

Let’s test the new shellcode by starting a netcat listener on Kali¬†with¬†the assigned IP address 10.1.1.1 and running the shellcode on a second box, which results in shellcode-fu:

linux_x86_shell_reverse_tcp-7

et voila, mission accomplished ūüôā

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- 497

SLAE: Shell Reverse TCP Shellcode (Linux/x86)
Tagged on:             

One thought on “SLAE: Shell Reverse TCP Shellcode (Linux/x86)

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.