渗透基础——通过LDAP协议暴力破解域用户的口令

0x00 前言


在域渗透中,如果已经掌握了一些域用户的口令,通常会选择寻找口令规律,生成字典文件,尝试对其他域用户的口令进行暴力破解。

站在防御的角度,需要确保域用户没有使用存在规律的弱口令,也需要能够发现暴力破解域用户口令的行为。

本文将要分别介绍在域内和域外暴力破解域用户口令的常用方法,结合利用思路,介绍检测方法。

0x01 简介


本文将要介绍以下内容:

  • 域内暴力破解域用户口令的方法
  • 域外暴力破解域用户口令的方法
  • 检测方法

0x02 暴力破解域用户口令需要注意的问题


多次口令输入错误会导致用户帐户被锁定,默认设置的错误次数为5

用户帐户被锁定后,默认需要等待30分钟才能恢复使用

最后一次口令输入错误的时间会被记录,无法通过修改LDAP数据进行清除,提示如下:

Error 0x209A Access to the attribute is not permitted because the attribute is owned by the Security Accounts Manager (SAM).

用户帐户被锁定后,即使输入正确的口令,也会提示口令错误

0x03 域内暴力破解域用户口令的方法


1.获得域内用户的口令策略,避免帐户被锁定

获取口令策略的详细方法可参考上篇文章《渗透基础——域内用户口令策略的获取》

2.获得所有域用户的列表

获取的详细方法可参考之前的文章《渗透基础——活动目录信息的获取》

这里需要额外对用户的属性进行判断,去除被禁用和被锁定的用户

(1)识别被禁用的用户

标识用户是否被禁用的位置位于userAccountControl属性中,具体的位置为0x0002

如下图

Alt text

参考资料:

https://support.microsoft.com/en-us/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties

使用PowerView查看所有用户的ACCOUNTDISABLE属性,命令如下:

Get-NetUser | select name,useraccountcontrol

输出结果如下图

Alt text

查看指定用户ACCOUNTDISABLE属性的具体值,命令如下:

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

输出结果如下图

Alt text

能够获得用户test2具有以下属性:

  • ACCOUNTDISABLE
  • NORMAL_ACCOUNT
  • DONT_EXPIRE_PASSWORD

(2)识别被锁定的用户

虽然用户的ACCOUNTDISABLE属性中偏移0x0010处标记为LOCKOUT,如下图

Alt text

但这个位置的值并不能用来判断当前用户是否被锁定

我们可以通过读取用户的badPwdCount属性和lockoutTime属性进行判断

使用PowerView查看所有用户的badPwdCount属性和lockoutTime属性,命令如下:

Get-NetUser | select name,badPwdCount,lockoutTime

输出结果如下图

Alt text

很明显,可以发现用户testa处于被锁定的状态

3.使用DomainPasswordSpray进行口令爆破

地址:

https://github.com/dafthack/DomainPasswordSpray

原理:通过ADSI(ActiveDirectoryServicesInterface)(活动目录服务接口)尝试进行LDAP查询,获得结果

实例如下:

Invoke-DomainPasswordSpray -UserList .\users.txt -Password DomainUser123! -Verbose 

输出结果如下图

Alt text

注:

DomainPasswordSpray支持筛选用户的功能,获得所有用户的列表,排除被禁用和被锁定的用户

命令如下:

Get-DomainUserList -RemoveDisabled -RemovePotentialLockouts

我在我的测试环境(dc:Server2012R2)下这个功能出现bug,无法识别出被锁定的用户testa

如下图

Alt text

实际上用户testa的状态被锁定,如下图

Alt text

Alt text

个人猜测产生bug的原因如下:

DomainPasswordSpray通过用户的ACCOUNTDISABLE属性中偏移0x0010处(标记为LOCKOUT)来判断用户是否被锁定,对应代码位置:https://github.com/dafthack/DomainPasswordSpray/blob/master/DomainPasswordSpray.ps1#L408

我的测试环境下得出的结论是不能通过这个值进行判断,正确的方法是通过badPwdCount属性和lockoutTime属性进行识别

0x04 域外暴力破解域用户口令的方法


1.Kali系统通过ldapsearch暴力破解域用户口令

在之前的文章文章《渗透基础——活动目录信息的获取》介绍了kali系统下使用ldapsearch连接LDAP服务器的方法

这里可以简单的加一个循环实现暴力破解,完整的bash命令如下:

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

test.txt保存所有用户名,如果口令正确,输出查询结果的个数,如果口令错误,返回验证错误:ldap_bind: Invalid credentials (49)

输出结果如下图

Alt text

成功暴力破解出用户testb的口令

2.Windows系统通过Invoke-DomainPasswordSprayOutsideTheDomain暴力破解域用户口令

DomainPasswordSpray的功能比较完整,但不支持域外的使用,所以我在DomainPasswordSpray的基础上做了一些修改,使其支持域外的使用

具体修改的位置如下:

原版中修改LDAP查询的语句:

$DomainContext = New-Object System.DirectoryServices.ActiveDirectory.DirectoryContext("domain",$Domain)
$DomainObject = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($DomainContext)
$CurrentDomain = "LDAP://" + ([ADSI]"LDAP://$Domain").distinguishedName

替换为LDAP的查询语句,示例:"192.168.1.1/DC=test,DC=com"

最终的完整查询语句为:LDAP://192.168.1.1/DC=test,DC=com

由于是在域外进行暴力破解,无法获得域用户的口令策略,所以我移除了DomainPasswordSpray中获得口令策略的功能

我已经将修改后的代码上传至github,地址如下:

https://github.com/3gstudent/Homework-of-Powershell/blob/master/Invoke-DomainPasswordSprayOutsideTheDomain.ps1

域外使用的示例命令如下:

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

输出结果如下图

Alt text

0x05 利用思路


1.域内暴力破解域用户口令

流程如下:

(1)获得域内用户的口令策略

根据lockoutThreshold的数值决定尝试的次数,避免帐户被锁定

(2)获得域用户列表

列出所有域用户后,需要对用户的属性进行判断,去除被禁用和被锁定的用户

(3)尝试破解

2.域外暴力破解域用户口令

如果已经获得了一个用户的口令,那么可以先读取域内用户的口令策略和用户列表,方法同上

如果没有任何用户的口令,只能进行盲目的尝试

0x06 检测方法


域用户属性中的lastbadpasswordattempt能够记录上次口令输入错误的登陆时间,这可以作为识别暴力破解攻击的依据

badPwdCount属性会记录用户口令错误的次数,但是用户输入正确的口令后,这个属性会被清零,无法作为判断的依据

如果攻击者从域内发起攻击,那么攻击者已经掌握了域内用户的口令策略和用户列表,站在防御的角度,需要确保域内用户的口令不存在规律,避免多个用户使用同一口令的情况

日志(4625 - An account failed to log on)能够记录登录失败的事件,例如Kali系统通过ldapsearch暴力破解域用户口令时产生的日志如下图

Alt text

使用kerbrute进行暴力破解不会产生日志(4625 - An account failed to log on),但是可以通过日志(4768 - A Kerberos authentication ticket (TGT) was requested和4771 - Kerberos pre-authentication failed)记录

0x07 小结


本文分别介绍了在域内和域外暴力破解域用户口令的常用方法,介绍了我在测试DomainPasswordSpray时发现的一个bug(需要在更多的环境进行测试),基于DomainPasswordSpray实现了域外暴力破解,结合利用思路,介绍检测方法。


LEAVE A REPLY

Written on December 26, 2019