Wrapper for LDAP search using impacket
(self, search_base, search_filter, attributes=None, size_limit=0)
| 447 | return all_results |
| 448 | |
| 449 | def search(self, search_base, search_filter, attributes=None, size_limit=0): |
| 450 | """Wrapper for LDAP search using impacket""" |
| 451 | try: |
| 452 | from impacket.ldap.ldap import LDAPConnection |
| 453 | from impacket.ldap import ldapasn1 |
| 454 | |
| 455 | # Create LDAP connection - try to get NetBIOS name for proper Kerberos SPN |
| 456 | target_host = self._resolve_dc_hostname(self.impacket_auth.target) |
| 457 | logger.debug(f"Using target {target_host} for LDAP connection") |
| 458 | |
| 459 | # Try to connect with resolved hostname (NetBIOS), fallback to original if it fails |
| 460 | ldapConnection = None |
| 461 | connection_error = None |
| 462 | try: |
| 463 | ldapConnection = LDAPConnection(f'ldap://{target_host}') |
| 464 | except Exception as e: |
| 465 | connection_error = e |
| 466 | logger.debug(f"Failed to connect to {target_host}: {e}") |
| 467 | if target_host != self.impacket_auth.target: |
| 468 | logger.debug(f"Falling back to original hostname: {self.impacket_auth.target}") |
| 469 | try: |
| 470 | ldapConnection = LDAPConnection(f'ldap://{self.impacket_auth.target}') |
| 471 | target_host = self.impacket_auth.target # Update for subsequent operations |
| 472 | except Exception as e2: |
| 473 | logger.error(f"Failed to connect to original hostname {self.impacket_auth.target}: {e2}") |
| 474 | raise |
| 475 | else: |
| 476 | raise |
| 477 | |
| 478 | # Authenticate based on available credentials |
| 479 | if self.impacket_auth.use_kerberos and self.impacket_auth.kerberos_ticket: |
| 480 | if not self.impacket_auth._load_kerberos_ticket(): |
| 481 | return [] |
| 482 | |
| 483 | # Try direct Kerberos LDAP authentication first |
| 484 | try: |
| 485 | logger.debug("Attempting direct Kerberos LDAP authentication") |
| 486 | ldapConnection.kerberosLogin( |
| 487 | self.impacket_auth.username, |
| 488 | self.impacket_auth.password, |
| 489 | self.impacket_auth.domain, |
| 490 | lmhash='', nthash='', aesKey='', kdcHost=self.impacket_auth.target, |
| 491 | useCache=True |
| 492 | ) |
| 493 | |
| 494 | # Perform the search with split search to handle large result sets |
| 495 | all_results = [] |
| 496 | |
| 497 | # Try regular search first |
| 498 | try: |
| 499 | resp = ldapConnection.search( |
| 500 | searchBase=search_base, |
| 501 | scope=2, |
| 502 | searchFilter=search_filter, |
| 503 | attributes=attributes if attributes else ['*'], |
| 504 | sizeLimit=0 |
| 505 | ) |
| 506 |