LDAP Anonymous Bind
1. 介绍
LDAP 匿名绑定是攻击者无需认证即可从 Active Directory 域获取信息的另一种方法。
这在 Windows Server 2000 域控制器上是默认开启的,之后的版本就不再默认开启了
但由于 Pre-Windows 2000 Compatible Access 组的缘故。从之前的版本迭代升级的域控仍然会保留之前的配置
2. 修复:
清除 AD 中目录服务对象内的 dsHeuristics 属性值。当该值设置为 0000002 时,允许匿名绑定。移除即可禁用匿名绑定
此外,还应确保 ANONYMOUS LOGON 对 Users CN 或其他对象(包括域对象本身)没有读取权限。
下面是一个修复脚本
# 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 作为命名上下文
浏览至 CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=yourdomain,DC=com ,右键点击 CN=Directory Service 并选择 Properties
进入 Attribute Editor 后,向下滚动找到 dsHeuristics 属性并清空其值。
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



