1- from dateutil .relativedelta import relativedelta as rd
2- from impacket .ldap import ldapasn1 as ldapasn1_impacket
3-
41
52class NXCModule :
63 """
@@ -21,90 +18,4 @@ def options(self, context, module_options):
2118 """No options available."""
2219
2320 def on_login (self , context , connection ):
24- # Are there even any FGPPs?
25- context .log .success ("Attempting to enumerate policies..." )
26- resp = connection .ldap_connection .search (searchBase = f"CN=Password Settings Container,CN=System,{ '' .join ([f'DC={ dc } ,' for dc in connection .domain .split ('.' )]).rstrip (',' )} " , searchFilter = "(objectclass=*)" )
27- if len (resp ) > 1 :
28- context .log .highlight (f"{ len (resp ) - 1 } PSO Objects found!" )
29- context .log .highlight ("" )
30- context .log .success ("Attempting to enumerate objects with an applied policy..." )
31-
32- # Who do they apply to?
33- resp = connection .search (searchFilter = "(objectclass=*)" , attributes = ["DistinguishedName" , "msDS-PSOApplied" ])
34- for attrs in resp :
35- if isinstance (attrs , ldapasn1_impacket .SearchResultEntry ) is not True :
36- continue
37- for attr in attrs ["attributes" ]:
38- if str (attr ["type" ]) in "msDS-PSOApplied" :
39- context .log .highlight (f"Object: { attrs ['objectName' ]} " )
40- context .log .highlight ("Applied Policy: " )
41- for value in attr ["vals" ]:
42- context .log .highlight (f"\t { value } " )
43- context .log .highlight ("" )
44-
45- # Let"s find out even more details!
46- context .log .success ("Attempting to enumerate details...\n " )
47- resp = connection .search (searchFilter = "(objectclass=msDS-PasswordSettings)" ,
48- attributes = ["name" , "msds-lockoutthreshold" , "msds-psoappliesto" , "msds-minimumpasswordlength" ,
49- "msds-passwordhistorylength" , "msds-lockoutobservationwindow" , "msds-lockoutduration" ,
50- "msds-passwordsettingsprecedence" , "msds-passwordcomplexityenabled" , "Description" ,
51- "msds-passwordreversibleencryptionenabled" , "msds-minimumpasswordage" , "msds-maximumpasswordage" ])
52- for attrs in resp :
53- if not isinstance (attrs , ldapasn1_impacket .SearchResultEntry ):
54- continue
55- policyName , description , passwordLength , passwordhistorylength , lockoutThreshold , observationWindow , lockoutDuration , complexity , minPassAge , maxPassAge , reverseibleEncryption , precedence , policyApplies = ("" ,) * 13
56- for attr in attrs ["attributes" ]:
57- if str (attr ["type" ]) == "name" :
58- policyName = attr ["vals" ][0 ]
59- elif str (attr ["type" ]) == "msDS-LockoutThreshold" :
60- lockoutThreshold = attr ["vals" ][0 ]
61- elif str (attr ["type" ]) == "msDS-MinimumPasswordLength" :
62- passwordLength = attr ["vals" ][0 ]
63- elif str (attr ["type" ]) == "msDS-PasswordHistoryLength" :
64- passwordhistorylength = attr ["vals" ][0 ]
65- elif str (attr ["type" ]) == "msDS-LockoutObservationWindow" :
66- observationWindow = attr ["vals" ][0 ]
67- elif str (attr ["type" ]) == "msDS-LockoutDuration" :
68- lockoutDuration = attr ["vals" ][0 ]
69- elif str (attr ["type" ]) == "msDS-PasswordSettingsPrecedence" :
70- precedence = attr ["vals" ][0 ]
71- elif str (attr ["type" ]) == "msDS-PasswordComplexityEnabled" :
72- complexity = attr ["vals" ][0 ]
73- elif str (attr ["type" ]) == "msDS-PasswordReversibleEncryptionEnabled" :
74- reverseibleEncryption = attr ["vals" ][0 ]
75- elif str (attr ["type" ]) == "msDS-MinimumPasswordAge" :
76- minPassAge = attr ["vals" ][0 ]
77- elif str (attr ["type" ]) == "msDS-MaximumPasswordAge" :
78- maxPassAge = attr ["vals" ][0 ]
79- elif str (attr ["type" ]) == "description" :
80- description = attr ["vals" ][0 ]
81- elif str (attr ["type" ]) == "msDS-PSOAppliesTo" :
82- policyApplies = ""
83- for value in attr ["vals" ]:
84- policyApplies += f"{ value } ;"
85- context .log .highlight (f"Policy Name: { policyName } " )
86- if description :
87- context .log .highlight (f"Description: { description } " )
88- context .log .highlight (f"Minimum Password Length: { passwordLength } " )
89- context .log .highlight (f"Minimum Password History Length: { passwordhistorylength } " )
90- context .log .highlight (f"Lockout Threshold: { lockoutThreshold } " )
91- context .log .highlight (f"Observation Window: { mins (observationWindow )} " )
92- context .log .highlight (f"Lockout Duration: { mins (lockoutDuration )} " )
93- context .log .highlight (f"Complexity Enabled: { complexity } " )
94- context .log .highlight (f"Minimum Password Age: { days (minPassAge )} " )
95- context .log .highlight (f"Maximum Password Age: { days (maxPassAge )} " )
96- context .log .highlight (f"Reversible Encryption: { reverseibleEncryption } " )
97- context .log .highlight (f"Precedence: { precedence } (Lower is Higher Priority)" )
98- context .log .highlight ("Policy Applies to:" )
99- for value in str (policyApplies )[:- 1 ].split (";" ):
100- if value :
101- context .log .highlight (f"\t { value } " )
102- context .log .highlight ("" )
103-
104-
105- def days (ldap_time ):
106- return f"{ rd (seconds = int (abs (int (ldap_time )) / 10000000 )).days } days"
107-
108-
109- def mins (ldap_time ):
110- return f"{ rd (seconds = int (abs (int (ldap_time )) / 10000000 )).minutes } minutes"
21+ context .log .fail ("[REMOVED] This module moved to the core option --pso" )
0 commit comments