- added PrintOffice365EndpointsSyncedByOneDrive
- added PrintOfficeMostRecentFiles - added PrintCurrentTenantInfo - cleanup
This commit is contained in:
parent
df843d3825
commit
49a4344730
@ -35,7 +35,7 @@ namespace winPEAS.Checks
|
||||
public static string PaintAdminUsers = "";
|
||||
|
||||
private static List<SystemCheck> _systemChecks;
|
||||
private static HashSet<string> _systemCheckSelectedKeysHashSet = new HashSet<string>();
|
||||
private static readonly HashSet<string> _systemCheckSelectedKeysHashSet = new HashSet<string>();
|
||||
|
||||
// github url for Linpeas.sh
|
||||
public static string LinpeasUrl = "https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh";
|
||||
|
@ -1,15 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
using winPEAS.Helpers.Search;
|
||||
using winPEAS.Info.FilesInfo.Certificates;
|
||||
using winPEAS.Info.FilesInfo.McAfee;
|
||||
using winPEAS.Info.FilesInfo.Office;
|
||||
using winPEAS.Info.FilesInfo.WSL;
|
||||
using winPEAS.Info.UserInfo;
|
||||
using winPEAS.InterestingFiles;
|
||||
@ -122,6 +121,7 @@ namespace winPEAS.Checks
|
||||
{
|
||||
Putty.PrintInfo,
|
||||
SuperPutty.PrintInfo,
|
||||
PrintOffice365EndpointsSyncedByOneDrive,
|
||||
PrintCloudCreds,
|
||||
PrintUnattendFiles,
|
||||
PrintSAMBackups,
|
||||
@ -135,6 +135,7 @@ namespace winPEAS.Checks
|
||||
PrintMachineAndUserCertificateFiles,
|
||||
PrintUsersInterestingFiles,
|
||||
PrintUsersDocsKeys,
|
||||
PrintOfficeMostRecentFiles,
|
||||
PrintRecentFiles,
|
||||
PrintRecycleBin,
|
||||
PrintHiddenFilesAndFolders,
|
||||
@ -865,5 +866,115 @@ namespace winPEAS.Checks
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintOfficeMostRecentFiles()
|
||||
{
|
||||
int limit = 50;
|
||||
|
||||
Beaprint.MainPrint($"Office Most Recent Files -- limit {limit}\n");
|
||||
|
||||
try
|
||||
{
|
||||
var infos = Office.GetOfficeRecentFileInfos(limit);
|
||||
|
||||
Beaprint.ColorPrint($" {"Last Access Date",-25} {"User",-45} {"Application",-20} {"Document"}", Beaprint.LBLUE);
|
||||
|
||||
foreach (var info in infos)
|
||||
{
|
||||
Beaprint.NoColorPrint($" {info.LastAccessDate.ToString("yyyy-MM-dd HH:mm"),-25} {info.User,-45} {info.Application,-20} {info.Target}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintOffice365EndpointsSyncedByOneDrive()
|
||||
{
|
||||
void PrintItem(KeyValuePair<string, string> mpSub)
|
||||
{
|
||||
string formattedDateString = string.Empty;
|
||||
|
||||
if (mpSub.Key == "LastModifiedTime")
|
||||
{
|
||||
DateTime.TryParse(mpSub.Value, out var parsedDate);
|
||||
string formattedDate = parsedDate.ToString("ddd dd MMM yyyy HH:mm:ss");
|
||||
formattedDateString = $"({formattedDate})";
|
||||
}
|
||||
|
||||
Beaprint.NoColorPrint($" {mpSub.Key,-40} {mpSub.Value,-50} {formattedDateString}");
|
||||
}
|
||||
|
||||
Beaprint.MainPrint("Enumerating Office 365 endpoints synced by OneDrive.\n");
|
||||
|
||||
try
|
||||
{
|
||||
var infos = Office.GetCloudSyncProviderInfos();
|
||||
|
||||
foreach (var info in infos)
|
||||
{
|
||||
Beaprint.NoColorPrint($" SID: {info.Sid}");
|
||||
|
||||
var odspInfo = info.OneDriveSyncProviderInfo;
|
||||
|
||||
foreach (var item in odspInfo.OneDriveList)
|
||||
{
|
||||
if (item.Value.Count > 0)
|
||||
{
|
||||
|
||||
string accName = item.Key;
|
||||
Beaprint.NoColorPrint($" Name: {accName}");
|
||||
|
||||
foreach (var subItem in item.Value)
|
||||
{
|
||||
Beaprint.NoColorPrint($" {subItem.Key,-40} {subItem.Value}");
|
||||
}
|
||||
|
||||
// mount points
|
||||
foreach (string mp in odspInfo.AccountToMountpointDict[accName])
|
||||
{
|
||||
Beaprint.NoColorPrint("");
|
||||
|
||||
if (odspInfo.MpList.ContainsKey(mp))
|
||||
{
|
||||
foreach (var mpSub in odspInfo.MpList[mp])
|
||||
{
|
||||
PrintItem(mpSub);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// iterate Orphaned accounts
|
||||
var allScopeIds = new List<string>(odspInfo.MpList.Keys);
|
||||
var orphanedScopeIds = new HashSet<string>();
|
||||
|
||||
foreach (var scopeId in allScopeIds.Where(scopeId => !odspInfo.UsedScopeIDs.Contains(scopeId)))
|
||||
{
|
||||
orphanedScopeIds.Add(scopeId);
|
||||
}
|
||||
|
||||
if (orphanedScopeIds.Count > 0)
|
||||
{
|
||||
Beaprint.ColorPrint("\n Orphaned items", Beaprint.LBLUE);
|
||||
|
||||
foreach (string scopeId in orphanedScopeIds)
|
||||
{
|
||||
foreach (var mpSub in odspInfo.MpList[scopeId])
|
||||
{
|
||||
PrintItem(mpSub);
|
||||
}
|
||||
Beaprint.NoColorPrint("");
|
||||
}
|
||||
}
|
||||
|
||||
Beaprint.PrintLineSeparator();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Extensions;
|
||||
using winPEAS.Info.UserInfo;
|
||||
using winPEAS.Info.UserInfo.LogonSessions;
|
||||
using winPEAS.Info.UserInfo.Tenant;
|
||||
using winPEAS.Info.UserInfo.Token;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Enums;
|
||||
@ -41,6 +44,7 @@ namespace winPEAS.Checks
|
||||
{
|
||||
PrintCU,
|
||||
PrintCurrentUserIdleTime,
|
||||
PrintCurrentTenantInfo,
|
||||
PrintTokenP,
|
||||
PrintClipboardText,
|
||||
PrintLoggedUsers,
|
||||
@ -391,5 +395,48 @@ namespace winPEAS.Checks
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void PrintCurrentTenantInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
Beaprint.MainPrint("Display Tenant information (DsRegCmd.exe /status)");
|
||||
|
||||
var info = Tenant.GetTenantInfo();
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
|
||||
Beaprint.NoColorPrint($" Tenant Display Name : {info.TenantDisplayName}\n" +
|
||||
$" Tenant Id : {info.TenantId}\n" +
|
||||
$" Idp Domain : {info.IdpDomain}\n" +
|
||||
$" Mdm Enrollment Url : {info.MdmEnrollmentUrl}\n" +
|
||||
$" Mdm TermsOfUse Url : {info.MdmTermsOfUseUrl}\n" +
|
||||
$" Mdm Compliance Url : {info.MdmComplianceUrl}\n" +
|
||||
$" User Setting Sync Url : {info.UserSettingSyncUrl}\n" +
|
||||
$" Device Id : {info.DeviceId}\n" +
|
||||
$" Join Type : {info.JType.GetDescription()}\n" +
|
||||
$" Join User Email : {info.JoinUserEmail}\n" +
|
||||
$" User Key Id : {info.UserKeyId}\n" +
|
||||
$" User Email : {info.UserEmail}\n" +
|
||||
$" User Keyname : {info.UserKeyname}\n");
|
||||
|
||||
foreach (var cert in info.CertInfo)
|
||||
{
|
||||
Beaprint.NoColorPrint($" Thumbprint : {cert.Thumbprint}\n" +
|
||||
$" Subject : {cert.Subject}\n" +
|
||||
$" Issuer : {cert.Issuer}\n" +
|
||||
$" Expiration : {cert.GetExpirationDateString()}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Beaprint.NoColorPrint(" Tenant is NOT Azure AD Joined.");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +150,11 @@ namespace winPEAS.Helpers.Registry
|
||||
{
|
||||
return new string[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] GetUserSIDs()
|
||||
{
|
||||
return Microsoft.Win32.Registry.Users.GetSubKeyNames() ?? new string[] { };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
226
winPEAS/winPEASexe/winPEAS/Info/FilesInfo/Office/Office.cs
Normal file
226
winPEAS/winPEASexe/winPEAS/Info/FilesInfo/Office/Office.cs
Normal file
@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Win32;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Helpers.Registry;
|
||||
using winPEAS.Info.FilesInfo.Office.OneDrive;
|
||||
using winPEAS.Native;
|
||||
|
||||
namespace winPEAS.Info.FilesInfo.Office
|
||||
{
|
||||
internal class Office
|
||||
{
|
||||
public static IEnumerable<OfficeRecentFileInfo> GetOfficeRecentFileInfos(int limit)
|
||||
{
|
||||
var orderedRecentFiles = GetRecentOfficeFiles().OrderByDescending(e => e.LastAccessDate).Take(limit);
|
||||
|
||||
foreach (var file in orderedRecentFiles)
|
||||
{
|
||||
yield return file;
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<CloudSyncProviderInfo> GetCloudSyncProviderInfos()
|
||||
{
|
||||
var keys = new List<string> { "DisplayName", "Business", "ServiceEndpointUri", "SPOResourceId", "UserEmail", "UserFolder", "UserName", "WebServiceUrl" };
|
||||
|
||||
// Get all of the user SIDs (so will cover all users if run as an admin or has access to other user's reg keys)
|
||||
var SIDs = RegistryHelper.GetUserSIDs();
|
||||
var account = new Dictionary<string, string>();
|
||||
|
||||
foreach (var sid in SIDs)
|
||||
{
|
||||
if (!sid.StartsWith("S-1-5") || sid.EndsWith("_Classes")) // Disregard anything that isn't a user
|
||||
continue;
|
||||
|
||||
var oneDriveSyncProviderInfo = new OneDriveSyncProviderInfo();
|
||||
|
||||
// Now get each of the IDs (they aren't GUIDs but are an identity value for the specific library to sync)
|
||||
var subKeys = RegistryHelper.GetRegSubkeys("HKU", $"{sid}\\Software\\SyncEngines\\Providers\\OneDrive");
|
||||
if (subKeys == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now go through each of them, get the metadata and stick it in the 'provider' dict. It'll get cross referenced later.
|
||||
foreach (string rname in subKeys)
|
||||
{
|
||||
var provider = new Dictionary<string, string>();
|
||||
foreach (string x in new List<string> { "LibraryType", "LastModifiedTime", "MountPoint", "UrlNamespace" })
|
||||
{
|
||||
var result = RegistryHelper.GetRegValue("HKU", $"{sid}\\Software\\SyncEngines\\Providers\\OneDrive\\{rname}", x);
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
provider[x] = result;
|
||||
}
|
||||
}
|
||||
oneDriveSyncProviderInfo.MpList[rname] = provider;
|
||||
}
|
||||
|
||||
var odAccounts = RegistryHelper.GetRegSubkeys("HKU", $"{sid}\\Software\\Microsoft\\OneDrive\\Accounts");
|
||||
if (odAccounts == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (string acc in odAccounts)
|
||||
{
|
||||
var business = false;
|
||||
foreach (string x in keys)
|
||||
{
|
||||
var result = RegistryHelper.GetRegValue("HKU", $"{sid}\\Software\\Microsoft\\OneDrive\\Accounts\\{acc}", x);
|
||||
if (!string.IsNullOrEmpty(result))
|
||||
{
|
||||
account[x] = result;
|
||||
}
|
||||
|
||||
if (x == "Business")
|
||||
{
|
||||
business = (String.Compare(result, "1") == 0) ? true : false;
|
||||
}
|
||||
}
|
||||
var odMountPoints = RegistryHelper.GetRegValues("HKU", $"{sid}\\Software\\Microsoft\\OneDrive\\Accounts\\{acc}\\ScopeIdToMountPointPathCache");
|
||||
var scopeIds = new List<string>();
|
||||
|
||||
if (business)
|
||||
{
|
||||
scopeIds.AddRange(odMountPoints.Select(mp => mp.Key));
|
||||
}
|
||||
else
|
||||
{
|
||||
scopeIds.Add(acc); // If its a personal account, OneDrive adds it as 'Personal' or the name of the account, not by the ScopeId itself. You can only have one personal account.
|
||||
}
|
||||
|
||||
oneDriveSyncProviderInfo.AccountToMountpointDict[acc] = scopeIds;
|
||||
oneDriveSyncProviderInfo.OneDriveList[acc] = account;
|
||||
oneDriveSyncProviderInfo.UsedScopeIDs.AddRange(scopeIds);
|
||||
}
|
||||
|
||||
yield return new CloudSyncProviderInfo(sid, oneDriveSyncProviderInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<OfficeRecentFileInfo> GetRecentOfficeFiles()
|
||||
{
|
||||
foreach (var sid in Registry.Users.GetSubKeyNames())
|
||||
{
|
||||
if (!sid.StartsWith("S-1") || sid.EndsWith("_Classes"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string userName = null;
|
||||
try
|
||||
{
|
||||
userName = Advapi32.TranslateSid(sid);
|
||||
}
|
||||
catch
|
||||
{
|
||||
userName = sid;
|
||||
}
|
||||
|
||||
var officeVersion = RegistryHelper.GetRegSubkeys("HKU", $"{sid}\\Software\\Microsoft\\Office")
|
||||
?.Where(k => float.TryParse(k, NumberStyles.AllowDecimalPoint, new CultureInfo("en-GB"), out _));
|
||||
|
||||
if (officeVersion is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var version in officeVersion)
|
||||
{
|
||||
foreach (OfficeRecentFileInfo mru in GetMRUsFromVersionKey($"{sid}\\Software\\Microsoft\\Office\\{version}"))
|
||||
{
|
||||
//if (mru.LastAccessDate <= DateTime.Now.AddDays(-lastDays)) continue;
|
||||
|
||||
mru.User = userName;
|
||||
yield return mru;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<OfficeRecentFileInfo> GetMRUsFromVersionKey(string officeVersionSubkeyPath)
|
||||
{
|
||||
var officeApplications = RegistryHelper.GetRegSubkeys("HKU", officeVersionSubkeyPath);
|
||||
if (officeApplications == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var app in officeApplications)
|
||||
{
|
||||
// 1) HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\<OFFICE APP>\File MRU
|
||||
foreach (var mru in GetMRUsValues($"{officeVersionSubkeyPath}\\{app}\\File MRU"))
|
||||
{
|
||||
yield return mru;
|
||||
}
|
||||
|
||||
// 2) HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\User MRU\ADAL_B7C22499E768F03875FA6C268E771D1493149B23934326A96F6CDFEEEE7F68DA72\File MRU
|
||||
// or HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Word\User MRU\LiveId_CC4B824314B318B42E93BE93C46A61575D25608BBACDEEEA1D2919BCC2CF51FF\File MRU
|
||||
|
||||
var logonAapps = RegistryHelper.GetRegSubkeys("HKU", $"{officeVersionSubkeyPath}\\{app}\\User MRU");
|
||||
if (logonAapps == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var logonApp in logonAapps)
|
||||
{
|
||||
foreach (var mru in GetMRUsValues($"{officeVersionSubkeyPath}\\{app}\\User MRU\\{logonApp}\\File MRU"))
|
||||
{
|
||||
((OfficeRecentFileInfo)mru).Application = app;
|
||||
yield return mru;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<OfficeRecentFileInfo> GetMRUsValues(string keyPath)
|
||||
{
|
||||
var values = RegistryHelper.GetRegValues("HKU", keyPath);
|
||||
if (values == null)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var mruString in values.Values.Cast<string>().Select(ParseMruString).Where(mruString => mruString != null))
|
||||
{
|
||||
yield return mruString;
|
||||
}
|
||||
}
|
||||
|
||||
private static OfficeRecentFileInfo ParseMruString(string mru)
|
||||
{
|
||||
var matches = Regex.Matches(mru, "\\[[a-zA-Z0-9]+?\\]\\[T([a-zA-Z0-9]+?)\\](\\[[a-zA-Z0-9]+?\\])?\\*(.+)");
|
||||
if (matches.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
long timestamp = 0;
|
||||
var dateHexString = matches[0].Groups[1].Value;
|
||||
var filename = matches[0].Groups[matches[0].Groups.Count - 1].Value;
|
||||
|
||||
try
|
||||
{
|
||||
timestamp = long.Parse(dateHexString, NumberStyles.HexNumber);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Beaprint.PrintException($"Could not parse MRU timestamp. Parsed timestamp: {dateHexString} MRU value: {mru}");
|
||||
}
|
||||
|
||||
return new OfficeRecentFileInfo
|
||||
{
|
||||
Application = "Office",
|
||||
User = null,
|
||||
Target = filename,
|
||||
LastAccessDate = DateTime.FromFileTimeUtc(timestamp),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace winPEAS.Info.FilesInfo.Office
|
||||
{
|
||||
internal class OfficeRecentFileInfo
|
||||
{
|
||||
public string Application { get; set; }
|
||||
public string User { get; set; }
|
||||
public string Target { get; set; }
|
||||
public DateTime LastAccessDate { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
namespace winPEAS.Info.FilesInfo.Office.OneDrive
|
||||
{
|
||||
internal class CloudSyncProviderInfo
|
||||
{
|
||||
public CloudSyncProviderInfo(string sid, OneDriveSyncProviderInfo oneDriveSyncProviderInfo)
|
||||
{
|
||||
Sid = sid;
|
||||
OneDriveSyncProviderInfo = oneDriveSyncProviderInfo;
|
||||
}
|
||||
public string Sid { get; }
|
||||
public OneDriveSyncProviderInfo OneDriveSyncProviderInfo { get; }
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace winPEAS.Info.FilesInfo.Office.OneDrive
|
||||
{
|
||||
internal class OneDriveSyncProviderInfo
|
||||
{
|
||||
// Stores the mapping between a sync ID and mount point
|
||||
public Dictionary<string, Dictionary<string, string>> MpList { get; set; } = new Dictionary<string, Dictionary<string, string>>();
|
||||
// Stores the list of OneDrive accounts configured in the registry
|
||||
public Dictionary<string, Dictionary<string, string>> OneDriveList { get; set; } = new Dictionary<string, Dictionary<string, string>>();
|
||||
// Stores the mapping between the account and the mountpoint IDs
|
||||
public Dictionary<string, List<string>> AccountToMountpointDict { get; set; } = new Dictionary<string, List<string>>();
|
||||
// Stores the 'used' scopeIDs (to identify orphans)
|
||||
public List<string> UsedScopeIDs { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
@ -13,14 +13,14 @@ namespace winPEAS.Info.FilesInfo.WSL
|
||||
$@"bash -c ""{linpeasCmd}""" :
|
||||
Environment.GetEnvironmentVariable("WinDir") + $"\\SysNative\\bash.exe -c \"{linpeasCmd}\"";
|
||||
|
||||
ExecuteCommandLine(command);
|
||||
ExecuteCommand(command);
|
||||
}
|
||||
|
||||
private static void ExecuteCommandLine(string fullCommandLine,
|
||||
private static void ExecuteCommand(string command,
|
||||
string workingFolder = null,
|
||||
string verb = "OPEN")
|
||||
{
|
||||
string executable = fullCommandLine;
|
||||
string executable = command;
|
||||
string args = null;
|
||||
|
||||
if (executable.StartsWith("\""))
|
||||
@ -64,14 +64,12 @@ namespace winPEAS.Info.FilesInfo.WSL
|
||||
{
|
||||
while (!process.StandardOutput.EndOfStream)
|
||||
{
|
||||
string line = process.StandardOutput.ReadLine();
|
||||
Console.WriteLine(line);
|
||||
Console.WriteLine(process.StandardOutput.ReadLine());
|
||||
}
|
||||
|
||||
while (!process.StandardError.EndOfStream)
|
||||
{
|
||||
string line = process.StandardError.ReadLine();
|
||||
Console.WriteLine(line);
|
||||
Console.WriteLine(process.StandardError.ReadLine());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
19
winPEAS/winPEASexe/winPEAS/Info/UserInfo/Tenant/JoinType.cs
Normal file
19
winPEAS/winPEASexe/winPEAS/Info/UserInfo/Tenant/JoinType.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace winPEAS.Info.UserInfo.Tenant
|
||||
{
|
||||
public enum JoinType
|
||||
{
|
||||
[Description("Unknown Join")]
|
||||
DSREG_UNKNOWN_JOIN,
|
||||
|
||||
[Description("Device Join")]
|
||||
DSREG_DEVICE_JOIN,
|
||||
|
||||
[Description("Workplace Join")]
|
||||
DSREG_WORKPLACE_JOIN,
|
||||
|
||||
[Description("No Join")]
|
||||
DSREG_NO_JOIN
|
||||
}
|
||||
}
|
77
winPEAS/winPEASexe/winPEAS/Info/UserInfo/Tenant/Tenant.cs
Normal file
77
winPEAS/winPEASexe/winPEAS/Info/UserInfo/Tenant/Tenant.cs
Normal file
@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using winPEAS.Helpers;
|
||||
using winPEAS.Native;
|
||||
using winPEAS.Native.Structs;
|
||||
|
||||
namespace winPEAS.Info.UserInfo.Tenant
|
||||
{
|
||||
internal class Tenant
|
||||
{
|
||||
public static TenantInfo GetTenantInfo()
|
||||
{
|
||||
//original code from https://github.com/ThomasKur/WPNinjas.Dsregcmd/blob/2cff7b273ad4d3fc705744f76c4bd0701b2c36f0/WPNinjas.Dsregcmd/DsRegCmd.cs
|
||||
|
||||
string tenantId = null;
|
||||
var retValue = Netapi32.NetGetAadJoinInformation(tenantId, out var ptrJoinInfo);
|
||||
if (retValue == 0)
|
||||
{
|
||||
var joinInfo = (DSREG_JOIN_INFO)Marshal.PtrToStructure(ptrJoinInfo, typeof(DSREG_JOIN_INFO));
|
||||
var jType = (JoinType)joinInfo.joinType;
|
||||
var did = new Guid(joinInfo.DeviceId);
|
||||
var tid = new Guid(joinInfo.TenantId);
|
||||
|
||||
var data = Convert.FromBase64String(joinInfo.UserSettingSyncUrl);
|
||||
var userSettingSyncUrl = Encoding.ASCII.GetString(data);
|
||||
var ptrUserInfo = joinInfo.pUserInfo;
|
||||
|
||||
DSREG_USER_INFO? userInfo = null;
|
||||
var certificateResult = new List<X509Certificate2>();
|
||||
Guid? uid = null;
|
||||
|
||||
if (ptrUserInfo != IntPtr.Zero)
|
||||
{
|
||||
userInfo = (DSREG_USER_INFO)Marshal.PtrToStructure(ptrUserInfo, typeof(DSREG_USER_INFO));
|
||||
uid = new Guid(userInfo?.UserKeyId);
|
||||
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
|
||||
store.Open(OpenFlags.ReadOnly);
|
||||
|
||||
foreach (var certificate in store.Certificates)
|
||||
{
|
||||
if (certificate.Subject.Equals($"CN={did}"))
|
||||
{
|
||||
certificateResult.Add(certificate);
|
||||
}
|
||||
}
|
||||
|
||||
Marshal.Release(ptrUserInfo);
|
||||
}
|
||||
|
||||
Marshal.Release(ptrJoinInfo);
|
||||
Netapi32.NetFreeAadJoinInformation(ptrJoinInfo);
|
||||
|
||||
return new TenantInfo(
|
||||
jType,
|
||||
did,
|
||||
joinInfo.IdpDomain,
|
||||
tid,
|
||||
joinInfo.JoinUserEmail,
|
||||
joinInfo.TenantDisplayName,
|
||||
joinInfo.MdmEnrollmentUrl,
|
||||
joinInfo.MdmTermsOfUseUrl,
|
||||
joinInfo.MdmComplianceUrl,
|
||||
userSettingSyncUrl,
|
||||
certificateResult,
|
||||
userInfo?.UserEmail,
|
||||
uid,
|
||||
userInfo?.UserKeyName
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace winPEAS.Info.UserInfo.Tenant
|
||||
{
|
||||
internal class TenantInfo
|
||||
{
|
||||
public JoinType JType { get; }
|
||||
public Guid DeviceId { get; }
|
||||
public string IdpDomain { get; }
|
||||
public Guid TenantId { get; }
|
||||
public string JoinUserEmail { get; }
|
||||
public string TenantDisplayName { get; }
|
||||
public string MdmEnrollmentUrl { get; }
|
||||
public string MdmTermsOfUseUrl { get; }
|
||||
public string MdmComplianceUrl { get; }
|
||||
public string UserSettingSyncUrl { get; }
|
||||
public List<X509Certificate2> CertInfo { get; }
|
||||
public string UserEmail { get; }
|
||||
public Guid? UserKeyId { get; }
|
||||
public string UserKeyname { get; }
|
||||
|
||||
public TenantInfo(JoinType jType, Guid deviceId, string idpDomain, Guid tenantId, string joinUserEmail, string tenantDisplayName,
|
||||
string mdmEnrollmentUrl, string mdmTermsOfUseUrl, string mdmComplianceUrl, string userSettingSyncUrl,
|
||||
List<X509Certificate2> certInfo, string userEmail, Guid? userKeyId, string userKeyname)
|
||||
{
|
||||
JType = jType;
|
||||
DeviceId = deviceId;
|
||||
IdpDomain = idpDomain;
|
||||
TenantId = tenantId;
|
||||
JoinUserEmail = joinUserEmail;
|
||||
TenantDisplayName = tenantDisplayName;
|
||||
MdmEnrollmentUrl = mdmEnrollmentUrl;
|
||||
MdmTermsOfUseUrl = mdmTermsOfUseUrl;
|
||||
MdmComplianceUrl = mdmComplianceUrl;
|
||||
UserSettingSyncUrl = userSettingSyncUrl;
|
||||
CertInfo = certInfo;
|
||||
UserEmail = userEmail;
|
||||
UserKeyId = userKeyId;
|
||||
UserKeyname = userKeyname;
|
||||
}
|
||||
}
|
||||
}
|
@ -113,6 +113,7 @@ namespace winPEAS.KnownFileCreds
|
||||
"PublicKeyFile",
|
||||
"PortForwardings",
|
||||
"ConnectionSharing",
|
||||
"AgentFwd",
|
||||
"ProxyPassword",
|
||||
"ProxyUsername",
|
||||
};
|
||||
@ -151,6 +152,7 @@ namespace winPEAS.KnownFileCreds
|
||||
"PublicKeyFile",
|
||||
"PortForwardings",
|
||||
"ConnectionSharing",
|
||||
"AgentFwd",
|
||||
"ProxyPassword",
|
||||
"ProxyUsername",
|
||||
};
|
||||
|
@ -2,8 +2,10 @@
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using winPEAS.Helpers.CredentialManager;
|
||||
using winPEAS.Info.NetworkInfo;
|
||||
using winPEAS.Native.Classes;
|
||||
using winPEAS.Native.Enums;
|
||||
using winPEAS.Native.Structs;
|
||||
@ -209,5 +211,48 @@ namespace winPEAS.Native
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SetThreadToken(IntPtr ThreadHandle, SafeTokenHandle TokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern bool LookupAccountSid(
|
||||
string? lpSystemName,
|
||||
[MarshalAs(UnmanagedType.LPArray)] byte[] Sid,
|
||||
StringBuilder lpName,
|
||||
ref uint cchName,
|
||||
StringBuilder ReferencedDomainName,
|
||||
ref uint cchReferencedDomainName,
|
||||
out SID_NAME_USE peUse);
|
||||
|
||||
public static string TranslateSid(string sid)
|
||||
{
|
||||
// adapted from http://www.pinvoke.net/default.aspx/advapi32.LookupAccountSid
|
||||
var accountSid = new SecurityIdentifier(sid);
|
||||
var accountSidByes = new byte[accountSid.BinaryLength];
|
||||
accountSid.GetBinaryForm(accountSidByes, 0);
|
||||
|
||||
var name = new StringBuilder();
|
||||
var cchName = (uint)name.Capacity;
|
||||
var referencedDomainName = new StringBuilder();
|
||||
var cchReferencedDomainName = (uint)referencedDomainName.Capacity;
|
||||
|
||||
var err = 0;
|
||||
if (!LookupAccountSid(null, accountSidByes, name, ref cchName, referencedDomainName, ref cchReferencedDomainName, out var sidUse))
|
||||
{
|
||||
err = Marshal.GetLastWin32Error();
|
||||
|
||||
if (err == Win32Error.InsufficientBuffer)
|
||||
{
|
||||
name.EnsureCapacity((int)cchName);
|
||||
referencedDomainName.EnsureCapacity((int)cchReferencedDomainName);
|
||||
err = 0;
|
||||
if (!LookupAccountSid(null, accountSidByes, name, ref cchName, referencedDomainName,
|
||||
ref cchReferencedDomainName, out sidUse))
|
||||
{
|
||||
err = Marshal.GetLastWin32Error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err == 0 ? $"{referencedDomainName}\\{name}" : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
winPEAS/winPEASexe/winPEAS/Native/Enums/SID_NAME_USE.cs
Normal file
15
winPEAS/winPEASexe/winPEAS/Native/Enums/SID_NAME_USE.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace winPEAS.Native.Enums
|
||||
{
|
||||
public enum SID_NAME_USE
|
||||
{
|
||||
SidTypeUser = 1,
|
||||
SidTypeGroup,
|
||||
SidTypeDomain,
|
||||
SidTypeAlias,
|
||||
SidTypeWellKnownGroup,
|
||||
SidTypeDeletedAccount,
|
||||
SidTypeInvalid,
|
||||
SidTypeUnknown,
|
||||
SidTypeComputer
|
||||
}
|
||||
}
|
@ -42,5 +42,11 @@ namespace winPEAS.Native
|
||||
out uint entriesRead,
|
||||
out uint totalEntries,
|
||||
out IntPtr resumeHandle);
|
||||
|
||||
[DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern void NetFreeAadJoinInformation(IntPtr pJoinInfo);
|
||||
|
||||
[DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
internal static extern int NetGetAadJoinInformation(string pcszTenantId, out IntPtr ppJoinInfo);
|
||||
}
|
||||
}
|
||||
|
22
winPEAS/winPEASexe/winPEAS/Native/Structs/DSREG_JOIN_INFO.cs
Normal file
22
winPEAS/winPEASexe/winPEAS/Native/Structs/DSREG_JOIN_INFO.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.Native.Structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct DSREG_JOIN_INFO
|
||||
{
|
||||
public int joinType;
|
||||
public IntPtr pJoinCertificate;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string DeviceId;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string IdpDomain;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string TenantId;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string JoinUserEmail;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string TenantDisplayName;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string MdmEnrollmentUrl;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string MdmTermsOfUseUrl;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string MdmComplianceUrl;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string UserSettingSyncUrl;
|
||||
public IntPtr pUserInfo;
|
||||
}
|
||||
}
|
12
winPEAS/winPEASexe/winPEAS/Native/Structs/DSREG_USER_INFO.cs
Normal file
12
winPEAS/winPEASexe/winPEAS/Native/Structs/DSREG_USER_INFO.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace winPEAS.Native.Structs
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct DSREG_USER_INFO
|
||||
{
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string UserEmail;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string UserKeyId;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public string UserKeyName;
|
||||
}
|
||||
}
|
@ -417,6 +417,10 @@
|
||||
<Compile Include="Info\FilesInfo\McAfee\McAfee.cs" />
|
||||
<Compile Include="Info\FilesInfo\McAfee\McAfeeSiteInfo.cs" />
|
||||
<Compile Include="Info\FilesInfo\McAfee\McAfeeSitelistInfo.cs" />
|
||||
<Compile Include="Info\FilesInfo\Office\Office.cs" />
|
||||
<Compile Include="Info\FilesInfo\Office\OfficeRecentFileInfo.cs" />
|
||||
<Compile Include="Info\FilesInfo\Office\OneDrive\CloudSyncProviderInfo.cs" />
|
||||
<Compile Include="Info\FilesInfo\Office\OneDrive\OneDriveSyncProviderInfo.cs" />
|
||||
<Compile Include="Info\FilesInfo\WSL\WSL.cs" />
|
||||
<Compile Include="Info\NetworkInfo\Enums\IPVersion.cs" />
|
||||
<Compile Include="Info\NetworkInfo\Enums\MibTcpState.cs" />
|
||||
@ -460,6 +464,9 @@
|
||||
<Compile Include="Info\SystemInfo\WindowsDefender\WindowsDefenderSettingsInfo.cs" />
|
||||
<Compile Include="Info\UserInfo\LogonSessions\LogonSessions.cs" />
|
||||
<Compile Include="Info\UserInfo\LogonSessions\LogonSessionsInfo.cs" />
|
||||
<Compile Include="Info\UserInfo\Tenant\JoinType.cs" />
|
||||
<Compile Include="Info\UserInfo\Tenant\Tenant.cs" />
|
||||
<Compile Include="Info\UserInfo\Tenant\TenantInfo.cs" />
|
||||
<Compile Include="InterestingFiles\GPP.cs" />
|
||||
<Compile Include="InterestingFiles\InterestingFiles.cs" />
|
||||
<Compile Include="InterestingFiles\Unattended.cs" />
|
||||
@ -523,6 +530,7 @@
|
||||
<Compile Include="Native\Enums\SECURITY_LOGON_TYPE.cs" />
|
||||
<Compile Include="Native\Enums\ServerTypes.cs" />
|
||||
<Compile Include="Native\Enums\SE_OBJECT_TYPE.cs" />
|
||||
<Compile Include="Native\Enums\SID_NAME_USE.cs" />
|
||||
<Compile Include="Native\Enums\TokenType.cs" />
|
||||
<Compile Include="Native\Enums\TOKEN_ELEVATION_TYPE.cs" />
|
||||
<Compile Include="Native\Enums\TOKEN_INFORMATION_CLASS.cs" />
|
||||
@ -535,6 +543,8 @@
|
||||
<Compile Include="Native\Psapi.cs" />
|
||||
<Compile Include="Native\Samlib.cs" />
|
||||
<Compile Include="Native\Secur32.cs" />
|
||||
<Compile Include="Native\Structs\DSREG_JOIN_INFO.cs" />
|
||||
<Compile Include="Native\Structs\DSREG_USER_INFO.cs" />
|
||||
<Compile Include="Native\Structs\LastInputInfo.cs" />
|
||||
<Compile Include="Native\Structs\LUID.cs" />
|
||||
<Compile Include="Native\Structs\LUID_AND_ATTRIBUTES.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user