main
mpgn 2023-02-12 15:59:52 -05:00
parent ce1293b12c
commit 60a7d8bdc0
1 changed files with 48 additions and 47 deletions

View File

@ -4,8 +4,13 @@
import ldap3 import ldap3
import ssl import ssl
import asyncio import asyncio
from msldap.connection import MSLDAPClientConnection from msldap.connection import MSLDAPClientConnection
from msldap.commons.factory import LDAPConnectionFactory from msldap.commons.target import MSLDAPTarget
from asyauth.common.constants import asyauthProtocol, asyauthSecret
from asyauth.common.credentials.ntlm import NTLMCredential
from asyauth.common.credentials.kerberos import KerberosCredential
class CMEModule: class CMEModule:
''' '''
@ -17,7 +22,7 @@ class CMEModule:
name = 'ldap-checker' name = 'ldap-checker'
description = 'Checks whether LDAP signing and binding are required and / or enforced' description = 'Checks whether LDAP signing and binding are required and / or enforced'
supported_protocols = ['ldap'] supported_protocols = ['ldap']
opsec_safe= True opsec_safe = True
multiple_hosts = True multiple_hosts = True
def options(self, context, module_options): def options(self, context, module_options):
@ -67,28 +72,27 @@ class CMEModule:
#you can determine whether the policy is set to "never" or #you can determine whether the policy is set to "never" or
#if it's set to "when supported" based on the potential #if it's set to "when supported" based on the potential
#error recieved from the bind attempt. #error recieved from the bind attempt.
async def run_ldaps_withEPA(inputUser, inputPassword, dcTarget): async def run_ldaps_withEPA(inputUser, inputPassword, dcTarget):
try: target = MSLDAPTarget(ip=connection.host, hostname=connection.hostname, domain=connection.domain, dc_ip=connection.domain)
url = 'ldaps+ntlm-password://'+inputUser + ':' + inputPassword +'@' + dcTarget stype = asyauthSecret.PASS if not connection.nthash else asyauthSecret.NT
conn_url = LDAPConnectionFactory.from_url(url) secret = connection.password if not connection.nthash else connection.nthash
ldaps_client = conn_url.get_client() credential = NTLMCredential(secret=secret, username=connection.username, domain=connection.domain, stype=stype)
ldapsClientConn = MSLDAPClientConnection(ldaps_client.target, ldaps_client.creds) ldapsClientConn = MSLDAPClientConnection(target, credential)
_, err = await ldapsClientConn.connect() _, err = await ldapsClientConn.connect()
if err is not None: if err is not None:
context.log.error("ERROR while connecting to " + dcTarget + ": " + err) context.log.error("ERROR while connecting to " + dcTarget + ": " + err)
#forcing a miscalculation of the "Channel Bindings" av pair in Type 3 NTLM message #forcing a miscalculation of the "Channel Bindings" av pair in Type 3 NTLM message
ldapsClientConn.cb_data = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ldapsClientConn.cb_data = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
_, err = await ldapsClientConn.bind() _, err = await ldapsClientConn.bind()
if "data 80090346" in str(err): if "data 80090346" in str(err):
return True return True
elif "data 52e" in str(err): elif "data 52e" in str(err):
return False return False
elif err is not None: elif err is not None:
context.log.error("ERROR while connecting to " + dcTarget + ": " + err) context.log.error("ERROR while connecting to " + dcTarget + ": " + err)
elif err is None: elif err is None:
return False return False
except Exception as e:
context.log.error("something went wrong during ldaps_withEPA bind:" + str(e))
#Domain Controllers do not have a certificate setup for #Domain Controllers do not have a certificate setup for
#LDAPS on port 636 by default. If this has not been setup, #LDAPS on port 636 by default. If this has not been setup,
@ -142,27 +146,24 @@ class CMEModule:
exit() exit()
#Run trough all our code blocks to determine LDAP signing and channel binding settings. #Run trough all our code blocks to determine LDAP signing and channel binding settings.
try:
ldapIsProtected = run_ldap(inputUser, inputPassword, dcTarget)
ldapIsProtected = run_ldap(inputUser, inputPassword, dcTarget)
if ldapIsProtected == False:
if ldapIsProtected == False: context.log.highlight("LDAP Signing NOT Enforced!")
context.log.highlight("LDAP Signing NOT Enforced!") elif ldapIsProtected == True:
elif ldapIsProtected == True: context.log.error("LDAP Signing IS Enforced")
context.log.error("LDAP Signing IS Enforced") if DoesLdapsCompleteHandshake(dcTarget) == True:
if DoesLdapsCompleteHandshake(dcTarget) == True: ldapsChannelBindingAlwaysCheck = run_ldaps_noEPA(inputUser, inputPassword, dcTarget)
ldapsChannelBindingAlwaysCheck = run_ldaps_noEPA(inputUser, inputPassword, dcTarget) ldapsChannelBindingWhenSupportedCheck = asyncio.run(run_ldaps_withEPA(inputUser, inputPassword, dcTarget))
ldapsChannelBindingWhenSupportedCheck = asyncio.run(run_ldaps_withEPA(inputUser, inputPassword, dcTarget)) if ldapsChannelBindingAlwaysCheck == False and ldapsChannelBindingWhenSupportedCheck == True:
if ldapsChannelBindingAlwaysCheck == False and ldapsChannelBindingWhenSupportedCheck == True: context.log.highlight('Channel Binding is set to \"when supported\" - Success of Attacks depends on client settings')
context.log.highlight('Channel Binding is set to \"when supported\" - Success of Attacks depends on client settings') elif ldapsChannelBindingAlwaysCheck == False and ldapsChannelBindingWhenSupportedCheck == False:
elif ldapsChannelBindingAlwaysCheck == False and ldapsChannelBindingWhenSupportedCheck == False: context.log.highlight('Channel Binding is set to \"NEVER\" - Time to PWN!')
context.log.highlight('Channel Binding is set to \"NEVER\" - Time to PWN!') elif ldapsChannelBindingAlwaysCheck == True:
elif ldapsChannelBindingAlwaysCheck == True: context.log.error('Channel Binding is set to \"Required\" - Meeeehhhh :(')
context.log.error('Channel Binding is set to \"Required\" - Meeeehhhh :(')
else:
context.log.error("\nSomething went wrong...")
exit()
else: else:
context.log.error(dcTarget + " - cannot complete TLS handshake, cert likely not configured") context.log.error("\nSomething went wrong...")
except Exception as e: exit()
context.log.error("ERROR: " + str(e)) else:
context.log.error(dcTarget + " - cannot complete TLS handshake, cert likely not configured")