Consolidate duplicated auth logic into shared module; add multi-environment test infrastructure#8
Open
Jacob-Strokus wants to merge 3 commits intodepthsecurity:masterfrom
Open
Consolidate duplicated auth logic into shared module; add multi-environment test infrastructure#8Jacob-Strokus wants to merge 3 commits intodepthsecurity:masterfrom
Jacob-Strokus wants to merge 3 commits intodepthsecurity:masterfrom
Conversation
Extract LDAP and RPC authentication logic that was duplicated across 5 files into a single core/auth module with 5 shared functions: - get_base_dn(): domain-to-DN conversion - is_kerberos_error(): Kerberos error detection - connect_ldap(): LDAP connection with auto ldaps fallback - configure_rpc_auth(): RPC transport credential setup - connect_dce(): DCE/RPC bind helper Refactored consumers: - core/target_parser.py: replaced ~80-line auth block - core/creds_checker.py: replaced ~50-line auth loop - detectors/ntlmv1_detector.py: LDAP and RPC auth paths - detectors/ghost_spn.py: LDAP connection logic - detectors/ntlm_reflection.py: RPC auth in 2 methods Also removed dead code left behind: unused SMBConnection import, unreferenced ldap_scheme/ldap_port/ldap_url variables, and orphaned _get_base_dn() method in CredentialChecker. Added 51 pytest tests covering all auth functions and integration scenarios with full dependency mocking for CI environments.
Add tox.ini with stubbed (mock-only) and full (real deps) test matrices across Python 3.8-3.12, plus a lint environment (pyflakes + pycodestyle). Add GitHub Actions workflow (.github/workflows/auth-tests.yml) running: - Stubbed tests: Python 3.8-3.12 x ubuntu/windows (10 combos) - Full dependency tests: Python 3.10-3.12 x ubuntu/windows (6 combos) - Static analysis: pyflakes + pycodestyle on core/auth.py Also add pytest config to pyproject.toml and remove unused transport import from core/auth.py caught by pyflakes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Consolidate duplicated auth logic into shared
core/authmoduleSummary
LDAP and RPC authentication logic was copy-pasted across 5 files with subtle inconsistencies. This PR extracts it into a single shared module (
core/auth), cleans up dead code left behind, and adds a full test suite with multi-environment CI.Motivation
The same authentication patterns — Kerberos login, pass-the-hash, SASL password bind, null/anonymous bind, and
ldap://→ldaps://channel binding fallback — were duplicated intarget_parser.py,creds_checker.py,ntlmv1_detector.py,ghost_spn.py, andntlm_reflection.py. Bug fixes (e.g., channel binding fallback) had to be applied in multiple places and were easy to miss, as seen withntlmv1_detector.check_gpo()which only triedldap://and had noldaps://fallback.Changes
New files
core/auth.pytests/conftest.pytests/test_auth.pytox.ini.github/workflows/auth-tests.ymlShared API (
core/auth)get_base_dn(domain)is_kerberos_error(error)connect_ldap(config, dc_ip=None)ldaps://fallbackconfigure_rpc_auth(config, transport, target)connect_dce(transport, use_kerberos, uuid)Refactored consumers
core/target_parser.py_enumerate_ad()auth block →connect_ldap()core/creds_checker.pyconnect_ldap()+is_kerberos_error()detectors/ntlmv1_detector.pycheck_gpo()+ RPC auth in_get_lm_compat_level()detectors/ghost_spn.py_connect_ldap()body → delegation to shared moduledetectors/ntlm_reflection.py_get_ubr_from_registry()+_check_printspooler_enabled()Dead code removed
from impacket.smbconnection import SMBConnection— imported but never used intarget_parser.pyfrom impacket.dcerpc.v5 import transport— imported but never used inauth.pyldap_scheme,ldap_port,ldap_urlvariables — computed but unreferenced afterconnect_ldap()handles connections internallyCredentialChecker._get_base_dn()— orphaned helper method + unusedget_base_dnimportBug fixes (via consolidation)
ntlmv1_detector.check_gpo()now correctly falls back fromldap://toldaps://on channel binding enforcement — previously it only triedldap://and would fail silently on hardened DCsTest coverage
51 tests covering all auth functions and integration scenarios:
TestGetBaseDn— simple, multi-part, single-label, empty, NoneTestIsKerberosError— 5 Kerberos patterns, 5 non-Kerberos, case sensitivityTestConnectLdapPassword— SASL login, protocol selection, explicit DC overrideTestConnectLdapChannelBindingFallback— autoldaps://retry on80090346TestConnectLdapPassTheHash— empty password + nthash, fallbackTestConnectLdapKerberos—kerberosLogin, uppercase domain, aesKeyTestConnectLdapNull— ldap3 anonymous bind, LDAPS variantTestConnectLdapDcResolution— config fallback, DNS resolution, empty domainTestConfigureRpcAuth— NTLM/Kerberos/PTH credentials,krb_dc_onlylogicTestConnectDce— bind lifecycle, Kerberos auth type, error propagationTestAuthIntegrationScenarios— end-to-end flows mimicking real consumer patternsTests use mock stubs so they run without impacket/ldap3 installed — safe for any CI environment.
CI matrix
How to test locally
Stats