Skip to content

Commit

Permalink
PingCastle 3.3.0.0 (#256)
Browse files Browse the repository at this point in the history
Co-authored-by: Vincent LE TOUX <[email protected]>
  • Loading branch information
vletoux and Vincent LE TOUX authored Sep 13, 2024
1 parent 5025359 commit df54c41
Show file tree
Hide file tree
Showing 81 changed files with 3,424 additions and 665 deletions.
29 changes: 26 additions & 3 deletions ADWS/ADItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,15 @@ public class DnsProperty
[AttributeUsage(AttributeTargets.Property)]
private class ADAttributeAttribute : Attribute
{
public ADAttributeAttribute(string aDAttribute, ADAttributeValueKind valueKind)
public ADAttributeAttribute(string aDAttribute, ADAttributeValueKind valueKind, object defaultValue = null)
{
ADAttribute = aDAttribute;
ValueKind = valueKind;
DefaultValue = defaultValue;
}
public string ADAttribute { get; set; }
public ADAttributeValueKind ValueKind { get; set; }
public object DefaultValue { get; set; }
}

private enum ADAttributeValueKind
Expand Down Expand Up @@ -118,7 +120,24 @@ static ADItem()
var attributes = prop.GetCustomAttributes(typeof(ADAttributeAttribute), false);
if (attributes != null && attributes.Length != 0)
{
AttributeTranslation.Add(((ADAttributeAttribute)attributes[0]).ADAttribute.ToLowerInvariant(), new ADAttributeTranslation((ADAttributeAttribute)attributes[0], prop));
var attribute = (ADAttributeAttribute)attributes[0];
AttributeTranslation.Add(attribute.ADAttribute.ToLowerInvariant(), new ADAttributeTranslation(attribute, prop));
}
}
}

protected ADItem()
{
foreach (var prop in typeof(ADItem).GetProperties())
{
var attributes = prop.GetCustomAttributes(typeof(ADAttributeAttribute), false);
if (attributes != null && attributes.Length != 0)
{
var attribute = (ADAttributeAttribute)attributes[0];
if (attribute.DefaultValue != null)
{
prop.SetValue(this, attribute.DefaultValue);
}
}
}
}
Expand Down Expand Up @@ -149,7 +168,7 @@ static ADItem()
public string DnsRoot { get; set; }
[ADAttributeAttribute("dSHeuristics", ADAttributeValueKind.StringValue)]
public string DSHeuristics { get; set; }
[ADAttributeAttribute("ms-DS-MachineAccountQuota", ADAttributeValueKind.IntValue)]
[ADAttributeAttribute("ms-DS-MachineAccountQuota", ADAttributeValueKind.IntValue, int.MaxValue)]
public int DSMachineAccountQuota { get; set; }
[ADAttributeAttribute("flags", ADAttributeValueKind.IntValue)]
public int Flags { get; set; }
Expand Down Expand Up @@ -187,6 +206,8 @@ static ADItem()
public SecurityIdentifier msDSCreatorSID { get; set; }
[ADAttributeAttribute("msDS-EnabledFeature", ADAttributeValueKind.StringArrayValue)]
public string[] msDSEnabledFeature { get; set; }
[ADAttributeAttribute("msDS-ExpirePasswordsOnSmartCardOnlyAccounts", ADAttributeValueKind.BoolValue)]
public bool msDSExpirePasswordsOnSmartCardOnlyAccounts { get; set; }
[ADAttributeAttribute("msDS-IntId", ADAttributeValueKind.IntValue)]
public int msDSIntId { get; set; }
[ADAttributeAttribute("msDS-SupportedEncryptionTypes", ADAttributeValueKind.IntValue)]
Expand All @@ -197,6 +218,8 @@ static ADItem()
public long msDSMaximumPasswordAge { get; set; }
[ADAttributeAttribute("msDS-MinimumPasswordLength", ADAttributeValueKind.IntValue)]
public int msDSMinimumPasswordLength { get; set; }
[ADAttributeAttribute("msDS-Other-Settings", ADAttributeValueKind.StringArrayValue)]
public string[] msDSOtherSettings { get; set; }
[ADAttributeAttribute("msDS-PasswordComplexityEnabled", ADAttributeValueKind.BoolValue)]
public bool msDSPasswordComplexityEnabled { get; set; }
[ADAttributeAttribute("msDS-PasswordHistoryLength", ADAttributeValueKind.IntValue)]
Expand Down
39 changes: 39 additions & 0 deletions ADWS/LDAPConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
using System.Diagnostics;
using System.DirectoryServices;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;

namespace PingCastle.ADWS
Expand Down Expand Up @@ -187,6 +190,10 @@ private ADDomainInfo GetLDAPDomainInfo()
// Windows 2000 does not support a bind to the rootDse and returns "The server is not operational" (0x8007203A)
if (ex.ErrorCode == -2147016646)
{
if (Port == 636)
{
EnsureLDAPSIsWorking();
}
if (Credential == null)
{
rootDse = new DirectoryEntry(@"LDAP://" + Server + (Port == 0 ? null : ":" + Port) + "/RootDSE", null, null, AuthenticationTypes.Secure | (Port == 636 ? AuthenticationTypes.SecureSocketsLayer : 0));
Expand All @@ -204,6 +211,38 @@ private ADDomainInfo GetLDAPDomainInfo()
return ADDomainInfo.Create(rootDse);
}

private void EnsureLDAPSIsWorking()
{
Trace.WriteLine("testing LDAPS connectivity");
using (TcpClient client = new TcpClient(Server, Port))
{
client.ReceiveTimeout = 1000;
client.SendTimeout = 1000;
using (SslStream sslstream = new SslStream(client.GetStream(), false,
(object sender, X509Certificate CACert, X509Chain CAChain, SslPolicyErrors sslPolicyErrors)
=>
{
Trace.WriteLine("Certificate presented: " + CACert.Subject);
Trace.WriteLine("Certificate expires: " + CACert.GetExpirationDateString());
Trace.WriteLine("SSLPolicyErrors: " + sslPolicyErrors);
if (sslPolicyErrors != SslPolicyErrors.None)
{
Console.WriteLine("While testing the LDAPS certificate, PingCastle found the following error: " + sslPolicyErrors);
Console.WriteLine("The certificate is untrusted and Windows prohibits PingCastle to connect to it");
Console.WriteLine("Certificate: " + CACert.Subject);
Console.WriteLine("Expires: " + CACert.GetExpirationDateString());
}
return true;
}
, null))
{
Trace.WriteLine("before testing LDAPS certificatre for " + Server);
sslstream.AuthenticateAsClient(Server, null, System.Security.Authentication.SslProtocols.Default, false);
Trace.WriteLine("testing LDAPS certificatre for " + Server + " worked");
}
}
}

// connecting using LDAP
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public override void EstablishConnection()
Expand Down
2 changes: 1 addition & 1 deletion Cloud/Analyzer/Analyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ private void AnalyzePolicies()
}
}

var ms = new MicrosoftGraph(new PRTCredential());
var ms = new MicrosoftGraph(credential);
var authorizationPolicies = ms.GetAuthorizationPolicy();
if (authorizationPolicies != null && authorizationPolicies.Count > 0)
{
Expand Down
42 changes: 41 additions & 1 deletion Cloud/RESTServices/Azure/MicrosoftGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ namespace PingCastle.Cloud.RESTServices
[AzureService("1b730954-1685-4b74-9bfd-dac224a7b894", "https://graph.microsoft.com")]
public class MicrosoftGraph : RESTClientBase<MicrosoftGraph>, IAzureService
{
public MicrosoftGraph(IAzureCredential credential) : base(credential)
public MicrosoftGraph(IAzureCredential credential)
: base(credential)
{
}
protected override string BuidEndPoint(string function, string optionalQuery)
Expand All @@ -42,6 +43,11 @@ public List<AuthorizationPolicy> GetAuthorizationPolicy()
return CallEndPointWithPaggingAsync<object, AuthorizationPolicy>("policies/authorizationPolicy", null).GetAwaiter().GetResult();
}

public permissionGrantPolicy GetPermissionGrantPolicies(string id)
{
return CallEndPointAsync<object, permissionGrantPolicy>("policies/permissionGrantPolicies/" + id, null).GetAwaiter().GetResult();
}

// message=Insufficient privileges to complete the operation.
public string GetTenantRelationships(string tenantId)
{
Expand All @@ -55,6 +61,7 @@ public class AuthorizationPolicy
public bool allowedToSignUpEmailBasedSubscriptions { get; set; }
public bool allowedToUseSSPR { get; set; }
public bool allowEmailVerifiedUsersToJoinOrganization { get; set; }
public bool? allowUserConsentForRiskyApps { get; set; }
public bool blockMsolPowerShell { get; set; }
public string description { get; set; }
public string displayName { get; set; }
Expand All @@ -72,5 +79,38 @@ public class UserRolePermissions
public bool allowedToReadBitlockerKeysForOwnedDevice { get; set; }
public bool allowedToReadOtherUsers { get; set; }
}

// Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
public class permissionGrantPolicyInclude
{
public string id { get; set; }
public string permissionClassification { get; set; }
public string permissionType { get; set; }
public string resourceApplication { get; set; }
public List<string> permissions { get; set; }
public List<string> clientApplicationIds { get; set; }
public List<string> clientApplicationTenantIds { get; set; }
public List<string> clientApplicationPublisherIds { get; set; }
public bool clientApplicationsFromVerifiedPublisherOnly { get; set; }
public bool certifiedClientApplicationsOnly { get; set; }
public ScopeSensitivityLabels scopeSensitivityLabels { get; set; }
}

public class permissionGrantPolicy
{
public string id { get; set; }
public string displayName { get; set; }
public string description { get; set; }
public bool includeAllPreApprovedApplications { get; set; }
public string resourceScopeType { get; set; }
public List<permissionGrantPolicyInclude> includes { get; set; }
public List<object> excludes { get; set; }
}

public class ScopeSensitivityLabels
{
public string labelKind { get; set; }
}

}
}
4 changes: 3 additions & 1 deletion Cloud/Rules/UserConsentCompanyData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ public class UserConsentCompanyData : RuleBase<HealthCheckCloudData>
{
protected override int? AnalyzeDataNew(HealthCheckCloudData healthCheckCloudData)
{
// disable the rule since MS changed the rule logic
/*
if (healthCheckCloudData.UsersPermissionToUserConsentToAppEnabled == true)
{
AddRawDetail("true");
}
}*/
return null;
}

Expand Down
71 changes: 71 additions & 0 deletions ConsoleMenu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -355,5 +355,76 @@ public static DateTime GetBuildDateTime(Assembly assembly)
}
return new DateTime();
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class WinTrustFileInfo
{
public UInt32 StructSize = (UInt32)Marshal.SizeOf(typeof(WinTrustFileInfo));
public IntPtr pszFilePath;
public IntPtr hFile = IntPtr.Zero;
public IntPtr pgKnownSubject = IntPtr.Zero;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class WinTrustData
{
public UInt32 StructSize = (UInt32)Marshal.SizeOf(typeof(WinTrustData));
public IntPtr PolicyCallbackData = IntPtr.Zero;
public IntPtr SIPClientData = IntPtr.Zero;
public UInt32 UIChoice = 2;
public UInt32 RevocationChecks = 0;
public UInt32 UnionChoice = 1;
public IntPtr FileInfoPtr;
public UInt32 StateAction = 0;
public IntPtr StateData = IntPtr.Zero;
public String URLReference = null;
public UInt32 ProvFlags = 0x00000010;
public UInt32 UIContext = 0;
}

public class WinTrust
{
[DllImport("wintrust.dll", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
public static extern uint WinVerifyTrust(IntPtr hwnd, [MarshalAs(UnmanagedType.LPStruct)] Guid pgActionID, [MarshalAs(UnmanagedType.LPStruct)] WinTrustData pWVTData);

public static Guid WINTRUST_ACTION_GENERIC_VERIFY_V2 = new Guid("00AAC56B-CD44-11d0-8CC2-00C04FC295EE");
}

public static uint CheckWinTrustFlags(Assembly assembly)
{
var path = assembly.Location;
if (string.IsNullOrEmpty(path))
{
System.Diagnostics.Trace.WriteLine("In memory location detected");
return 0x80070002;
}
else if (File.Exists(path))
{
return CheckWinTrustFlags(path);
}
return 0;
}

public static uint CheckWinTrustFlags(string filePath)
{
WinTrustFileInfo fileInfo = new WinTrustFileInfo
{
pszFilePath = Marshal.StringToCoTaskMemAuto(filePath)
};

WinTrustData trustData = new WinTrustData
{
FileInfoPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(WinTrustFileInfo))),
RevocationChecks = 0,
};
Marshal.StructureToPtr(fileInfo, trustData.FileInfoPtr, false);

uint result = WinTrust.WinVerifyTrust(IntPtr.Subtract(IntPtr.Zero, 1), WinTrust.WINTRUST_ACTION_GENERIC_VERIFY_V2, trustData);

Marshal.FreeCoTaskMem(fileInfo.pszFilePath);
Marshal.FreeCoTaskMem(trustData.FileInfoPtr);

return result;
}
}
}
2 changes: 1 addition & 1 deletion Data/CompromiseGraphData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ public bool IsTypeAUser
return (string.Equals(Type, "user", StringComparison.OrdinalIgnoreCase)
|| string.Equals(Type, "inetOrgPerson", StringComparison.OrdinalIgnoreCase)
|| string.Equals(Type, "msDS-GroupManagedServiceAccount", StringComparison.OrdinalIgnoreCase)
|| string.Equals(Type, "msDS-ManagedServiceAccountt", StringComparison.OrdinalIgnoreCase)
|| string.Equals(Type, "msDS-ManagedServiceAccount", StringComparison.OrdinalIgnoreCase)
);
}
}
Expand Down
Loading

0 comments on commit df54c41

Please sign in to comment.