from termcolor import colored NT35_BDC_CONTINUOUS_UPDATE = 0b10 RC4_SUPPORT = 0b100 BDC_HANDLING_CHANGELOGS = 0b10000 RESTARTING_FULL_DC_SYNC = 0b100000 NO_VALIDATION_LEVEL_2_FOR_NON_GENERIC_PASSTHROUGH = 0b10000000 DATABASE_REDO = 0b10000000 REFUSAL_OF_PASSWORD_CHANGES = 0b100000000 NETRLOGON_SEND_TO_SAM = 0b1000000000 GENERIC_PASS_THROUGH = 0b10000000000 CONCURRENT_RPC_CALLS = 0b100000000000 AVOID_USER_ACCOUNT_DATABASE_REPLICATION = 0b1000000000000 AVOID_SECURITY_AUTHORITY_DATABASE_REPLICATION = 0b10000000000000 STRONG_KEYS = 0b100000000000000 TRANSITIVE_TRUSTS = 0b1000000000000000 NETR_SERVER_PASSWORD_SET2 = 0b100000000000000000 NETR_LOGON_GET_DOMAIN_INFO = 0b1000000000000000000 CROSS_FOREST_TRUSTS = 0b10000000000000000000 NO_NT4_EMULATION = 0b100000000000000000000 RODC_PASS_THROUGH = 0b1000000000000000000000 AES_128_BIT_CFB_AND_SHA2 = 0b1000000000000000000000000 AUTHENTICATED_RPC_VIA_LSASS_SUPPORTED = 0b100000000000000000000000000000 SECURE_RPC_AUTHENTICATION = 0b1000000000000000000000000000000 KERBEROS_FOR_SECURE_CHANNEL_SETUP = 0b10000000000000000000000000000000 # 3.1.4.2 Netlogon Negotiate Options class FLAGS: def __init__(self, flag: int): self.flag = flag if flag < 0 or flag > 0xFFFFFFFF: raise ValueError("Flags must be a 32-bit unsigned integer.") self.flag_values = { 0b1: "A IGNORED (Account lockout)", 0b10: "B NT3.5 BDC continuous update", 0b100: "C RC4 support", 0b1000: "D IGNORED (Promotion count(deprecated))", 0b10000: "E Supports BDC handling Changelogs", 0b100000: "F Supports Restarting full DC sync", 0b1000000: "G Does not require ValidationLevel 2 for nongeneric passthrough", 0b10000000: "H Supports DatabaseRedo", 0b100000000: "I Supports refusal of password changes", 0b1000000000: "J Supports NetrLogonSendToSam", 0b10000000000: "K Supports generic pass-through", 0b100000000000: "L Supports concurrent RPC calls", 0b1000000000000: "M Supports avoid of user account database replication", 0b10000000000000: "N Supports avoid of Security Authority database replication", 0b100000000000000: "O Supports Strong keys", 0b1000000000000000: "P Supports transitive trusts", 0b10000000000000000: "Q IGNORED (Supports DNS trusts)", 0b100000000000000000: "R Supports NetrServerPasswordSet2", 0b1000000000000000000: "S Supports NetrLogonGetDomainInfo", 0b10000000000000000000: "T Supports cross-forest trusts", 0b100000000000000000000: "U No NT4 Emulation", 0b1000000000000000000000: "V Supports RODC pass-through", 0b10000000000000000000000: "0", 0b100000000000000000000000: "0", 0b1000000000000000000000000: "W Supports AES 128-bit CFB and SHA2", 0b10000000000000000000000000: "0", 0b100000000000000000000000000: "0", 0b1000000000000000000000000000: "0", 0b10000000000000000000000000000: "0", 0b100000000000000000000000000000: "X IGNORED (Authenticated RPC via lsass supported)", 0b1000000000000000000000000000000: "Y Supports secure RPC authentication", 0b10000000000000000000000000000000: "Z Supports Kerberos for secure channel setup", } def compare(self, other): if not isinstance(other, FLAGS): raise TypeError("Comparison is only supported with another FLAGS instance.") if self.flag == other.flag: return "Equal" else: out = "Self - Other - Difference:\n" for i in range(1, 33): if (self.flag & (1 << i)) != (other.flag & (1 << i)): out += f"{(self.flag & (1 << i)) >> i} - {(other.flag & (1 << i)) >> i}: {self.flag_values[1 << i]}\n" return out def set_bit(self, flag: int): if flag < 0 or flag > 0xFFFFFFFF: raise ValueError("Flags must be a 32-bit unsigned integer.") self.flag |= flag def unset_bit(self, flag: int): if flag < 0 or flag > 0xFFFFFFFF: raise ValueError("Flags must be a 32-bit unsigned integer.") self.flag &= ~flag def __str__(self): out = "" out += f"{self.flag & 1}: A IGNORED (Account lockout)" out += f"\n{(self.flag & 2) >> 1}: B NT3.5 BDC continuous update" out += f"\n{(self.flag & 4) >> 2}: C RC4 support" out += f"\n{(self.flag & 8) >> 3}: D IGNORED (Promotion count(deprecated))" out += f"\n{(self.flag & 0x10) >> 4}: E Supports BDC handling Changelogs" out += f"\n{(self.flag & 0x20) >> 5}: F Supports Restarting full DC sync" out += f"\n{(self.flag & 0x40) >> 6}: G Does not require ValidationLevel 2 for nongeneric passthrough" out += f"\n{(self.flag & 0x80) >> 7}: H Supports DatabaseRedo" out += f"\n{(self.flag & 0x100) >> 8}: I Supports refusal of password changes" out += f"\n{(self.flag & 0x200) >> 9}: J Supports NetrLogonSendToSam" out += f"\n{(self.flag & 0x400) >> 10}: K Supports generic pass-through" out += f"\n{(self.flag & 0x800) >> 11}: L Supports concurrent RPC calls" out += f"\n{(self.flag & 0x1000) >> 12}: M Supports avoid of user account database replication" out += f"\n{(self.flag & 0x2000) >> 13}: N Supports avoid of Security Authority database replication" out += f"\n{(self.flag & 0x4000) >> 14}: O Supports Strong keys" out += f"\n{(self.flag & 0x8000) >> 15}: P Supports transitive trusts" out += f"\n{(self.flag & 0x10000) >> 16}: Q IGNORED (Supports DNS trusts)" out += f"\n{(self.flag & 0x20000) >> 17}: R Supports NetrServerPasswordSet2" out += f"\n{(self.flag & 0x40000) >> 18}: S Supports NetrLogonGetDomainInfo" out += f"\n{(self.flag & 0x80000) >> 19}: T Supports cross-forest trusts" out += f"\n{(self.flag & 0x100000) >> 20}: U No NT4 Emulation" out += f"\n{(self.flag & 0x200000) >> 21}: V Supports RODC pass-through" out += f"\n{(self.flag & 0x400000) >> 22}: 0" out += f"\n{(self.flag & 0x800000) >> 23}: 0" out += f"\n{(self.flag & 0x1000000) >> 24}: W Supports AES 128-bit CFB and SHA2" out += f"\n{(self.flag & 0x2000000) >> 25}: 0" out += f"\n{(self.flag & 0x4000000) >> 26}: 0" out += f"\n{(self.flag & 0x8000000) >> 27}: 0" out += f"\n{(self.flag & 0x10000000) >> 28}: 0" out += f"\n{(self.flag & 0x20000000) >> 29}: X IGNORED (Authenticated RPC via lsass supported)" out += f"\n{(self.flag & 0x40000000) >> 30}: Y Supports secure RPC authentication" out += f"\n{(self.flag & 0x80000000) >> 31}: Z Supports Kerberos for secure channel setup" return out def __eq__(self, value): if not isinstance(value, FLAGS): return NotImplemented return self.flag == value.flag def log(message, color=None): """Simple logging function to print messages.""" if color: if color == "blue": print(f"{colored('[*]', 'blue', attrs=['bold'])} {message}") elif color == "orange": print(f"{colored('[!]', 'yellow', attrs=['bold'])} {message}") else: print(colored(f"{message}", color, attrs=["bold"])) else: print(f"{colored('[+]', 'green', attrs=['bold'])} {message}")