This blog post has been created for completing the requirements for the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert
Student ID: SLAE-824
Requirements
- Choose at least 3 shellcode samples created using Msfvenom for linux/x86
- Use GDB/Ndisasm/Libemu to dissect the functionality of the shellcode
- Present your analysis
Source code for this assignment can be found here
Analysis
For this analysis I have chosen to analyze linux/x86/exec
. My initial
instinct is that this payload essentially just runs execve
with
the supplied arguments. Let’s see if thats how it plays out!
The Code
First we need to see what options this payload supports:
It looks as though the only basic option is the command we want to run. Seems logical, lets generate some assembly.
Lets break down the code and see what it is doing:
We know from previous exercises that syscall 11 is execve. We can verify that this code actually calls execve by running it through libemu:
Sure enough we can see that it does in fact call execve as hypothesized. Let’s keep going:
Since the call instruction is executing code at an offset in the
shellcode our disassembler has failed us making the instructions
after the call seem random and non-sensical. libemu seems to
have gotten them right but we can also drop the bytes
57 53 89 e1 cd 80
into our favorite online disassembler
here.
Another trick is to use a bit of perl like so:
Looking at the results we get:
These look a little more logical. Before we talk about
these instructions though, what about the bytes 69 64 00
that lie between the call instruction and these bytes
that we just disassembled and that the call instruction
is invoking?
We know 00
is often used to null terminate
a string. We also know that 69 64
falls within the range
of ascii values. Consulting the ascii table we determine that
69 is lowercase i
and 64 is lowercase d
. Right! this is the
command that we configured to run on the machine… id
.
We also know that a call instruction places the next instruction
onto the stack. This means that 69 64 00 57
would be placed
on the stack. The 57 will never be reached because the null
terminator will terminate the string.
Next, the values of edi (the pointer to the -c argument) and ebx (the
pointer to /bin/sh) are pushed onto the stack. Since a pointer to
the string id
was already pushed onto the stack via the invocation
of the call
instruction, the stack will contain /bin/sh -c id
.
A pointer to those arguments are placed into ecx.
We can confirm this by loading our code in the usual sample program and using GDB to step through the program and look at the state of the stack.
Reminding ourselves of the signature of execve
we see:
We then call our int 0x80
interupt and execute our command.