- refactoring/cleanup
- added .net versions check - added PrintMappedDrivesWMI - added PrintMicrosoftUpdatesCOM - added PrintSystemLastShutdownTime - added PrintCurrentUserIdleTime - added PowerShell Core Version check - updated ListCloudCreds - updated GetMcAfeeSitelistFiles - added PrintMachineAndUserCertificateFiles
This commit is contained in:
parent
839e4a79ba
commit
343b8bb96b
@ -6,6 +6,7 @@ using System.Management;
|
|||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.AppLocker;
|
using winPEAS.Helpers.AppLocker;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Helpers.Search;
|
using winPEAS.Helpers.Search;
|
||||||
using winPEAS.Info.UserInfo;
|
using winPEAS.Info.UserInfo;
|
||||||
|
|
||||||
|
@ -4,7 +4,10 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Helpers.Search;
|
using winPEAS.Helpers.Search;
|
||||||
|
using winPEAS.Info.FilesInfo.Certificates;
|
||||||
|
using winPEAS.Info.FilesInfo.McAfee;
|
||||||
using winPEAS.Info.UserInfo;
|
using winPEAS.Info.UserInfo;
|
||||||
using winPEAS.InterestingFiles;
|
using winPEAS.InterestingFiles;
|
||||||
using winPEAS.KnownFileCreds;
|
using winPEAS.KnownFileCreds;
|
||||||
@ -126,6 +129,7 @@ namespace winPEAS.Checks
|
|||||||
PrintUserCredsFiles,
|
PrintUserCredsFiles,
|
||||||
PrintOracleSQLDeveloperConfigFiles,
|
PrintOracleSQLDeveloperConfigFiles,
|
||||||
Slack.PrintInfo,
|
Slack.PrintInfo,
|
||||||
|
PrintMachineAndUserCertificateFiles,
|
||||||
PrintUsersInterestingFiles,
|
PrintUsersInterestingFiles,
|
||||||
PrintUsersDocsKeys,
|
PrintUsersDocsKeys,
|
||||||
PrintRecentFiles,
|
PrintRecentFiles,
|
||||||
@ -199,17 +203,37 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintMcAffeSitelistFiles()
|
private static void PrintMcAffeSitelistFiles()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for McAfee Sitelist.xml Files");
|
Beaprint.MainPrint("Looking for McAfee Sitelist.xml Files");
|
||||||
List<string> sam_files = InterestingFiles.InterestingFiles.GetMcAfeeSitelistFiles();
|
var sitelistFilesInfos = McAfee.GetMcAfeeSitelistInfos();
|
||||||
foreach (string path in sam_files)
|
|
||||||
{
|
|
||||||
Beaprint.BadPrint(" " + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
foreach (var sitelistFilesInfo in sitelistFilesInfos)
|
||||||
|
{
|
||||||
|
Beaprint.NoColorPrint($" Path: {sitelistFilesInfo.Path}");
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(sitelistFilesInfo.ParseException))
|
||||||
|
{
|
||||||
|
Beaprint.NoColorPrint($" Parse Exception: {sitelistFilesInfo.ParseException}");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var site in sitelistFilesInfo.Sites)
|
||||||
|
{
|
||||||
|
Beaprint.BadPrint($" ShareName : {site.ShareName}\n" +
|
||||||
|
$" UserName : {site.UserName}\n" +
|
||||||
|
$" Server : {site.Server}\n" +
|
||||||
|
$" EncPassword : {site.EncPassword}\n" +
|
||||||
|
$" DecPassword : {site.DecPassword}\n" +
|
||||||
|
$" DomainName : {site.DomainName}\n" +
|
||||||
|
$" Name : {site.Name}\n" +
|
||||||
|
$" Type : {site.Type}\n" +
|
||||||
|
$" RelativePath : {site.RelativePath}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Beaprint.PrintLineSeparator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -716,7 +740,7 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PrintOracleSQLDeveloperConfigFiles()
|
private static void PrintOracleSQLDeveloperConfigFiles()
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint($"Searching for Oracle SQL Developer config files\n");
|
Beaprint.MainPrint($"Searching for Oracle SQL Developer config files\n");
|
||||||
|
|
||||||
@ -747,5 +771,49 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PrintMachineAndUserCertificateFiles()
|
||||||
|
{
|
||||||
|
Beaprint.MainPrint($"Enumerating machine and user certificate files\n");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var certificateInfos = Certificates.GetCertificateInfos();
|
||||||
|
|
||||||
|
foreach (var certificateInfo in certificateInfos)
|
||||||
|
{
|
||||||
|
|
||||||
|
Beaprint.NoColorPrint($" Issuer : {certificateInfo.Issuer}\n" +
|
||||||
|
$" Subject : {certificateInfo.Subject}\n" +
|
||||||
|
$" ValidDate : {certificateInfo.ValidDate}\n" +
|
||||||
|
$" ExpiryDate : {certificateInfo.ExpiryDate}\n" +
|
||||||
|
$" HasPrivateKey : {certificateInfo.HasPrivateKey}\n" +
|
||||||
|
$" StoreLocation : {certificateInfo.StoreLocation}\n" +
|
||||||
|
$" KeyExportable : {certificateInfo.KeyExportable}\n" +
|
||||||
|
$" Thumbprint : {certificateInfo.Thumbprint}\n");
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(certificateInfo.Template))
|
||||||
|
{
|
||||||
|
Beaprint.NoColorPrint($" Template : {certificateInfo.Template}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (certificateInfo.EnhancedKeyUsages?.Count > 0)
|
||||||
|
{
|
||||||
|
Beaprint.ColorPrint(" Enhanced Key Usages", Beaprint.LBLUE);
|
||||||
|
|
||||||
|
foreach (var keyUsages in certificateInfo.EnhancedKeyUsages)
|
||||||
|
{
|
||||||
|
var info = keyUsages == "Client Authentication" ? " [*] Certificate is used for client authentication!" : string.Empty;
|
||||||
|
|
||||||
|
Beaprint.NoColorPrint($" {keyUsages}{info}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Beaprint.PrintLineSeparator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Management;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Extensions;
|
using winPEAS.Helpers.Extensions;
|
||||||
using winPEAS.Info.NetworkInfo;
|
using winPEAS.Info.NetworkInfo;
|
||||||
@ -28,6 +29,7 @@ namespace winPEAS.Checks
|
|||||||
new List<Action>
|
new List<Action>
|
||||||
{
|
{
|
||||||
PrintNetShares,
|
PrintNetShares,
|
||||||
|
PrintMappedDrivesWMI,
|
||||||
PrintHostsFile,
|
PrintHostsFile,
|
||||||
PrintNetworkIfaces,
|
PrintNetworkIfaces,
|
||||||
PrintListeningPorts,
|
PrintListeningPorts,
|
||||||
@ -333,5 +335,36 @@ namespace winPEAS.Checks
|
|||||||
Beaprint.PrintException(ex.Message);
|
Beaprint.PrintException(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PrintMappedDrivesWMI()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Beaprint.MainPrint("Enumerate Network Mapped Drives (WMI)");
|
||||||
|
|
||||||
|
using (var wmiData = new ManagementObjectSearcher(@"root\cimv2", "SELECT * FROM win32_networkconnection"))
|
||||||
|
{
|
||||||
|
using (var data = wmiData.Get())
|
||||||
|
{
|
||||||
|
foreach (ManagementObject result in data)
|
||||||
|
{
|
||||||
|
Beaprint.NoColorPrint($" Local Name : {result["LocalName"]}\n" +
|
||||||
|
$" Remote Name : {result["RemoteName"]}\n" +
|
||||||
|
$" Remote Path : {result["RemotePath"]}\n" +
|
||||||
|
$" Status : {result["Status"]}\n" +
|
||||||
|
$" Connection State : {result["ConnectionState"]}\n" +
|
||||||
|
$" Persistent : {result["Persistent"]}\n" +
|
||||||
|
$" UserName : {result["UserName"]}\n" +
|
||||||
|
$" Description : {result["Description"]}\n");
|
||||||
|
|
||||||
|
Beaprint.PrintLineSeparator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.AppLocker;
|
using winPEAS.Helpers.AppLocker;
|
||||||
using winPEAS._3rdParty.Watson;
|
using winPEAS._3rdParty.Watson;
|
||||||
@ -10,6 +13,8 @@ using winPEAS.Info.SystemInfo.NamedPipes;
|
|||||||
using winPEAS.Info.SystemInfo;
|
using winPEAS.Info.SystemInfo;
|
||||||
using winPEAS.Info.SystemInfo.SysMon;
|
using winPEAS.Info.SystemInfo.SysMon;
|
||||||
using winPEAS.Helpers.Extensions;
|
using winPEAS.Helpers.Extensions;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
|
using winPEAS.Info.SystemInfo.DotNet;
|
||||||
using winPEAS.Info.SystemInfo.WindowsDefender;
|
using winPEAS.Info.SystemInfo.WindowsDefender;
|
||||||
|
|
||||||
namespace winPEAS.Checks
|
namespace winPEAS.Checks
|
||||||
@ -47,6 +52,8 @@ namespace winPEAS.Checks
|
|||||||
new List<Action>
|
new List<Action>
|
||||||
{
|
{
|
||||||
PrintBasicSystemInfo,
|
PrintBasicSystemInfo,
|
||||||
|
PrintMicrosoftUpdatesCOM,
|
||||||
|
PrintSystemLastShutdownTime,
|
||||||
PrintUserEV,
|
PrintUserEV,
|
||||||
PrintSystemEV,
|
PrintSystemEV,
|
||||||
PrintAuditInfo,
|
PrintAuditInfo,
|
||||||
@ -70,11 +77,12 @@ namespace winPEAS.Checks
|
|||||||
PrintPrintersWMIInfo,
|
PrintPrintersWMIInfo,
|
||||||
PrintNamedPipes,
|
PrintNamedPipes,
|
||||||
PrintAMSIProviders,
|
PrintAMSIProviders,
|
||||||
PrintSysmon
|
PrintSysmon,
|
||||||
|
PrintDotNetVersions
|
||||||
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintBasicSystemInfo()
|
private static void PrintBasicSystemInfo()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -99,6 +107,61 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PrintMicrosoftUpdatesCOM()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Beaprint.MainPrint("Showing All Microsoft Updates");
|
||||||
|
|
||||||
|
var searcher = Type.GetTypeFromProgID("Microsoft.Update.Searcher");
|
||||||
|
var searcherObj = Activator.CreateInstance(searcher);
|
||||||
|
|
||||||
|
// get the total number of updates
|
||||||
|
var count = (int)searcherObj.GetType().InvokeMember("GetTotalHistoryCount", BindingFlags.InvokeMethod, null, searcherObj, new object[] { });
|
||||||
|
|
||||||
|
// get the pointer to the update collection
|
||||||
|
var results = searcherObj.GetType().InvokeMember("QueryHistory", BindingFlags.InvokeMethod, null, searcherObj, new object[] { 0, count });
|
||||||
|
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
// get the actual update item
|
||||||
|
var item = searcherObj.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, results, new object[] { i });
|
||||||
|
|
||||||
|
// get our properties
|
||||||
|
// ref - https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nn-wuapi-iupdatehistoryentry
|
||||||
|
var title = searcherObj.GetType().InvokeMember("Title", BindingFlags.GetProperty, null, item, new object[] { }).ToString();
|
||||||
|
var date = searcherObj.GetType().InvokeMember("Date", BindingFlags.GetProperty, null, item, new object[] { });
|
||||||
|
var description = searcherObj.GetType().InvokeMember("Description", BindingFlags.GetProperty, null, item, new object[] { });
|
||||||
|
var clientApplicationID = searcherObj.GetType().InvokeMember("ClientApplicationID", BindingFlags.GetProperty, null, item, new object[] { });
|
||||||
|
|
||||||
|
string hotfixId = "";
|
||||||
|
Regex reg = new Regex(@"KB\d+");
|
||||||
|
var matches = reg.Matches(title);
|
||||||
|
if (matches.Count > 0)
|
||||||
|
{
|
||||||
|
hotfixId = matches[0].ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
Beaprint.NoColorPrint($" HotFix ID : {hotfixId}\n" +
|
||||||
|
$" Installed At (UTC) : {Convert.ToDateTime(date.ToString()).ToUniversalTime()}\n" +
|
||||||
|
$" Title : {title}\n" +
|
||||||
|
$" Client Application ID : {clientApplicationID}\n" +
|
||||||
|
$" Description : {description}\n");
|
||||||
|
|
||||||
|
Beaprint.PrintLineSeparator();
|
||||||
|
|
||||||
|
Marshal.ReleaseComObject(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
Marshal.ReleaseComObject(results);
|
||||||
|
Marshal.ReleaseComObject(searcherObj);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Beaprint.PrintException(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void PrintPSInfo()
|
static void PrintPSInfo()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -703,8 +766,6 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Windows Defender configuration");
|
Beaprint.MainPrint("Windows Defender configuration");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DisplayDefenderSettings(WindowsDefenderSettings settings)
|
void DisplayDefenderSettings(WindowsDefenderSettings settings)
|
||||||
{
|
{
|
||||||
var pathExclusions = settings.PathExclusions;
|
var pathExclusions = settings.PathExclusions;
|
||||||
@ -797,5 +858,81 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PrintDotNetVersions()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Beaprint.MainPrint("Installed .NET versions\n");
|
||||||
|
|
||||||
|
var info = DotNet.GetDotNetInfo();
|
||||||
|
|
||||||
|
Beaprint.ColorPrint(" CLR Versions", Beaprint.LBLUE);
|
||||||
|
foreach (var version in info.ClrVersions)
|
||||||
|
{
|
||||||
|
Beaprint.NoColorPrint($" {version}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Beaprint.ColorPrint("\n .NET Versions", Beaprint.LBLUE);
|
||||||
|
foreach (var version in info.DotNetVersions)
|
||||||
|
{
|
||||||
|
Beaprint.NoColorPrint($" {version}");
|
||||||
|
}
|
||||||
|
|
||||||
|
var colors = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "True", Beaprint.ansi_color_good },
|
||||||
|
{ "False", Beaprint.ansi_color_bad },
|
||||||
|
};
|
||||||
|
|
||||||
|
Beaprint.ColorPrint("\n .NET & AMSI (Anti-Malware Scan Interface) support", Beaprint.LBLUE);
|
||||||
|
Beaprint.AnsiPrint($" .NET version supports AMSI : {info.IsAmsiSupportedByDotNet}\n" +
|
||||||
|
$" OS supports AMSI : {info.IsAmsiSupportedByOs}",
|
||||||
|
colors);
|
||||||
|
|
||||||
|
var highestVersion = info.HighestVersion;
|
||||||
|
var lowestVersion = info.LowestVersion;
|
||||||
|
|
||||||
|
if ((highestVersion.Major == DotNetInfo.AmsiSupportedByDotNetMinMajorVersion) && (highestVersion.Minor >= DotNetInfo.AmsiSupportedByDotNetMinMinorVersion))
|
||||||
|
{
|
||||||
|
Beaprint.NoColorPrint($" [!] The highest .NET version is enrolled in AMSI!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
info.IsAmsiSupportedByOs &&
|
||||||
|
info.IsAmsiSupportedByDotNet &&
|
||||||
|
((
|
||||||
|
(lowestVersion.Major == DotNetInfo.AmsiSupportedByDotNetMinMajorVersion - 1)
|
||||||
|
) ||
|
||||||
|
((lowestVersion.Major == DotNetInfo.AmsiSupportedByDotNetMinMajorVersion) && (lowestVersion.Minor < DotNetInfo.AmsiSupportedByDotNetMinMinorVersion)))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Beaprint.NoColorPrint($" [-] You can invoke .NET version {lowestVersion.Major}.{lowestVersion.Minor} to bypass AMSI.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void PrintSystemLastShutdownTime()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Beaprint.MainPrint("System Last Shutdown Date/time (from Registry)\n");
|
||||||
|
|
||||||
|
var shutdownBytes = RegistryHelper.GetRegValueBytes("HKLM", "SYSTEM\\ControlSet001\\Control\\Windows", "ShutdownTime");
|
||||||
|
if (shutdownBytes != null)
|
||||||
|
{
|
||||||
|
var shutdownInt = BitConverter.ToInt64(shutdownBytes, 0);
|
||||||
|
var shutdownTime = DateTime.FromFileTime(shutdownInt);
|
||||||
|
|
||||||
|
Beaprint.NoColorPrint($" Last Shutdown Date/time : {shutdownTime}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Info.UserInfo;
|
using winPEAS.Info.UserInfo;
|
||||||
using winPEAS.Info.UserInfo.LogonSessions;
|
using winPEAS.Info.UserInfo.LogonSessions;
|
||||||
using winPEAS.Info.UserInfo.Token;
|
using winPEAS.Info.UserInfo.Token;
|
||||||
|
using winPEAS.Native;
|
||||||
|
using winPEAS.Native.Structs;
|
||||||
|
|
||||||
namespace winPEAS.Checks
|
namespace winPEAS.Checks
|
||||||
{
|
{
|
||||||
@ -35,6 +39,7 @@ namespace winPEAS.Checks
|
|||||||
new List<Action>
|
new List<Action>
|
||||||
{
|
{
|
||||||
PrintCU,
|
PrintCU,
|
||||||
|
PrintCurrentUserIdleTime,
|
||||||
PrintTokenP,
|
PrintTokenP,
|
||||||
PrintClipboardText,
|
PrintClipboardText,
|
||||||
PrintLoggedUsers,
|
PrintLoggedUsers,
|
||||||
@ -306,5 +311,30 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void PrintCurrentUserIdleTime()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Beaprint.MainPrint("Current User Idle Time");
|
||||||
|
|
||||||
|
var lastInputInfo = new LastInputInfo();
|
||||||
|
lastInputInfo.Size = (uint)Marshal.SizeOf(lastInputInfo);
|
||||||
|
|
||||||
|
if (User32.GetLastInputInfo(ref lastInputInfo))
|
||||||
|
{
|
||||||
|
var currentUser = WindowsIdentity.GetCurrent().Name;
|
||||||
|
var idleTimeMiliSeconds = (uint) Environment.TickCount - lastInputInfo.Time;
|
||||||
|
var timeSpan = TimeSpan.FromMilliseconds(idleTimeMiliSeconds);
|
||||||
|
var idleTimeString = $"{timeSpan.Hours:D2}h:{timeSpan.Minutes:D2}m:{timeSpan.Seconds:D2}s:{timeSpan.Milliseconds:D3}ms";
|
||||||
|
|
||||||
|
Beaprint.NoColorPrint($" Current User : {currentUser}\n" +
|
||||||
|
$" Idle Time : {idleTimeString}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using System.Xml;
|
using System.Xml;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.CredentialManager;
|
using winPEAS.Helpers.CredentialManager;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.KnownFileCreds;
|
using winPEAS.KnownFileCreds;
|
||||||
using winPEAS.KnownFileCreds.Kerberos;
|
using winPEAS.KnownFileCreds.Kerberos;
|
||||||
using winPEAS.KnownFileCreds.SecurityPackages;
|
using winPEAS.KnownFileCreds.SecurityPackages;
|
||||||
|
@ -8,6 +8,7 @@ using System.Reflection;
|
|||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
@ -84,6 +85,12 @@ namespace winPEAS.Helpers
|
|||||||
return binaryPath;
|
return binaryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static bool IsBase64String(string text)
|
||||||
|
{
|
||||||
|
text = text.Trim();
|
||||||
|
return (text.Length % 4 == 0) && Regex.IsMatch(text, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
|
||||||
|
}
|
||||||
|
|
||||||
public static string ReconstructExecPath(string path)
|
public static string ReconstructExecPath(string path)
|
||||||
{
|
{
|
||||||
if (!path.Contains(".exe") && !path.Contains(".dll") && !path.Contains(".sys"))
|
if (!path.Contains(".exe") && !path.Contains(".dll") && !path.Contains(".sys"))
|
||||||
@ -136,6 +143,10 @@ namespace winPEAS.Helpers
|
|||||||
return dirs.ToList();
|
return dirs.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static byte[] CombineArrays(byte[] first, byte[] second)
|
||||||
|
{
|
||||||
|
return first.Concat(second).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
//From Seatbelt
|
//From Seatbelt
|
||||||
public static bool IsHighIntegrity()
|
public static bool IsHighIntegrity()
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers.Registry
|
||||||
{
|
{
|
||||||
static class RegistryHelper
|
static class RegistryHelper
|
||||||
{
|
{
|
||||||
@ -19,7 +18,7 @@ namespace winPEAS.Helpers
|
|||||||
string regKeyValue = "";
|
string regKeyValue = "";
|
||||||
if (hive == "HKCU")
|
if (hive == "HKCU")
|
||||||
{
|
{
|
||||||
var regKey = Registry.CurrentUser.OpenSubKey(path);
|
var regKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path);
|
||||||
if (regKey != null)
|
if (regKey != null)
|
||||||
{
|
{
|
||||||
regKeyValue = string.Format("{0}", regKey.GetValue(value));
|
regKeyValue = string.Format("{0}", regKey.GetValue(value));
|
||||||
@ -28,7 +27,7 @@ namespace winPEAS.Helpers
|
|||||||
}
|
}
|
||||||
else if (hive == "HKU")
|
else if (hive == "HKU")
|
||||||
{
|
{
|
||||||
var regKey = Registry.Users.OpenSubKey(path);
|
var regKey = Microsoft.Win32.Registry.Users.OpenSubKey(path);
|
||||||
if (regKey != null)
|
if (regKey != null)
|
||||||
{
|
{
|
||||||
regKeyValue = string.Format("{0}", regKey.GetValue(value));
|
regKeyValue = string.Format("{0}", regKey.GetValue(value));
|
||||||
@ -37,7 +36,7 @@ namespace winPEAS.Helpers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var regKey = Registry.LocalMachine.OpenSubKey(path);
|
var regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path);
|
||||||
if (regKey != null)
|
if (regKey != null)
|
||||||
{
|
{
|
||||||
regKeyValue = string.Format("{0}", regKey.GetValue(value));
|
regKeyValue = string.Format("{0}", regKey.GetValue(value));
|
||||||
@ -54,7 +53,7 @@ namespace winPEAS.Helpers
|
|||||||
{
|
{
|
||||||
if (hive == "HKCU")
|
if (hive == "HKCU")
|
||||||
{
|
{
|
||||||
using (var regKeyValues = Registry.CurrentUser.OpenSubKey(path))
|
using (var regKeyValues = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path))
|
||||||
{
|
{
|
||||||
if (regKeyValues != null)
|
if (regKeyValues != null)
|
||||||
{
|
{
|
||||||
@ -65,7 +64,7 @@ namespace winPEAS.Helpers
|
|||||||
}
|
}
|
||||||
else if (hive == "HKU")
|
else if (hive == "HKU")
|
||||||
{
|
{
|
||||||
using (var regKeyValues = Registry.Users.OpenSubKey(path))
|
using (var regKeyValues = Microsoft.Win32.Registry.Users.OpenSubKey(path))
|
||||||
{
|
{
|
||||||
if (regKeyValues != null)
|
if (regKeyValues != null)
|
||||||
{
|
{
|
||||||
@ -76,7 +75,7 @@ namespace winPEAS.Helpers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
using (var regKeyValues = Registry.LocalMachine.OpenSubKey(path))
|
using (var regKeyValues = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path))
|
||||||
{
|
{
|
||||||
if (regKeyValues != null)
|
if (regKeyValues != null)
|
||||||
{
|
{
|
||||||
@ -99,7 +98,7 @@ namespace winPEAS.Helpers
|
|||||||
byte[] regKeyValue = null;
|
byte[] regKeyValue = null;
|
||||||
if (hive == "HKCU")
|
if (hive == "HKCU")
|
||||||
{
|
{
|
||||||
var regKey = Registry.CurrentUser.OpenSubKey(path);
|
var regKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path);
|
||||||
if (regKey != null)
|
if (regKey != null)
|
||||||
{
|
{
|
||||||
regKeyValue = (byte[])regKey.GetValue(value);
|
regKeyValue = (byte[])regKey.GetValue(value);
|
||||||
@ -108,7 +107,7 @@ namespace winPEAS.Helpers
|
|||||||
}
|
}
|
||||||
else if (hive == "HKU")
|
else if (hive == "HKU")
|
||||||
{
|
{
|
||||||
var regKey = Registry.Users.OpenSubKey(path);
|
var regKey = Microsoft.Win32.Registry.Users.OpenSubKey(path);
|
||||||
if (regKey != null)
|
if (regKey != null)
|
||||||
{
|
{
|
||||||
regKeyValue = (byte[])regKey.GetValue(value);
|
regKeyValue = (byte[])regKey.GetValue(value);
|
||||||
@ -117,7 +116,7 @@ namespace winPEAS.Helpers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var regKey = Registry.LocalMachine.OpenSubKey(path);
|
var regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path);
|
||||||
if (regKey != null)
|
if (regKey != null)
|
||||||
{
|
{
|
||||||
regKeyValue = (byte[])regKey.GetValue(value);
|
regKeyValue = (byte[])regKey.GetValue(value);
|
||||||
@ -134,15 +133,15 @@ namespace winPEAS.Helpers
|
|||||||
RegistryKey myKey = null;
|
RegistryKey myKey = null;
|
||||||
if (hive == "HKLM")
|
if (hive == "HKLM")
|
||||||
{
|
{
|
||||||
myKey = Registry.LocalMachine.OpenSubKey(path);
|
myKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path);
|
||||||
}
|
}
|
||||||
else if (hive == "HKU")
|
else if (hive == "HKU")
|
||||||
{
|
{
|
||||||
myKey = Registry.Users.OpenSubKey(path);
|
myKey = Microsoft.Win32.Registry.Users.OpenSubKey(path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
myKey = Registry.CurrentUser.OpenSubKey(path);
|
myKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(path);
|
||||||
}
|
}
|
||||||
String[] subkeyNames = myKey.GetSubKeyNames();
|
String[] subkeyNames = myKey.GetSubKeyNames();
|
||||||
return myKey.GetSubKeyNames();
|
return myKey.GetSubKeyNames();
|
||||||
|
@ -17,6 +17,9 @@ namespace winPEAS.Helpers.Search
|
|||||||
private static List<CustomFileInfo> DocumentsAndSettings;
|
private static List<CustomFileInfo> DocumentsAndSettings;
|
||||||
private static List<CustomFileInfo> GroupPolicyHistory;
|
private static List<CustomFileInfo> GroupPolicyHistory;
|
||||||
|
|
||||||
|
private static string SystemDrive = Environment.GetEnvironmentVariable("SystemDrive");
|
||||||
|
private static string GlobalPattern = "*";
|
||||||
|
|
||||||
public static List<CustomFileInfo> GetFilesFast(string folder, string pattern = "*", HashSet<string> excludedDirs = null, bool isFoldersIncluded = false)
|
public static List<CustomFileInfo> GetFilesFast(string folder, string pattern = "*", HashSet<string> excludedDirs = null, bool isFoldersIncluded = false)
|
||||||
{
|
{
|
||||||
ConcurrentBag<CustomFileInfo> files = new ConcurrentBag<CustomFileInfo>();
|
ConcurrentBag<CustomFileInfo> files = new ConcurrentBag<CustomFileInfo>();
|
||||||
@ -166,37 +169,34 @@ namespace winPEAS.Helpers.Search
|
|||||||
|
|
||||||
internal static void CreateSearchDirectoriesList()
|
internal static void CreateSearchDirectoriesList()
|
||||||
{
|
{
|
||||||
string globalPattern = "*";
|
|
||||||
string systemDrive = Environment.GetEnvironmentVariable("SystemDrive");
|
|
||||||
|
|
||||||
// c:\users
|
// c:\users
|
||||||
string rootUsersSearchPath = $"{systemDrive}\\Users\\";
|
string rootUsersSearchPath = $"{SystemDrive}\\Users\\";
|
||||||
SearchHelper.RootDirUsers = SearchHelper.GetFilesFast(rootUsersSearchPath, globalPattern, isFoldersIncluded: true);
|
SearchHelper.RootDirUsers = SearchHelper.GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\users\current_user
|
// c:\users\current_user
|
||||||
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
|
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||||
SearchHelper.RootDirCurrentUser = SearchHelper.GetFilesFast(rootCurrentUserSearchPath, globalPattern);
|
SearchHelper.RootDirCurrentUser = SearchHelper.GetFilesFast(rootCurrentUserSearchPath, GlobalPattern);
|
||||||
|
|
||||||
// c:\Program Files\
|
// c:\Program Files\
|
||||||
string rootProgramFiles = $"{systemDrive}\\Program Files\\";
|
string rootProgramFiles = $"{SystemDrive}\\Program Files\\";
|
||||||
SearchHelper.ProgramFiles = SearchHelper.GetFilesFast(rootProgramFiles, globalPattern);
|
SearchHelper.ProgramFiles = SearchHelper.GetFilesFast(rootProgramFiles, GlobalPattern);
|
||||||
|
|
||||||
// c:\Program Files (x86)\
|
// c:\Program Files (x86)\
|
||||||
string rootProgramFilesX86 = $"{systemDrive}\\Program Files (x86)\\";
|
string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\";
|
||||||
SearchHelper.ProgramFilesX86 = SearchHelper.GetFilesFast(rootProgramFilesX86, globalPattern);
|
SearchHelper.ProgramFilesX86 = SearchHelper.GetFilesFast(rootProgramFilesX86, GlobalPattern);
|
||||||
|
|
||||||
// c:\Documents and Settings\
|
// c:\Documents and Settings\
|
||||||
string documentsAndSettings = $"{systemDrive}\\Documents and Settings\\";
|
string documentsAndSettings = $"{SystemDrive}\\Documents and Settings\\";
|
||||||
SearchHelper.DocumentsAndSettings = SearchHelper.GetFilesFast(documentsAndSettings, globalPattern);
|
SearchHelper.DocumentsAndSettings = SearchHelper.GetFilesFast(documentsAndSettings, GlobalPattern);
|
||||||
|
|
||||||
// c:\ProgramData\Microsoft\Group Policy\History
|
// c:\ProgramData\Microsoft\Group Policy\History
|
||||||
string groupPolicyHistory = $"{systemDrive}\\ProgramData\\Microsoft\\Group Policy\\History";
|
string groupPolicyHistory = $"{SystemDrive}\\ProgramData\\Microsoft\\Group Policy\\History";
|
||||||
SearchHelper.GroupPolicyHistory = SearchHelper.GetFilesFast(groupPolicyHistory, globalPattern);
|
SearchHelper.GroupPolicyHistory = SearchHelper.GetFilesFast(groupPolicyHistory, GlobalPattern);
|
||||||
|
|
||||||
// c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History
|
// c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History
|
||||||
string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History";
|
string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History";
|
||||||
//SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
|
//SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
|
||||||
var groupPolicyHistoryLegacyFiles = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
|
var groupPolicyHistoryLegacyFiles = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern);
|
||||||
|
|
||||||
SearchHelper.GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
|
SearchHelper.GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
|
||||||
}
|
}
|
||||||
@ -304,18 +304,20 @@ namespace winPEAS.Helpers.Search
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<string> SearchMcAfeeSitelistFiles()
|
internal static IEnumerable<string> SearchMcAfeeSitelistFiles()
|
||||||
{
|
{
|
||||||
var result = new List<string>();
|
var allowedFilenames = new HashSet<string>
|
||||||
|
|
||||||
HashSet<string> allowedFilenames = new HashSet<string>()
|
|
||||||
{
|
{
|
||||||
"sitelist.xml"
|
"sitelist.xml"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
string programDataPath = $"{SystemDrive}\\ProgramData\\";
|
||||||
|
var programData = SearchHelper.GetFilesFast(programDataPath, GlobalPattern);
|
||||||
|
|
||||||
var searchFiles = new List<CustomFileInfo>();
|
var searchFiles = new List<CustomFileInfo>();
|
||||||
searchFiles.AddRange(SearchHelper.ProgramFiles);
|
searchFiles.AddRange(SearchHelper.ProgramFiles);
|
||||||
searchFiles.AddRange(SearchHelper.ProgramFilesX86);
|
searchFiles.AddRange(SearchHelper.ProgramFilesX86);
|
||||||
|
searchFiles.AddRange(programData);
|
||||||
searchFiles.AddRange(SearchHelper.DocumentsAndSettings);
|
searchFiles.AddRange(SearchHelper.DocumentsAndSettings);
|
||||||
searchFiles.AddRange(SearchHelper.RootDirUsers);
|
searchFiles.AddRange(SearchHelper.RootDirUsers);
|
||||||
|
|
||||||
@ -327,12 +329,10 @@ namespace winPEAS.Helpers.Search
|
|||||||
|
|
||||||
if (allowedFilenames.Contains(filenameToLower))
|
if (allowedFilenames.Contains(filenameToLower))
|
||||||
{
|
{
|
||||||
result.Add(file.FullPath);
|
yield return file.FullPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static List<string> SearchCurrentUserDocs()
|
internal static List<string> SearchCurrentUserDocs()
|
||||||
|
@ -6,6 +6,7 @@ using System.Management;
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.Info.ApplicationInfo
|
namespace winPEAS.Info.ApplicationInfo
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.Info.ApplicationInfo
|
namespace winPEAS.Info.ApplicationInfo
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace winPEAS.Info.EventsInfo.PowerShell
|
namespace winPEAS.Info.EventsInfo
|
||||||
{
|
{
|
||||||
internal static class Common
|
internal static class Common
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace winPEAS.Info.FilesInfo.Certificates
|
||||||
|
{
|
||||||
|
internal class CertificateInfo
|
||||||
|
{
|
||||||
|
public string StoreLocation { get; set; }
|
||||||
|
public string Issuer { get; set; }
|
||||||
|
public string Subject { get; set; }
|
||||||
|
public DateTime ValidDate { get; set; }
|
||||||
|
public DateTime ExpiryDate { get; set; }
|
||||||
|
public bool HasPrivateKey { get; set; }
|
||||||
|
public bool? KeyExportable { get; set; }
|
||||||
|
public string Thumbprint { get; set; }
|
||||||
|
public string Template { get; set; }
|
||||||
|
public List<string> EnhancedKeyUsages { get; set; } = new List<string>();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Cryptography.X509Certificates;
|
||||||
|
|
||||||
|
namespace winPEAS.Info.FilesInfo.Certificates
|
||||||
|
{
|
||||||
|
internal class Certificates
|
||||||
|
{
|
||||||
|
public static IEnumerable<CertificateInfo> GetCertificateInfos()
|
||||||
|
{
|
||||||
|
foreach (var storeLocation in new[] { StoreLocation.CurrentUser, StoreLocation.LocalMachine })
|
||||||
|
{
|
||||||
|
var store = new X509Store(StoreName.My, storeLocation);
|
||||||
|
store.Open(OpenFlags.ReadOnly);
|
||||||
|
|
||||||
|
foreach (var certificate in store.Certificates)
|
||||||
|
{
|
||||||
|
var template = "";
|
||||||
|
var enhancedKeyUsages = new List<string>();
|
||||||
|
bool? keyExportable = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
certificate.PrivateKey.ToXmlString(true);
|
||||||
|
keyExportable = true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
keyExportable = !e.Message.Contains("not valid for use in specified state");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var ext in certificate.Extensions)
|
||||||
|
{
|
||||||
|
switch (ext.Oid.FriendlyName)
|
||||||
|
{
|
||||||
|
case "Enhanced Key Usage":
|
||||||
|
{
|
||||||
|
var extUsages = ((X509EnhancedKeyUsageExtension)ext).EnhancedKeyUsages;
|
||||||
|
|
||||||
|
if (extUsages.Count == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (var extUsage in extUsages)
|
||||||
|
{
|
||||||
|
enhancedKeyUsages.Add(extUsage.FriendlyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "Certificate Template Name":
|
||||||
|
case "Certificate Template Information":
|
||||||
|
template = ext.Format(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return new CertificateInfo
|
||||||
|
{
|
||||||
|
StoreLocation = $"{storeLocation}",
|
||||||
|
Issuer = certificate.Issuer,
|
||||||
|
Subject = certificate.Subject,
|
||||||
|
ValidDate = certificate.NotBefore,
|
||||||
|
ExpiryDate = certificate.NotAfter,
|
||||||
|
HasPrivateKey = certificate.HasPrivateKey,
|
||||||
|
KeyExportable = keyExportable,
|
||||||
|
Template = template,
|
||||||
|
Thumbprint = certificate.Thumbprint,
|
||||||
|
EnhancedKeyUsages = enhancedKeyUsages
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
store.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
156
winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfee.cs
Normal file
156
winPEAS/winPEASexe/winPEAS/Info/FilesInfo/McAfee/McAfee.cs
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Xml;
|
||||||
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Search;
|
||||||
|
|
||||||
|
namespace winPEAS.Info.FilesInfo.McAfee
|
||||||
|
{
|
||||||
|
internal class McAfee
|
||||||
|
{
|
||||||
|
public static IList<McAfeeSitelistInfo> GetMcAfeeSitelistInfos()
|
||||||
|
{
|
||||||
|
var result = new List<McAfeeSitelistInfo>();
|
||||||
|
var sitelistFiles = SearchHelper.SearchMcAfeeSitelistFiles()?.ToList();
|
||||||
|
|
||||||
|
if (sitelistFiles != null)
|
||||||
|
{
|
||||||
|
foreach (var sitelistFile in sitelistFiles)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var xmlString = File.ReadAllText(sitelistFile);
|
||||||
|
xmlString = xmlString.Replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "");
|
||||||
|
var xmlDoc = new XmlDocument();
|
||||||
|
|
||||||
|
xmlDoc.LoadXml(xmlString);
|
||||||
|
|
||||||
|
var sites = xmlDoc.GetElementsByTagName("SiteList");
|
||||||
|
|
||||||
|
if (sites[0].ChildNodes.Count == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var mcAfeeSites = new List<McAfeeSiteInfo>();
|
||||||
|
|
||||||
|
foreach (XmlNode site in sites[0].ChildNodes)
|
||||||
|
{
|
||||||
|
if (site.Attributes["Name"] == null || site.Attributes["Server"] == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var server = site.Attributes["Server"].Value;
|
||||||
|
var name = site.Attributes["Name"].Value;
|
||||||
|
var type = site.Name;
|
||||||
|
|
||||||
|
var encPassword = string.Empty;
|
||||||
|
var decPassword = string.Empty;
|
||||||
|
var relativePath = string.Empty;
|
||||||
|
var shareName = string.Empty;
|
||||||
|
var user = string.Empty;
|
||||||
|
var domainName = string.Empty;
|
||||||
|
|
||||||
|
foreach (XmlElement attribute in site.ChildNodes)
|
||||||
|
{
|
||||||
|
switch (attribute.Name)
|
||||||
|
{
|
||||||
|
case "UserName":
|
||||||
|
user = attribute.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Password":
|
||||||
|
if (MyUtils.IsBase64String(attribute.InnerText))
|
||||||
|
{
|
||||||
|
encPassword = attribute.InnerText;
|
||||||
|
decPassword = DecryptPassword(encPassword);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
decPassword = attribute.InnerText;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "DomainName":
|
||||||
|
domainName = attribute.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "RelativePath":
|
||||||
|
relativePath = attribute.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "ShareName":
|
||||||
|
shareName = attribute.InnerText;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = new McAfeeSiteInfo(type, name, server, relativePath, shareName, user, domainName, encPassword, decPassword);
|
||||||
|
|
||||||
|
mcAfeeSites.Add(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mcAfeeSites.Count > 0)
|
||||||
|
{
|
||||||
|
//yield return new McAfeeSitelistInfo(sitelistFile, mcAfeeSites);
|
||||||
|
result.Add(new McAfeeSitelistInfo(sitelistFile, mcAfeeSites));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
result.Add(new McAfeeSitelistInfo(sitelistFile, new List<McAfeeSiteInfo>(), ex.Message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string DecryptPassword(string base64password)
|
||||||
|
{
|
||||||
|
// Adapted from PowerUp: https://github.com/PowerShellMafia/PowerSploit/blob/master/Privesc/PowerUp.ps1#L4128-L4326
|
||||||
|
|
||||||
|
// References:
|
||||||
|
// https://github.com/funoverip/mcafee-sitelist-pwd-decryption/
|
||||||
|
// https://funoverip.net/2016/02/mcafee-sitelist-xml-password-decryption/
|
||||||
|
// https://github.com/tfairane/HackStory/blob/master/McAfeePrivesc.md
|
||||||
|
// https://www.syss.de/fileadmin/dokumente/Publikationen/2011/SySS_2011_Deeg_Privilege_Escalation_via_Antivirus_Software.pdf
|
||||||
|
|
||||||
|
// static McAfee key XOR key LOL
|
||||||
|
byte[] XORKey = { 0x12, 0x15, 0x0F, 0x10, 0x11, 0x1C, 0x1A, 0x06, 0x0A, 0x1F, 0x1B, 0x18, 0x17, 0x16, 0x05, 0x19 };
|
||||||
|
|
||||||
|
// xor the input b64 string with the static XOR key
|
||||||
|
var passwordBytes = System.Convert.FromBase64String(base64password);
|
||||||
|
for (var i = 0; i < passwordBytes.Length; i++)
|
||||||
|
{
|
||||||
|
passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]);
|
||||||
|
}
|
||||||
|
|
||||||
|
SHA1 crypto = new SHA1CryptoServiceProvider();
|
||||||
|
|
||||||
|
var tDESKey = MyUtils.CombineArrays(crypto.ComputeHash(System.Text.Encoding.ASCII.GetBytes("<!@#$%^>")), new byte[] { 0x00, 0x00, 0x00, 0x00 });
|
||||||
|
|
||||||
|
// set the options we need
|
||||||
|
var tDESalg = new TripleDESCryptoServiceProvider();
|
||||||
|
tDESalg.Mode = CipherMode.ECB;
|
||||||
|
tDESalg.Padding = PaddingMode.None;
|
||||||
|
tDESalg.Key = tDESKey;
|
||||||
|
|
||||||
|
// decrypt the unXor'ed block
|
||||||
|
var decrypted = tDESalg.CreateDecryptor().TransformFinalBlock(passwordBytes, 0, passwordBytes.Length);
|
||||||
|
var end = Array.IndexOf(decrypted, (byte)0x00);
|
||||||
|
|
||||||
|
// return the final password string
|
||||||
|
var password = System.Text.Encoding.ASCII.GetString(decrypted, 0, end);
|
||||||
|
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
namespace winPEAS.Info.FilesInfo.McAfee
|
||||||
|
{
|
||||||
|
internal class McAfeeSiteInfo
|
||||||
|
{
|
||||||
|
public string Type { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Server { get; set; }
|
||||||
|
public string RelativePath { get; set; }
|
||||||
|
public string ShareName { get; set; }
|
||||||
|
public string UserName { get; set; }
|
||||||
|
public string DomainName { get; set; }
|
||||||
|
public string EncPassword { get; set; }
|
||||||
|
public string DecPassword { get; set; }
|
||||||
|
|
||||||
|
public McAfeeSiteInfo(
|
||||||
|
string type,
|
||||||
|
string name,
|
||||||
|
string server,
|
||||||
|
string relativePath,
|
||||||
|
string shareName,
|
||||||
|
string userName,
|
||||||
|
string domainName,
|
||||||
|
string encPassword,
|
||||||
|
string decPassword)
|
||||||
|
{
|
||||||
|
Type = type;
|
||||||
|
Name = name;
|
||||||
|
Server = server;
|
||||||
|
RelativePath = relativePath;
|
||||||
|
ShareName = shareName;
|
||||||
|
UserName = userName;
|
||||||
|
DomainName = domainName;
|
||||||
|
EncPassword = encPassword;
|
||||||
|
DecPassword = decPassword;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace winPEAS.Info.FilesInfo.McAfee
|
||||||
|
{
|
||||||
|
internal class McAfeeSitelistInfo
|
||||||
|
{
|
||||||
|
public string Path { get; set; }
|
||||||
|
public List<McAfeeSiteInfo> Sites { get; set; }
|
||||||
|
|
||||||
|
public string ParseException { get; set; }
|
||||||
|
|
||||||
|
public McAfeeSitelistInfo(string path, List<McAfeeSiteInfo> sites, string parseException = null)
|
||||||
|
{
|
||||||
|
Path = path;
|
||||||
|
Sites = sites ?? new List<McAfeeSiteInfo>();
|
||||||
|
ParseException = parseException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace winPEAS.Info.NetworkInfo
|
namespace winPEAS.Info.NetworkInfo.Enums
|
||||||
{
|
{
|
||||||
public enum MibTcpState
|
public enum MibTcpState
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using winPEAS.Info.NetworkInfo.Enums;
|
||||||
|
|
||||||
namespace winPEAS.Info.NetworkInfo.Structs
|
namespace winPEAS.Info.NetworkInfo.Structs
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using winPEAS.Info.NetworkInfo.Enums;
|
||||||
|
|
||||||
namespace winPEAS.Info.NetworkInfo.Structs
|
namespace winPEAS.Info.NetworkInfo.Structs
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@ using System.ServiceProcess;
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.KnownFileCreds;
|
using winPEAS.KnownFileCreds;
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
|
||||||
|
71
winPEAS/winPEASexe/winPEAS/Info/SystemInfo/DotNet/DotNet.cs
Normal file
71
winPEAS/winPEASexe/winPEAS/Info/SystemInfo/DotNet/DotNet.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Management;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
|
namespace winPEAS.Info.SystemInfo.DotNet
|
||||||
|
{
|
||||||
|
internal class DotNet
|
||||||
|
{
|
||||||
|
public static DotNetInfo GetDotNetInfo()
|
||||||
|
{
|
||||||
|
var installedDotNetVersions = new List<string>();
|
||||||
|
var installedClrVersions = new List<string>();
|
||||||
|
installedClrVersions.AddRange(GetClrVersions());
|
||||||
|
|
||||||
|
var dotNet35Version = RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.5", "Version");
|
||||||
|
if (!string.IsNullOrEmpty(dotNet35Version))
|
||||||
|
{
|
||||||
|
installedDotNetVersions.Add(dotNet35Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dotNet4Version = RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full", "Version");
|
||||||
|
if (!string.IsNullOrEmpty(dotNet4Version))
|
||||||
|
{
|
||||||
|
installedDotNetVersions.Add(dotNet4Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
var osVersion = GetOSVersion().Split('.')[0];
|
||||||
|
int osVersionMajor = int.Parse(osVersion);
|
||||||
|
|
||||||
|
return new DotNetInfo(
|
||||||
|
installedClrVersions,
|
||||||
|
installedDotNetVersions,
|
||||||
|
osVersionMajor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetOSVersion()
|
||||||
|
{
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var wmiData = new ManagementObjectSearcher(@"root\cimv2", "SELECT Version FROM Win32_OperatingSystem"))
|
||||||
|
{
|
||||||
|
using (var data = wmiData.Get())
|
||||||
|
{
|
||||||
|
foreach (var os in data)
|
||||||
|
{
|
||||||
|
return os["Version"].ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<string> GetClrVersions()
|
||||||
|
{
|
||||||
|
var dirs = Directory.EnumerateDirectories("\\Windows\\Microsoft.Net\\Framework\\");
|
||||||
|
|
||||||
|
return (from dir in dirs
|
||||||
|
where File.Exists($"{dir}\\System.dll")
|
||||||
|
select Path.GetFileName(dir.TrimEnd(Path.DirectorySeparatorChar))
|
||||||
|
into fileName
|
||||||
|
select fileName.TrimStart('v')).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace winPEAS.Info.SystemInfo.DotNet
|
||||||
|
{
|
||||||
|
internal class DotNetInfo
|
||||||
|
{
|
||||||
|
public const int AmsiSupportedByDotNetMinMajorVersion = 4;
|
||||||
|
public const int AmsiSupportedByDotNetMinMinorVersion = 8;
|
||||||
|
|
||||||
|
private const int AmsiSupportedByOsMinVersion = 10;
|
||||||
|
|
||||||
|
public IEnumerable<string> ClrVersions { get; }
|
||||||
|
public IEnumerable<string> DotNetVersions { get; }
|
||||||
|
public bool IsAmsiSupportedByOs { get; }
|
||||||
|
public bool IsAmsiSupportedByDotNet { get; }
|
||||||
|
public Version LowestVersion { get; set; }
|
||||||
|
public Version HighestVersion { get; set; }
|
||||||
|
|
||||||
|
public DotNetInfo(
|
||||||
|
IEnumerable<string> installedClrVersions,
|
||||||
|
IEnumerable<string> installedDotNetVersions,
|
||||||
|
int osVersionMajor)
|
||||||
|
{
|
||||||
|
ClrVersions = (installedClrVersions ?? new List<string>()).ToList();
|
||||||
|
DotNetVersions = (installedDotNetVersions ?? new List<string>()).ToList(); ;
|
||||||
|
IsAmsiSupportedByOs = osVersionMajor >= AmsiSupportedByOsMinVersion;
|
||||||
|
|
||||||
|
LowestVersion = DotNetVersions.Min(v => (new Version(v)));
|
||||||
|
HighestVersion = DotNetVersions.Max(v => (new Version(v)));
|
||||||
|
|
||||||
|
IsAmsiSupportedByDotNet = (HighestVersion.Major >= AmsiSupportedByDotNetMinMajorVersion) &&
|
||||||
|
(LowestVersion.Minor >= AmsiSupportedByDotNetMinMinorVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics.Eventing.Reader;
|
using System.Diagnostics.Eventing.Reader;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.SysMon
|
namespace winPEAS.Info.SystemInfo.SysMon
|
||||||
{
|
{
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Management;
|
using System.Management;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.KnownFileCreds;
|
using winPEAS.KnownFileCreds;
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo
|
namespace winPEAS.Info.SystemInfo
|
||||||
@ -229,6 +231,7 @@ namespace winPEAS.Info.SystemInfo
|
|||||||
{
|
{
|
||||||
results["PowerShell v2 Version"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\PowerShell\\1\\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["PowerShell v5 Version"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\PowerShell\\3\\PowerShellEngine", "PowerShellVersion");
|
||||||
|
results["PowerShell Core Version"] = string.Join(", ", GetPowerShellCoreVersions());
|
||||||
results["Transcription Settings"] = "";
|
results["Transcription Settings"] = "";
|
||||||
results["Module Logging Settings"] = "";
|
results["Module Logging Settings"] = "";
|
||||||
results["Scriptblock Logging Settings"] = "";
|
results["Scriptblock Logging Settings"] = "";
|
||||||
@ -331,6 +334,15 @@ namespace winPEAS.Info.SystemInfo
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<string> GetPowerShellCoreVersions()
|
||||||
|
{
|
||||||
|
var keys = RegistryHelper.GetRegSubkeys("HKLM", @"SOFTWARE\Microsoft\PowerShellCore\InstalledVersions\") ?? new string[] { };
|
||||||
|
|
||||||
|
return keys.Select(key =>
|
||||||
|
RegistryHelper.GetRegValue("HKLM", @"SOFTWARE\Microsoft\PowerShellCore\InstalledVersions\" + key, "SemanticVersion"))
|
||||||
|
.Where(version => version != null).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
// From seatbelt
|
// From seatbelt
|
||||||
public static Dictionary<string, string> GetAuditSettings()
|
public static Dictionary<string, string> GetAuditSettings()
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@ using System.DirectoryServices.AccountManagement;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Info.UserInfo.SAM;
|
using winPEAS.Info.UserInfo.SAM;
|
||||||
using winPEAS.KnownFileCreds;
|
using winPEAS.KnownFileCreds;
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
@ -37,28 +37,6 @@ namespace winPEAS.InterestingFiles
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<string> GetMcAfeeSitelistFiles()
|
|
||||||
{
|
|
||||||
//From SharpUP
|
|
||||||
List<string> results = new List<string>();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
results = SearchHelper.SearchMcAfeeSitelistFiles();
|
|
||||||
|
|
||||||
//results.AddRange(
|
|
||||||
// searchLocations.SelectMany(
|
|
||||||
// searchLocation => SearchHelper.FindFiles(searchLocation, "SiteList.xml")));
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Beaprint.PrintException(ex.Message);
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<string> GetLinuxShells()
|
public static List<string> GetLinuxShells()
|
||||||
{
|
{
|
||||||
var results = new List<string>();
|
var results = new List<string>();
|
||||||
|
@ -8,6 +8,7 @@ using System.Text.RegularExpressions;
|
|||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using winPEAS.Checks;
|
using winPEAS.Checks;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.KnownFileCreds.Browsers.Models;
|
using winPEAS.KnownFileCreds.Browsers.Models;
|
||||||
|
|
||||||
namespace winPEAS.KnownFileCreds.Browsers
|
namespace winPEAS.KnownFileCreds.Browsers
|
||||||
|
@ -8,6 +8,7 @@ using System.Text;
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.KnownFileCreds
|
namespace winPEAS.KnownFileCreds
|
||||||
{
|
{
|
||||||
@ -42,198 +43,80 @@ namespace winPEAS.KnownFileCreds
|
|||||||
// adapted from https://twitter.com/cmaddalena's SharpCloud project (https://github.com/chrismaddalena/SharpCloud/)
|
// adapted from https://twitter.com/cmaddalena's SharpCloud project (https://github.com/chrismaddalena/SharpCloud/)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var cloudCredsDict = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
// AWS
|
||||||
|
{ ".aws\\credentials", "AWS keys file" },
|
||||||
|
|
||||||
|
// Google Cloud
|
||||||
|
{ "AppData\\Roaming\\gcloud\\credentials.db", "GC Compute creds" },
|
||||||
|
{ "AppData\\Roaming\\gcloud\\legacy_credentials", "GC Compute creds legacy" },
|
||||||
|
{ "AppData\\Roaming\\gcloud\\access_tokens.db", "GC Compute tokens" },
|
||||||
|
|
||||||
|
// Azure
|
||||||
|
{ ".azure\\accessTokens.json", "Azure tokens" },
|
||||||
|
{ ".azure\\azureProfile.json", "Azure profile" },
|
||||||
|
{ ".azure\\TokenCache.dat", "Azure Token Cache" },
|
||||||
|
{ ".azure\\AzureRMContext.json", "Azure RM Context" },
|
||||||
|
{ "AppData\\Roaming\\Windows Azure Powershell\\TokenCache.dat", "Azure PowerShell Token Cache" },
|
||||||
|
{ "AppData\\Roaming\\Windows Azure Powershell\\AzureRMContext.json", "Azure PowerShell RM Context" },
|
||||||
|
|
||||||
|
// Bluemix
|
||||||
|
{ ".bluemix\\config.json", "Bluemix Config" },
|
||||||
|
{ ".bluemix\\.cf\\config.json", "Bluemix Alternate Config" },
|
||||||
|
};
|
||||||
|
|
||||||
|
IEnumerable<string> userDirs;
|
||||||
|
|
||||||
if (MyUtils.IsHighIntegrity())
|
if (MyUtils.IsHighIntegrity())
|
||||||
{
|
{
|
||||||
string userFolder = string.Format("{0}\\Users\\", Environment.GetEnvironmentVariable("SystemDrive"));
|
string userFolders = $"{Environment.GetEnvironmentVariable("SystemDrive")}\\Users\\";
|
||||||
var dirs = Directory.EnumerateDirectories(userFolder);
|
userDirs = Directory.EnumerateDirectories(userFolders);
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
string awsKeyFile = string.Format("{0}\\.aws\\credentials", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||||
if (System.IO.File.Exists(awsKeyFile))
|
userDirs = new List<string>{ currentUserDir };
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var userDir in userDirs)
|
||||||
|
{
|
||||||
|
foreach (var item in cloudCredsDict)
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(awsKeyFile);
|
var file = item.Key;
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(awsKeyFile);
|
var description = item.Value;
|
||||||
long size = new System.IO.FileInfo(awsKeyFile).Length;
|
|
||||||
results.Add(new Dictionary<string, string>() {
|
var fullFilePath = Path.Combine(userDir, file);
|
||||||
{ "file", awsKeyFile },
|
|
||||||
{ "Description", "AWS keys file" },
|
AddCloudCredentialFromFile(fullFilePath, description, results);
|
||||||
{ "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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Beaprint.GrayPrint(string.Format(" [X] Exception: {0}", ex));
|
Beaprint.PrintException(ex.Message);
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void AddCloudCredentialFromFile(string filePath, string description, ICollection<Dictionary<string, string>> results)
|
||||||
|
{
|
||||||
|
if (File.Exists(filePath))
|
||||||
|
{
|
||||||
|
DateTime lastAccessed = File.GetLastAccessTime(filePath);
|
||||||
|
DateTime lastModified = File.GetLastWriteTime(filePath);
|
||||||
|
long size = new FileInfo(filePath).Length;
|
||||||
|
|
||||||
|
results?.Add(new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ "file", filePath },
|
||||||
|
{ "Description", description },
|
||||||
|
{ "Accessed", $"{lastAccessed}"},
|
||||||
|
{ "Modified", $"{lastModified}"},
|
||||||
|
{ "Size", $"{size}"}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static List<Dictionary<string, string>> GetRecentFiles()
|
public static List<Dictionary<string, string>> GetRecentFiles()
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.KnownFileCreds
|
namespace winPEAS.KnownFileCreds
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@ using System.IO;
|
|||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.KnownFileCreds
|
namespace winPEAS.KnownFileCreds
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
namespace winPEAS.Native.Structs
|
||||||
|
{
|
||||||
|
internal struct LastInputInfo
|
||||||
|
{
|
||||||
|
public uint Size;
|
||||||
|
public uint Time;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using winPEAS.Native.Structs;
|
||||||
|
|
||||||
namespace winPEAS.Native
|
namespace winPEAS.Native
|
||||||
{
|
{
|
||||||
@ -12,5 +13,10 @@ namespace winPEAS.Native
|
|||||||
|
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
|
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
|
||||||
|
[DllImport("User32.dll")]
|
||||||
|
public static extern bool GetLastInputInfo(ref LastInputInfo lastInputInfo);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern bool SetProcessDPIAware();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -410,6 +410,11 @@
|
|||||||
<Compile Include="Info\EventsInfo\Common.cs" />
|
<Compile Include="Info\EventsInfo\Common.cs" />
|
||||||
<Compile Include="Info\EventsInfo\ProcessCreation\ProcessCreation.cs" />
|
<Compile Include="Info\EventsInfo\ProcessCreation\ProcessCreation.cs" />
|
||||||
<Compile Include="Info\EventsInfo\ProcessCreation\ProcessCreationEventInfo.cs" />
|
<Compile Include="Info\EventsInfo\ProcessCreation\ProcessCreationEventInfo.cs" />
|
||||||
|
<Compile Include="Info\FilesInfo\Certificates\CertificateInfo.cs" />
|
||||||
|
<Compile Include="Info\FilesInfo\Certificates\Certificates.cs" />
|
||||||
|
<Compile Include="Info\FilesInfo\McAfee\McAfee.cs" />
|
||||||
|
<Compile Include="Info\FilesInfo\McAfee\McAfeeSiteInfo.cs" />
|
||||||
|
<Compile Include="Info\FilesInfo\McAfee\McAfeeSitelistInfo.cs" />
|
||||||
<Compile Include="Info\NetworkInfo\Enums\IPVersion.cs" />
|
<Compile Include="Info\NetworkInfo\Enums\IPVersion.cs" />
|
||||||
<Compile Include="Info\NetworkInfo\Enums\MibTcpState.cs" />
|
<Compile Include="Info\NetworkInfo\Enums\MibTcpState.cs" />
|
||||||
<Compile Include="Info\NetworkInfo\Enums\Protocol.cs" />
|
<Compile Include="Info\NetworkInfo\Enums\Protocol.cs" />
|
||||||
@ -428,6 +433,8 @@
|
|||||||
<Compile Include="Info\NetworkInfo\UdpConnectionInfo.cs" />
|
<Compile Include="Info\NetworkInfo\UdpConnectionInfo.cs" />
|
||||||
<Compile Include="Info\NetworkInfo\Win32Error.cs" />
|
<Compile Include="Info\NetworkInfo\Win32Error.cs" />
|
||||||
<Compile Include="Info\SystemInfo\CredentialGuard.cs" />
|
<Compile Include="Info\SystemInfo\CredentialGuard.cs" />
|
||||||
|
<Compile Include="Info\SystemInfo\DotNet\DotNet.cs" />
|
||||||
|
<Compile Include="Info\SystemInfo\DotNet\DotNetInfo.cs" />
|
||||||
<Compile Include="Info\SystemInfo\NamedPipes\NamedPipeInfo.cs" />
|
<Compile Include="Info\SystemInfo\NamedPipes\NamedPipeInfo.cs" />
|
||||||
<Compile Include="Info\SystemInfo\NamedPipes\NamedPipes.cs" />
|
<Compile Include="Info\SystemInfo\NamedPipes\NamedPipes.cs" />
|
||||||
<Compile Include="Info\SystemInfo\Printers\PrinterInfo.cs" />
|
<Compile Include="Info\SystemInfo\Printers\PrinterInfo.cs" />
|
||||||
@ -514,6 +521,7 @@
|
|||||||
<Compile Include="Native\Psapi.cs" />
|
<Compile Include="Native\Psapi.cs" />
|
||||||
<Compile Include="Native\Samlib.cs" />
|
<Compile Include="Native\Samlib.cs" />
|
||||||
<Compile Include="Native\Secur32.cs" />
|
<Compile Include="Native\Secur32.cs" />
|
||||||
|
<Compile Include="Native\Structs\LastInputInfo.cs" />
|
||||||
<Compile Include="Native\Structs\LUID.cs" />
|
<Compile Include="Native\Structs\LUID.cs" />
|
||||||
<Compile Include="Native\Structs\LUID_AND_ATTRIBUTES.cs" />
|
<Compile Include="Native\Structs\LUID_AND_ATTRIBUTES.cs" />
|
||||||
<Compile Include="Native\Structs\PRIVILEGE_SET.cs" />
|
<Compile Include="Native\Structs\PRIVILEGE_SET.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user