SLAE64: Assignment 5 – Metasploit payloads analysis #3

This is the last payload that I’ve debugged so far for the 5th assignment on SecurityTube Linux Assembly Expert certification.

This time I opted by looking at the payload linux/x64/exec with the option to run ‘/bin/sh’.

Here’s how I generated the payload with msfvenom.

This is the smallest payload so far, with only 47 bytes and 8 of them are for the command that one wants to run.

I continue having no luck in disassembling shellcode created with msfvenom, neither using hte, gdb nor objdump. So this time I remembered I have a license for Hopper, an impressive debugger with a nice version for Linux (can’t wait for v4 to be released on Linux).

The first two lines load 0x3b into rax, which immediately tells us that we will be running on execve() syscall (0x3b == 59 or __NR_execve as per unistd_64.h).

The way the code is setup actually took me quite a while to understand, but once I got it I thought it is very smart.

If you remember your Operating Systems classes, this is the signature for execve() syscall

This means we need to pass in the following arguments in the following registers:

RDI – address of the string containing the path of the application
RSI – address to the array of arguments including the applications as 1st arg
RDX – address to array of environment variables

So, where we left off in the code they are just filling rbx with the string ‘/bin/sh‘, pushing it on the stack and loading it’s address back onto rdi.

One continues by loading ‘-c‘ onto the stack and loading the address onto rsi.

rdx will be 0 (a.k.a NULL) for *envp.

For the last argument, which is the actual command to run, a similar approach to the Jump-Call-Pop is used. The function call jumps over the definition of the null terminated string representing the command to run thus leaving the string’s address as RET address on the stack. Ontop one pushes both rsi and rdi and the stack ends up with

[ address of ‘/bin/sh’ on the stack, address of ‘-c’ on the stack, address of the command string ]

which makes up our the const char* argc[] argument to execve().

I was not lying, I thought the strategy for a variable length command string to be very smart.


This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert Certification.

Student ID: SLAE64-1440

Leave a Reply

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