Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ldap simple auth #231

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions certipy/commands/parsers/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,9 @@ def add_argument_group(
"-ldap-channel-binding",
action="store_true",
help="Use LDAP channel binding for LDAP communication (LDAPS only)",
)
group.add_argument(
"-ldap-auth-simple",
action="store_true",
help="Use ldap3.SIMPLE auth type"
)
16 changes: 11 additions & 5 deletions certipy/lib/ldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
from typing import Any, List, Union

import ldap3
from ldap3.core.results import RESULT_STRONGER_AUTH_REQUIRED
from ldap3.protocol.microsoft import security_descriptor_control

from certipy.lib.constants import WELLKNOWN_SIDS
from certipy.lib.kerberos import get_kerberos_type1
from certipy.lib.logger import logging
from certipy.lib.target import Target
from ldap3.core.results import RESULT_STRONGER_AUTH_REQUIRED
from ldap3.protocol.microsoft import security_descriptor_control


# https://github.com/fox-it/BloodHound.py/blob/d665959c58d881900378040e6670fa12f801ccd4/bloodhound/ad/utils.py#L216
Expand Down Expand Up @@ -70,7 +71,12 @@ def __init__(self, target: Target, scheme: str = "ldaps"):
self._user_sids = {}

def connect(self, version: ssl._SSLMethod = None) -> None:
user = "%s\\%s" % (self.target.domain, self.target.username)
if self.target.auth_type == 'simple':
user = f'{self.target.username}@{self.target.domain}'
auth_type = ldap3.SIMPLE
else:
user = "%s\\%s" % (self.target.domain, self.target.username)
auth_type = ldap3.NTLM

if version is None:
try:
Expand Down Expand Up @@ -126,7 +132,7 @@ def connect(self, version: ssl._SSLMethod = None) -> None:
ldap_server,
user=user,
password=ldap_pass,
authentication=ldap3.NTLM,
authentication=auth_type,
auto_referrals=False,
receive_timeout=self.target.timeout * 10,
**channel_binding
Expand All @@ -150,7 +156,7 @@ def connect(self, version: ssl._SSLMethod = None) -> None:
else:
if result["description"] == "invalidCredentials" and result["message"].split(":")[0] == "80090346":
raise Exception(
"Failed to bind to LDAP. LDAP channel binding or signing is required. Use -scheme ldaps -ldap-channel-binding"
"Failed to bind to LDAP. LDAP channel binding or signing is required. Use -scheme ldaps -ldap-channel-binding or try with -ldap-auth-simple"
)
raise Exception(
"Failed to authenticate to LDAP: (%s) %s"
Expand Down
10 changes: 8 additions & 2 deletions certipy/lib/target.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import os
import platform
import socket
from typing import Literal

from certipy.lib.logger import logging
from dns.resolver import Resolver
from impacket.krb5.ccache import CCache

from certipy.lib.logger import logging


def is_ip(hostname: str) -> bool:
try:
Expand Down Expand Up @@ -106,9 +108,10 @@ def get_logon_session():
if platform.system().lower() != "windows":
raise Exception("Cannot use SSPI on non-Windows platform")

from certipy.lib.sspi import get_tgt
from winacl.functions.highlevel import get_logon_info

from certipy.lib.sspi import get_tgt

info = get_logon_info()

logonserver = info["logonserver"]
Expand Down Expand Up @@ -159,13 +162,16 @@ def __init__(self):
self.timeout: int = 5
self.resolver: Resolver = None
self.ldap_channel_binding = None
self.auth_type: Literal['ntlm', 'simple'] = None

@staticmethod
def from_options(
options, dc_as_target: bool = False, ptt: bool = False
) -> "Target":
self = Target()

self.auth_type = 'simple' if options.ldap_auth_simple else 'ntlm'

principal = options.username
domain = ""
if principal is not None:
Expand Down