diff --git a/nxc/protocols/ldap.py b/nxc/protocols/ldap.py index 5de597e3..633a6685 100644 --- a/nxc/protocols/ldap.py +++ b/nxc/protocols/ldap.py @@ -303,16 +303,7 @@ class ldap(connection): self.logger.extra["protocol"] = "LDAP" return True - def kerberos_login( - self, - domain, - username, - password="", - ntlm_hash="", - aesKey="", - kdcHost="", - useCache=False, - ): + def kerberos_login(self, domain, username, password="", ntlm_hash="", aesKey="", kdcHost="", useCache=False): self.username = username self.password = password self.domain = domain @@ -346,20 +337,13 @@ class ldap(connection): try: # Connect to LDAP + self.logger.extra["protocol"] = "LDAPS" if (self.args.gmsa or self.port == 636) else "LDAP" + self.logger.extra["port"] = "636" if (self.args.gmsa or self.port == 636) else "389" proto = "ldaps" if (self.args.gmsa or self.port == 636) else "ldap" ldap_url = f"{proto}://{self.target}" self.logger.info(f"Connecting to {ldap_url} - {self.baseDN} [1]") self.ldapConnection = ldap_impacket.LDAPConnection(ldap_url, self.baseDN) - self.ldapConnection.kerberosLogin( - username, - password, - domain, - self.lmhash, - self.nthash, - aesKey, - kdcHost=kdcHost, - useCache=useCache, - ) + self.ldapConnection.kerberosLogin(username, password, domain, self.lmhash, self.nthash, aesKey, kdcHost=kdcHost, useCache=useCache) if self.username == "": self.username = self.get_ldap_username() @@ -367,11 +351,7 @@ class ldap(connection): self.check_if_admin() used_ccache = " from ccache" if useCache else f":{process_secret(kerb_pass)}" - out = f"{domain}\\{self.username}{used_ccache} {self.mark_pwned()}" - - self.logger.extra["protocol"] = "LDAP" - self.logger.extra["port"] = "636" if (self.args.gmsa or self.port == 636) else "389" - self.logger.success(out) + self.logger.success(f"{domain}\\{self.username}{used_ccache} {self.mark_pwned()}") if not self.args.local_auth and self.username != "": add_user_bh(self.username, self.domain, self.logger, self.config) @@ -404,19 +384,12 @@ class ldap(connection): # We need to try SSL try: # Connect to LDAPS + self.logger.extra["protocol"] = "LDAPS" + self.logger.extra["port"] = "636" ldaps_url = f"ldaps://{self.target}" self.logger.info(f"Connecting to {ldaps_url} - {self.baseDN} [2]") self.ldapConnection = ldap_impacket.LDAPConnection(ldaps_url, self.baseDN) - self.ldapConnection.kerberosLogin( - username, - password, - domain, - self.lmhash, - self.nthash, - aesKey, - kdcHost=kdcHost, - useCache=useCache, - ) + self.ldapConnection.kerberosLogin(username, password, domain, self.lmhash, self.nthash, aesKey, kdcHost=kdcHost, useCache=useCache) if self.username == "": self.username = self.get_ldap_username() @@ -424,11 +397,7 @@ class ldap(connection): self.check_if_admin() # Prepare success credential text - out = f"{domain}\\{self.username} {self.mark_pwned()}" - - self.logger.extra["protocol"] = "LDAPS" - self.logger.extra["port"] = "636" - self.logger.success(out) + self.logger.success(f"{domain}\\{self.username} {self.mark_pwned()}") if not self.args.local_auth and self.username != "": add_user_bh(self.username, self.domain, self.logger, self.config) @@ -472,6 +441,8 @@ class ldap(connection): try: # Connect to LDAP + self.logger.extra["protocol"] = "LDAPS" if (self.args.gmsa or self.port == 636) else "LDAP" + self.logger.extra["port"] = "636" if (self.args.gmsa or self.port == 636) else "389" proto = "ldaps" if (self.args.gmsa or self.port == 636) else "ldap" ldap_url = f"{proto}://{self.target}" self.logger.debug(f"Connecting to {ldap_url} - {self.baseDN} [3]") @@ -480,11 +451,7 @@ class ldap(connection): self.check_if_admin() # Prepare success credential text - out = f"{domain}\\{self.username}:{process_secret(self.password)} {self.mark_pwned()}" - - self.logger.extra["protocol"] = "LDAP" - self.logger.extra["port"] = "636" if (self.args.gmsa or self.port == 636) else "389" - self.logger.success(out) + self.logger.success(f"{domain}\\{self.username}:{process_secret(self.password)} {self.mark_pwned()}") if not self.args.local_auth and self.username != "": add_user_bh(self.username, self.domain, self.logger, self.config) @@ -496,23 +463,16 @@ class ldap(connection): # We need to try SSL try: # Connect to LDAPS + self.logger.extra["protocol"] = "LDAPS" + self.logger.extra["port"] = "636" ldaps_url = f"ldaps://{self.target}" self.logger.info(f"Connecting to {ldaps_url} - {self.baseDN} [4]") self.ldapConnection = ldap_impacket.LDAPConnection(ldaps_url, self.baseDN) - self.ldapConnection.login( - self.username, - self.password, - self.domain, - self.lmhash, - self.nthash, - ) + self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash) self.check_if_admin() # Prepare success credential text - out = f"{domain}\\{self.username}:{process_secret(self.password)} {self.mark_pwned()}" - self.logger.extra["protocol"] = "LDAPS" - self.logger.extra["port"] = "636" - self.logger.success(out) + self.logger.success(f"{domain}\\{self.username}:{process_secret(self.password)} {self.mark_pwned()}") if not self.args.local_auth and self.username != "": add_user_bh(self.username, self.domain, self.logger, self.config) @@ -525,12 +485,15 @@ class ldap(connection): f"{self.domain}\\{self.username}:{process_secret(self.password)} {ldap_error_status[error_code] if error_code in ldap_error_status else ''}", color="magenta" if (error_code in ldap_error_status and error_code != 1) else "red", ) + self.logger.fail("LDAPS channel binding might be enabled, this is only supported with kerberos authentication. Try using '-k'.") else: error_code = str(e).split()[-2][:-1] self.logger.fail( f"{self.domain}\\{self.username}:{process_secret(self.password)} {ldap_error_status[error_code] if error_code in ldap_error_status else ''}", color="magenta" if (error_code in ldap_error_status and error_code != 1) else "red", ) + if proto == "ldaps": + self.logger.fail("LDAPS channel binding might be enabled, this is only supported with kerberos authentication. Try using '-k'.") return False except OSError as e: self.logger.fail(f"{self.domain}\\{self.username}:{process_secret(self.password)} {'Error connecting to the domain, are you sure LDAP service is running on the target?'} \nError: {e}") @@ -567,6 +530,8 @@ class ldap(connection): try: # Connect to LDAP + self.logger.extra["protocol"] = "LDAPS" if (self.args.gmsa or self.port == 636) else "LDAP" + self.logger.extra["port"] = "636" if (self.args.gmsa or self.port == 636) else "389" proto = "ldaps" if (self.args.gmsa or self.port == 636) else "ldap" ldaps_url = f"{proto}://{self.target}" self.logger.info(f"Connecting to {ldaps_url} - {self.baseDN}") @@ -576,8 +541,6 @@ class ldap(connection): # Prepare success credential text out = f"{domain}\\{self.username}:{process_secret(self.nthash)} {self.mark_pwned()}" - self.logger.extra["protocol"] = "LDAP" - self.logger.extra["port"] = "636" if (self.args.gmsa or self.port == 636) else "389" self.logger.success(out) if not self.args.local_auth and self.username != "": @@ -589,6 +552,8 @@ class ldap(connection): if str(e).find("strongerAuthRequired") >= 0: try: # We need to try SSL + self.logger.extra["protocol"] = "LDAPS" + self.logger.extra["port"] = "636" ldaps_url = f"{proto}://{self.target}" self.logger.debug(f"Connecting to {ldaps_url} - {self.baseDN}") self.ldapConnection = ldap_impacket.LDAPConnection(ldaps_url, self.baseDN) @@ -603,8 +568,6 @@ class ldap(connection): # Prepare success credential text out = f"{domain}\\{self.username}:{process_secret(self.nthash)} {self.mark_pwned()}" - self.logger.extra["protocol"] = "LDAPS" - self.logger.extra["port"] = "636" self.logger.success(out) if not self.args.local_auth and self.username != "": @@ -618,12 +581,15 @@ class ldap(connection): f"{self.domain}\\{self.username}:{process_secret(nthash)} {ldap_error_status[error_code] if error_code in ldap_error_status else ''}", color="magenta" if (error_code in ldap_error_status and error_code != 1) else "red", ) + self.logger.fail("LDAPS channel binding might be enabled, this is only supported with kerberos authentication. Try using '-k'.") else: error_code = str(e).split()[-2][:-1] self.logger.fail( f"{self.domain}\\{self.username}:{process_secret(nthash)} {ldap_error_status[error_code] if error_code in ldap_error_status else ''}", color="magenta" if (error_code in ldap_error_status and error_code != 1) else "red", ) + if proto == "ldaps": + self.logger.fail("LDAPS channel binding might be enabled, this is only supported with kerberos authentication. Try using '-k'.") return False except OSError as e: self.logger.fail(f"{self.domain}\\{self.username}:{process_secret(self.password)} {'Error connecting to the domain, are you sure LDAP service is running on the target?'} \nError: {e}") @@ -691,7 +657,7 @@ class ldap(connection): attributes = ["objectSid"] resp = self.search(search_filter, attributes, sizeLimit=0) answers = [] - if resp and self.password != "" and self.username != "": + if resp and (self.password != "" or self.lmhash != "" or self.nthash != "") and self.username != "": for attribute in resp[0][1]: if str(attribute["type"]) == "objectSid": sid = self.sid_to_str(attribute["vals"][0])