mirror of
https://github.com/carlospolop/PEASS-ng
synced 2025-02-14 08:54:27 +01:00
- refactoring / cleanup
- split files into multiple classes - implemented native wifi - getting saved credentials - added registry helper
This commit is contained in:
parent
d091dbcba5
commit
19f6cda357
@ -9,6 +9,7 @@ using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
using winPEAS.Utils;
|
||||
|
||||
namespace winPEAS
|
||||
{
|
||||
@ -83,12 +84,12 @@ namespace winPEAS
|
||||
results.Concat(results2).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||
|
||||
//Get from Uninstall
|
||||
string[] subkeys = MyUtils.GetRegSubkeys("HKLM", @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
|
||||
string[] subkeys = RegistryHelper.GetRegSubkeys("HKLM", @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
|
||||
if (subkeys != null)
|
||||
{
|
||||
foreach (string app in subkeys)
|
||||
{
|
||||
string installLocation = MyUtils.GetRegValue("HKLM", String.Format(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0}", app), "InstallLocation");
|
||||
string installLocation = RegistryHelper.GetRegValue("HKLM", String.Format(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{0}", app), "InstallLocation");
|
||||
if (String.IsNullOrEmpty(installLocation))
|
||||
continue;
|
||||
|
||||
@ -114,12 +115,12 @@ namespace winPEAS
|
||||
}
|
||||
}
|
||||
|
||||
subkeys = MyUtils.GetRegSubkeys("HKLM", @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
|
||||
subkeys = RegistryHelper.GetRegSubkeys("HKLM", @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
|
||||
if (subkeys != null)
|
||||
{
|
||||
foreach (string app in subkeys)
|
||||
{
|
||||
string installLocation = MyUtils.GetRegValue("HKLM", String.Format(@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{0}", app), "InstallLocation");
|
||||
string installLocation = RegistryHelper.GetRegValue("HKLM", String.Format(@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{0}", app), "InstallLocation");
|
||||
if (String.IsNullOrEmpty(installLocation))
|
||||
continue;
|
||||
|
||||
@ -241,7 +242,7 @@ namespace winPEAS
|
||||
//Add the keyvalues inside autorunLocationsKeys to autorunLocations
|
||||
foreach (List<String> autorunLocationKey in autorunLocationsKeys)
|
||||
{
|
||||
List<String> subkeys = MyUtils.GetRegSubkeys(autorunLocationKey[0], autorunLocationKey[1]).ToList();
|
||||
List<String> subkeys = RegistryHelper.GetRegSubkeys(autorunLocationKey[0], autorunLocationKey[1]).ToList();
|
||||
foreach (String keyname in subkeys)
|
||||
{
|
||||
string clsid_name = keyname;
|
||||
@ -259,7 +260,7 @@ namespace winPEAS
|
||||
//Read registry and get values
|
||||
foreach (List<String> autorunLocation in autorunLocations)
|
||||
{
|
||||
Dictionary<string, object> settings = MyUtils.GetRegValues(autorunLocation[0], autorunLocation[1]);
|
||||
Dictionary<string, object> settings = RegistryHelper.GetRegValues(autorunLocation[0], autorunLocation[1]);
|
||||
if ((settings != null) && (settings.Count != 0))
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in settings)
|
||||
@ -320,7 +321,7 @@ namespace winPEAS
|
||||
//Check the autoruns that depends on CLSIDs
|
||||
foreach (List<String> autorunLocation in autorunLocationsKeysCLSIDs)
|
||||
{
|
||||
List<String> CLSIDs = MyUtils.GetRegSubkeys(autorunLocation[0], autorunLocation[1]).ToList();
|
||||
List<String> CLSIDs = RegistryHelper.GetRegSubkeys(autorunLocation[0], autorunLocation[1]).ToList();
|
||||
foreach (String clsid in CLSIDs)
|
||||
{
|
||||
string reg = autorunLocation[1] + "\\" + clsid;
|
||||
|
@ -171,6 +171,12 @@ namespace winPEAS
|
||||
GrayPrint(" =================================================================================================");
|
||||
System.Console.WriteLine();
|
||||
}
|
||||
|
||||
public static void PrintException(string message)
|
||||
{
|
||||
GrayPrint($" [X] Exception: {message}");
|
||||
}
|
||||
|
||||
public static void AnsiPrint(string to_print, Dictionary<string, string> ansi_colors_regexp)
|
||||
{
|
||||
if (to_print.Trim().Length > 0)
|
||||
|
@ -74,15 +74,15 @@ namespace FastSearchLibrary
|
||||
return new List<DirectoryInfo>();
|
||||
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
return new List<DirectoryInfo>();
|
||||
}
|
||||
catch (PathTooLongException ex)
|
||||
catch (PathTooLongException)
|
||||
{
|
||||
return new List<DirectoryInfo>();
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
return new List<DirectoryInfo>();
|
||||
}
|
||||
@ -90,7 +90,7 @@ namespace FastSearchLibrary
|
||||
return GetStartDirectories(directories[0].FullName, files, pattern);
|
||||
}
|
||||
|
||||
static public List<FileInfo> GetFiles(string folder, string pattern = "*")
|
||||
public static List<FileInfo> GetFiles(string folder, string pattern = "*")
|
||||
{
|
||||
DirectoryInfo dirInfo;
|
||||
DirectoryInfo[] directories;
|
||||
@ -102,15 +102,15 @@ namespace FastSearchLibrary
|
||||
if (directories.Length == 0)
|
||||
return new List<FileInfo>(dirInfo.GetFiles(pattern));
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
return new List<FileInfo>();
|
||||
}
|
||||
catch (PathTooLongException ex)
|
||||
catch (PathTooLongException)
|
||||
{
|
||||
return new List<FileInfo>();
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
return new List<FileInfo>();
|
||||
}
|
||||
@ -126,13 +126,13 @@ namespace FastSearchLibrary
|
||||
{
|
||||
result.AddRange(dirInfo.GetFiles(pattern));
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
}
|
||||
catch (PathTooLongException ex)
|
||||
catch (PathTooLongException)
|
||||
{
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
catch (DirectoryNotFoundException)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
@ -9,41 +10,36 @@ using System.Xml;
|
||||
|
||||
namespace winPEAS
|
||||
{
|
||||
class InterestingFiles
|
||||
{
|
||||
private InterestingFiles() {}
|
||||
static class InterestingFiles
|
||||
{
|
||||
public static List<string> GetUnattendedInstallFiles()
|
||||
{ //From SharpUP
|
||||
List<string> results = new List<string>();
|
||||
{
|
||||
//From SharpUP
|
||||
var results = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
string windir = System.Environment.GetEnvironmentVariable("windir");
|
||||
string[] SearchLocations =
|
||||
var winDir = System.Environment.GetEnvironmentVariable("windir");
|
||||
string[] searchLocations =
|
||||
{
|
||||
String.Format("{0}\\sysprep\\sysprep.xml", windir),
|
||||
String.Format("{0}\\sysprep\\sysprep.inf", windir),
|
||||
String.Format("{0}\\sysprep.inf", windir),
|
||||
String.Format("{0}\\Panther\\Unattended.xml", windir),
|
||||
String.Format("{0}\\Panther\\Unattend.xml", windir),
|
||||
String.Format("{0}\\Panther\\Unattend\\Unattend.xml", windir),
|
||||
String.Format("{0}\\Panther\\Unattend\\Unattended.xml", windir),
|
||||
String.Format("{0}\\System32\\Sysprep\\unattend.xml", windir),
|
||||
String.Format("{0}\\System32\\Sysprep\\Panther\\unattend.xml", windir),
|
||||
String.Format("{0}\\..\\unattend.xml", windir),
|
||||
String.Format("{0}\\..\\unattend.inf", windir),
|
||||
$"{winDir}\\sysprep\\sysprep.xml",
|
||||
$"{winDir}\\sysprep\\sysprep.inf",
|
||||
$"{winDir}\\sysprep.inf",
|
||||
$"{winDir}\\Panther\\Unattended.xml",
|
||||
$"{winDir}\\Panther\\Unattend.xml",
|
||||
$"{winDir}\\Panther\\Unattend\\Unattend.xml",
|
||||
$"{winDir}\\Panther\\Unattend\\Unattended.xml",
|
||||
$"{winDir}\\System32\\Sysprep\\unattend.xml",
|
||||
$"{winDir}\\System32\\Sysprep\\Panther\\unattend.xml",
|
||||
$"{winDir}\\..\\unattend.xml",
|
||||
$"{winDir}\\..\\unattend.inf",
|
||||
};
|
||||
|
||||
foreach (string SearchLocation in SearchLocations)
|
||||
{
|
||||
if (System.IO.File.Exists(SearchLocation))
|
||||
results.Add(SearchLocation);
|
||||
|
||||
}
|
||||
results.AddRange(searchLocations.Where(System.IO.File.Exists));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
@ -51,81 +47,78 @@ namespace winPEAS
|
||||
public static List<string> ExtractUnattenededPwd(string path)
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
try {
|
||||
|
||||
try
|
||||
{
|
||||
string text = File.ReadAllText(path);
|
||||
text = text.Replace("\n", "");
|
||||
text = text.Replace("\r", "");
|
||||
Regex regex = new Regex(@"<Password>.*</Password>");
|
||||
foreach (Match match in regex.Matches(text))
|
||||
results.Add(match.Value);
|
||||
|
||||
foreach (Match match in regex.Matches(text))
|
||||
{
|
||||
results.Add(match.Value);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<string> GetSAMBackups()
|
||||
{ //From SharpUP
|
||||
List<string> results = new List<string>();
|
||||
{
|
||||
//From SharpUP
|
||||
var results = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
string systemRoot = System.Environment.GetEnvironmentVariable("SystemRoot");
|
||||
string[] SearchLocations =
|
||||
string systemRoot = Environment.GetEnvironmentVariable("SystemRoot");
|
||||
string[] searchLocations =
|
||||
{
|
||||
String.Format(@"{0}\repair\SAM", systemRoot),
|
||||
String.Format(@"{0}\System32\config\RegBack\SAM", systemRoot),
|
||||
//String.Format(@"{0}\System32\config\SAM", systemRoot),
|
||||
String.Format(@"{0}\repair\SYSTEM", systemRoot),
|
||||
//String.Format(@"{0}\System32\config\SYSTEM", systemRoot),
|
||||
String.Format(@"{0}\System32\config\RegBack\SYSTEM", systemRoot),
|
||||
$@"{systemRoot}\repair\SAM",
|
||||
$@"{systemRoot}\System32\config\RegBack\SAM",
|
||||
//$@"{0}\System32\config\SAM"
|
||||
$@"{systemRoot}\repair\SYSTEM",
|
||||
//$@"{0}\System32\config\SYSTEM", systemRoot),
|
||||
$@"{systemRoot}\System32\config\RegBack\SYSTEM",
|
||||
};
|
||||
|
||||
foreach (string SearchLocation in SearchLocations)
|
||||
{
|
||||
if (System.IO.File.Exists(SearchLocation))
|
||||
results.Add(SearchLocation);
|
||||
|
||||
}
|
||||
results.AddRange(searchLocations.Where(searchLocation => System.IO.File.Exists(searchLocation)));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<string> GetMcAfeeSitelistFiles()
|
||||
{ //From SharpUP
|
||||
{
|
||||
//From SharpUP
|
||||
List<string> results = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
string drive = System.Environment.GetEnvironmentVariable("SystemDrive");
|
||||
|
||||
string[] SearchLocations =
|
||||
string[] searchLocations =
|
||||
{
|
||||
String.Format("{0}\\Program Files\\", drive),
|
||||
String.Format("{0}\\Program Files (x86)\\", drive),
|
||||
String.Format("{0}\\Documents and Settings\\", drive),
|
||||
String.Format("{0}\\Users\\", drive)
|
||||
$"{drive}\\Program Files\\",
|
||||
$"{drive}\\Program Files (x86)\\",
|
||||
$"{drive}\\Documents and Settings\\",
|
||||
$"{drive}\\Users\\",
|
||||
};
|
||||
|
||||
foreach (string SearchLocation in SearchLocations)
|
||||
{
|
||||
List<string> files = MyUtils.FindFiles(SearchLocation, "SiteList.xml");
|
||||
|
||||
foreach (string file in files)
|
||||
results.Add(file);
|
||||
|
||||
}
|
||||
results.AddRange(
|
||||
searchLocations.SelectMany(
|
||||
searchLocation => MyUtils.FindFiles(searchLocation, "SiteList.xml")));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
@ -146,7 +139,7 @@ namespace winPEAS
|
||||
}
|
||||
allUsers += "\\Microsoft\\Group Policy\\History"; // look only in the GPO cache folder
|
||||
|
||||
List<String> files = MyUtils.FindFiles(allUsers, "*.xml");
|
||||
List<string> files = MyUtils.FindFiles(allUsers, "*.xml");
|
||||
|
||||
// files will contain all XML files
|
||||
foreach (string file in files)
|
||||
@ -354,36 +347,36 @@ namespace winPEAS
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
public static string DecryptGPP(string cpassword)
|
||||
{ //From SharpUP
|
||||
int mod = cpassword.Length % 4;
|
||||
public static string DecryptGPP(string cPassword)
|
||||
{
|
||||
//From SharpUP
|
||||
int mod = cPassword.Length % 4;
|
||||
|
||||
switch (mod)
|
||||
{
|
||||
case 1:
|
||||
cpassword = cpassword.Substring(0, cpassword.Length - 1);
|
||||
cPassword = cPassword.Substring(0, cPassword.Length - 1);
|
||||
break;
|
||||
case 2:
|
||||
cpassword += "".PadLeft(4 - mod, '=');
|
||||
cPassword += "".PadLeft(4 - mod, '=');
|
||||
break;
|
||||
case 3:
|
||||
cpassword += "".PadLeft(4 - mod, '=');
|
||||
break;
|
||||
default:
|
||||
cPassword += "".PadLeft(4 - mod, '=');
|
||||
break;
|
||||
}
|
||||
|
||||
byte[] base64decoded = Convert.FromBase64String(cpassword);
|
||||
byte[] base64decoded = Convert.FromBase64String(cPassword);
|
||||
|
||||
AesCryptoServiceProvider aesObject = new AesCryptoServiceProvider();
|
||||
|
||||
byte[] aesKey = { 0x4e, 0x99, 0x06, 0xe8, 0xfc, 0xb6, 0x6c, 0xc9, 0xfa, 0xf4, 0x93, 0x10, 0x62, 0x0f, 0xfe, 0xe8, 0xf4, 0x96, 0xe8, 0x06, 0xcc, 0x05, 0x79, 0x90, 0x20, 0x9b, 0x09, 0xa4, 0x33, 0xb6, 0x6c, 0x1b };
|
||||
byte[] aesKey = { 0x4e, 0x99, 0x06, 0xe8, 0xfc, 0xb6, 0x6c, 0xc9, 0xfa, 0xf4, 0x93, 0x10, 0x62, 0x0f,
|
||||
0xfe, 0xe8, 0xf4, 0x96, 0xe8, 0x06, 0xcc, 0x05, 0x79, 0x90, 0x20, 0x9b, 0x09, 0xa4, 0x33, 0xb6, 0x6c, 0x1b };
|
||||
byte[] aesIV = new byte[aesObject.IV.Length];
|
||||
|
||||
aesObject.IV = aesIV;
|
||||
@ -405,7 +398,7 @@ namespace winPEAS
|
||||
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string searchPath = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string searchPath = $"{Environment.GetEnvironmentVariable("SystemDrive")}\\Users\\";
|
||||
|
||||
List<string> files = MyUtils.FindFiles(searchPath, patterns);
|
||||
|
||||
@ -438,6 +431,33 @@ namespace winPEAS
|
||||
return results;
|
||||
}
|
||||
|
||||
private static object InvokeMemberMethod(object target, string name, object[] args = null)
|
||||
{
|
||||
if (target == null) throw new ArgumentNullException(nameof(target));
|
||||
|
||||
object result = InvokeMember(target, name, BindingFlags.InvokeMethod, args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static object InvokeMemberProperty(object target, string name, object[] args = null)
|
||||
{
|
||||
if (target == null) throw new ArgumentNullException(nameof(target));
|
||||
|
||||
object result = InvokeMember(target, name, BindingFlags.GetProperty, args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static object InvokeMember(object target, string name, BindingFlags invokeAttr, object[] args = null)
|
||||
{
|
||||
if (target == null) throw new ArgumentNullException(nameof(target));
|
||||
|
||||
object result = target.GetType().InvokeMember(name, invokeAttr, null, target, args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, string>> GetRecycleBin()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
@ -452,37 +472,37 @@ namespace winPEAS
|
||||
|
||||
// Shell COM object GUID
|
||||
Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000"));
|
||||
Object shellObj = Activator.CreateInstance(shell);
|
||||
object shellObj = Activator.CreateInstance(shell);
|
||||
|
||||
// namespace for recycle bin == 10 - https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494(v=vs.85).aspx
|
||||
Object recycle = shellObj.GetType().InvokeMember("Namespace", BindingFlags.InvokeMethod, null, shellObj, new object[] { 10 });
|
||||
object recycle = InvokeMemberMethod(shellObj, "Namespace", new object[] { 10 });
|
||||
// grab all the deletes items
|
||||
Object items = recycle.GetType().InvokeMember("Items", BindingFlags.InvokeMethod, null, recycle, null);
|
||||
object items = InvokeMemberMethod(recycle, "Items");
|
||||
// grab the number of deleted items
|
||||
Object count = items.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, items, null);
|
||||
object count = InvokeMemberProperty(items, "Count");
|
||||
int deletedCount = Int32.Parse(count.ToString());
|
||||
|
||||
// iterate through each item
|
||||
for (int i = 0; i < deletedCount; i++)
|
||||
{
|
||||
// grab the specific deleted item
|
||||
Object item = items.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, items, new object[] { i });
|
||||
Object DateDeleted = item.GetType().InvokeMember("ExtendedProperty", BindingFlags.InvokeMethod, null, item, new object[] { "System.Recycle.DateDeleted" });
|
||||
DateTime modifiedDate = DateTime.Parse(DateDeleted.ToString());
|
||||
object item = InvokeMemberMethod(items, "Item", new object[] { i });
|
||||
object dateDeleted = InvokeMemberMethod(item, "ExtendedProperty", new object[] { "System.Recycle.DateDeleted" });
|
||||
DateTime modifiedDate = DateTime.Parse(dateDeleted.ToString());
|
||||
if (modifiedDate > startTime)
|
||||
{
|
||||
// additional extended properties from https://blogs.msdn.microsoft.com/oldnewthing/20140421-00/?p=1183
|
||||
Object Name = item.GetType().InvokeMember("Name", BindingFlags.GetProperty, null, item, null);
|
||||
Object Path = item.GetType().InvokeMember("Path", BindingFlags.GetProperty, null, item, null);
|
||||
Object Size = item.GetType().InvokeMember("Size", BindingFlags.GetProperty, null, item, null);
|
||||
Object DeletedFrom = item.GetType().InvokeMember("ExtendedProperty", BindingFlags.InvokeMethod, null, item, new object[] { "System.Recycle.DeletedFrom" });
|
||||
object name = InvokeMemberProperty(item, "Name");
|
||||
object path = InvokeMemberProperty(item, "Path");
|
||||
object size = InvokeMemberProperty(item, "Size");
|
||||
object deletedFrom = InvokeMemberMethod(item, "ExtendedProperty", new object[] { "System.Recycle.DeletedFrom" });
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "Name", String.Format("{0}", Name) },
|
||||
{ "Path", String.Format("{0}", Path) },
|
||||
{ "Size", String.Format("{0}", Size) },
|
||||
{ "Deleted from", String.Format("{0}", DeletedFrom) },
|
||||
{ "Date Deleted", String.Format("{0}", DateDeleted) }
|
||||
{ "Name", name.ToString() },
|
||||
{ "Path", path.ToString() },
|
||||
{ "Size", size.ToString() },
|
||||
{ "Deleted from", deletedFrom.ToString() },
|
||||
{ "Date Deleted", dateDeleted.ToString() }
|
||||
});
|
||||
}
|
||||
Marshal.ReleaseComObject(item);
|
||||
|
172
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Chrome.cs
Normal file
172
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Chrome.cs
Normal file
@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.Script.Serialization;
|
||||
|
||||
namespace winPEAS.KnownFileCreds
|
||||
{
|
||||
static class Chrome
|
||||
{
|
||||
public static Dictionary<string, string> GetChromeDbs()
|
||||
{
|
||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
||||
// checks if Chrome has a history database
|
||||
try
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string[] dirs = Directory.GetDirectories(userFolder);
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
string[] parts = dir.Split('\\');
|
||||
string userName = parts[parts.Length - 1];
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
string userChromeCookiesPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies", dir);
|
||||
if (System.IO.File.Exists(userChromeCookiesPath))
|
||||
results["userChromeCookiesPath"] = userChromeCookiesPath;
|
||||
|
||||
string userChromeLoginDataPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data", dir);
|
||||
if (System.IO.File.Exists(userChromeLoginDataPath))
|
||||
results["userChromeLoginDataPath"] = userChromeLoginDataPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string userChromeCookiesPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
if (System.IO.File.Exists(userChromeCookiesPath))
|
||||
results["userChromeCookiesPath"] = userChromeCookiesPath;
|
||||
|
||||
string userChromeLoginDataPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
if (System.IO.File.Exists(userChromeLoginDataPath))
|
||||
results["userChromeLoginDataPath"] = userChromeLoginDataPath;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<string> ParseChromeHistory(string path)
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
|
||||
// parses a Chrome history file via regex
|
||||
if (System.IO.File.Exists(path))
|
||||
{
|
||||
Regex historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?");
|
||||
|
||||
try
|
||||
{
|
||||
using (StreamReader r = new StreamReader(path))
|
||||
{
|
||||
string line;
|
||||
while ((line = r.ReadLine()) != null)
|
||||
{
|
||||
Match m = historyRegex.Match(line);
|
||||
if (m.Success)
|
||||
{
|
||||
results.Add(m.Groups[0].ToString().Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.IO.IOException exception)
|
||||
{
|
||||
Console.WriteLine("\r\n [x] IO exception, history file likely in use (i.e. Browser is likely running): ", exception.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static Dictionary<string, List<string>> GetChromeHistBook()
|
||||
{
|
||||
Dictionary<string, List<string>> results = new Dictionary<string, List<string>>()
|
||||
{
|
||||
{ "history", new List<string>() },
|
||||
{ "bookarks", new List<string>() },
|
||||
};
|
||||
try
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
Console.WriteLine("\r\n\r\n=== Chrome (All Users) ===");
|
||||
|
||||
string userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string[] dirs = Directory.GetDirectories(userFolder);
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
string[] parts = dir.Split('\\');
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
string userChromeHistoryPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", dir);
|
||||
results["history"] = ParseChromeHistory(userChromeHistoryPath);
|
||||
|
||||
string userChromeBookmarkPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", dir);
|
||||
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string userChromeHistoryPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
results["history"] = ParseChromeHistory(userChromeHistoryPath);
|
||||
|
||||
string userChromeBookmarkPath = String.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
|
||||
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<string> ParseChromeBookmarks(string path)
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
// parses a Chrome bookmarks
|
||||
if (System.IO.File.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
string contents = System.IO.File.ReadAllText(path);
|
||||
|
||||
// reference: http://www.tomasvera.com/programming/using-javascriptserializer-to-parse-json-objects/
|
||||
JavaScriptSerializer json = new JavaScriptSerializer();
|
||||
Dictionary<string, object> deserialized = json.Deserialize<Dictionary<string, object>>(contents);
|
||||
Dictionary<string, object> roots = (Dictionary<string, object>)deserialized["roots"];
|
||||
Dictionary<string, object> bookmark_bar = (Dictionary<string, object>)roots["bookmark_bar"];
|
||||
System.Collections.ArrayList children = (System.Collections.ArrayList)bookmark_bar["children"];
|
||||
|
||||
foreach (Dictionary<string, object> entry in children)
|
||||
{
|
||||
//Console.WriteLine(" Name: {0}", entry["name"].ToString().Trim());
|
||||
if (entry.ContainsKey("url"))
|
||||
results.Add(entry["url"].ToString().Trim());
|
||||
}
|
||||
}
|
||||
catch (System.IO.IOException exception)
|
||||
{
|
||||
Console.WriteLine("\r\n [x] IO exception, Bookmarks file likely in use (i.e. Chrome is likely running).", exception.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
145
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Firefox.cs
Normal file
145
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Firefox.cs
Normal file
@ -0,0 +1,145 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace winPEAS.KnownFileCreds
|
||||
{
|
||||
static class Firefox
|
||||
{
|
||||
public static List<string> GetFirefoxDbs()
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
// checks if Firefox has a history database
|
||||
try
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string[] dirs = Directory.GetDirectories(userFolder);
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
string[] parts = dir.Split('\\');
|
||||
string userName = parts[parts.Length - 1];
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
string userFirefoxBasePath = String.Format("{0}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\", dir);
|
||||
if (System.IO.Directory.Exists(userFirefoxBasePath))
|
||||
{
|
||||
string[] directories = Directory.GetDirectories(userFirefoxBasePath);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
string firefoxCredentialFile3 = String.Format("{0}\\{1}", directory, "key3.db");
|
||||
if (System.IO.File.Exists(firefoxCredentialFile3))
|
||||
results.Add(firefoxCredentialFile3);
|
||||
|
||||
string firefoxCredentialFile4 = String.Format("{0}\\{1}", directory, "key4.db");
|
||||
if (System.IO.File.Exists(firefoxCredentialFile4))
|
||||
results.Add(firefoxCredentialFile3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||
string userFirefoxBasePath = String.Format("{0}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
|
||||
if (System.IO.Directory.Exists(userFirefoxBasePath))
|
||||
{
|
||||
string[] directories = Directory.GetDirectories(userFirefoxBasePath);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
string firefoxCredentialFile3 = String.Format("{0}\\{1}", directory, "key3.db");
|
||||
if (System.IO.File.Exists(firefoxCredentialFile3))
|
||||
results.Add(firefoxCredentialFile3);
|
||||
|
||||
string firefoxCredentialFile4 = String.Format("{0}\\{1}", directory, "key4.db");
|
||||
if (System.IO.File.Exists(firefoxCredentialFile4))
|
||||
results.Add(firefoxCredentialFile4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<string> GetFirefoxHistory()
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
try
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string[] dirs = Directory.GetDirectories(userFolder);
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
string[] parts = dir.Split('\\');
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
string userFirefoxBasePath = String.Format("{0}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\", dir);
|
||||
results = ParseFirefoxHistory(userFirefoxBasePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string userFirefoxBasePath = String.Format("{0}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
results = ParseFirefoxHistory(userFirefoxBasePath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<string> ParseFirefoxHistory(string path)
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
// parses a Firefox history file via regex
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
string[] directories = Directory.GetDirectories(path);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
string firefoxHistoryFile = String.Format("{0}\\{1}", directory, "places.sqlite");
|
||||
Regex historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?");
|
||||
|
||||
try
|
||||
{
|
||||
using (StreamReader r = new StreamReader(firefoxHistoryFile))
|
||||
{
|
||||
string line;
|
||||
while ((line = r.ReadLine()) != null)
|
||||
{
|
||||
Match m = historyRegex.Match(line);
|
||||
if (m.Success)
|
||||
{
|
||||
results.Add(m.Groups[0].ToString().Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException exception)
|
||||
{
|
||||
Console.WriteLine("\r\n [x] IO exception, places.sqlite file likely in use (i.e. Firefox is likely running).", exception.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
205
winPEAS/winPEASexe/winPEAS/KnownFileCreds/InternetExplorer.cs
Normal file
205
winPEAS/winPEASexe/winPEAS/KnownFileCreds/InternetExplorer.cs
Normal file
@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Utils;
|
||||
|
||||
namespace winPEAS.KnownFileCreds
|
||||
{
|
||||
static class InternetExplorer
|
||||
{
|
||||
public static Dictionary<string, List<string>> GetIEHistFav()
|
||||
{
|
||||
int lastDays = 90;
|
||||
Dictionary<string, List<string>> results = new Dictionary<string, List<string>>()
|
||||
{
|
||||
{ "history", new List<string>() },
|
||||
{ "favorites", new List<string>() },
|
||||
};
|
||||
|
||||
DateTime startTime = System.DateTime.Now.AddDays(-lastDays);
|
||||
|
||||
try
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string[] SIDs = Registry.Users.GetSubKeyNames();
|
||||
foreach (string SID in SIDs)
|
||||
{
|
||||
if (SID.StartsWith("S-1-5") && !SID.EndsWith("_Classes"))
|
||||
{
|
||||
Dictionary<string, object> settings = RegistryHelper.GetRegValues("HKU", String.Format("{0}\\SOFTWARE\\Microsoft\\Internet Explorer\\TypedURLs", SID));
|
||||
if ((settings != null) && (settings.Count > 1))
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in settings)
|
||||
{
|
||||
byte[] timeBytes = RegistryHelper.GetRegValueBytes("HKU", String.Format("{0}\\SOFTWARE\\Microsoft\\Internet Explorer\\TypedURLsTime", SID), kvp.Key.ToString().Trim());
|
||||
if (timeBytes != null)
|
||||
{
|
||||
long timeLong = (long)(BitConverter.ToInt64(timeBytes, 0));
|
||||
DateTime urlTime = DateTime.FromFileTime(timeLong);
|
||||
if (urlTime > startTime)
|
||||
{
|
||||
results["history"].Add(kvp.Value.ToString().Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string[] dirs = Directory.GetDirectories(userFolder);
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
string[] parts = dir.Split('\\');
|
||||
string userName = parts[parts.Length - 1];
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
string userIEBookmarkPath = String.Format("{0}\\Favorites\\", dir);
|
||||
|
||||
if (Directory.Exists(userIEBookmarkPath))
|
||||
{
|
||||
string[] bookmarkPaths = Directory.GetFiles(userIEBookmarkPath, "*.url", SearchOption.AllDirectories);
|
||||
if (bookmarkPaths.Length != 0)
|
||||
{
|
||||
foreach (string bookmarkPath in bookmarkPaths)
|
||||
{
|
||||
using (StreamReader rdr = new StreamReader(bookmarkPath))
|
||||
{
|
||||
string line;
|
||||
string url = "";
|
||||
while ((line = rdr.ReadLine()) != null)
|
||||
{
|
||||
if (line.StartsWith("URL=", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
if (line.Length > 4)
|
||||
url = line.Substring(4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
results["history"].Add(url.ToString().Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> settings = RegistryHelper.GetRegValues("HKCU", "SOFTWARE\\Microsoft\\Internet Explorer\\TypedURLs");
|
||||
if ((settings != null) && (settings.Count != 0))
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in settings)
|
||||
{
|
||||
byte[] timeBytes = RegistryHelper.GetRegValueBytes("HKCU", "SOFTWARE\\Microsoft\\Internet Explorer\\TypedURLsTime", kvp.Key.ToString().Trim());
|
||||
if (timeBytes != null)
|
||||
{
|
||||
long timeLong = (long)(BitConverter.ToInt64(timeBytes, 0));
|
||||
DateTime urlTime = DateTime.FromFileTime(timeLong);
|
||||
if (urlTime > startTime)
|
||||
{
|
||||
results["history"].Add(kvp.Value.ToString().Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string userIEBookmarkPath = String.Format("{0}\\Favorites\\", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
|
||||
string[] bookmarkPaths = Directory.GetFiles(userIEBookmarkPath, "*.url", SearchOption.AllDirectories);
|
||||
|
||||
foreach (string bookmarkPath in bookmarkPaths)
|
||||
{
|
||||
using (StreamReader rdr = new StreamReader(bookmarkPath))
|
||||
{
|
||||
string line;
|
||||
string url = "";
|
||||
while ((line = rdr.ReadLine()) != null)
|
||||
{
|
||||
if (line.StartsWith("URL=", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
if (line.Length > 4)
|
||||
url = line.Substring(4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
results["favorites"].Add(url.ToString().Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
public static List<string> GetCurrentIETabs()
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
// Lists currently open Internet Explorer tabs, via COM
|
||||
// Notes:
|
||||
// https://searchcode.com/codesearch/view/9859954/
|
||||
// https://gist.github.com/yizhang82/a1268d3ea7295a8a1496e01d60ada816
|
||||
|
||||
try
|
||||
{
|
||||
// Shell.Application COM GUID
|
||||
Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000"));
|
||||
|
||||
// actually instantiate the Shell.Application COM object
|
||||
Object shellObj = Activator.CreateInstance(shell);
|
||||
|
||||
// grab all the current windows
|
||||
Object windows = shellObj.GetType().InvokeMember("Windows", BindingFlags.InvokeMethod, null, shellObj, null);
|
||||
|
||||
// grab the open tab count
|
||||
Object openTabs = windows.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, windows, null);
|
||||
int openTabsCount = Int32.Parse(openTabs.ToString());
|
||||
|
||||
for (int i = 0; i < openTabsCount; i++)
|
||||
{
|
||||
// grab the acutal tab
|
||||
Object item = windows.GetType().InvokeMember("Item", BindingFlags.InvokeMethod, null, windows, new object[] { i });
|
||||
try
|
||||
{
|
||||
// extract the tab properties
|
||||
Object locationName = item.GetType().InvokeMember("LocationName", BindingFlags.GetProperty, null, item, null);
|
||||
Object locationURL = item.GetType().InvokeMember("LocationUrl", BindingFlags.GetProperty, null, item, null);
|
||||
|
||||
// ensure we have a site address
|
||||
if (Regex.IsMatch(locationURL.ToString(), @"(^https?://.+)|(^ftp://)"))
|
||||
{
|
||||
results.Add(String.Format("{0}", locationURL));
|
||||
}
|
||||
Marshal.ReleaseComObject(item);
|
||||
item = null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
Marshal.ReleaseComObject(windows);
|
||||
windows = null;
|
||||
Marshal.ReleaseComObject(shellObj);
|
||||
shellObj = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
134
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Kerberos/Helpers.cs
Normal file
134
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Kerberos/Helpers.cs
Normal file
@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.KnownFileCreds.Kerberos.structs;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Kerberos
|
||||
{
|
||||
static class Helpers
|
||||
{
|
||||
[DllImport("secur32.dll", SetLastError = true)]
|
||||
public static extern int
|
||||
LsaRegisterLogonProcess(LSA_STRING_IN LogonProcessName, out IntPtr LsaHandle, out ulong SecurityMode);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool
|
||||
OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll")]
|
||||
public extern static bool
|
||||
DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool
|
||||
ImpersonateLoggedOnUser(IntPtr hToken);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool
|
||||
CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool
|
||||
RevertToSelf();
|
||||
|
||||
[DllImport("Secur32.dll", SetLastError = false)]
|
||||
public static extern uint LsaEnumerateLogonSessions(out UInt64 LogonSessionCount, out IntPtr LogonSessionList);
|
||||
|
||||
[DllImport("Secur32.dll", SetLastError = false)]
|
||||
public static extern uint LsaGetLogonSessionData(IntPtr luid, out IntPtr ppLogonSessionData);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern int LsaLookupAuthenticationPackage([In] IntPtr LsaHandle, [In] ref LSA_STRING_IN PackageName, [Out] out int AuthenticationPackage);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern int LsaCallAuthenticationPackage(IntPtr LsaHandle, int AuthenticationPackage, ref KERB_QUERY_TKT_CACHE_REQUEST ProtocolSubmitBuffer, int SubmitBufferLength, out IntPtr ProtocolReturnBuffer, out int ReturnBufferLength, out int ProtocolStatus);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern uint LsaFreeReturnBuffer(IntPtr buffer);
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern int LsaConnectUntrusted([Out] out IntPtr LsaHandle);
|
||||
|
||||
[DllImport("secur32.dll", SetLastError = false)]
|
||||
public static extern int LsaDeregisterLogonProcess([In] IntPtr LsaHandle);
|
||||
|
||||
[DllImport("secur32.dll", EntryPoint = "LsaCallAuthenticationPackage", SetLastError = false)]
|
||||
public static extern int LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT(IntPtr LsaHandle, int AuthenticationPackage, ref KERB_RETRIEVE_TKT_REQUEST ProtocolSubmitBuffer, int SubmitBufferLength, out IntPtr ProtocolReturnBuffer, out int ReturnBufferLength, out int ProtocolStatus);
|
||||
|
||||
|
||||
public static IntPtr LsaRegisterLogonProcessHelper()
|
||||
{
|
||||
// helper that establishes a connection to the LSA server and verifies that the caller is a logon application
|
||||
// used for Kerberos ticket enumeration
|
||||
|
||||
string logonProcessName = "User32LogonProcesss";
|
||||
LSA_STRING_IN LSAString;
|
||||
IntPtr lsaHandle = IntPtr.Zero;
|
||||
UInt64 securityMode = 0;
|
||||
|
||||
LSAString.Length = (ushort)logonProcessName.Length;
|
||||
LSAString.MaximumLength = (ushort)(logonProcessName.Length + 1);
|
||||
LSAString.Buffer = logonProcessName;
|
||||
|
||||
int ret = LsaRegisterLogonProcess(LSAString, out lsaHandle, out securityMode);
|
||||
|
||||
return lsaHandle;
|
||||
}
|
||||
|
||||
public static bool GetSystem()
|
||||
{
|
||||
// helper to elevate to SYSTEM for Kerberos ticket enumeration via token impersonation
|
||||
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
IntPtr hToken = IntPtr.Zero;
|
||||
|
||||
// Open winlogon's token with TOKEN_DUPLICATE accesss so ca can make a copy of the token with DuplicateToken
|
||||
Process[] processes = Process.GetProcessesByName("winlogon");
|
||||
IntPtr handle = processes[0].Handle;
|
||||
|
||||
// TOKEN_DUPLICATE = 0x0002
|
||||
bool success = OpenProcessToken(handle, 0x0002, out hToken);
|
||||
if (!success)
|
||||
{
|
||||
//Console.WriteLine("OpenProcessToken failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// make a copy of the NT AUTHORITY\SYSTEM token from winlogon
|
||||
// 2 == SecurityImpersonation
|
||||
IntPtr hDupToken = IntPtr.Zero;
|
||||
success = DuplicateToken(hToken, 2, ref hDupToken);
|
||||
if (!success)
|
||||
{
|
||||
//Console.WriteLine("DuplicateToken failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
success = ImpersonateLoggedOnUser(hDupToken);
|
||||
if (!success)
|
||||
{
|
||||
//Console.WriteLine("ImpersonateLoggedOnUser failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// clean up the handles we created
|
||||
CloseHandle(hToken);
|
||||
CloseHandle(hDupToken);
|
||||
|
||||
string name = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
|
||||
if (name != "NT AUTHORITY\\SYSTEM")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
569
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Kerberos/Kerberos.cs
Normal file
569
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Kerberos/Kerberos.cs
Normal file
@ -0,0 +1,569 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.KnownFileCreds.Kerberos.enums;
|
||||
using winPEAS.KnownFileCreds.Kerberos.structs;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Kerberos
|
||||
{
|
||||
static class Kerberos
|
||||
{
|
||||
public static List<Dictionary<string, string>> ListKerberosTickets()
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
return ListKerberosTicketsAllUsers();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ListKerberosTicketsCurrentUser();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, string>> ListKerberosTicketsAllUsers()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
// adapted partially from Vincent LE TOUX' work
|
||||
// https://github.com/vletoux/MakeMeEnterpriseAdmin/blob/master/MakeMeEnterpriseAdmin.ps1#L2939-L2950
|
||||
// and https://www.dreamincode.net/forums/topic/135033-increment-memory-pointer-issue/
|
||||
// also Jared Atkinson's work at https://github.com/Invoke-IR/ACE/blob/master/ACE-Management/PS-ACE/Scripts/ACE_Get-KerberosTicketCache.ps1
|
||||
|
||||
IntPtr hLsa = Helpers.LsaRegisterLogonProcessHelper();
|
||||
int totalTicketCount = 0;
|
||||
|
||||
// if the original call fails then it is likely we don't have SeTcbPrivilege
|
||||
// to get SeTcbPrivilege we can Impersonate a NT AUTHORITY\SYSTEM Token
|
||||
if (hLsa == IntPtr.Zero)
|
||||
{
|
||||
Helpers.GetSystem();
|
||||
// should now have the proper privileges to get a Handle to LSA
|
||||
hLsa = Helpers.LsaRegisterLogonProcessHelper();
|
||||
// we don't need our NT AUTHORITY\SYSTEM Token anymore so we can revert to our original token
|
||||
Helpers.RevertToSelf();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// first return all the logon sessions
|
||||
|
||||
DateTime systime = new DateTime(1601, 1, 1, 0, 0, 0, 0); //win32 systemdate
|
||||
UInt64 count;
|
||||
IntPtr luidPtr = IntPtr.Zero;
|
||||
IntPtr iter = luidPtr;
|
||||
|
||||
uint ret = Helpers.LsaEnumerateLogonSessions(out count, out luidPtr); // get an array of pointers to LUIDs
|
||||
|
||||
for (ulong i = 0; i < count; i++)
|
||||
{
|
||||
IntPtr sessionData;
|
||||
ret = Helpers.LsaGetLogonSessionData(luidPtr, out sessionData);
|
||||
SECURITY_LOGON_SESSION_DATA data = (SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(sessionData, typeof(SECURITY_LOGON_SESSION_DATA));
|
||||
|
||||
// if we have a valid logon
|
||||
if (data.PSiD != IntPtr.Zero)
|
||||
{
|
||||
// user session data
|
||||
string username = Marshal.PtrToStringUni(data.Username.Buffer).Trim();
|
||||
System.Security.Principal.SecurityIdentifier sid = new System.Security.Principal.SecurityIdentifier(data.PSiD);
|
||||
string domain = Marshal.PtrToStringUni(data.LoginDomain.Buffer).Trim();
|
||||
string authpackage = Marshal.PtrToStringUni(data.AuthenticationPackage.Buffer).Trim();
|
||||
SECURITY_LOGON_TYPE logonType = (SECURITY_LOGON_TYPE)data.LogonType;
|
||||
DateTime logonTime = systime.AddTicks((long)data.LoginTime);
|
||||
string logonServer = Marshal.PtrToStringUni(data.LogonServer.Buffer).Trim();
|
||||
string dnsDomainName = Marshal.PtrToStringUni(data.DnsDomainName.Buffer).Trim();
|
||||
string upn = Marshal.PtrToStringUni(data.Upn.Buffer).Trim();
|
||||
|
||||
// now we want to get the tickets for this logon ID
|
||||
string name = "kerberos";
|
||||
LSA_STRING_IN LSAString;
|
||||
LSAString.Length = (ushort)name.Length;
|
||||
LSAString.MaximumLength = (ushort)(name.Length + 1);
|
||||
LSAString.Buffer = name;
|
||||
|
||||
IntPtr ticketPointer = IntPtr.Zero;
|
||||
IntPtr ticketsPointer = IntPtr.Zero;
|
||||
DateTime sysTime = new DateTime(1601, 1, 1, 0, 0, 0, 0);
|
||||
int authPack;
|
||||
int returnBufferLength = 0;
|
||||
int protocalStatus = 0;
|
||||
int retCode;
|
||||
|
||||
KERB_QUERY_TKT_CACHE_REQUEST tQuery = new KERB_QUERY_TKT_CACHE_REQUEST();
|
||||
KERB_QUERY_TKT_CACHE_RESPONSE tickets = new KERB_QUERY_TKT_CACHE_RESPONSE();
|
||||
KERB_TICKET_CACHE_INFO ticket;
|
||||
|
||||
// obtains the unique identifier for the kerberos authentication package.
|
||||
retCode = Helpers.LsaLookupAuthenticationPackage(hLsa, ref LSAString, out authPack);
|
||||
|
||||
// input object for querying the ticket cache for a specific logon ID
|
||||
LUID userLogonID = new LUID();
|
||||
userLogonID.LowPart = data.LoginID.LowPart;
|
||||
userLogonID.HighPart = 0;
|
||||
tQuery.LogonId = userLogonID;
|
||||
tQuery.MessageType = KERB_PROTOCOL_MESSAGE_TYPE.KerbQueryTicketCacheMessage;
|
||||
|
||||
// query LSA, specifying we want the ticket cache
|
||||
retCode = Helpers.LsaCallAuthenticationPackage(hLsa, authPack, ref tQuery, Marshal.SizeOf(tQuery), out ticketPointer, out returnBufferLength, out protocalStatus);
|
||||
|
||||
/*Console.WriteLine("\r\n UserName : {0}", username);
|
||||
Console.WriteLine(" Domain : {0}", domain);
|
||||
Console.WriteLine(" LogonId : {0}", data.LoginID.LowPart);
|
||||
Console.WriteLine(" UserSID : {0}", sid.AccountDomainSid);
|
||||
Console.WriteLine(" AuthenticationPackage : {0}", authpackage);
|
||||
Console.WriteLine(" LogonType : {0}", logonType);
|
||||
Console.WriteLine(" LogonType : {0}", logonTime);
|
||||
Console.WriteLine(" LogonServer : {0}", logonServer);
|
||||
Console.WriteLine(" LogonServerDNSDomain : {0}", dnsDomainName);
|
||||
Console.WriteLine(" UserPrincipalName : {0}\r\n", upn);*/
|
||||
|
||||
if (ticketPointer != IntPtr.Zero)
|
||||
{
|
||||
// parse the returned pointer into our initial KERB_QUERY_TKT_CACHE_RESPONSE structure
|
||||
tickets = (KERB_QUERY_TKT_CACHE_RESPONSE)Marshal.PtrToStructure((System.IntPtr)ticketPointer, typeof(KERB_QUERY_TKT_CACHE_RESPONSE));
|
||||
int count2 = tickets.CountOfTickets;
|
||||
|
||||
if (count2 != 0)
|
||||
{
|
||||
Console.WriteLine(" [*] Enumerated {0} ticket(s):\r\n", count2);
|
||||
totalTicketCount += count2;
|
||||
// get the size of the structures we're iterating over
|
||||
Int32 dataSize = Marshal.SizeOf(typeof(KERB_TICKET_CACHE_INFO));
|
||||
|
||||
for (int j = 0; j < count2; j++)
|
||||
{
|
||||
// iterate through the structures
|
||||
IntPtr currTicketPtr = (IntPtr)(long)((ticketPointer.ToInt64() + (int)(8 + j * dataSize)));
|
||||
|
||||
// parse the new ptr to the appropriate structure
|
||||
ticket = (KERB_TICKET_CACHE_INFO)Marshal.PtrToStructure(currTicketPtr, typeof(KERB_TICKET_CACHE_INFO));
|
||||
|
||||
// extract our fields
|
||||
string serverName = Marshal.PtrToStringUni(ticket.ServerName.Buffer, ticket.ServerName.Length / 2);
|
||||
string realmName = Marshal.PtrToStringUni(ticket.RealmName.Buffer, ticket.RealmName.Length / 2);
|
||||
DateTime startTime = DateTime.FromFileTime(ticket.StartTime);
|
||||
DateTime endTime = DateTime.FromFileTime(ticket.EndTime);
|
||||
DateTime renewTime = DateTime.FromFileTime(ticket.RenewTime);
|
||||
string encryptionType = ((KERB_ENCRYPTION_TYPE)ticket.EncryptionType).ToString();
|
||||
string ticketFlags = ((KERB_TICKET_FLAGS)ticket.TicketFlags).ToString();
|
||||
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "UserPrincipalName", upn },
|
||||
{ "serverName", serverName },
|
||||
{ "RealmName", realmName },
|
||||
{ "StartTime", String.Format("{0}", startTime) },
|
||||
{ "EndTime", String.Format("{0}", endTime) },
|
||||
{ "RenewTime", String.Format("{0}", renewTime) },
|
||||
{ "EncryptionType", encryptionType },
|
||||
{ "TicketFlags", ticketFlags },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// move the pointer forward
|
||||
luidPtr = (IntPtr)((long)luidPtr.ToInt64() + Marshal.SizeOf(typeof(LUID)));
|
||||
Helpers.LsaFreeReturnBuffer(sessionData);
|
||||
}
|
||||
Helpers.LsaFreeReturnBuffer(luidPtr);
|
||||
|
||||
// disconnect from LSA
|
||||
Helpers.LsaDeregisterLogonProcess(hLsa);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, string>> ListKerberosTicketsCurrentUser()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
// adapted partially from Vincent LE TOUX' work
|
||||
// https://github.com/vletoux/MakeMeEnterpriseAdmin/blob/master/MakeMeEnterpriseAdmin.ps1#L2939-L2950
|
||||
// and https://www.dreamincode.net/forums/topic/135033-increment-memory-pointer-issue/
|
||||
// also Jared Atkinson's work at https://github.com/Invoke-IR/ACE/blob/master/ACE-Management/PS-ACE/Scripts/ACE_Get-KerberosTicketCache.ps1
|
||||
|
||||
try
|
||||
{
|
||||
string name = "kerberos";
|
||||
LSA_STRING_IN LSAString;
|
||||
LSAString.Length = (ushort)name.Length;
|
||||
LSAString.MaximumLength = (ushort)(name.Length + 1);
|
||||
LSAString.Buffer = name;
|
||||
|
||||
IntPtr ticketPointer = IntPtr.Zero;
|
||||
IntPtr ticketsPointer = IntPtr.Zero;
|
||||
DateTime sysTime = new DateTime(1601, 1, 1, 0, 0, 0, 0);
|
||||
int authPack;
|
||||
int returnBufferLength = 0;
|
||||
int protocalStatus = 0;
|
||||
IntPtr lsaHandle;
|
||||
int retCode;
|
||||
|
||||
// If we want to look at tickets from a session other than our own
|
||||
// then we need to use LsaRegisterLogonProcess instead of LsaConnectUntrusted
|
||||
retCode = Helpers.LsaConnectUntrusted(out lsaHandle);
|
||||
|
||||
KERB_QUERY_TKT_CACHE_REQUEST tQuery = new KERB_QUERY_TKT_CACHE_REQUEST();
|
||||
KERB_QUERY_TKT_CACHE_RESPONSE tickets = new KERB_QUERY_TKT_CACHE_RESPONSE();
|
||||
KERB_TICKET_CACHE_INFO ticket;
|
||||
|
||||
// obtains the unique identifier for the kerberos authentication package.
|
||||
retCode = Helpers.LsaLookupAuthenticationPackage(lsaHandle, ref LSAString, out authPack);
|
||||
|
||||
// input object for querying the ticket cache (https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_kerb_query_tkt_cache_request)
|
||||
tQuery.LogonId = new LUID();
|
||||
tQuery.MessageType = KERB_PROTOCOL_MESSAGE_TYPE.KerbQueryTicketCacheMessage;
|
||||
|
||||
// query LSA, specifying we want the ticket cache
|
||||
retCode = Helpers.LsaCallAuthenticationPackage(lsaHandle, authPack, ref tQuery, Marshal.SizeOf(tQuery), out ticketPointer, out returnBufferLength, out protocalStatus);
|
||||
|
||||
// parse the returned pointer into our initial KERB_QUERY_TKT_CACHE_RESPONSE structure
|
||||
tickets = (KERB_QUERY_TKT_CACHE_RESPONSE)Marshal.PtrToStructure((System.IntPtr)ticketPointer, typeof(KERB_QUERY_TKT_CACHE_RESPONSE));
|
||||
int count = tickets.CountOfTickets;
|
||||
|
||||
// get the size of the structures we're iterating over
|
||||
Int32 dataSize = Marshal.SizeOf(typeof(KERB_TICKET_CACHE_INFO));
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
// iterate through the structures
|
||||
IntPtr currTicketPtr = (IntPtr)(long)((ticketPointer.ToInt64() + (int)(8 + i * dataSize)));
|
||||
|
||||
// parse the new ptr to the appropriate structure
|
||||
ticket = (KERB_TICKET_CACHE_INFO)Marshal.PtrToStructure(currTicketPtr, typeof(KERB_TICKET_CACHE_INFO));
|
||||
|
||||
// extract our fields
|
||||
string serverName = Marshal.PtrToStringUni(ticket.ServerName.Buffer, ticket.ServerName.Length / 2);
|
||||
string realmName = Marshal.PtrToStringUni(ticket.RealmName.Buffer, ticket.RealmName.Length / 2);
|
||||
DateTime startTime = DateTime.FromFileTime(ticket.StartTime);
|
||||
DateTime endTime = DateTime.FromFileTime(ticket.EndTime);
|
||||
DateTime renewTime = DateTime.FromFileTime(ticket.RenewTime);
|
||||
string encryptionType = ((KERB_ENCRYPTION_TYPE)ticket.EncryptionType).ToString();
|
||||
string ticketFlags = ((KERB_TICKET_FLAGS)ticket.TicketFlags).ToString();
|
||||
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "serverName", serverName },
|
||||
{ "RealmName", realmName },
|
||||
{ "StartTime", String.Format("{0}", startTime) },
|
||||
{ "EndTime", String.Format("{0}", endTime) },
|
||||
{ "RenewTime", String.Format("{0}", renewTime) },
|
||||
{ "EncryptionType", encryptionType },
|
||||
{ "TicketFlags", ticketFlags },
|
||||
});
|
||||
}
|
||||
|
||||
// disconnect from LSA
|
||||
Helpers.LsaDeregisterLogonProcess(lsaHandle);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, string>> GetKerberosTGTData()
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
return ListKerberosTGTDataAllUsers();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ListKerberosTGTDataCurrentUser();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, string>> ListKerberosTGTDataAllUsers()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
// adapted partially from Vincent LE TOUX' work
|
||||
// https://github.com/vletoux/MakeMeEnterpriseAdmin/blob/master/MakeMeEnterpriseAdmin.ps1#L2939-L2950
|
||||
// and https://www.dreamincode.net/forums/topic/135033-increment-memory-pointer-issue/
|
||||
// also Jared Atkinson's work at https://github.com/Invoke-IR/ACE/blob/master/ACE-Management/PS-ACE/Scripts/ACE_Get-KerberosTicketCache.ps1
|
||||
|
||||
IntPtr hLsa = Helpers.LsaRegisterLogonProcessHelper();
|
||||
int totalTicketCount = 0;
|
||||
|
||||
// if the original call fails then it is likely we don't have SeTcbPrivilege
|
||||
// to get SeTcbPrivilege we can Impersonate a NT AUTHORITY\SYSTEM Token
|
||||
if (hLsa == IntPtr.Zero)
|
||||
{
|
||||
Helpers.GetSystem();
|
||||
// should now have the proper privileges to get a Handle to LSA
|
||||
hLsa = Helpers.LsaRegisterLogonProcessHelper();
|
||||
// we don't need our NT AUTHORITY\SYSTEM Token anymore so we can revert to our original token
|
||||
Helpers.RevertToSelf();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// first return all the logon sessions
|
||||
|
||||
DateTime systime = new DateTime(1601, 1, 1, 0, 0, 0, 0); //win32 systemdate
|
||||
UInt64 count;
|
||||
IntPtr luidPtr = IntPtr.Zero;
|
||||
IntPtr iter = luidPtr;
|
||||
|
||||
uint ret = Helpers.LsaEnumerateLogonSessions(out count, out luidPtr); // get an array of pointers to LUIDs
|
||||
|
||||
for (ulong i = 0; i < count; i++)
|
||||
{
|
||||
IntPtr sessionData;
|
||||
ret = Helpers.LsaGetLogonSessionData(luidPtr, out sessionData);
|
||||
SECURITY_LOGON_SESSION_DATA data = (SECURITY_LOGON_SESSION_DATA)Marshal.PtrToStructure(sessionData, typeof(SECURITY_LOGON_SESSION_DATA));
|
||||
|
||||
// if we have a valid logon
|
||||
if (data.PSiD != IntPtr.Zero)
|
||||
{
|
||||
// user session data
|
||||
string username = Marshal.PtrToStringUni(data.Username.Buffer).Trim();
|
||||
System.Security.Principal.SecurityIdentifier sid = new System.Security.Principal.SecurityIdentifier(data.PSiD);
|
||||
string domain = Marshal.PtrToStringUni(data.LoginDomain.Buffer).Trim();
|
||||
string authpackage = Marshal.PtrToStringUni(data.AuthenticationPackage.Buffer).Trim();
|
||||
SECURITY_LOGON_TYPE logonType = (SECURITY_LOGON_TYPE)data.LogonType;
|
||||
DateTime logonTime = systime.AddTicks((long)data.LoginTime);
|
||||
string logonServer = Marshal.PtrToStringUni(data.LogonServer.Buffer).Trim();
|
||||
string dnsDomainName = Marshal.PtrToStringUni(data.DnsDomainName.Buffer).Trim();
|
||||
string upn = Marshal.PtrToStringUni(data.Upn.Buffer).Trim();
|
||||
|
||||
// now we want to get the tickets for this logon ID
|
||||
string name = "kerberos";
|
||||
LSA_STRING_IN LSAString;
|
||||
LSAString.Length = (ushort)name.Length;
|
||||
LSAString.MaximumLength = (ushort)(name.Length + 1);
|
||||
LSAString.Buffer = name;
|
||||
|
||||
IntPtr responsePointer = IntPtr.Zero;
|
||||
int authPack;
|
||||
int returnBufferLength = 0;
|
||||
int protocalStatus = 0;
|
||||
int retCode;
|
||||
|
||||
KERB_RETRIEVE_TKT_REQUEST tQuery = new KERB_RETRIEVE_TKT_REQUEST();
|
||||
KERB_RETRIEVE_TKT_RESPONSE response = new KERB_RETRIEVE_TKT_RESPONSE();
|
||||
|
||||
// obtains the unique identifier for the kerberos authentication package.
|
||||
retCode = Helpers.LsaLookupAuthenticationPackage(hLsa, ref LSAString, out authPack);
|
||||
|
||||
// input object for querying the TGT for a specific logon ID (https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_kerb_retrieve_tkt_request)
|
||||
LUID userLogonID = new LUID();
|
||||
userLogonID.LowPart = data.LoginID.LowPart;
|
||||
userLogonID.HighPart = 0;
|
||||
tQuery.LogonId = userLogonID;
|
||||
tQuery.MessageType = KERB_PROTOCOL_MESSAGE_TYPE.KerbRetrieveTicketMessage;
|
||||
// indicate we want kerb creds yo'
|
||||
tQuery.CacheOptions = KERB_CACHE_OPTIONS.KERB_RETRIEVE_TICKET_AS_KERB_CRED;
|
||||
|
||||
// query LSA, specifying we want the the TGT data
|
||||
retCode = Helpers.LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT(hLsa, authPack, ref tQuery, Marshal.SizeOf(tQuery), out responsePointer, out returnBufferLength, out protocalStatus);
|
||||
|
||||
if ((retCode) == 0 && (responsePointer != IntPtr.Zero))
|
||||
{
|
||||
/*Console.WriteLine("\r\n UserName : {0}", username);
|
||||
Console.WriteLine(" Domain : {0}", domain);
|
||||
Console.WriteLine(" LogonId : {0}", data.LoginID.LowPart);
|
||||
Console.WriteLine(" UserSID : {0}", sid.AccountDomainSid);
|
||||
Console.WriteLine(" AuthenticationPackage : {0}", authpackage);
|
||||
Console.WriteLine(" LogonType : {0}", logonType);
|
||||
Console.WriteLine(" LogonType : {0}", logonTime);
|
||||
Console.WriteLine(" LogonServer : {0}", logonServer);
|
||||
Console.WriteLine(" LogonServerDNSDomain : {0}", dnsDomainName);
|
||||
Console.WriteLine(" UserPrincipalName : {0}", upn);*/
|
||||
|
||||
// parse the returned pointer into our initial KERB_RETRIEVE_TKT_RESPONSE structure
|
||||
response = (KERB_RETRIEVE_TKT_RESPONSE)Marshal.PtrToStructure((System.IntPtr)responsePointer, typeof(KERB_RETRIEVE_TKT_RESPONSE));
|
||||
|
||||
KERB_EXTERNAL_NAME serviceNameStruct = (KERB_EXTERNAL_NAME)Marshal.PtrToStructure(response.Ticket.ServiceName, typeof(KERB_EXTERNAL_NAME));
|
||||
string serviceName = Marshal.PtrToStringUni(serviceNameStruct.Names.Buffer, serviceNameStruct.Names.Length / 2).Trim();
|
||||
|
||||
string targetName = "";
|
||||
if (response.Ticket.TargetName != IntPtr.Zero)
|
||||
{
|
||||
KERB_EXTERNAL_NAME targetNameStruct = (KERB_EXTERNAL_NAME)Marshal.PtrToStructure(response.Ticket.TargetName, typeof(KERB_EXTERNAL_NAME));
|
||||
targetName = Marshal.PtrToStringUni(targetNameStruct.Names.Buffer, targetNameStruct.Names.Length / 2).Trim();
|
||||
}
|
||||
|
||||
KERB_EXTERNAL_NAME clientNameStruct = (KERB_EXTERNAL_NAME)Marshal.PtrToStructure(response.Ticket.ClientName, typeof(KERB_EXTERNAL_NAME));
|
||||
string clientName = Marshal.PtrToStringUni(clientNameStruct.Names.Buffer, clientNameStruct.Names.Length / 2).Trim();
|
||||
|
||||
string domainName = Marshal.PtrToStringUni(response.Ticket.DomainName.Buffer, response.Ticket.DomainName.Length / 2).Trim();
|
||||
string targetDomainName = Marshal.PtrToStringUni(response.Ticket.TargetDomainName.Buffer, response.Ticket.TargetDomainName.Length / 2).Trim();
|
||||
string altTargetDomainName = Marshal.PtrToStringUni(response.Ticket.AltTargetDomainName.Buffer, response.Ticket.AltTargetDomainName.Length / 2).Trim();
|
||||
|
||||
// extract the session key
|
||||
KERB_ENCRYPTION_TYPE sessionKeyType = (KERB_ENCRYPTION_TYPE)response.Ticket.SessionKey.KeyType;
|
||||
Int32 sessionKeyLength = response.Ticket.SessionKey.Length;
|
||||
byte[] sessionKey = new byte[sessionKeyLength];
|
||||
Marshal.Copy(response.Ticket.SessionKey.Value, sessionKey, 0, sessionKeyLength);
|
||||
string base64SessionKey = Convert.ToBase64String(sessionKey);
|
||||
|
||||
DateTime keyExpirationTime = DateTime.FromFileTime(response.Ticket.KeyExpirationTime);
|
||||
DateTime startTime = DateTime.FromFileTime(response.Ticket.StartTime);
|
||||
DateTime endTime = DateTime.FromFileTime(response.Ticket.EndTime);
|
||||
DateTime renewUntil = DateTime.FromFileTime(response.Ticket.RenewUntil);
|
||||
Int64 timeSkew = response.Ticket.TimeSkew;
|
||||
Int32 encodedTicketSize = response.Ticket.EncodedTicketSize;
|
||||
|
||||
string ticketFlags = ((KERB_TICKET_FLAGS)response.Ticket.TicketFlags).ToString();
|
||||
|
||||
// extract the TGT and base64 encode it
|
||||
byte[] encodedTicket = new byte[encodedTicketSize];
|
||||
Marshal.Copy(response.Ticket.EncodedTicket, encodedTicket, 0, encodedTicketSize);
|
||||
string base64TGT = Convert.ToBase64String(encodedTicket);
|
||||
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "UserPrincipalName", upn },
|
||||
{ "ServiceName", serviceName },
|
||||
{ "TargetName", targetName },
|
||||
{ "ClientName", clientName },
|
||||
{ "DomainName", domainName },
|
||||
{ "TargetDomainName", targetDomainName },
|
||||
{ "SessionKeyType", String.Format("{0}", sessionKeyType) },
|
||||
{ "Base64SessionKey", base64SessionKey },
|
||||
{ "KeyExpirationTime", String.Format("{0}", keyExpirationTime) },
|
||||
{ "TicketFlags", ticketFlags },
|
||||
{ "StartTime", String.Format("{0}", startTime) },
|
||||
{ "EndTime", String.Format("{0}", endTime) },
|
||||
{ "RenewUntil", String.Format("{0}", renewUntil) },
|
||||
{ "TimeSkew", String.Format("{0}", timeSkew) },
|
||||
{ "EncodedTicketSize", String.Format("{0}", encodedTicketSize) },
|
||||
{ "Base64EncodedTicket", base64TGT },
|
||||
});
|
||||
totalTicketCount++;
|
||||
}
|
||||
}
|
||||
luidPtr = (IntPtr)((long)luidPtr.ToInt64() + Marshal.SizeOf(typeof(LUID)));
|
||||
//move the pointer forward
|
||||
Helpers.LsaFreeReturnBuffer(sessionData);
|
||||
//free the SECURITY_LOGON_SESSION_DATA memory in the struct
|
||||
}
|
||||
Helpers.LsaFreeReturnBuffer(luidPtr); //free the array of LUIDs
|
||||
|
||||
// disconnect from LSA
|
||||
Helpers.LsaDeregisterLogonProcess(hLsa);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
public static List<Dictionary<string, string>> ListKerberosTGTDataCurrentUser()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
// adapted partially from Vincent LE TOUX' work
|
||||
// https://github.com/vletoux/MakeMeEnterpriseAdmin/blob/master/MakeMeEnterpriseAdmin.ps1#L2939-L2950
|
||||
// and https://www.dreamincode.net/forums/topic/135033-increment-memory-pointer-issue/
|
||||
// also Jared Atkinson's work at https://github.com/Invoke-IR/ACE/blob/master/ACE-Management/PS-ACE/Scripts/ACE_Get-KerberosTicketCache.ps1
|
||||
|
||||
try
|
||||
{
|
||||
string name = "kerberos";
|
||||
LSA_STRING_IN LSAString;
|
||||
LSAString.Length = (ushort)name.Length;
|
||||
LSAString.MaximumLength = (ushort)(name.Length + 1);
|
||||
LSAString.Buffer = name;
|
||||
|
||||
IntPtr responsePointer = IntPtr.Zero;
|
||||
int authPack;
|
||||
int returnBufferLength = 0;
|
||||
int protocalStatus = 0;
|
||||
IntPtr lsaHandle;
|
||||
int retCode;
|
||||
|
||||
// If we want to look at tickets from a session other than our own
|
||||
// then we need to use LsaRegisterLogonProcess instead of LsaConnectUntrusted
|
||||
retCode = Helpers.LsaConnectUntrusted(out lsaHandle);
|
||||
|
||||
KERB_RETRIEVE_TKT_REQUEST tQuery = new KERB_RETRIEVE_TKT_REQUEST();
|
||||
KERB_RETRIEVE_TKT_RESPONSE response = new KERB_RETRIEVE_TKT_RESPONSE();
|
||||
|
||||
// obtains the unique identifier for the kerberos authentication package.
|
||||
retCode = Helpers.LsaLookupAuthenticationPackage(lsaHandle, ref LSAString, out authPack);
|
||||
|
||||
// input object for querying the TGT (https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_kerb_retrieve_tkt_request)
|
||||
tQuery.LogonId = new LUID();
|
||||
tQuery.MessageType = KERB_PROTOCOL_MESSAGE_TYPE.KerbRetrieveTicketMessage;
|
||||
// indicate we want kerb creds yo'
|
||||
//tQuery.CacheOptions = KERB_CACHE_OPTIONS.KERB_RETRIEVE_TICKET_AS_KERB_CRED;
|
||||
|
||||
// query LSA, specifying we want the the TGT data
|
||||
retCode = Helpers.LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT(lsaHandle, authPack, ref tQuery, Marshal.SizeOf(tQuery), out responsePointer, out returnBufferLength, out protocalStatus);
|
||||
|
||||
// parse the returned pointer into our initial KERB_RETRIEVE_TKT_RESPONSE structure
|
||||
response = (KERB_RETRIEVE_TKT_RESPONSE)Marshal.PtrToStructure((System.IntPtr)responsePointer, typeof(KERB_RETRIEVE_TKT_RESPONSE));
|
||||
|
||||
KERB_EXTERNAL_NAME serviceNameStruct = (KERB_EXTERNAL_NAME)Marshal.PtrToStructure(response.Ticket.ServiceName, typeof(KERB_EXTERNAL_NAME));
|
||||
string serviceName = Marshal.PtrToStringUni(serviceNameStruct.Names.Buffer, serviceNameStruct.Names.Length / 2).Trim();
|
||||
|
||||
string targetName = "";
|
||||
if (response.Ticket.TargetName != IntPtr.Zero)
|
||||
{
|
||||
KERB_EXTERNAL_NAME targetNameStruct = (KERB_EXTERNAL_NAME)Marshal.PtrToStructure(response.Ticket.TargetName, typeof(KERB_EXTERNAL_NAME));
|
||||
targetName = Marshal.PtrToStringUni(targetNameStruct.Names.Buffer, targetNameStruct.Names.Length / 2).Trim();
|
||||
}
|
||||
|
||||
KERB_EXTERNAL_NAME clientNameStruct = (KERB_EXTERNAL_NAME)Marshal.PtrToStructure(response.Ticket.ClientName, typeof(KERB_EXTERNAL_NAME));
|
||||
string clientName = Marshal.PtrToStringUni(clientNameStruct.Names.Buffer, clientNameStruct.Names.Length / 2).Trim();
|
||||
|
||||
string domainName = Marshal.PtrToStringUni(response.Ticket.DomainName.Buffer, response.Ticket.DomainName.Length / 2).Trim();
|
||||
string targetDomainName = Marshal.PtrToStringUni(response.Ticket.TargetDomainName.Buffer, response.Ticket.TargetDomainName.Length / 2).Trim();
|
||||
string altTargetDomainName = Marshal.PtrToStringUni(response.Ticket.AltTargetDomainName.Buffer, response.Ticket.AltTargetDomainName.Length / 2).Trim();
|
||||
|
||||
// extract the session key
|
||||
KERB_ENCRYPTION_TYPE sessionKeyType = (KERB_ENCRYPTION_TYPE)response.Ticket.SessionKey.KeyType;
|
||||
Int32 sessionKeyLength = response.Ticket.SessionKey.Length;
|
||||
byte[] sessionKey = new byte[sessionKeyLength];
|
||||
Marshal.Copy(response.Ticket.SessionKey.Value, sessionKey, 0, sessionKeyLength);
|
||||
string base64SessionKey = Convert.ToBase64String(sessionKey);
|
||||
|
||||
DateTime keyExpirationTime = DateTime.FromFileTime(response.Ticket.KeyExpirationTime);
|
||||
DateTime startTime = DateTime.FromFileTime(response.Ticket.StartTime);
|
||||
DateTime endTime = DateTime.FromFileTime(response.Ticket.EndTime);
|
||||
DateTime renewUntil = DateTime.FromFileTime(response.Ticket.RenewUntil);
|
||||
Int64 timeSkew = response.Ticket.TimeSkew;
|
||||
Int32 encodedTicketSize = response.Ticket.EncodedTicketSize;
|
||||
|
||||
string ticketFlags = ((KERB_TICKET_FLAGS)response.Ticket.TicketFlags).ToString();
|
||||
|
||||
// extract the TGT and base64 encode it
|
||||
byte[] encodedTicket = new byte[encodedTicketSize];
|
||||
Marshal.Copy(response.Ticket.EncodedTicket, encodedTicket, 0, encodedTicketSize);
|
||||
string base64TGT = Convert.ToBase64String(encodedTicket);
|
||||
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "ServiceName", serviceName },
|
||||
{ "TargetName", targetName },
|
||||
{ "ClientName", clientName },
|
||||
{ "DomainName", domainName },
|
||||
{ "TargetDomainName", targetDomainName },
|
||||
{ "SessionKeyType", String.Format("{0}", sessionKeyType) },
|
||||
{ "Base64SessionKey", base64SessionKey },
|
||||
{ "KeyExpirationTime", String.Format("{0}", keyExpirationTime) },
|
||||
{ "TicketFlags", ticketFlags },
|
||||
{ "StartTime", String.Format("{0}", startTime) },
|
||||
{ "EndTime", String.Format("{0}", endTime) },
|
||||
{ "RenewUntil", String.Format("{0}", renewUntil) },
|
||||
{ "TimeSkew", String.Format("{0}", timeSkew) },
|
||||
{ "EncodedTicketSize", String.Format("{0}", encodedTicketSize) },
|
||||
{ "Base64EncodedTicket", base64TGT },
|
||||
});
|
||||
|
||||
// disconnect from LSA
|
||||
Helpers.LsaDeregisterLogonProcess(lsaHandle);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Kerberos.enums
|
||||
{
|
||||
|
||||
public enum SECURITY_LOGON_TYPE : uint
|
||||
{
|
||||
Interactive = 2, // logging on interactively.
|
||||
Network, // logging using a network.
|
||||
Batch, // logon for a batch process.
|
||||
Service, // logon for a service account.
|
||||
Proxy, // Not supported.
|
||||
Unlock, // Tattempt to unlock a workstation.
|
||||
NetworkCleartext, // network logon with cleartext credentials
|
||||
NewCredentials, // caller can clone its current token and specify new credentials for outbound connections
|
||||
RemoteInteractive, // terminal server session that is both remote and interactive
|
||||
CachedInteractive, // attempt to use the cached credentials without going out across the network
|
||||
CachedRemoteInteractive,// same as RemoteInteractive, except used internally for auditing purposes
|
||||
CachedUnlock // attempt to unlock a workstation
|
||||
}
|
||||
public enum KERB_ENCRYPTION_TYPE : UInt32
|
||||
{
|
||||
reserved0 = 0,
|
||||
des_cbc_crc = 1,
|
||||
des_cbc_md4 = 2,
|
||||
des_cbc_md5 = 3,
|
||||
reserved1 = 4,
|
||||
des3_cbc_md5 = 5,
|
||||
reserved2 = 6,
|
||||
des3_cbc_sha1 = 7,
|
||||
dsaWithSHA1_CmsOID = 9,
|
||||
md5WithRSAEncryption_CmsOID = 10,
|
||||
sha1WithRSAEncryption_CmsOID = 11,
|
||||
rc2CBC_EnvOID = 12,
|
||||
rsaEncryption_EnvOID = 13,
|
||||
rsaES_OAEP_ENV_OID = 14,
|
||||
des_ede3_cbc_Env_OID = 15,
|
||||
des3_cbc_sha1_kd = 16,
|
||||
aes128_cts_hmac_sha1_96 = 17,
|
||||
aes256_cts_hmac_sha1_96 = 18,
|
||||
aes128_cts_hmac_sha256_128 = 19,
|
||||
aes256_cts_hmac_sha384_192 = 20,
|
||||
rc4_hmac = 23,
|
||||
rc4_hmac_exp = 24,
|
||||
camellia128_cts_cmac = 25,
|
||||
camellia256_cts_cmac = 26,
|
||||
subkey_keymaterial = 65
|
||||
}
|
||||
[Flags]
|
||||
public enum KERB_TICKET_FLAGS : UInt32
|
||||
{
|
||||
reserved = 2147483648,
|
||||
forwardable = 0x40000000,
|
||||
forwarded = 0x20000000,
|
||||
proxiable = 0x10000000,
|
||||
proxy = 0x08000000,
|
||||
may_postdate = 0x04000000,
|
||||
postdated = 0x02000000,
|
||||
invalid = 0x01000000,
|
||||
renewable = 0x00800000,
|
||||
initial = 0x00400000,
|
||||
pre_authent = 0x00200000,
|
||||
hw_authent = 0x00100000,
|
||||
ok_as_delegate = 0x00040000,
|
||||
name_canonicalize = 0x00010000,
|
||||
//cname_in_pa_data = 0x00040000,
|
||||
enc_pa_rep = 0x00010000,
|
||||
reserved1 = 0x00000001
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Flags]
|
||||
public enum KERB_CACHE_OPTIONS : UInt64
|
||||
{
|
||||
KERB_RETRIEVE_TICKET_DEFAULT = 0x0,
|
||||
KERB_RETRIEVE_TICKET_DONT_USE_CACHE = 0x1,
|
||||
KERB_RETRIEVE_TICKET_USE_CACHE_ONLY = 0x2,
|
||||
KERB_RETRIEVE_TICKET_USE_CREDHANDLE = 0x4,
|
||||
KERB_RETRIEVE_TICKET_AS_KERB_CRED = 0x8,
|
||||
KERB_RETRIEVE_TICKET_WITH_SEC_CRED = 0x10,
|
||||
KERB_RETRIEVE_TICKET_CACHE_TICKET = 0x20,
|
||||
KERB_RETRIEVE_TICKET_MAX_LIFETIME = 0x40,
|
||||
}
|
||||
|
||||
public enum KERB_PROTOCOL_MESSAGE_TYPE : UInt32
|
||||
{
|
||||
KerbDebugRequestMessage = 0,
|
||||
KerbQueryTicketCacheMessage = 1,
|
||||
KerbChangeMachinePasswordMessage = 2,
|
||||
KerbVerifyPacMessage = 3,
|
||||
KerbRetrieveTicketMessage = 4,
|
||||
KerbUpdateAddressesMessage = 5,
|
||||
KerbPurgeTicketCacheMessage = 6,
|
||||
KerbChangePasswordMessage = 7,
|
||||
KerbRetrieveEncodedTicketMessage = 8,
|
||||
KerbDecryptDataMessage = 9,
|
||||
KerbAddBindingCacheEntryMessage = 10,
|
||||
KerbSetPasswordMessage = 11,
|
||||
KerbSetPasswordExMessage = 12,
|
||||
KerbVerifyCredentialsMessage = 13,
|
||||
KerbQueryTicketCacheExMessage = 14,
|
||||
KerbPurgeTicketCacheExMessage = 15,
|
||||
KerbRefreshSmartcardCredentialsMessage = 16,
|
||||
KerbAddExtraCredentialsMessage = 17,
|
||||
KerbQuerySupplementalCredentialsMessage = 18,
|
||||
KerbTransferCredentialsMessage = 19,
|
||||
KerbQueryTicketCacheEx2Message = 20,
|
||||
KerbSubmitTicketMessage = 21,
|
||||
KerbAddExtraCredentialsExMessage = 22,
|
||||
KerbQueryKdcProxyCacheMessage = 23,
|
||||
KerbPurgeKdcProxyCacheMessage = 24,
|
||||
KerbQueryTicketCacheEx3Message = 25,
|
||||
KerbCleanupMachinePkinitCredsMessage = 26,
|
||||
KerbAddBindingCacheEntryExMessage = 27,
|
||||
KerbQueryBindingCacheMessage = 28,
|
||||
KerbPurgeBindingCacheMessage = 29,
|
||||
KerbQueryDomainExtendedPoliciesMessage = 30,
|
||||
KerbQueryS4U2ProxyCacheMessage = 31
|
||||
}
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.KnownFileCreds.Kerberos.enums;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Kerberos.structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KERB_QUERY_TKT_CACHE_REQUEST
|
||||
{
|
||||
public KERB_PROTOCOL_MESSAGE_TYPE MessageType;
|
||||
public LUID LogonId;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LUID
|
||||
{
|
||||
public uint LowPart;
|
||||
public int HighPart;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LSA_STRING_IN
|
||||
{
|
||||
public UInt16 Length;
|
||||
public UInt16 MaximumLength;
|
||||
public string Buffer;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LSA_STRING_OUT
|
||||
{
|
||||
public UInt16 Length;
|
||||
public UInt16 MaximumLength;
|
||||
public IntPtr Buffer;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SECURITY_LOGON_SESSION_DATA
|
||||
{
|
||||
public UInt32 Size;
|
||||
public LUID LoginID;
|
||||
public LSA_STRING_OUT Username;
|
||||
public LSA_STRING_OUT LoginDomain;
|
||||
public LSA_STRING_OUT AuthenticationPackage;
|
||||
public UInt32 LogonType;
|
||||
public UInt32 Session;
|
||||
public IntPtr PSiD;
|
||||
public UInt64 LoginTime;
|
||||
public LSA_STRING_OUT LogonServer;
|
||||
public LSA_STRING_OUT DnsDomainName;
|
||||
public LSA_STRING_OUT Upn;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KERB_QUERY_TKT_CACHE_RESPONSE
|
||||
{
|
||||
public KERB_PROTOCOL_MESSAGE_TYPE MessageType;
|
||||
public int CountOfTickets;
|
||||
// public KERB_TICKET_CACHE_INFO[] Tickets;
|
||||
public IntPtr Tickets;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KERB_TICKET_CACHE_INFO
|
||||
{
|
||||
public LSA_STRING_OUT ServerName;
|
||||
public LSA_STRING_OUT RealmName;
|
||||
public Int64 StartTime;
|
||||
public Int64 EndTime;
|
||||
public Int64 RenewTime;
|
||||
public Int32 EncryptionType;
|
||||
public UInt32 TicketFlags;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KERB_RETRIEVE_TKT_RESPONSE
|
||||
{
|
||||
public KERB_EXTERNAL_TICKET Ticket;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KERB_CRYPTO_KEY
|
||||
{
|
||||
public Int32 KeyType;
|
||||
public Int32 Length;
|
||||
public IntPtr Value;
|
||||
}
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KERB_EXTERNAL_TICKET
|
||||
{
|
||||
public IntPtr ServiceName;
|
||||
public IntPtr TargetName;
|
||||
public IntPtr ClientName;
|
||||
public LSA_STRING_OUT DomainName;
|
||||
public LSA_STRING_OUT TargetDomainName;
|
||||
public LSA_STRING_OUT AltTargetDomainName;
|
||||
public KERB_CRYPTO_KEY SessionKey;
|
||||
public UInt32 TicketFlags;
|
||||
public UInt32 Flags;
|
||||
public Int64 KeyExpirationTime;
|
||||
public Int64 StartTime;
|
||||
public Int64 EndTime;
|
||||
public Int64 RenewUntil;
|
||||
public Int64 TimeSkew;
|
||||
public Int32 EncodedTicketSize;
|
||||
public IntPtr EncodedTicket;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KERB_RETRIEVE_TKT_REQUEST
|
||||
{
|
||||
public KERB_PROTOCOL_MESSAGE_TYPE MessageType;
|
||||
public LUID LogonId;
|
||||
public LSA_STRING_IN TargetName;
|
||||
public UInt64 TicketFlags;
|
||||
public KERB_CACHE_OPTIONS CacheOptions;
|
||||
public Int64 EncryptionType;
|
||||
public SECURITY_HANDLE CredentialsHandle;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SECURITY_HANDLE
|
||||
{
|
||||
public IntPtr LowPart;
|
||||
public IntPtr HighPart;
|
||||
public SECURITY_HANDLE(int dummy)
|
||||
{
|
||||
LowPart = HighPart = IntPtr.Zero;
|
||||
}
|
||||
};
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct KERB_EXTERNAL_NAME
|
||||
{
|
||||
public Int16 NameType;
|
||||
public UInt16 NameCount;
|
||||
public LSA_STRING_OUT Names;
|
||||
}
|
||||
}
|
591
winPEAS/winPEASexe/winPEAS/KnownFileCreds/KnownFileCredsInfo.cs
Normal file
591
winPEAS/winPEASexe/winPEAS/KnownFileCreds/KnownFileCredsInfo.cs
Normal file
@ -0,0 +1,591 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Utils;
|
||||
|
||||
namespace winPEAS.KnownFileCreds
|
||||
{
|
||||
static class KnownFileCredsInfo
|
||||
{
|
||||
public static Dictionary<string, object> GetRecentRunCommands()
|
||||
{
|
||||
Dictionary<string, object> results = new Dictionary<string, object>();
|
||||
// lists recently run commands via the RunMRU registry key
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string[] SIDs = Registry.Users.GetSubKeyNames();
|
||||
foreach (string SID in SIDs)
|
||||
{
|
||||
if (SID.StartsWith("S-1-5") && !SID.EndsWith("_Classes"))
|
||||
results = RegistryHelper.GetRegValues("HKU", String.Format("{0}\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU", SID));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
results = RegistryHelper.GetRegValues("HKCU", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU");
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, string>> ListCloudCreds()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
// checks for various cloud credential files (AWS, Microsoft Azure, and Google Compute)
|
||||
// adapted from https://twitter.com/cmaddalena's SharpCloud project (https://github.com/chrismaddalena/SharpCloud/)
|
||||
try
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string[] dirs = Directory.GetDirectories(userFolder);
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
string[] parts = dir.Split('\\');
|
||||
string userName = parts[parts.Length - 1];
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
string awsKeyFile = String.Format("{0}\\.aws\\credentials", dir);
|
||||
if (System.IO.File.Exists(awsKeyFile))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(awsKeyFile);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(awsKeyFile);
|
||||
long size = new System.IO.FileInfo(awsKeyFile).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", awsKeyFile },
|
||||
{ "Description", "AWS credentials file" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
string computeCredsDb = String.Format("{0}\\AppData\\Roaming\\gcloud\\credentials.db", dir);
|
||||
if (System.IO.File.Exists(computeCredsDb))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeCredsDb);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(computeCredsDb);
|
||||
long size = new System.IO.FileInfo(computeCredsDb).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", computeCredsDb },
|
||||
{ "Description", "GC Compute creds" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
string computeLegacyCreds = String.Format("{0}\\AppData\\Roaming\\gcloud\\legacy_credentials", dir);
|
||||
if (System.IO.File.Exists(computeLegacyCreds))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeLegacyCreds);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(computeLegacyCreds);
|
||||
long size = new System.IO.FileInfo(computeLegacyCreds).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", computeLegacyCreds },
|
||||
{ "Description", "GC Compute creds legacy" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
string computeAccessTokensDb = String.Format("{0}\\AppData\\Roaming\\gcloud\\access_tokens.db", dir);
|
||||
if (System.IO.File.Exists(computeAccessTokensDb))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeAccessTokensDb);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(computeAccessTokensDb);
|
||||
long size = new System.IO.FileInfo(computeAccessTokensDb).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", computeAccessTokensDb },
|
||||
{ "Description", "GC Compute tokens" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
string azureTokens = String.Format("{0}\\.azure\\accessTokens.json", dir);
|
||||
if (System.IO.File.Exists(azureTokens))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(azureTokens);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(azureTokens);
|
||||
long size = new System.IO.FileInfo(azureTokens).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", azureTokens },
|
||||
{ "Description", "Azure tokens" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
string azureProfile = String.Format("{0}\\.azure\\azureProfile.json", dir);
|
||||
if (System.IO.File.Exists(azureProfile))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(azureProfile);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(azureProfile);
|
||||
long size = new System.IO.FileInfo(azureProfile).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", azureProfile },
|
||||
{ "Description", "Azure profile" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string awsKeyFile = String.Format("{0}\\.aws\\credentials", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
if (System.IO.File.Exists(awsKeyFile))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(awsKeyFile);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(awsKeyFile);
|
||||
long size = new System.IO.FileInfo(awsKeyFile).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", awsKeyFile },
|
||||
{ "Description", "AWS keys file" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
string computeCredsDb = String.Format("{0}\\AppData\\Roaming\\gcloud\\credentials.db", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
if (System.IO.File.Exists(computeCredsDb))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeCredsDb);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(computeCredsDb);
|
||||
long size = new System.IO.FileInfo(computeCredsDb).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", computeCredsDb },
|
||||
{ "Description", "GC Compute creds" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
string computeLegacyCreds = String.Format("{0}\\AppData\\Roaming\\gcloud\\legacy_credentials", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
if (System.IO.File.Exists(computeLegacyCreds))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeLegacyCreds);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(computeLegacyCreds);
|
||||
long size = new System.IO.FileInfo(computeLegacyCreds).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", computeLegacyCreds },
|
||||
{ "Description", "GC Compute creds legacy" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
string computeAccessTokensDb = String.Format("{0}\\AppData\\Roaming\\gcloud\\access_tokens.db", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
if (System.IO.File.Exists(computeAccessTokensDb))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(computeAccessTokensDb);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(computeAccessTokensDb);
|
||||
long size = new System.IO.FileInfo(computeAccessTokensDb).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", computeAccessTokensDb },
|
||||
{ "Description", "GC Compute tokens" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
string azureTokens = String.Format("{0}\\.azure\\accessTokens.json", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
if (System.IO.File.Exists(azureTokens))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(azureTokens);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(azureTokens);
|
||||
long size = new System.IO.FileInfo(azureTokens).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", azureTokens },
|
||||
{ "Description", "Azure tokens" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
string azureProfile = String.Format("{0}\\.azure\\azureProfile.json", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
if (System.IO.File.Exists(azureProfile))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(azureProfile);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(azureProfile);
|
||||
long size = new System.IO.FileInfo(azureProfile).Length;
|
||||
results.Add(new Dictionary<string, string>() {
|
||||
{ "file", azureProfile },
|
||||
{ "Description", "Azure profile" },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
public static List<Dictionary<string, string>> GetRecentFiles()
|
||||
{
|
||||
// parses recent file shortcuts via COM
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
int lastDays = 7;
|
||||
DateTime startTime = System.DateTime.Now.AddDays(-lastDays);
|
||||
|
||||
try
|
||||
{
|
||||
// WshShell COM object GUID
|
||||
Type shell = Type.GetTypeFromCLSID(new Guid("F935DC22-1CF0-11d0-ADB9-00C04FD58A0B"));
|
||||
Object shellObj = Activator.CreateInstance(shell);
|
||||
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string[] dirs = Directory.GetDirectories(userFolder);
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
string[] parts = dir.Split('\\');
|
||||
string userName = parts[parts.Length - 1];
|
||||
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
string recentPath = String.Format("{0}\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\", dir);
|
||||
try
|
||||
{
|
||||
string[] recentFiles = Directory.GetFiles(recentPath, "*.lnk", SearchOption.AllDirectories);
|
||||
|
||||
if (recentFiles.Length != 0)
|
||||
{
|
||||
Console.WriteLine(" {0} :\r\n", userName);
|
||||
foreach (string recentFile in recentFiles)
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile);
|
||||
|
||||
if (lastAccessed > startTime)
|
||||
{
|
||||
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
||||
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
||||
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
||||
|
||||
if (TargetPath.ToString().Trim() != "")
|
||||
{
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "Target", TargetPath.ToString() },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) }
|
||||
});
|
||||
}
|
||||
Marshal.ReleaseComObject(shortcut);
|
||||
shortcut = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string recentPath = String.Format("{0}\\Microsoft\\Windows\\Recent\\", System.Environment.GetEnvironmentVariable("APPDATA"));
|
||||
|
||||
string[] recentFiles = Directory.GetFiles(recentPath, "*.lnk", SearchOption.AllDirectories);
|
||||
|
||||
foreach (string recentFile in recentFiles)
|
||||
{
|
||||
// old method (needed interop dll)
|
||||
//WshShell shell = new WshShell();
|
||||
//IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(recentFile);
|
||||
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile);
|
||||
|
||||
if (lastAccessed > startTime)
|
||||
{
|
||||
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
||||
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
||||
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
||||
if (TargetPath.ToString().Trim() != "")
|
||||
{
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "Target", TargetPath.ToString() },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) }
|
||||
});
|
||||
}
|
||||
Marshal.ReleaseComObject(shortcut);
|
||||
shortcut = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// release the WshShell COM object
|
||||
Marshal.ReleaseComObject(shellObj);
|
||||
shellObj = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, string>> ListMasterKeys()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
// lists any found DPAPI master keys
|
||||
try
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string[] dirs = Directory.GetDirectories(userFolder);
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
string[] parts = dir.Split('\\');
|
||||
string userName = parts[parts.Length - 1];
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
List<string> userDPAPIBasePaths = new List<string>();
|
||||
userDPAPIBasePaths.Add(String.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
||||
userDPAPIBasePaths.Add(String.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
||||
|
||||
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
||||
{
|
||||
if (System.IO.Directory.Exists(userDPAPIBasePath))
|
||||
{
|
||||
string[] directories = Directory.GetDirectories(userDPAPIBasePath);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
string[] files = Directory.GetFiles(directory);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
||||
string fileName = System.IO.Path.GetFileName(file);
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "MasterKey", file },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||
List<string> userDPAPIBasePaths = new List<string>();
|
||||
userDPAPIBasePaths.Add(String.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
||||
userDPAPIBasePaths.Add(String.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
||||
|
||||
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
||||
{
|
||||
if (System.IO.Directory.Exists(userDPAPIBasePath))
|
||||
{
|
||||
string[] directories = Directory.GetDirectories(userDPAPIBasePath);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
string[] files = Directory.GetFiles(directory);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
||||
string fileName = System.IO.Path.GetFileName(file);
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "MasterKey", file },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, string>> GetCredFiles()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
// lists any found files in Local\Microsoft\Credentials\*
|
||||
try
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string[] dirs = Directory.GetDirectories(userFolder);
|
||||
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
string[] parts = dir.Split('\\');
|
||||
string userName = parts[parts.Length - 1];
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
List<string> userCredFilePaths = new List<string>();
|
||||
userCredFilePaths.Add(String.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", dir));
|
||||
userCredFilePaths.Add(String.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", dir));
|
||||
|
||||
foreach (string userCredFilePath in userCredFilePaths)
|
||||
{
|
||||
if (System.IO.Directory.Exists(userCredFilePath))
|
||||
{
|
||||
string[] systemFiles = Directory.GetFiles(userCredFilePath);
|
||||
if ((systemFiles != null) && (systemFiles.Length != 0))
|
||||
{
|
||||
foreach (string file in systemFiles)
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
||||
long size = new System.IO.FileInfo(file).Length;
|
||||
string fileName = System.IO.Path.GetFileName(file);
|
||||
|
||||
// jankily parse the bytes to extract the credential type and master key GUID
|
||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||
byte[] credentialArray = File.ReadAllBytes(file);
|
||||
byte[] guidMasterKeyArray = new byte[16];
|
||||
Array.Copy(credentialArray, 36, guidMasterKeyArray, 0, 16);
|
||||
Guid guidMasterKey = new Guid(guidMasterKeyArray);
|
||||
|
||||
byte[] stringLenArray = new byte[16];
|
||||
Array.Copy(credentialArray, 56, stringLenArray, 0, 4);
|
||||
int descLen = BitConverter.ToInt32(stringLenArray, 0);
|
||||
|
||||
byte[] descBytes = new byte[descLen];
|
||||
Array.Copy(credentialArray, 60, descBytes, 0, descLen - 4);
|
||||
|
||||
string desc = Encoding.Unicode.GetString(descBytes);
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "CredFile", file },
|
||||
{ "Description", desc },
|
||||
{ "MasterKey", String.Format("{0}", guidMasterKey) },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string systemFolder = String.Format("{0}\\System32\\config\\systemprofile\\AppData\\Local\\Microsoft\\Credentials", Environment.GetEnvironmentVariable("SystemRoot"));
|
||||
string[] files = Directory.GetFiles(systemFolder);
|
||||
if ((files != null) && (files.Length != 0))
|
||||
{
|
||||
foreach (string file in files)
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
||||
long size = new System.IO.FileInfo(file).Length;
|
||||
string fileName = System.IO.Path.GetFileName(file);
|
||||
|
||||
// jankily parse the bytes to extract the credential type and master key GUID
|
||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||
byte[] credentialArray = File.ReadAllBytes(file);
|
||||
byte[] guidMasterKeyArray = new byte[16];
|
||||
Array.Copy(credentialArray, 36, guidMasterKeyArray, 0, 16);
|
||||
Guid guidMasterKey = new Guid(guidMasterKeyArray);
|
||||
|
||||
byte[] stringLenArray = new byte[16];
|
||||
Array.Copy(credentialArray, 56, stringLenArray, 0, 4);
|
||||
int descLen = BitConverter.ToInt32(stringLenArray, 0);
|
||||
|
||||
byte[] descBytes = new byte[descLen];
|
||||
Array.Copy(credentialArray, 60, descBytes, 0, descLen - 4);
|
||||
|
||||
string desc = Encoding.Unicode.GetString(descBytes);
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "CredFile", file },
|
||||
{ "Description", desc },
|
||||
{ "MasterKey", String.Format("{0}", guidMasterKey) },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||
List<string> userCredFilePaths = new List<string>();
|
||||
userCredFilePaths.Add(String.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
||||
userCredFilePaths.Add(String.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
||||
|
||||
foreach (string userCredFilePath in userCredFilePaths)
|
||||
{
|
||||
if (System.IO.Directory.Exists(userCredFilePath))
|
||||
{
|
||||
string[] files = Directory.GetFiles(userCredFilePath);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
||||
long size = new System.IO.FileInfo(file).Length;
|
||||
string fileName = System.IO.Path.GetFileName(file);
|
||||
|
||||
// jankily parse the bytes to extract the credential type and master key GUID
|
||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||
byte[] credentialArray = File.ReadAllBytes(file);
|
||||
byte[] guidMasterKeyArray = new byte[16];
|
||||
Array.Copy(credentialArray, 36, guidMasterKeyArray, 0, 16);
|
||||
Guid guidMasterKey = new Guid(guidMasterKeyArray);
|
||||
|
||||
byte[] stringLenArray = new byte[16];
|
||||
Array.Copy(credentialArray, 56, stringLenArray, 0, 4);
|
||||
int descLen = BitConverter.ToInt32(stringLenArray, 0);
|
||||
|
||||
byte[] descBytes = new byte[descLen];
|
||||
Array.Copy(credentialArray, 60, descBytes, 0, descLen - 4);
|
||||
|
||||
string desc = Encoding.Unicode.GetString(descBytes);
|
||||
results.Add(new Dictionary<string, string>()
|
||||
{
|
||||
{ "CredFile", file },
|
||||
{ "Description", desc },
|
||||
{ "MasterKey", String.Format("{0}", guidMasterKey) },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ "Size", String.Format("{0}", size) },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
144
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Putty.cs
Normal file
144
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Putty.cs
Normal file
@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Utils;
|
||||
|
||||
namespace winPEAS.KnownFileCreds
|
||||
{
|
||||
static class Putty
|
||||
{
|
||||
public static List<Dictionary<string, string>> GetPuttySessions()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
// extracts saved putty sessions and basic configs (via the registry)
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
Console.WriteLine("\r\n\r\n=== Putty Saved Session Information (All Users) ===\r\n");
|
||||
|
||||
string[] SIDs = Registry.Users.GetSubKeyNames();
|
||||
foreach (string SID in SIDs)
|
||||
{
|
||||
if (SID.StartsWith("S-1-5") && !SID.EndsWith("_Classes"))
|
||||
{
|
||||
string[] subKeys = RegistryHelper.GetRegSubkeys("HKU", String.Format("{0}\\Software\\SimonTatham\\PuTTY\\Sessions\\", SID));
|
||||
|
||||
foreach (string sessionName in subKeys)
|
||||
{
|
||||
Dictionary<string, string> putty_sess = new Dictionary<string, string>()
|
||||
{
|
||||
{ "User SID", SID },
|
||||
{ "SessionName", sessionName },
|
||||
{ "HostName", "" },
|
||||
{ "PortNumber", ""},
|
||||
{ "UserName", "" },
|
||||
{ "PublicKeyFile", "" },
|
||||
{ "PortForwardings", "" },
|
||||
{ "ConnectionSharing", "" },
|
||||
{ "ProxyPassword", "" },
|
||||
{ "ProxyUsername", "" },
|
||||
};
|
||||
|
||||
string[] keys =
|
||||
{
|
||||
"HostName",
|
||||
"PortNumber",
|
||||
"UserName",
|
||||
"PublicKeyFile",
|
||||
"PortForwardings",
|
||||
"ConnectionSharing",
|
||||
"ProxyPassword",
|
||||
"ProxyUsername",
|
||||
};
|
||||
|
||||
foreach (string key in keys)
|
||||
putty_sess[key] = RegistryHelper.GetRegValue("HKU", String.Format("{0}\\Software\\SimonTatham\\PuTTY\\Sessions\\{1}", SID, sessionName), key);
|
||||
|
||||
results.Add(putty_sess);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] subKeys = RegistryHelper.GetRegSubkeys("HKCU", "Software\\SimonTatham\\PuTTY\\Sessions\\");
|
||||
foreach (string sessionName in subKeys)
|
||||
{
|
||||
Dictionary<string, string> putty_sess = new Dictionary<string, string>()
|
||||
{
|
||||
{ "SessionName", sessionName },
|
||||
{ "HostName", "" },
|
||||
{ "PortNumber", "" },
|
||||
{ "UserName", "" },
|
||||
{ "PublicKeyFile", "" },
|
||||
{ "PortForwardings", "" },
|
||||
{ "ConnectionSharing", "" },
|
||||
{ "ProxyPassword", "" },
|
||||
{ "ProxyUsername", "" },
|
||||
};
|
||||
|
||||
string[] keys =
|
||||
{
|
||||
"HostName",
|
||||
"PortNumber",
|
||||
"UserName",
|
||||
"PublicKeyFile",
|
||||
"PortForwardings",
|
||||
"ConnectionSharing",
|
||||
"ProxyPassword",
|
||||
"ProxyUsername",
|
||||
};
|
||||
|
||||
foreach (string key in keys)
|
||||
putty_sess[key] = RegistryHelper.GetRegValue("HKCU", String.Format("Software\\SimonTatham\\PuTTY\\Sessions\\{0}", sessionName), key);
|
||||
|
||||
results.Add(putty_sess);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
public static List<Dictionary<string, string>> ListPuttySSHHostKeys()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
// extracts saved putty host keys (via the registry)
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
Console.WriteLine("\r\n\r\n=== Putty SSH Host Hosts (All Users) ===\r\n");
|
||||
|
||||
string[] SIDs = Registry.Users.GetSubKeyNames();
|
||||
foreach (string SID in SIDs)
|
||||
{
|
||||
if (SID.StartsWith("S-1-5") && !SID.EndsWith("_Classes"))
|
||||
{
|
||||
Dictionary<string, object> hostKeys = RegistryHelper.GetRegValues("HKU", String.Format("{0}\\Software\\SimonTatham\\PuTTY\\SshHostKeys\\", SID));
|
||||
if ((hostKeys != null) && (hostKeys.Count != 0))
|
||||
{
|
||||
Dictionary<string, string> putty_ssh = new Dictionary<string, string>();
|
||||
putty_ssh["UserSID"] = SID;
|
||||
foreach (KeyValuePair<string, object> kvp in hostKeys)
|
||||
{
|
||||
putty_ssh[kvp.Key] = ""; //Looks like only matters the key name, not the value
|
||||
}
|
||||
results.Add(putty_ssh);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<string, object> hostKeys = RegistryHelper.GetRegValues("HKCU", "Software\\SimonTatham\\PuTTY\\SshHostKeys\\");
|
||||
if ((hostKeys != null) && (hostKeys.Count != 0))
|
||||
{
|
||||
Dictionary<string, string> putty_ssh = new Dictionary<string, string>();
|
||||
foreach (KeyValuePair<string, object> kvp in hostKeys)
|
||||
{
|
||||
putty_ssh[kvp.Key] = ""; //Looks like only matters the key name, not the value
|
||||
}
|
||||
results.Add(putty_ssh);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
146
winPEAS/winPEASexe/winPEAS/KnownFileCreds/RemoteDesktop.cs
Normal file
146
winPEAS/winPEASexe/winPEAS/KnownFileCreds/RemoteDesktop.cs
Normal file
@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Utils;
|
||||
|
||||
namespace winPEAS.KnownFileCreds
|
||||
{
|
||||
static class RemoteDesktop
|
||||
{
|
||||
public static List<Dictionary<string, string>> GetSavedRDPConnections()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
//shows saved RDP connections, including username hints (if present)
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string[] SIDs = Registry.Users.GetSubKeyNames();
|
||||
foreach (string SID in SIDs)
|
||||
{
|
||||
if (SID.StartsWith("S-1-5") && !SID.EndsWith("_Classes"))
|
||||
{
|
||||
string[] subkeys = RegistryHelper.GetRegSubkeys("HKU", String.Format("{0}\\Software\\Microsoft\\Terminal Server Client\\Servers", SID));
|
||||
if (subkeys != null)
|
||||
{
|
||||
//Console.WriteLine("\r\n\r\n=== Saved RDP Connection Information ({0}) ===", SID);
|
||||
foreach (string host in subkeys)
|
||||
{
|
||||
string usernameHint = RegistryHelper.GetRegValue("HKCU", String.Format("Software\\Microsoft\\Terminal Server Client\\Servers\\{0}", host), "UsernameHint");
|
||||
Dictionary<string, string> rdp_info = new Dictionary<string, string>() {
|
||||
{ "SID", SID },
|
||||
{ "Host", host },
|
||||
{ "Username Hint", usernameHint },
|
||||
};
|
||||
results.Add(rdp_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] subkeys = RegistryHelper.GetRegSubkeys("HKCU", "Software\\Microsoft\\Terminal Server Client\\Servers");
|
||||
if (subkeys != null)
|
||||
{
|
||||
foreach (string host in subkeys)
|
||||
{
|
||||
string usernameHint = RegistryHelper.GetRegValue("HKCU", String.Format("Software\\Microsoft\\Terminal Server Client\\Servers\\{0}", host), "UsernameHint");
|
||||
Dictionary<string, string> rdp_info = new Dictionary<string, string>() {
|
||||
{ "SID", "" },
|
||||
{ "Host", host },
|
||||
{ "Username Hint", usernameHint },
|
||||
};
|
||||
results.Add(rdp_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<Dictionary<string, string>> GetRDCManFiles()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
// lists any found files in Local\Microsoft\Credentials\*
|
||||
try
|
||||
{
|
||||
if (MyUtils.IsHighIntegrity())
|
||||
{
|
||||
string userFolder = String.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
||||
string[] dirs = Directory.GetDirectories(userFolder);
|
||||
|
||||
foreach (string dir in dirs)
|
||||
{
|
||||
string[] parts = dir.Split('\\');
|
||||
string userName = parts[parts.Length - 1];
|
||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||
{
|
||||
string userRDManFile = String.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", dir);
|
||||
if (System.IO.File.Exists(userRDManFile))
|
||||
{
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
xmlDoc.Load(userRDManFile);
|
||||
|
||||
// grab the recent RDG files
|
||||
XmlNodeList filesToOpen = xmlDoc.GetElementsByTagName("FilesToOpen");
|
||||
XmlNodeList items = filesToOpen[0].ChildNodes;
|
||||
XmlNode node = items[0];
|
||||
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile);
|
||||
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
||||
{ "RDCManFile", userRDManFile },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ ".RDG Files", "" },
|
||||
};
|
||||
|
||||
foreach (XmlNode rdgFile in items)
|
||||
rdg[".RDG Files"] += rdgFile.InnerText;
|
||||
|
||||
results.Add(rdg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||
string userRDManFile = String.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||
|
||||
if (System.IO.File.Exists(userRDManFile))
|
||||
{
|
||||
XmlDocument xmlDoc = new XmlDocument();
|
||||
xmlDoc.Load(userRDManFile);
|
||||
|
||||
// grab the recent RDG files
|
||||
XmlNodeList filesToOpen = xmlDoc.GetElementsByTagName("FilesToOpen");
|
||||
XmlNodeList items = filesToOpen[0].ChildNodes;
|
||||
XmlNode node = items[0];
|
||||
|
||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile);
|
||||
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile);
|
||||
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
||||
{ "RDCManFile", userRDManFile },
|
||||
{ "Accessed", String.Format("{0}", lastAccessed) },
|
||||
{ "Modified", String.Format("{0}", lastModified) },
|
||||
{ ".RDG Files", "" },
|
||||
};
|
||||
|
||||
foreach (XmlNode rdgFile in items)
|
||||
rdg[".RDG Files"] += rdgFile.InnerText;
|
||||
results.Add(rdg);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.PrintException(ex.Message);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
252
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Vault/VaultCli.cs
Normal file
252
winPEAS/winPEASexe/winPEAS/KnownFileCreds/Vault/VaultCli.cs
Normal file
@ -0,0 +1,252 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.KnownFileCreds.Vault.structs;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Vault
|
||||
{
|
||||
public static class VaultCli
|
||||
{
|
||||
// pulled directly from @djhohnstein's SharpWeb project: https://github.com/djhohnstein/SharpWeb/blob/master/Edge/SharpEdge.cs
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultOpenVault(ref Guid vaultGuid, UInt32 offset, ref IntPtr vaultHandle);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultEnumerateVaults(Int32 offset, ref Int32 vaultCount, ref IntPtr vaultGuid);
|
||||
|
||||
[DllImport("vaultcli.dll")]
|
||||
public extern static Int32 VaultEnumerateItems(IntPtr vaultHandle, Int32 chunkSize, ref Int32 vaultItemCount, ref IntPtr vaultItem);
|
||||
|
||||
[DllImport("vaultcli.dll", EntryPoint = "VaultGetItem")]
|
||||
public extern static Int32 VaultGetItem_WIN8(IntPtr vaultHandle, ref Guid schemaId, IntPtr pResourceElement, IntPtr pIdentityElement, IntPtr pPackageSid, IntPtr zero, Int32 arg6, ref IntPtr passwordVaultPtr);
|
||||
|
||||
[DllImport("vaultcli.dll", EntryPoint = "VaultGetItem")]
|
||||
public extern static Int32 VaultGetItem_WIN7(IntPtr vaultHandle, ref Guid schemaId, IntPtr pResourceElement, IntPtr pIdentityElement, IntPtr zero, Int32 arg5, ref IntPtr passwordVaultPtr);
|
||||
|
||||
public static List<Dictionary<string, string>> DumpVault()
|
||||
{
|
||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||
|
||||
try
|
||||
{
|
||||
// pulled directly from @djhohnstein's SharpWeb project: https://github.com/djhohnstein/SharpWeb/blob/master/Edge/SharpEdge.cs
|
||||
var OSVersion = Environment.OSVersion.Version;
|
||||
var OSMajor = OSVersion.Major;
|
||||
var OSMinor = OSVersion.Minor;
|
||||
|
||||
Type VAULT_ITEM;
|
||||
|
||||
if (OSMajor >= 6 && OSMinor >= 2)
|
||||
{
|
||||
VAULT_ITEM = typeof(VAULT_ITEM_WIN8);
|
||||
}
|
||||
else
|
||||
{
|
||||
VAULT_ITEM = typeof(VAULT_ITEM_WIN7);
|
||||
}
|
||||
|
||||
Int32 vaultCount = 0;
|
||||
IntPtr vaultGuidPtr = IntPtr.Zero;
|
||||
var result = VaultCli.VaultEnumerateVaults(0, ref vaultCount, ref vaultGuidPtr);
|
||||
|
||||
//var result = CallVaultEnumerateVaults(VaultEnum, 0, ref vaultCount, ref vaultGuidPtr);
|
||||
|
||||
if ((int)result != 0)
|
||||
{
|
||||
Console.WriteLine(" [ERROR] Unable to enumerate vaults. Error (0x" + result.ToString() + ")");
|
||||
return results;
|
||||
}
|
||||
|
||||
// Create dictionary to translate Guids to human readable elements
|
||||
IntPtr guidAddress = vaultGuidPtr;
|
||||
Dictionary<Guid, string> vaultSchema = new Dictionary<Guid, string>();
|
||||
vaultSchema.Add(new Guid("2F1A6504-0641-44CF-8BB5-3612D865F2E5"), "Windows Secure Note");
|
||||
vaultSchema.Add(new Guid("3CCD5499-87A8-4B10-A215-608888DD3B55"), "Windows Web Password Credential");
|
||||
vaultSchema.Add(new Guid("154E23D0-C644-4E6F-8CE6-5069272F999F"), "Windows Credential Picker Protector");
|
||||
vaultSchema.Add(new Guid("4BF4C442-9B8A-41A0-B380-DD4A704DDB28"), "Web Credentials");
|
||||
vaultSchema.Add(new Guid("77BC582B-F0A6-4E15-4E80-61736B6F3B29"), "Windows Credentials");
|
||||
vaultSchema.Add(new Guid("E69D7838-91B5-4FC9-89D5-230D4D4CC2BC"), "Windows Domain Certificate Credential");
|
||||
vaultSchema.Add(new Guid("3E0E35BE-1B77-43E7-B873-AED901B6275B"), "Windows Domain Password Credential");
|
||||
vaultSchema.Add(new Guid("3C886FF3-2669-4AA2-A8FB-3F6759A77548"), "Windows Extended Credential");
|
||||
vaultSchema.Add(new Guid("00000000-0000-0000-0000-000000000000"), null);
|
||||
|
||||
for (int i = 0; i < vaultCount; i++)
|
||||
{
|
||||
|
||||
// Open vault block
|
||||
object vaultGuidString = System.Runtime.InteropServices.Marshal.PtrToStructure(guidAddress, typeof(Guid));
|
||||
Guid vaultGuid = new Guid(vaultGuidString.ToString());
|
||||
guidAddress = (IntPtr)(guidAddress.ToInt64() + System.Runtime.InteropServices.Marshal.SizeOf(typeof(Guid)));
|
||||
IntPtr vaultHandle = IntPtr.Zero;
|
||||
string vaultType;
|
||||
if (vaultSchema.ContainsKey(vaultGuid))
|
||||
{
|
||||
vaultType = vaultSchema[vaultGuid];
|
||||
}
|
||||
else
|
||||
{
|
||||
vaultType = vaultGuid.ToString();
|
||||
}
|
||||
result = VaultCli.VaultOpenVault(ref vaultGuid, (UInt32)0, ref vaultHandle);
|
||||
if (result != 0)
|
||||
{
|
||||
Console.WriteLine("Unable to open the following vault: " + vaultType + ". Error: 0x" + result.ToString());
|
||||
continue;
|
||||
}
|
||||
// Vault opened successfully! Continue.
|
||||
|
||||
// Fetch all items within Vault
|
||||
int vaultItemCount = 0;
|
||||
IntPtr vaultItemPtr = IntPtr.Zero;
|
||||
result = VaultCli.VaultEnumerateItems(vaultHandle, 512, ref vaultItemCount, ref vaultItemPtr);
|
||||
if (result != 0)
|
||||
{
|
||||
Console.WriteLine("Unable to enumerate vault items from the following vault: " + vaultType + ". Error 0x" + result.ToString());
|
||||
continue;
|
||||
}
|
||||
var structAddress = vaultItemPtr;
|
||||
if (vaultItemCount > 0)
|
||||
{
|
||||
// For each vault item...
|
||||
for (int j = 1; j <= vaultItemCount; j++)
|
||||
{
|
||||
Dictionary<string, string> vault_cred = new Dictionary<string, string>() {
|
||||
{ "GUID", String.Format("{0}", vaultGuid) },
|
||||
{ "Type", vaultType },
|
||||
{ "Resource", "" },
|
||||
{ "Identity", "" },
|
||||
{ "PacakgeSid", "" },
|
||||
{ "Credential", "" },
|
||||
{ "Last Modified", "" },
|
||||
{ "Error", "" }
|
||||
};
|
||||
|
||||
// Begin fetching vault item...
|
||||
var currentItem = System.Runtime.InteropServices.Marshal.PtrToStructure(structAddress, VAULT_ITEM);
|
||||
structAddress = (IntPtr)(structAddress.ToInt64() + System.Runtime.InteropServices.Marshal.SizeOf(VAULT_ITEM));
|
||||
|
||||
IntPtr passwordVaultItem = IntPtr.Zero;
|
||||
// Field Info retrieval
|
||||
FieldInfo schemaIdInfo = currentItem.GetType().GetField("SchemaId");
|
||||
Guid schemaId = new Guid(schemaIdInfo.GetValue(currentItem).ToString());
|
||||
FieldInfo pResourceElementInfo = currentItem.GetType().GetField("pResourceElement");
|
||||
IntPtr pResourceElement = (IntPtr)pResourceElementInfo.GetValue(currentItem);
|
||||
FieldInfo pIdentityElementInfo = currentItem.GetType().GetField("pIdentityElement");
|
||||
IntPtr pIdentityElement = (IntPtr)pIdentityElementInfo.GetValue(currentItem);
|
||||
FieldInfo dateTimeInfo = currentItem.GetType().GetField("LastModified");
|
||||
UInt64 lastModified = (UInt64)dateTimeInfo.GetValue(currentItem);
|
||||
|
||||
IntPtr pPackageSid = IntPtr.Zero;
|
||||
if (OSMajor >= 6 && OSMinor >= 2)
|
||||
{
|
||||
// Newer versions have package sid
|
||||
FieldInfo pPackageSidInfo = currentItem.GetType().GetField("pPackageSid");
|
||||
pPackageSid = (IntPtr)pPackageSidInfo.GetValue(currentItem);
|
||||
result = VaultCli.VaultGetItem_WIN8(vaultHandle, ref schemaId, pResourceElement, pIdentityElement, pPackageSid, IntPtr.Zero, 0, ref passwordVaultItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = VaultCli.VaultGetItem_WIN7(vaultHandle, ref schemaId, pResourceElement, pIdentityElement, IntPtr.Zero, 0, ref passwordVaultItem);
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
vault_cred["Error"] = "Occured while retrieving vault item. Error: 0x" + result.ToString();
|
||||
continue;
|
||||
}
|
||||
object passwordItem = System.Runtime.InteropServices.Marshal.PtrToStructure(passwordVaultItem, VAULT_ITEM);
|
||||
FieldInfo pAuthenticatorElementInfo = passwordItem.GetType().GetField("pAuthenticatorElement");
|
||||
IntPtr pAuthenticatorElement = (IntPtr)pAuthenticatorElementInfo.GetValue(passwordItem);
|
||||
// Fetch the credential from the authenticator element
|
||||
object cred = GetVaultElementValue(pAuthenticatorElement);
|
||||
object packageSid = null;
|
||||
if (pPackageSid != IntPtr.Zero && pPackageSid != null)
|
||||
{
|
||||
packageSid = GetVaultElementValue(pPackageSid);
|
||||
}
|
||||
if (cred != null) // Indicates successful fetch
|
||||
{
|
||||
object resource = GetVaultElementValue(pResourceElement);
|
||||
if (resource != null)
|
||||
{
|
||||
vault_cred["Resource"] = String.Format("{0}", resource);
|
||||
}
|
||||
object identity = GetVaultElementValue(pIdentityElement);
|
||||
if (identity != null)
|
||||
{
|
||||
vault_cred["Identity"] = String.Format("{0}", identity);
|
||||
}
|
||||
if (packageSid != null)
|
||||
{
|
||||
vault_cred["PacakgeSid"] = String.Format("{0}", packageSid);
|
||||
}
|
||||
vault_cred["Credential"] = String.Format("{0}", cred);
|
||||
vault_cred["Last Modified"] = String.Format("{0}", System.DateTime.FromFileTimeUtc((long)lastModified));
|
||||
results.Add(vault_cred);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static object GetVaultElementValue(IntPtr vaultElementPtr)
|
||||
{
|
||||
// Helper function to extract the ItemValue field from a VAULT_ITEM_ELEMENT struct
|
||||
// pulled directly from @djhohnstein's SharpWeb project: https://github.com/djhohnstein/SharpWeb/blob/master/Edge/SharpEdge.cs
|
||||
object results;
|
||||
object partialElement = System.Runtime.InteropServices.Marshal.PtrToStructure(vaultElementPtr, typeof(VAULT_ITEM_ELEMENT));
|
||||
FieldInfo partialElementInfo = partialElement.GetType().GetField("Type");
|
||||
var partialElementType = partialElementInfo.GetValue(partialElement);
|
||||
|
||||
IntPtr elementPtr = (IntPtr)(vaultElementPtr.ToInt64() + 16);
|
||||
switch ((int)partialElementType)
|
||||
{
|
||||
case 7: // VAULT_ELEMENT_TYPE == String; These are the plaintext passwords!
|
||||
IntPtr StringPtr = System.Runtime.InteropServices.Marshal.ReadIntPtr(elementPtr);
|
||||
results = System.Runtime.InteropServices.Marshal.PtrToStringUni(StringPtr);
|
||||
break;
|
||||
case 0: // VAULT_ELEMENT_TYPE == bool
|
||||
results = System.Runtime.InteropServices.Marshal.ReadByte(elementPtr);
|
||||
results = (bool)results;
|
||||
break;
|
||||
case 1: // VAULT_ELEMENT_TYPE == Short
|
||||
results = System.Runtime.InteropServices.Marshal.ReadInt16(elementPtr);
|
||||
break;
|
||||
case 2: // VAULT_ELEMENT_TYPE == Unsigned Short
|
||||
results = System.Runtime.InteropServices.Marshal.ReadInt16(elementPtr);
|
||||
break;
|
||||
case 3: // VAULT_ELEMENT_TYPE == Int
|
||||
results = System.Runtime.InteropServices.Marshal.ReadInt32(elementPtr);
|
||||
break;
|
||||
case 4: // VAULT_ELEMENT_TYPE == Unsigned Int
|
||||
results = System.Runtime.InteropServices.Marshal.ReadInt32(elementPtr);
|
||||
break;
|
||||
case 5: // VAULT_ELEMENT_TYPE == Double
|
||||
results = System.Runtime.InteropServices.Marshal.PtrToStructure(elementPtr, typeof(Double));
|
||||
break;
|
||||
case 6: // VAULT_ELEMENT_TYPE == GUID
|
||||
results = System.Runtime.InteropServices.Marshal.PtrToStructure(elementPtr, typeof(Guid));
|
||||
break;
|
||||
case 12: // VAULT_ELEMENT_TYPE == Sid
|
||||
IntPtr sidPtr = System.Runtime.InteropServices.Marshal.ReadIntPtr(elementPtr);
|
||||
var sidObject = new System.Security.Principal.SecurityIdentifier(sidPtr);
|
||||
results = sidObject.Value;
|
||||
break;
|
||||
default:
|
||||
/* Several VAULT_ELEMENT_TYPES are currently unimplemented according to
|
||||
* Lord Graeber. Thus we do not implement them. */
|
||||
results = null;
|
||||
break;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Vault.enums
|
||||
{
|
||||
public enum VAULT_ELEMENT_TYPE : Int32
|
||||
{
|
||||
Undefined = -1,
|
||||
Boolean = 0,
|
||||
Short = 1,
|
||||
UnsignedShort = 2,
|
||||
Int = 3,
|
||||
UnsignedInt = 4,
|
||||
Double = 5,
|
||||
Guid = 6,
|
||||
String = 7,
|
||||
ByteArray = 8,
|
||||
TimeStamp = 9,
|
||||
ProtectedArray = 10,
|
||||
Attribute = 11,
|
||||
Sid = 12,
|
||||
Last = 13
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Vault.enums
|
||||
{
|
||||
public enum VAULT_SCHEMA_ELEMENT_ID : Int32
|
||||
{
|
||||
Illegal = 0,
|
||||
Resource = 1,
|
||||
Identity = 2,
|
||||
Authenticator = 3,
|
||||
Tag = 4,
|
||||
PackageSid = 5,
|
||||
AppStart = 100,
|
||||
AppEnd = 10000
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.KnownFileCreds.Vault.enums;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Vault.structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi)]
|
||||
public struct VAULT_ITEM_ELEMENT
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public VAULT_SCHEMA_ELEMENT_ID SchemaElementId;
|
||||
[FieldOffset(8)]
|
||||
public VAULT_ELEMENT_TYPE Type;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Vault.structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public struct VAULT_ITEM_WIN7
|
||||
{
|
||||
public Guid SchemaId;
|
||||
public IntPtr pszCredentialFriendlyName;
|
||||
public IntPtr pResourceElement;
|
||||
public IntPtr pIdentityElement;
|
||||
public IntPtr pAuthenticatorElement;
|
||||
public UInt64 LastModified;
|
||||
public UInt32 dwFlags;
|
||||
public UInt32 dwPropertiesCount;
|
||||
public IntPtr pPropertyElements;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.KnownFileCreds.Vault.structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
public struct VAULT_ITEM_WIN8
|
||||
{
|
||||
public Guid SchemaId;
|
||||
public IntPtr pszCredentialFriendlyName;
|
||||
public IntPtr pResourceElement;
|
||||
public IntPtr pIdentityElement;
|
||||
public IntPtr pAuthenticatorElement;
|
||||
public IntPtr pPackageSid;
|
||||
public UInt64 LastModified;
|
||||
public UInt32 dwFlags;
|
||||
public UInt32 dwPropertiesCount;
|
||||
public IntPtr pPropertyElements;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@ using System.Security.AccessControl;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using FastSearchLibrary;
|
||||
using winPEAS.Utils;
|
||||
|
||||
namespace winPEAS
|
||||
{
|
||||
@ -95,159 +96,12 @@ namespace winPEAS
|
||||
//By default local
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
/// Interf. for Keys and Values in Reg. ///
|
||||
///////////////////////////////////////////
|
||||
/// Functions related to obtain keys and values from the registry
|
||||
/// Some parts adapted from Seatbelt
|
||||
public static string GetRegValue(string hive, string path, string value)
|
||||
{
|
||||
// returns a single registry value under the specified path in the specified hive (HKLM/HKCU)
|
||||
string regKeyValue = "";
|
||||
if (hive == "HKCU")
|
||||
{
|
||||
var regKey = Registry.CurrentUser.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = String.Format("{0}", regKey.GetValue(value));
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
var regKey = Registry.Users.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = String.Format("{0}", regKey.GetValue(value));
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var regKey = Registry.LocalMachine.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = String.Format("{0}", regKey.GetValue(value));
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GetRegValues(string hive, string path)
|
||||
{
|
||||
// returns all registry values under the specified path in the specified hive (HKLM/HKCU)
|
||||
Dictionary<string, object> keyValuePairs = null;
|
||||
try
|
||||
{
|
||||
if (hive == "HKCU")
|
||||
{
|
||||
using (var regKeyValues = Registry.CurrentUser.OpenSubKey(path))
|
||||
{
|
||||
if (regKeyValues != null)
|
||||
{
|
||||
var valueNames = regKeyValues.GetValueNames();
|
||||
keyValuePairs = valueNames.ToDictionary(name => name, regKeyValues.GetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
using (var regKeyValues = Registry.Users.OpenSubKey(path))
|
||||
{
|
||||
if (regKeyValues != null)
|
||||
{
|
||||
var valueNames = regKeyValues.GetValueNames();
|
||||
keyValuePairs = valueNames.ToDictionary(name => name, regKeyValues.GetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var regKeyValues = Registry.LocalMachine.OpenSubKey(path))
|
||||
{
|
||||
if (regKeyValues != null)
|
||||
{
|
||||
var valueNames = regKeyValues.GetValueNames();
|
||||
keyValuePairs = valueNames.ToDictionary(name => name, regKeyValues.GetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return keyValuePairs;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] GetRegValueBytes(string hive, string path, string value)
|
||||
{
|
||||
// returns a byte array of single registry value under the specified path in the specified hive (HKLM/HKCU)
|
||||
byte[] regKeyValue = null;
|
||||
if (hive == "HKCU")
|
||||
{
|
||||
var regKey = Registry.CurrentUser.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = (byte[])regKey.GetValue(value);
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
var regKey = Registry.Users.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = (byte[])regKey.GetValue(value);
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var regKey = Registry.LocalMachine.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = (byte[])regKey.GetValue(value);
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] GetRegSubkeys(string hive, string path)
|
||||
{
|
||||
// returns an array of the subkeys names under the specified path in the specified hive (HKLM/HKCU/HKU)
|
||||
try
|
||||
{
|
||||
Microsoft.Win32.RegistryKey myKey = null;
|
||||
if (hive == "HKLM")
|
||||
{
|
||||
myKey = Registry.LocalMachine.OpenSubKey(path);
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
myKey = Registry.Users.OpenSubKey(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
myKey = Registry.CurrentUser.OpenSubKey(path);
|
||||
}
|
||||
String[] subkeyNames = myKey.GetSubKeyNames();
|
||||
return myKey.GetSubKeyNames();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new string[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static string GetCLSIDBinPath(string CLSID)
|
||||
{
|
||||
return GetRegValue("HKLM", @"SOFTWARE\Classes\CLSID\" + CLSID + @"\InprocServer32", ""); //To get the default object you need to use an empty string
|
||||
return RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\Classes\CLSID\" + CLSID + @"\InprocServer32", ""); //To get the default object you need to use an empty string
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////
|
||||
//////// Check Permissions ////////
|
||||
///////////////////////////////////
|
||||
|
1333
winPEAS/winPEASexe/winPEAS/NativeWifiApi/Interop.cs
Normal file
1333
winPEAS/winPEASexe/winPEAS/NativeWifiApi/Interop.cs
Normal file
File diff suppressed because it is too large
Load Diff
231
winPEAS/winPEASexe/winPEAS/NativeWifiApi/WlanClient.cs
Normal file
231
winPEAS/winPEASexe/winPEAS/NativeWifiApi/WlanClient.cs
Normal file
@ -0,0 +1,231 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace winPEAS.NativeWifiApi
|
||||
{
|
||||
class WlanClient
|
||||
{
|
||||
public class WlanInterface
|
||||
{
|
||||
private WlanClient client;
|
||||
private Wlan.WlanInterfaceInfo info;
|
||||
|
||||
#region Event queue
|
||||
|
||||
private bool queueEvents;
|
||||
private AutoResetEvent eventQueueFilled = new AutoResetEvent(false);
|
||||
private Queue<object> eventQueue = new Queue<object>();
|
||||
|
||||
#endregion
|
||||
|
||||
internal WlanInterface(WlanClient client, Wlan.WlanInterfaceInfo info)
|
||||
{
|
||||
this.client = client;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Converts a pointer to a BSS list (header + entries) to an array of BSS entries.
|
||||
/// </summary>
|
||||
/// <param name="bssListPtr">A pointer to a BSS list's header.</param>
|
||||
/// <returns>An array of BSS entries.</returns>
|
||||
private Wlan.WlanBssEntry[] ConvertBssListPtr(IntPtr bssListPtr)
|
||||
{
|
||||
Wlan.WlanBssListHeader bssListHeader = (Wlan.WlanBssListHeader)Marshal.PtrToStructure(bssListPtr, typeof(Wlan.WlanBssListHeader));
|
||||
long bssListIt = bssListPtr.ToInt64() + Marshal.SizeOf(typeof(Wlan.WlanBssListHeader));
|
||||
Wlan.WlanBssEntry[] bssEntries = new Wlan.WlanBssEntry[bssListHeader.numberOfItems];
|
||||
for (int i = 0; i < bssListHeader.numberOfItems; ++i)
|
||||
{
|
||||
bssEntries[i] = (Wlan.WlanBssEntry)Marshal.PtrToStructure(new IntPtr(bssListIt), typeof(Wlan.WlanBssEntry));
|
||||
bssListIt += Marshal.SizeOf(typeof(Wlan.WlanBssEntry));
|
||||
}
|
||||
return bssEntries;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the basic service sets (BSS) list of all available networks.
|
||||
/// </summary>
|
||||
public Wlan.WlanBssEntry[] GetNetworkBssList()
|
||||
{
|
||||
IntPtr bssListPtr;
|
||||
Wlan.ThrowIfError(
|
||||
Wlan.WlanGetNetworkBssList(client.clientHandle, info.interfaceGuid, IntPtr.Zero, Wlan.Dot11BssType.Any, false, IntPtr.Zero, out bssListPtr));
|
||||
try
|
||||
{
|
||||
return ConvertBssListPtr(bssListPtr);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Wlan.WlanFreeMemory(bssListPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the basic service sets (BSS) list of the specified network.
|
||||
/// </summary>
|
||||
/// <param name="ssid">Specifies the SSID of the network from which the BSS list is requested.</param>
|
||||
/// <param name="bssType">Indicates the BSS type of the network.</param>
|
||||
/// <param name="securityEnabled">Indicates whether security is enabled on the network.</param>
|
||||
public Wlan.WlanBssEntry[] GetNetworkBssList(Wlan.Dot11Ssid ssid, Wlan.Dot11BssType bssType, bool securityEnabled)
|
||||
{
|
||||
IntPtr ssidPtr = Marshal.AllocHGlobal(Marshal.SizeOf(ssid));
|
||||
Marshal.StructureToPtr(ssid, ssidPtr, false);
|
||||
try
|
||||
{
|
||||
IntPtr bssListPtr;
|
||||
Wlan.ThrowIfError(
|
||||
Wlan.WlanGetNetworkBssList(client.clientHandle, info.interfaceGuid, ssidPtr, bssType, securityEnabled, IntPtr.Zero, out bssListPtr));
|
||||
try
|
||||
{
|
||||
return ConvertBssListPtr(bssListPtr);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Wlan.WlanFreeMemory(bssListPtr);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(ssidPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the profile's XML specification.
|
||||
/// </summary>
|
||||
/// <param name="profileName">The name of the profile.</param>
|
||||
/// <param name="unencryptedPassword">Whether the password should be unencrypted in the returned XML. By default this is false and the password is left encrypted.</param>
|
||||
/// <returns>The XML document.</returns>
|
||||
public string GetProfileXml(string profileName, bool unencryptedPassword = true)
|
||||
{
|
||||
IntPtr profileXmlPtr;
|
||||
Wlan.WlanProfileFlags flags = unencryptedPassword ? Wlan.WlanProfileFlags.GetPlaintextKey : Wlan.WlanProfileFlags.None;
|
||||
Wlan.WlanAccess access;
|
||||
Wlan.ThrowIfError(
|
||||
Wlan.WlanGetProfile(client.clientHandle, info.interfaceGuid, profileName, IntPtr.Zero, out profileXmlPtr, out flags,
|
||||
out access));
|
||||
try
|
||||
{
|
||||
return Marshal.PtrToStringUni(profileXmlPtr);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Wlan.WlanFreeMemory(profileXmlPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the information of all profiles on this interface.
|
||||
/// </summary>
|
||||
/// <returns>The profiles information.</returns>
|
||||
public Wlan.WlanProfileInfo[] GetProfiles()
|
||||
{
|
||||
IntPtr profileListPtr;
|
||||
Wlan.ThrowIfError(
|
||||
Wlan.WlanGetProfileList(client.clientHandle, info.interfaceGuid, IntPtr.Zero, out profileListPtr));
|
||||
try
|
||||
{
|
||||
Wlan.WlanProfileInfoListHeader header = (Wlan.WlanProfileInfoListHeader)Marshal.PtrToStructure(profileListPtr, typeof(Wlan.WlanProfileInfoListHeader));
|
||||
Wlan.WlanProfileInfo[] profileInfos = new Wlan.WlanProfileInfo[header.numberOfItems];
|
||||
long profileListIterator = profileListPtr.ToInt64() + Marshal.SizeOf(header);
|
||||
for (int i = 0; i < header.numberOfItems; ++i)
|
||||
{
|
||||
Wlan.WlanProfileInfo profileInfo = (Wlan.WlanProfileInfo)Marshal.PtrToStructure(new IntPtr(profileListIterator), typeof(Wlan.WlanProfileInfo));
|
||||
profileInfos[i] = profileInfo;
|
||||
profileListIterator += Marshal.SizeOf(profileInfo);
|
||||
}
|
||||
return profileInfos;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Wlan.WlanFreeMemory(profileListPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enqueues a notification event to be processed serially.
|
||||
/// </summary>
|
||||
private void EnqueueEvent(object queuedEvent)
|
||||
{
|
||||
lock (eventQueue)
|
||||
eventQueue.Enqueue(queuedEvent);
|
||||
eventQueueFilled.Set();
|
||||
}
|
||||
}
|
||||
|
||||
private IntPtr clientHandle;
|
||||
private uint negotiatedVersion;
|
||||
private Wlan.WlanNotificationCallbackDelegate wlanNotificationCallback;
|
||||
|
||||
private Dictionary<Guid, WlanInterface> ifaces = new Dictionary<Guid, WlanInterface>();
|
||||
|
||||
public WlanClient()
|
||||
{
|
||||
Wlan.ThrowIfError(
|
||||
Wlan.WlanOpenHandle(Wlan.WLAN_CLIENT_VERSION_XP_SP2, IntPtr.Zero, out negotiatedVersion, out clientHandle));
|
||||
}
|
||||
|
||||
~WlanClient()
|
||||
{
|
||||
Wlan.WlanCloseHandle(clientHandle, IntPtr.Zero);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the WLAN interfaces.
|
||||
/// </summary>
|
||||
/// <value>The WLAN interfaces.</value>
|
||||
public WlanInterface[] Interfaces
|
||||
{
|
||||
get
|
||||
{
|
||||
IntPtr ifaceList;
|
||||
Wlan.ThrowIfError(
|
||||
Wlan.WlanEnumInterfaces(clientHandle, IntPtr.Zero, out ifaceList));
|
||||
try
|
||||
{
|
||||
Wlan.WlanInterfaceInfoListHeader header =
|
||||
(Wlan.WlanInterfaceInfoListHeader)Marshal.PtrToStructure(ifaceList, typeof(Wlan.WlanInterfaceInfoListHeader));
|
||||
Int64 listIterator = ifaceList.ToInt64() + Marshal.SizeOf(header);
|
||||
WlanInterface[] interfaces = new WlanInterface[header.numberOfItems];
|
||||
List<Guid> currentIfaceGuids = new List<Guid>();
|
||||
for (int i = 0; i < header.numberOfItems; ++i)
|
||||
{
|
||||
Wlan.WlanInterfaceInfo info =
|
||||
(Wlan.WlanInterfaceInfo)Marshal.PtrToStructure(new IntPtr(listIterator), typeof(Wlan.WlanInterfaceInfo));
|
||||
listIterator += Marshal.SizeOf(info);
|
||||
WlanInterface wlanIface;
|
||||
currentIfaceGuids.Add(info.interfaceGuid);
|
||||
if (ifaces.ContainsKey(info.interfaceGuid))
|
||||
wlanIface = ifaces[info.interfaceGuid];
|
||||
else
|
||||
wlanIface = new WlanInterface(this, info);
|
||||
interfaces[i] = wlanIface;
|
||||
ifaces[info.interfaceGuid] = wlanIface;
|
||||
}
|
||||
|
||||
// Remove stale interfaces
|
||||
Queue<Guid> deadIfacesGuids = new Queue<Guid>();
|
||||
foreach (Guid ifaceGuid in ifaces.Keys)
|
||||
{
|
||||
if (!currentIfaceGuids.Contains(ifaceGuid))
|
||||
deadIfacesGuids.Enqueue(ifaceGuid);
|
||||
}
|
||||
while (deadIfacesGuids.Count != 0)
|
||||
{
|
||||
Guid deadIfaceGuid = deadIfacesGuids.Dequeue();
|
||||
ifaces.Remove(deadIfaceGuid);
|
||||
}
|
||||
|
||||
return interfaces;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Wlan.WlanFreeMemory(ifaceList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -369,7 +369,7 @@ namespace winPEAS
|
||||
current_perm = Convert.ToInt32(result.Properties["ReturnValue"].Value);
|
||||
perm_str = MyUtils.PermInt2Str(current_perm);
|
||||
}
|
||||
catch (ManagementException me)
|
||||
catch (ManagementException)
|
||||
{
|
||||
perm_str = ""; //no permissions are set on the share
|
||||
}
|
||||
|
1460
winPEAS/winPEASexe/winPEAS/ProcessesInfo.cs → winPEAS/winPEASexe/winPEAS/ProcessInfo/DefensiveProcesses.cs
Executable file → Normal file
1460
winPEAS/winPEASexe/winPEAS/ProcessesInfo.cs → winPEAS/winPEASexe/winPEAS/ProcessInfo/DefensiveProcesses.cs
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace winPEAS.ProcessInfo
|
||||
{
|
||||
static class InterestingProcesses
|
||||
{
|
||||
public static Dictionary<string, string> Definitions = new Dictionary<string, string>()
|
||||
{
|
||||
{"CmRcService.exe" , "Configuration Manager Remote Control Service"},
|
||||
{"ftp.exe" , "Misc. FTP client"},
|
||||
{"LMIGuardian.exe" , "LogMeIn Reporter"},
|
||||
{"LogMeInSystray.exe" , "LogMeIn System Tray"},
|
||||
{"RaMaint.exe" , "LogMeIn maintenance sevice"},
|
||||
{"mmc.exe" , "Microsoft Management Console"},
|
||||
{"putty.exe" , "Putty SSH client"},
|
||||
{"pscp.exe" , "Putty SCP client"},
|
||||
{"psftp.exe" , "Putty SFTP client"},
|
||||
{"puttytel.exe" , "Putty Telnet client"},
|
||||
{"plink.exe" , "Putty CLI client"},
|
||||
{"pageant.exe" , "Putty SSH auth agent"},
|
||||
{"kitty.exe" , "Kitty SSH client"},
|
||||
{"telnet.exe" , "Misc. Telnet client"},
|
||||
{"SecureCRT.exe" , "SecureCRT SSH/Telnet client"},
|
||||
{"TeamViewer.exe" , "TeamViewer"},
|
||||
{"tv_x64.exe" , "TeamViewer x64 remote control"},
|
||||
{"tv_w32.exe" , "TeamViewer x86 remote control"},
|
||||
{"keepass.exe" , "KeePass password vault"},
|
||||
{"mstsc.exe" , "Microsoft RDP client"},
|
||||
{"vnc.exe" , "Possible VNC client"},
|
||||
{"powershell.exe" , "PowerShell host process"},
|
||||
{"cmd.exe" , "Command Prompt"},
|
||||
};
|
||||
}
|
||||
}
|
102
winPEAS/winPEASexe/winPEAS/ProcessInfo/ProcessesInfo.cs
Normal file
102
winPEAS/winPEASexe/winPEAS/ProcessInfo/ProcessesInfo.cs
Normal file
@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace winPEAS
|
||||
{
|
||||
class ProcessesInfo
|
||||
{
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
private static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool CloseHandle(IntPtr hObject);
|
||||
private static string GetProcU(Process p)
|
||||
{
|
||||
IntPtr pHandle = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
OpenProcessToken(p.Handle, 8, out pHandle);
|
||||
WindowsIdentity WI = new WindowsIdentity(pHandle);
|
||||
String uSEr = WI.Name;
|
||||
return uSEr.Contains(@"\") ? uSEr.Substring(uSEr.IndexOf(@"\") + 1) : uSEr;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pHandle != IntPtr.Zero)
|
||||
{
|
||||
CloseHandle(pHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check out https://github.com/harleyQu1nn/AggressorScripts/blob/master/ProcessColor.cna#L10
|
||||
public static List<Dictionary<string, string>> GetProcInfo()
|
||||
{
|
||||
List<Dictionary<string, string>> f_results = new List<Dictionary<string, string>>();
|
||||
try
|
||||
{
|
||||
var wmiQueRyStr = "SELECT ProcessId, ExecutablePath, CommandLine FROM Win32_Process";
|
||||
using (var srcher = new ManagementObjectSearcher(wmiQueRyStr))
|
||||
using (var reslts = srcher.Get())
|
||||
{
|
||||
var queRy = from p in Process.GetProcesses()
|
||||
join mo in reslts.Cast<ManagementObject>()
|
||||
on p.Id equals (int)(uint)mo["ProcessId"]
|
||||
select new
|
||||
{
|
||||
Proc = p,
|
||||
Pth = (string)mo["ExecutablePath"],
|
||||
CommLine = (string)mo["CommandLine"],
|
||||
Owner = GetProcU(p), //Needed inside the next foreach
|
||||
};
|
||||
|
||||
foreach (var itm in queRy)
|
||||
{
|
||||
if (itm.Pth != null)
|
||||
{
|
||||
string companyName = "";
|
||||
string isDotNet = "";
|
||||
try
|
||||
{
|
||||
FileVersionInfo myFileVerInfo = FileVersionInfo.GetVersionInfo(itm.Pth);
|
||||
//compName = myFileVerInfo.CompanyName;
|
||||
isDotNet = MyUtils.CheckIfDotNet(itm.Pth) ? "isDotNet" : "";
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Not enough privileges
|
||||
}
|
||||
if ((String.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
||||
{
|
||||
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
||||
to_add["Name"] = itm.Proc.ProcessName;
|
||||
to_add["ProcessID"] = itm.Proc.Id.ToString();
|
||||
to_add["ExecutablePath"] = itm.Pth;
|
||||
to_add["Product"] = companyName;
|
||||
to_add["Owner"] = itm.Owner == null ? "" : itm.Owner;
|
||||
to_add["isDotNet"] = isDotNet;
|
||||
to_add["CommandLine"] = itm.CommLine;
|
||||
f_results.Add(to_add);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
return f_results;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@ using System.ServiceProcess;
|
||||
using System.Reflection;
|
||||
using System.Security.AccessControl;
|
||||
using System.Runtime.InteropServices;
|
||||
using winPEAS.Utils;
|
||||
|
||||
namespace winPEAS
|
||||
{
|
||||
@ -41,7 +42,7 @@ namespace winPEAS
|
||||
companyName = myFileVersionInfo.CompanyName;
|
||||
isDotNet = MyUtils.CheckIfDotNet(binaryPath) ? "isDotNet" : "";
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
// Not enough privileges
|
||||
}
|
||||
@ -76,9 +77,9 @@ namespace winPEAS
|
||||
|
||||
try
|
||||
{
|
||||
foreach (string key in MyUtils.GetRegSubkeys("HKLM", @"SYSTEM\CurrentControlSet\Services"))
|
||||
foreach (string key in RegistryHelper.GetRegSubkeys("HKLM", @"SYSTEM\CurrentControlSet\Services"))
|
||||
{
|
||||
Dictionary<string, object> key_values = MyUtils.GetRegValues("HKLM", @"SYSTEM\CurrentControlSet\Services\" + key);
|
||||
Dictionary<string, object> key_values = RegistryHelper.GetRegValues("HKLM", @"SYSTEM\CurrentControlSet\Services\" + key);
|
||||
|
||||
if (key_values.ContainsKey("DisplayName") && key_values.ContainsKey("ImagePath"))
|
||||
{
|
||||
@ -94,7 +95,7 @@ namespace winPEAS
|
||||
companyName = myFileVersionInfo.CompanyName;
|
||||
isDotNet = MyUtils.CheckIfDotNet(binaryPath) ? "isDotNet" : "";
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
// Not enough privileges
|
||||
}
|
||||
@ -231,7 +232,7 @@ namespace winPEAS
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception)
|
||||
{
|
||||
//Beaprint.GrayPrint(String.Format(" [X] Exception: {0}", ex.Message));
|
||||
}
|
||||
@ -280,7 +281,7 @@ namespace winPEAS
|
||||
try
|
||||
{
|
||||
// grabbed from the registry instead of System.Environment.GetEnvironmentVariable to prevent false positives
|
||||
string path = MyUtils.GetRegValue("HKLM", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "Path");
|
||||
string path = RegistryHelper.GetRegValue("HKLM", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", "Path");
|
||||
if (String.IsNullOrEmpty(path))
|
||||
path = Environment.GetEnvironmentVariable("PATH");
|
||||
|
||||
|
@ -6,6 +6,7 @@ using System.Management;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Windows.Forms;
|
||||
using winPEAS.Utils;
|
||||
|
||||
namespace winPEAS
|
||||
{
|
||||
@ -48,12 +49,12 @@ namespace winPEAS
|
||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
string ProductName = MyUtils.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName");
|
||||
string EditionID = MyUtils.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "EditionID");
|
||||
string ReleaseId = MyUtils.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ReleaseId");
|
||||
string BuildBranch = MyUtils.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "BuildBranch");
|
||||
string CurrentMajorVersionNumber = MyUtils.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentMajorVersionNumber");
|
||||
string CurrentVersion = MyUtils.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentVersion");
|
||||
string ProductName = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName");
|
||||
string EditionID = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "EditionID");
|
||||
string ReleaseId = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ReleaseId");
|
||||
string BuildBranch = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "BuildBranch");
|
||||
string CurrentMajorVersionNumber = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentMajorVersionNumber");
|
||||
string CurrentVersion = RegistryHelper.GetRegValue("HKLM", "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentVersion");
|
||||
|
||||
bool isHighIntegrity = MyUtils.IsHighIntegrity();
|
||||
|
||||
@ -148,7 +149,7 @@ namespace winPEAS
|
||||
string whitelistpaths = "";
|
||||
try
|
||||
{
|
||||
whitelistpaths = String.Join("\n ", MyUtils.GetRegValues("HKLM", @"SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths").Keys);
|
||||
whitelistpaths = String.Join("\n ", RegistryHelper.GetRegValues("HKLM", @"SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths").Keys);
|
||||
ManagementObjectSearcher wmiData = new ManagementObjectSearcher(@"root\SecurityCenter2", "SELECT * FROM AntiVirusProduct");
|
||||
ManagementObjectCollection data = wmiData.Get();
|
||||
|
||||
@ -176,7 +177,7 @@ namespace winPEAS
|
||||
|
||||
try
|
||||
{
|
||||
string ConsentPromptBehaviorAdmin = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "ConsentPromptBehaviorAdmin");
|
||||
string ConsentPromptBehaviorAdmin = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "ConsentPromptBehaviorAdmin");
|
||||
switch (ConsentPromptBehaviorAdmin)
|
||||
{
|
||||
case "0":
|
||||
@ -202,13 +203,13 @@ namespace winPEAS
|
||||
break;
|
||||
}
|
||||
|
||||
string EnableLUA = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "EnableLUA");
|
||||
string EnableLUA = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "EnableLUA");
|
||||
results["EnableLUA"] = EnableLUA;
|
||||
|
||||
string LocalAccountTokenFilterPolicy = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "LocalAccountTokenFilterPolicy");
|
||||
string LocalAccountTokenFilterPolicy = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "LocalAccountTokenFilterPolicy");
|
||||
results["LocalAccountTokenFilterPolicy"] = LocalAccountTokenFilterPolicy;
|
||||
|
||||
string FilterAdministratorToken = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "FilterAdministratorToken");
|
||||
string FilterAdministratorToken = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", "FilterAdministratorToken");
|
||||
results["FilterAdministratorToken"] = FilterAdministratorToken;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -225,18 +226,18 @@ namespace winPEAS
|
||||
|
||||
try
|
||||
{
|
||||
results["PowerShell v2 Version"] = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellEngine", "PowerShellVersion");
|
||||
results["PowerShell v5 Version"] = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\PowerShell\\3\\PowerShellEngine", "PowerShellVersion");
|
||||
results["PowerShell v2 Version"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellEngine", "PowerShellVersion");
|
||||
results["PowerShell v5 Version"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\PowerShell\\3\\PowerShellEngine", "PowerShellVersion");
|
||||
results["Transcription Settings"] = "";
|
||||
results["Module Logging Settings"] = "";
|
||||
results["Scriptblock Logging Settings"] = "";
|
||||
results["PS history file"] = "";
|
||||
results["PS history size"] = "";
|
||||
|
||||
Dictionary<string, object> transcriptionSettingsCU = MyUtils.GetRegValues("HKCU",
|
||||
Dictionary<string, object> transcriptionSettingsCU = RegistryHelper.GetRegValues("HKCU",
|
||||
"SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\Transcription");
|
||||
if ((transcriptionSettingsCU == null) || (transcriptionSettingsCU.Count == 0))
|
||||
transcriptionSettingsCU = MyUtils.GetRegValues("HKCU", @"HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\Transcription");
|
||||
transcriptionSettingsCU = RegistryHelper.GetRegValues("HKCU", @"HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\Transcription");
|
||||
|
||||
if ((transcriptionSettingsCU != null) && (transcriptionSettingsCU.Count != 0))
|
||||
{
|
||||
@ -246,10 +247,10 @@ namespace winPEAS
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string, object> transcriptionSettingsLM = MyUtils.GetRegValues("HKLM",
|
||||
Dictionary<string, object> transcriptionSettingsLM = RegistryHelper.GetRegValues("HKLM",
|
||||
"SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\Transcription");
|
||||
if ((transcriptionSettingsLM == null) || (transcriptionSettingsLM.Count == 0))
|
||||
transcriptionSettingsLM = MyUtils.GetRegValues("HKLM", @"HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\Transcription");
|
||||
transcriptionSettingsLM = RegistryHelper.GetRegValues("HKLM", @"HKLM\SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\Transcription");
|
||||
|
||||
if ((transcriptionSettingsLM != null) && (transcriptionSettingsLM.Count != 0))
|
||||
{
|
||||
@ -259,9 +260,9 @@ namespace winPEAS
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string, object> moduleLoggingSettingsLM = MyUtils.GetRegValues("HKLM", "SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ModuleLogging");
|
||||
Dictionary<string, object> moduleLoggingSettingsLM = RegistryHelper.GetRegValues("HKLM", "SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ModuleLogging");
|
||||
if ((moduleLoggingSettingsLM == null) || (moduleLoggingSettingsLM.Count == 0))
|
||||
moduleLoggingSettingsLM = MyUtils.GetRegValues("HKLM", @"SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging");
|
||||
moduleLoggingSettingsLM = RegistryHelper.GetRegValues("HKLM", @"SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging");
|
||||
|
||||
if ((moduleLoggingSettingsLM != null) && (moduleLoggingSettingsLM.Count != 0))
|
||||
{
|
||||
@ -271,9 +272,9 @@ namespace winPEAS
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string, object> moduleLoggingSettingsCU = MyUtils.GetRegValues("HKCU", "SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ModuleLogging");
|
||||
Dictionary<string, object> moduleLoggingSettingsCU = RegistryHelper.GetRegValues("HKCU", "SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ModuleLogging");
|
||||
if ((moduleLoggingSettingsCU == null) || (moduleLoggingSettingsCU.Count == 0))
|
||||
moduleLoggingSettingsCU = MyUtils.GetRegValues("HKCU", @"SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging");
|
||||
moduleLoggingSettingsCU = RegistryHelper.GetRegValues("HKCU", @"SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ModuleLogging");
|
||||
|
||||
if ((moduleLoggingSettingsCU != null) && (moduleLoggingSettingsCU.Count != 0))
|
||||
{
|
||||
@ -283,9 +284,9 @@ namespace winPEAS
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string, object> scriptBlockSettingsLM = MyUtils.GetRegValues("HKLM", "SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging");
|
||||
Dictionary<string, object> scriptBlockSettingsLM = RegistryHelper.GetRegValues("HKLM", "SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging");
|
||||
if ((scriptBlockSettingsLM == null) || (scriptBlockSettingsLM.Count == 0))
|
||||
scriptBlockSettingsLM = MyUtils.GetRegValues("HKLM", @"SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging");
|
||||
scriptBlockSettingsLM = RegistryHelper.GetRegValues("HKLM", @"SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging");
|
||||
|
||||
if ((scriptBlockSettingsLM != null) && (scriptBlockSettingsLM.Count != 0))
|
||||
{
|
||||
@ -295,9 +296,9 @@ namespace winPEAS
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string, object> scriptBlockSettingsCU = MyUtils.GetRegValues("HKCU", "SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging");
|
||||
Dictionary<string, object> scriptBlockSettingsCU = RegistryHelper.GetRegValues("HKCU", "SOFTWARE\\Policies\\Microsoft\\Windows\\PowerShell\\ScriptBlockLogging");
|
||||
if ((scriptBlockSettingsCU == null) || (scriptBlockSettingsCU.Count == 0))
|
||||
scriptBlockSettingsCU = MyUtils.GetRegValues("HKCU", @"SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging");
|
||||
scriptBlockSettingsCU = RegistryHelper.GetRegValues("HKCU", @"SOFTWARE\Wow6432Node\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging");
|
||||
|
||||
if ((scriptBlockSettingsCU != null) && (scriptBlockSettingsCU.Count != 0))
|
||||
{
|
||||
@ -331,7 +332,7 @@ namespace winPEAS
|
||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
Dictionary<string, object> settings = MyUtils.GetRegValues("HKLM", "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\Audit");
|
||||
Dictionary<string, object> settings = RegistryHelper.GetRegValues("HKLM", "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\\Audit");
|
||||
if ((settings != null) && (settings.Count != 0))
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in settings)
|
||||
@ -361,7 +362,7 @@ namespace winPEAS
|
||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
Dictionary<string, object> settings = MyUtils.GetRegValues("HKLM", "Software\\Policies\\Microsoft\\Windows\\EventLog\\EventForwarding\\SubscriptionManager");
|
||||
Dictionary<string, object> settings = RegistryHelper.GetRegValues("HKLM", "Software\\Policies\\Microsoft\\Windows\\EventLog\\EventForwarding\\SubscriptionManager");
|
||||
if ((settings != null) && (settings.Count != 0))
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in settings)
|
||||
@ -391,15 +392,15 @@ namespace winPEAS
|
||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
string AdmPwdEnabled = MyUtils.GetRegValue("HKLM", "Software\\Policies\\Microsoft Services\\AdmPwd", "AdmPwdEnabled");
|
||||
string AdmPwdEnabled = RegistryHelper.GetRegValue("HKLM", "Software\\Policies\\Microsoft Services\\AdmPwd", "AdmPwdEnabled");
|
||||
|
||||
if (AdmPwdEnabled != "")
|
||||
{
|
||||
results["LAPS Enabled"] = AdmPwdEnabled;
|
||||
results["LAPS Admin Account Name"] = MyUtils.GetRegValue("HKLM", "Software\\Policies\\Microsoft Services\\AdmPwd", "AdminAccountName");
|
||||
results["LAPS Password Complexity"] = MyUtils.GetRegValue("HKLM", "Software\\Policies\\Microsoft Services\\AdmPwd", "PasswordComplexity");
|
||||
results["LAPS Password Length"] = MyUtils.GetRegValue("HKLM", "Software\\Policies\\Microsoft Services\\AdmPwd", "PasswordLength");
|
||||
results["LAPS Expiration Protection Enabled"] = MyUtils.GetRegValue("HKLM", "Software\\Policies\\Microsoft Services\\AdmPwd", "PwdExpirationProtectionEnabled");
|
||||
results["LAPS Admin Account Name"] = RegistryHelper.GetRegValue("HKLM", "Software\\Policies\\Microsoft Services\\AdmPwd", "AdminAccountName");
|
||||
results["LAPS Password Complexity"] = RegistryHelper.GetRegValue("HKLM", "Software\\Policies\\Microsoft Services\\AdmPwd", "PasswordComplexity");
|
||||
results["LAPS Password Length"] = RegistryHelper.GetRegValue("HKLM", "Software\\Policies\\Microsoft Services\\AdmPwd", "PasswordLength");
|
||||
results["LAPS Expiration Protection Enabled"] = RegistryHelper.GetRegValue("HKLM", "Software\\Policies\\Microsoft Services\\AdmPwd", "PwdExpirationProtectionEnabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -435,7 +436,7 @@ namespace winPEAS
|
||||
Dictionary<string, string> result = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
Dictionary<string, object> settings = MyUtils.GetRegValues("HKLM", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment");
|
||||
Dictionary<string, object> settings = RegistryHelper.GetRegValues("HKLM", "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment");
|
||||
if ((settings != null) && (settings.Count != 0))
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in settings)
|
||||
@ -456,7 +457,7 @@ namespace winPEAS
|
||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
Dictionary<string, object> proxySettings = MyUtils.GetRegValues(root_reg, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
|
||||
Dictionary<string, object> proxySettings = RegistryHelper.GetRegValues(root_reg, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
|
||||
if ((proxySettings != null) && (proxySettings.Count != 0))
|
||||
{
|
||||
foreach (KeyValuePair<string, object> kvp in proxySettings)
|
||||
|
@ -6,6 +6,7 @@ using System.Security.Principal;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.Text.RegularExpressions;
|
||||
using winPEAS.Utils;
|
||||
|
||||
//Configuring Fody: https://tech.trailmax.info/2014/01/bundling-all-your-assemblies-into-one-or-alternative-to-ilmerge/
|
||||
//I have also created the folder Costura32 and Costura64 with the respective Dlls of Colorful.Console
|
||||
@ -962,12 +963,12 @@ namespace winPEAS
|
||||
{
|
||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
||||
|
||||
results["DefaultDomainName"] = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName");
|
||||
results["DefaultUserName"] = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName");
|
||||
results["DefaultPassword"] = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword");
|
||||
results["AltDefaultDomainName"] = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName");
|
||||
results["AltDefaultUserName"] = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName");
|
||||
results["AltDefaultPassword"] = MyUtils.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword");
|
||||
results["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName");
|
||||
results["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName");
|
||||
results["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword");
|
||||
results["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName");
|
||||
results["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName");
|
||||
results["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword");
|
||||
return results;
|
||||
}
|
||||
|
||||
|
155
winPEAS/winPEASexe/winPEAS/Utils/RegistryHelper.cs
Normal file
155
winPEAS/winPEASexe/winPEAS/Utils/RegistryHelper.cs
Normal file
@ -0,0 +1,155 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace winPEAS.Utils
|
||||
{
|
||||
static class RegistryHelper
|
||||
{
|
||||
///////////////////////////////////////////
|
||||
/// Interf. for Keys and Values in Reg. ///
|
||||
///////////////////////////////////////////
|
||||
/// Functions related to obtain keys and values from the registry
|
||||
/// Some parts adapted from Seatbelt
|
||||
public static string GetRegValue(string hive, string path, string value)
|
||||
{
|
||||
// returns a single registry value under the specified path in the specified hive (HKLM/HKCU)
|
||||
string regKeyValue = "";
|
||||
if (hive == "HKCU")
|
||||
{
|
||||
var regKey = Registry.CurrentUser.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = String.Format("{0}", regKey.GetValue(value));
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
var regKey = Registry.Users.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = String.Format("{0}", regKey.GetValue(value));
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var regKey = Registry.LocalMachine.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = String.Format("{0}", regKey.GetValue(value));
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> GetRegValues(string hive, string path)
|
||||
{
|
||||
// returns all registry values under the specified path in the specified hive (HKLM/HKCU)
|
||||
Dictionary<string, object> keyValuePairs = null;
|
||||
try
|
||||
{
|
||||
if (hive == "HKCU")
|
||||
{
|
||||
using (var regKeyValues = Registry.CurrentUser.OpenSubKey(path))
|
||||
{
|
||||
if (regKeyValues != null)
|
||||
{
|
||||
var valueNames = regKeyValues.GetValueNames();
|
||||
keyValuePairs = valueNames.ToDictionary(name => name, regKeyValues.GetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
using (var regKeyValues = Registry.Users.OpenSubKey(path))
|
||||
{
|
||||
if (regKeyValues != null)
|
||||
{
|
||||
var valueNames = regKeyValues.GetValueNames();
|
||||
keyValuePairs = valueNames.ToDictionary(name => name, regKeyValues.GetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var regKeyValues = Registry.LocalMachine.OpenSubKey(path))
|
||||
{
|
||||
if (regKeyValues != null)
|
||||
{
|
||||
var valueNames = regKeyValues.GetValueNames();
|
||||
keyValuePairs = valueNames.ToDictionary(name => name, regKeyValues.GetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
return keyValuePairs;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] GetRegValueBytes(string hive, string path, string value)
|
||||
{
|
||||
// returns a byte array of single registry value under the specified path in the specified hive (HKLM/HKCU)
|
||||
byte[] regKeyValue = null;
|
||||
if (hive == "HKCU")
|
||||
{
|
||||
var regKey = Registry.CurrentUser.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = (byte[])regKey.GetValue(value);
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
var regKey = Registry.Users.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = (byte[])regKey.GetValue(value);
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var regKey = Registry.LocalMachine.OpenSubKey(path);
|
||||
if (regKey != null)
|
||||
{
|
||||
regKeyValue = (byte[])regKey.GetValue(value);
|
||||
}
|
||||
return regKeyValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] GetRegSubkeys(string hive, string path)
|
||||
{
|
||||
// returns an array of the subkeys names under the specified path in the specified hive (HKLM/HKCU/HKU)
|
||||
try
|
||||
{
|
||||
RegistryKey myKey = null;
|
||||
if (hive == "HKLM")
|
||||
{
|
||||
myKey = Registry.LocalMachine.OpenSubKey(path);
|
||||
}
|
||||
else if (hive == "HKU")
|
||||
{
|
||||
myKey = Registry.Users.OpenSubKey(path);
|
||||
}
|
||||
else
|
||||
{
|
||||
myKey = Registry.CurrentUser.OpenSubKey(path);
|
||||
}
|
||||
String[] subkeyNames = myKey.GetSubKeyNames();
|
||||
return myKey.GetSubKeyNames();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new string[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Management;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace winPEAS
|
||||
{
|
||||
class Wifi
|
||||
@ -50,6 +53,5 @@ namespace winPEAS
|
||||
|
||||
return password;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -109,10 +109,27 @@
|
||||
<Compile Include="Beaprint.cs" />
|
||||
<Compile Include="FastSearch\FileSearcher\FileSearcher.cs" />
|
||||
<Compile Include="InterestingFiles.cs" />
|
||||
<Compile Include="KnownFileCredsInfo.cs" />
|
||||
<Compile Include="KnownFileCreds\Chrome.cs" />
|
||||
<Compile Include="KnownFileCreds\Firefox.cs" />
|
||||
<Compile Include="KnownFileCreds\InternetExplorer.cs" />
|
||||
<Compile Include="KnownFileCreds\Kerberos\enums\enums.cs" />
|
||||
<Compile Include="KnownFileCreds\Kerberos\Helpers.cs" />
|
||||
<Compile Include="KnownFileCreds\Kerberos\Kerberos.cs" />
|
||||
<Compile Include="KnownFileCreds\Kerberos\structs\structs.cs" />
|
||||
<Compile Include="KnownFileCreds\KnownFileCredsInfo.cs" />
|
||||
<Compile Include="KnownFileCreds\Putty.cs" />
|
||||
<Compile Include="KnownFileCreds\RemoteDesktop.cs" />
|
||||
<Compile Include="KnownFileCreds\Vault\enums\VAULT_ELEMENT_TYPE.cs" />
|
||||
<Compile Include="KnownFileCreds\Vault\enums\VAULT_SCHEMA_ELEMENT_ID.cs" />
|
||||
<Compile Include="KnownFileCreds\Vault\structs\VAULT_ITEM_ELEMENT.cs" />
|
||||
<Compile Include="KnownFileCreds\Vault\structs\VAULT_ITEM_WIN7.cs" />
|
||||
<Compile Include="KnownFileCreds\Vault\structs\VAULT_ITEM_WIN8.cs" />
|
||||
<Compile Include="KnownFileCreds\Vault\VaultCli.cs" />
|
||||
<Compile Include="MyUtils.cs" />
|
||||
<Compile Include="NetworkInfo.cs" />
|
||||
<Compile Include="ProcessesInfo.cs" />
|
||||
<Compile Include="ProcessInfo\DefensiveProcesses.cs" />
|
||||
<Compile Include="ProcessInfo\InterestingProcesses.cs" />
|
||||
<Compile Include="ProcessInfo\ProcessesInfo.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
@ -158,6 +175,7 @@
|
||||
<Compile Include="TaskScheduler\Wildcard.cs" />
|
||||
<Compile Include="TaskScheduler\XmlSerializationHelper.cs" />
|
||||
<Compile Include="UserInfo.cs" />
|
||||
<Compile Include="Utils\RegistryHelper.cs" />
|
||||
<Compile Include="Watson\Msrc\CVE-2019-0836.cs" />
|
||||
<Compile Include="Watson\Msrc\CVE-2019-0841.cs" />
|
||||
<Compile Include="Watson\Msrc\CVE-2019-1064.cs" />
|
||||
@ -175,6 +193,8 @@
|
||||
<Compile Include="Watson\Watson.cs" />
|
||||
<Compile Include="Watson\Wmi.cs" />
|
||||
<Compile Include="Wifi.cs" />
|
||||
<Compile Include="NativeWifiApi\Interop.cs" />
|
||||
<Compile Include="NativeWifiApi\WlanClient.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
|
Loading…
Reference in New Issue
Block a user