Skip to content

Commit

Permalink
helping signing scanners, adding timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
SkelSec committed Mar 13, 2024
1 parent bb3691e commit 416affa
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 6 deletions.
2 changes: 1 addition & 1 deletion msldap/_version.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

__version__ = "0.5.9"
__version__ = "0.5.10"
__banner__ = \
"""
# msldap %s
Expand Down
6 changes: 6 additions & 0 deletions msldap/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ def __init__(self, target:MSLDAPTarget, creds:UniCredential, connection = None,
self.target = target
self.keepalive = keepalive
self.ldap_query_page_size = 1000
self._disable_channel_binding = False
self._disable_signing = False
self._null_channel_binding = False
if self.target is not None:
self.ldap_query_page_size = self.target.ldap_query_page_size

Expand Down Expand Up @@ -109,6 +112,9 @@ async def connect(self):
self.disconnected_evt = asyncio.Event()
if self._con is None:
self._con = MSLDAPClientConnection(self.target, self.creds)
self._con._disable_channel_binding = self._disable_channel_binding
self._con._disable_signing = self._disable_signing
self._con._null_channel_binding = self._null_channel_binding
_, err = await self._con.connect()
if err is not None:
raise err
Expand Down
25 changes: 21 additions & 4 deletions msldap/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def __init__(self, target:MSLDAPTarget, credential:UniCredential, auth=None):
self.message_table_notify = {}
self.encryption_sequence_counter = 0 # this will be set by the inderlying auth algo
self.cb_data = None #for channel binding
self._disable_channel_binding = False # putting it here for scanners to be able to turn it off
self._disable_signing = False
self._null_channel_binding = False

if self.credential.protocol == asyauthProtocol.NONE:
self.is_anon = True
Expand Down Expand Up @@ -187,12 +190,15 @@ async def connect(self):
self.connection_closed_evt = asyncio.Event()
packetizer = LDAPPacketizer()
client = UniClient(self.target, packetizer)
self.network = await client.connect()
self.network = await asyncio.wait_for(client.connect(), timeout=self.target.timeout)

# now processing channel binding options
if self.target.protocol == UniProto.CLIENT_SSL_TCP:
certdata = self.network.get_peer_certificate()
self.cb_data = b'tls-server-end-point:' + sha256(certdata).digest()
if self.target.protocol == UniProto.CLIENT_SSL_TCP and self._disable_channel_binding is False:
if self._null_channel_binding is True:
self.cb_data = b'tls-server-end-point:' + sha256(b'').digest()
else:
certdata = self.network.get_peer_certificate()
self.cb_data = b'tls-server-end-point:' + sha256(certdata).digest()

self.handle_incoming_task = asyncio.create_task(self.__handle_incoming())
self.status = MSLDAPClientStatus.CONNECTED
Expand Down Expand Up @@ -250,6 +256,12 @@ async def bind(self):
flags = ISC_REQ.CONNECTION|ISC_REQ.CONFIDENTIALITY|ISC_REQ.INTEGRITY
if self.target.protocol == UniProto.CLIENT_SSL_TCP:
flags = ISC_REQ.CONNECTION

# this switch is for the case when we are using NTLM and we want to disable signing
# useful for testing if the server supports it
if self._disable_signing is True:
flags = ISC_REQ.CONNECTION

data, to_continue, err = await self.auth.authenticate(None, spn=self.target.to_target_string(), flags=flags, cb_data = self.cb_data)
if err is not None:
return None, err
Expand Down Expand Up @@ -385,6 +397,11 @@ async def bind(self):
if self.target.protocol == UniProto.CLIENT_SSL_TCP:
flags = ISC_REQ.CONNECTION

# this switch is for the case when we are using NTLM and we want to disable signing
# useful for testing if the server supports it
if self.credential.protocol == asyauthProtocol.NTLM and self._disable_signing is True:
flags = ISC_REQ.CONNECTION

data, to_continue, err = await self.auth.authenticate(challenge, cb_data = self.cb_data, spn=self.target.to_target_string(), flags=flags)
if err is not None:
raise err
Expand Down
23 changes: 23 additions & 0 deletions msldap/examples/msldapclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ def __init__(self, url = None):
self.adinfo = None
self.ldapinfo = None
self.domain_name = None
self.noisig = False
self.nocb = False
self._disable_channel_binding = False
self._disable_signing = False
self._null_channel_binding = False
self.__current_dirs = {}
self._current_dn = None

Expand All @@ -73,6 +78,9 @@ async def do_login(self, url = None):

self.connection = self.conn_url.get_client()
self.connection.keepalive = True
self.connection._disable_channel_binding = self._disable_channel_binding
self.connection._disable_signing = self._disable_signing
self.connection._null_channel_binding = self._null_channel_binding
_, err = await self.connection.connect()
if err is not None:
raise err
Expand All @@ -88,6 +96,21 @@ async def do_login(self, url = None):
except:
traceback.print_exc()
return False

async def do_nosig(self):
"""Disables signing"""
self._disable_signing = True
return True

async def do_nocb(self):
"""Disables channel binding"""
self._disable_channel_binding = True
return True

async def do_nullcb(self):
"""Sets incorrect channel binding data"""
self._null_channel_binding = True
return True

async def do_ldapinfo(self, show = True):
"""Prints detailed LDAP connection info (DSA)"""
Expand Down
8 changes: 7 additions & 1 deletion msldap/ldap_objects/adinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
'objectGUID', 'objectSid', 'pwdHistoryLength',
'pwdProperties', 'serverState', 'systemFlags', 'uASCompat', 'uSNChanged',
'uSNCreated', 'whenChanged', 'whenCreated', 'rIDManagerReference',
'msDS-Behavior-Version', 'description', 'isDeleted', 'gPLink'
'msDS-Behavior-Version', 'description', 'isDeleted', 'gPLink', 'ms-DS-MachineAccountQuota'
]

class MSADInfo:
Expand Down Expand Up @@ -54,6 +54,7 @@ def __init__(self):
self.description = None
self.isDeleted = None
self.gPLink = None
self.machineAccountQuota = None

@staticmethod
def from_ldap(entry):
Expand Down Expand Up @@ -91,6 +92,7 @@ def from_ldap(entry):
adi.description = entry['attributes'].get('description')
adi.isDeleted = entry['attributes'].get('isDeleted')
adi.gPLink = entry['attributes'].get('gPLink')
adi.machineAccountQuota = entry['attributes'].get('ms-DS-MachineAccountQuota')

#https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/564dc969-6db3-49b3-891a-f2f8d0a68a7f
adi.domainmodelevel = entry['attributes'].get('msDS-Behavior-Version')
Expand Down Expand Up @@ -130,6 +132,7 @@ def to_dict(self):
d['whenCreated'] = self.whenCreated
d['domainmodelevel'] = self.domainmodelevel
d['description'] = self.description
d['ms-DS-MachineAccountQuota'] = self.machineAccountQuota
return d


Expand Down Expand Up @@ -166,6 +169,9 @@ def __str__(self):
t += 'whenCreated: %s\n' % self.whenCreated
t += 'domainmodelevel: %s\n' % self.domainmodelevel
t += 'description: %s\n' % self.description
t += 'isDeleted: %s\n' % self.isDeleted
t += 'gPLink: %s\n' % self.gPLink
t += 'ms-DS-MachineAccountQuota: %s\n' % self.machineAccountQuota
return t

def get_row(self, attrs):
Expand Down

0 comments on commit 416affa

Please sign in to comment.