diff --git a/examples/dacledit.py b/examples/dacledit.py index f5c729bda5..71d59fa6bb 100755 --- a/examples/dacledit.py +++ b/examples/dacledit.py @@ -716,6 +716,7 @@ def parse_args(): parser = argparse.ArgumentParser(add_help=True, description='Python editor for a principal\'s DACL.') parser.add_argument('identity', action='store', help='domain.local/username[:password]') parser.add_argument('-use-ldaps', action='store_true', help='Use LDAPS instead of LDAP') + parser.add_argument('-use-channel-binding', action='store_true', help='Enable LDAPS Channel Binding') parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output') parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') @@ -769,7 +770,7 @@ def main(): domain, username, password, lmhash, nthash, args.k = parse_identity(args.identity, args.hashes, args.no_pass, args.aesKey, args.k) try: - ldap_server, ldap_session = init_ldap_session(domain, username, password, lmhash, nthash, args.k, args.dc_ip, args.dc_host, args.aesKey, args.use_ldaps) + ldap_server, ldap_session = init_ldap_session(domain, username, password, lmhash, nthash, args.k, args.dc_ip, args.dc_host, args.aesKey, args.use_ldaps, args.use_channel_binding) dacledit = DACLedit(ldap_server, ldap_session, args) if args.action == 'read': dacledit.read() diff --git a/examples/owneredit.py b/examples/owneredit.py index cb9c78a5cb..2a60147217 100644 --- a/examples/owneredit.py +++ b/examples/owneredit.py @@ -230,6 +230,7 @@ def parse_args(): parser = argparse.ArgumentParser(add_help=True, description='Python editor for a principal\'s DACL.') parser.add_argument('identity', action='store', help='domain.local/username[:password]') parser.add_argument('-use-ldaps', action='store_true', help='Use LDAPS instead of LDAP') + parser.add_argument('-use-channel-binding', action='store_true', help='Enable LDAPS Channel Binding') parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output') parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') @@ -278,7 +279,7 @@ def main(): domain, username, password, lmhash, nthash, args.k = parse_identity(args.identity, args.hashes, args.no_pass, args.aesKey, args.k) try: - ldap_server, ldap_session = init_ldap_session(domain, username, password, lmhash, nthash, args.k, args.dc_ip, args.dc_host, args.aesKey, args.use_ldaps) + ldap_server, ldap_session = init_ldap_session(domain, username, password, lmhash, nthash, args.k, args.dc_ip, args.dc_host, args.aesKey, args.use_ldaps, args.use_channel_binding) owneredit = OwnerEdit(ldap_server, ldap_session, args) if args.action == 'read': owneredit.read() diff --git a/examples/rbcd.py b/examples/rbcd.py index 1e7e059036..e3a88026dd 100755 --- a/examples/rbcd.py +++ b/examples/rbcd.py @@ -272,6 +272,7 @@ def parse_args(): help='Action to operate on msDS-AllowedToActOnBehalfOfOtherIdentity') parser.add_argument('-use-ldaps', action='store_true', help='Use LDAPS instead of LDAP') + parser.add_argument('-use-channel-binding', action='store_true', help='Enable LDAPS Channel Binding') parser.add_argument('-ts', action='store_true', help='Adds timestamp to every logging output') parser.add_argument('-debug', action='store_true', help='Turn DEBUG output ON') @@ -314,7 +315,7 @@ def main(): domain, username, password, lmhash, nthash, args.k = parse_identity(args.identity, args.hashes, args.no_pass, args.aesKey, args.k) try: - ldap_server, ldap_session = init_ldap_session(domain, username, password, lmhash, nthash, args.k, args.dc_ip, args.dc_host, args.aesKey, args.use_ldaps) + ldap_server, ldap_session = init_ldap_session(domain, username, password, lmhash, nthash, args.k, args.dc_ip, args.dc_host, args.aesKey, args.use_ldaps, args.use_channel_binding) rbcd = RBCD(ldap_server, ldap_session, args.delegate_to) if args.action == 'read': rbcd.read() diff --git a/impacket/examples/utils.py b/impacket/examples/utils.py index ac997b495d..c2b7e205c0 100644 --- a/impacket/examples/utils.py +++ b/impacket/examples/utils.py @@ -210,7 +210,7 @@ def ldap3_kerberos_login(connection, target, user, password, domain='', lmhash=' return True -def _init_ldap_connection(target, use_ssl, domain, username, password, lmhash, nthash, k, dc_ip, aesKey): +def _init_ldap_connection(target, use_ssl, domain, username, password, lmhash, nthash, k, dc_ip, aesKey, use_channel_binding): user = '%s\\%s' % (domain, username) connect_to = target if dc_ip is not None: @@ -218,19 +218,26 @@ def _init_ldap_connection(target, use_ssl, domain, username, password, lmhash, n port = 636 if use_ssl else 389 ldap_server = ldap3.Server(connect_to, get_info=ldap3.ALL, port=port, use_ssl=use_ssl) + channel_binding = dict() + if use_channel_binding: + if not hasattr(ldap3, 'TLS_CHANNEL_BINDING'): + raise RuntimeError('To use LDAP channel binding, install the dev branch of ldap3: pip3 install git+https://github.com/cannatag/ldap3@dev') + if k: + raise RuntimeError('Channel binding is not yet implemented for Kerberos') + channel_binding = dict(channel_binding=ldap3.TLS_CHANNEL_BINDING) if k: - ldap_session = ldap3.Connection(ldap_server) + ldap_session = ldap3.Connection(ldap_server, **channel_binding) ldap_session.bind() ldap3_kerberos_login(ldap_session, target, username, password, domain, lmhash, nthash, aesKey, kdcHost=dc_ip) elif lmhash == '' and nthash == '': - ldap_session = ldap3.Connection(ldap_server, user=user, password=password, authentication=ldap3.NTLM, auto_bind=True) + ldap_session = ldap3.Connection(ldap_server, user=user, password=password, authentication=ldap3.NTLM, auto_bind=True, **channel_binding) else: - ldap_session = ldap3.Connection(ldap_server, user=user, password=lmhash + ":" + nthash, authentication=ldap3.NTLM, auto_bind=True) + ldap_session = ldap3.Connection(ldap_server, user=user, password=lmhash + ":" + nthash, authentication=ldap3.NTLM, auto_bind=True, **channel_binding) return ldap_server, ldap_session -def init_ldap_session(domain, username, password, lmhash, nthash, k, dc_ip, dc_host, aesKey, use_ldaps): +def init_ldap_session(domain, username, password, lmhash, nthash, k, dc_ip, dc_host, aesKey, use_ldaps, use_channel_binding=False): if k: if dc_host is not None: target = dc_host @@ -244,7 +251,7 @@ def init_ldap_session(domain, username, password, lmhash, nthash, k, dc_ip, dc_h else: target = domain - return _init_ldap_connection(target, use_ldaps, domain, username, password, lmhash, nthash, k, dc_ip, aesKey) + return _init_ldap_connection(target, use_ldaps, domain, username, password, lmhash, nthash, k, dc_ip, aesKey, use_channel_binding) # ---------- @@ -342,4 +349,4 @@ def get_connected_socket(ip, port, ipv6=False): s = socket.socket(socket.AF_INET6 if ipv6 else socket.AF_INET) _, address = get_address(ip, port, ipv6) s.connect(address) - return s \ No newline at end of file + return s