渗透基础——域用户的密码永不过期属性
0x00 前言
在域环境中,域用户的凭据是十分重要的信息。为了增强安全性,域组策略会设置所有域用户口令的最长有效时间,到达过期时间后强制用户更改口令。
在实际环境中,有些域用户需要设置为密码永不过期,这可以通过添加密码永不过期属性来实现。
在域渗透中,我们需要枚举出具有密码永不过期属性的域用户,也需要能够将某个域用户设置为密码永不过期。
相对的站在防御角度,我们需要尽可能减少具有密码永不过期属性的域用户,也需要能够实时掌握这个域用户列表。
所以本文将会介绍不同条件下多种枚举、添加和删除密码永不过期属性的方法,分析原理,开源代码。
0x01 简介
本文将要介绍以下内容:
- 实现原理
- 枚举密码设置为永不过期的用户
- 向指定用户添加密码永不过期属性的方法
- 向指定用户删除密码永不过期属性的方法
0x02 实现原理
域用户的密码永不过期属性保存在域用户的 userAccountControl
属性中
userAccountControl 属性使用数字表示,数值是多个具体属性数值的总和
每个具体属性对应一个不同的数值,具体的数值可参考: https://support.microsoft.com/en-us/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties
下面举例进行说明:
用户 test1 的 userAccountControl 属性值为 514,那么这个用户的具体属性如下:
- ACCOUNTDISABLE,2
- NORMAL_ACCOUNT,512
计算方法为 2+512=514
添加密码永不过期属性的方法:
密码永不过期属性对应的值为 65536(DONT_EXPIRE_PASSWORD),将 userAccountControl 属性值 514 再加上 65536,设置为 66048 即可
注:在程序设计上,为了可重复使用,采用的方法是同 65536 作按位或运算( 运算符|
)
按位或运算的运算规则:参加运算的两个数,按二进制位进行或运算,只要对应的二进位有一个为 1 时,结果位就为 1,否则为 0
删除密码永不过期属性的方法:
将 userAccountControl 属性值减去 65536 即可
注:在程序设计上,为了可重复使用,采用的方法是同 65536 作按位异或运算( 运算符^
)
按位异或运算的运算规则:参加运算的两个数,按二进制位进行"异或"运算,如果两个相应位相同,则结果为 0,否则为 1
查看密码永不过期属性的方法:
userAccountControl 属性值是各个数值的总和,我们无法通过简单的加减法计算出 userAccountControl 属性值是否包括 65536 这个被加数
这里可以通过按位与运算( 运算符&
) 来实现
按位与运算的运算规则:参加运算的两个数,按二进制位进行"与"运算,只有两个数的二进制同时为 1,结果才为 1,否则为 0
查看密码永不过期属性的计算方法:
将 userAccountControl 属性值同 65536 做按位与运算,如果结果为 65536,那么代表具有密码永不过期的属性
0x03 枚举密码设置为永不过期的用户
我们在域控制器上,通过 Active Directory Users and Computers
查看每个域用户的 Account
属性,可以看到用户是否设置为密码永不过期,如下图
下面介绍不同环境下的枚举方法
1.从域内进行枚举的方法
(1)Windows 系统使用 Powershell ActiveDirectory 模块
命令示例:
Import-Module ActiveDirectory
Search-ADAccount -PasswordNeverExpires | FT Name
或者:
Import-Module ActiveDirectory
Get-ADUser -filter * -properties Name, PasswordNeverExpires | where {$_.passwordNeverExpires -eq "true" }| FT Name
(2)Windows 系统使用 PowerView
https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1
命令示例:显示出指定用户的属性:
import-module .\PowerView.ps1
Get-NetUser test1| select useraccountcontrol | ConvertFrom-UACValue
如下图
筛选出符合条件的所有用户:
import-module .\PowerView.ps1
ForEach($User in (Get-NetUser))
{
if(($User.useraccountcontrol -band 65536) -eq 65536)
{
Write-Output $User.samaccountname
}
}
(3)Windows 系统使用 C#实现
使用命名空间 System.DirectoryServices
,详细代码已上传至 github,地址如下:https://github.com/3gstudent/Homework-of-C-Sharp/blob/master/List_passwordneverexpires_user_byLDAP.cs
如果使用当前用户的凭据,需要将代码 DirectoryEntry de = new DirectoryEntry("LDAP://" + args[0],args[1],args[2]);
替换为 DirectoryEntry de = new DirectoryEntry("LDAP://" + args[0]);
测试如下图
(4)Kali 系统通过 ldapsearch 枚举
命令示例:
ldapsearch -x -H ldap://192.168.1.1:389 -D "CN=testa,CN=Users,DC=test,DC=com" -w DomainPassword123! -b "DC=test,DC=com" "(&(objectClass=user)(objectCategory=person))" grep userAccountControl
测试如下图
获取 userAccountControl 属性值后再同 65536 做按位与运算,获得最终结果
2.从域外进行枚举的方法
(1)Windows 系统使用 Powershell ActiveDirectory 模块
命令示例:
import-module .\Microsoft.ActiveDirectory.Management.dll
$uname="test1"
$pwd=ConvertTo-SecureString "DomainPassword123!" -AsPlainText –Force
$cred=New-Object System.Management.Automation.PSCredential($uname,$pwd)
Search-ADAccount -Server 192.168.1.1 -Credential $cred -Verbose -PasswordNeverExpires | FT Name
或者:
import-module .\Microsoft.ActiveDirectory.Management.dll
$uname="test1"
$pwd=ConvertTo-SecureString "DomainPassword123!" -AsPlainText –Force
$cred=New-Object System.Management.Automation.PSCredential($uname,$pwd)
Get-ADUser -Server 192.168.1.1 -Credential $cred -filter * -properties Name, PasswordNeverExpires | where {$_.passwordNeverExpires -eq "true" }| FT Name
注:
域控制器默认安装 ActiveDirectory 模块,Microsoft.ActiveDirectory.Management.dll 在安装 powershell 模块 Active Directory 后生成,我已经提取出来并上传至 github:https://github.com/3gstudent/test/blob/master/Microsoft.ActiveDirectory.Management.dll
对于未安装 Active Directory 模块的系统,可以通过如下命令导入 Active Directory 模块:
import-module .\Microsoft.ActiveDirectory.Management.dll
(2)Windows 系统使用 PowerView
https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1
命令示例:
import-module .\PowerView.ps1
$uname="test1"
$pwd=ConvertTo-SecureString "DomainPassword123!" -AsPlainText –Force
$cred=New-Object System.Management.Automation.PSCredential($uname,$pwd)
$Users=Get-NetUser -Domain "test.com" -DomainController 192.168.1.1 -Credential $cred
ForEach($User in $Users)
{
if(($User.useraccountcontrol -band 65536) -eq 65536)
{
Write-Output $User.samaccountname
}
}
(3)Windows 系统使用 C#实现
使用命名空间 System.DirectoryServices,详细代码已上传至 github,地址如下:https://github.com/3gstudent/Homework-of-C-Sharp/blob/master/List_passwordneverexpires_user_byLDAP.cs
0x04 向指定用户添加密码永不过期属性的方法
有以下两种实现方法:
1.userAccountControl 属性值同 65536 作按位或运算( 运算符|
) 2.userAccountControl 属性值直接加上 65536
为了能够重复使用,以下方法均使用同 65536 作按位或运算的方法实现
1.从域内实现
(1) 使用 dsmod 命令
命令实例:
dsmod user "CN=testc,CN=Users,DC=test,DC=com" -pwdneverexpires yes
(2) 使用 Powershell ActiveDirectory 模块
命令实例:
Set-ADUser -Identity testc -PasswordNeverExpires $true
(3) 使用 PowerView
命令实例:
Set-ADObject -SamAccountName testc -PropertyName useraccountcontrol -PropertyXorValue 65536
(4)C#实现
使用命名空间 System.DirectoryServices,详细代码已上传至 github,地址如下:
https://github.com/3gstudent/Homework-of-C-Sharp/blob/master/Add_passwordneverexpires_user_byLDAP.cs
2.从域外实现
(1) 使用 Powershell ActiveDirectory 模块
命令实例:
import-module .\Microsoft.ActiveDirectory.Management.dll
$uname="administrator"
$pwd=ConvertTo-SecureString "DomainPassword123!" -AsPlainText –Force
$cred=New-Object System.Management.Automation.PSCredential($uname,$pwd)
Set-ADUser -Server 192.168.1.1 -Credential $cred -Identity testc -PasswordNeverExpires $true
(2) 使用 PowerView
命令实例:
$uname="administrator"
$pwd=ConvertTo-SecureString "DomainPassword123!" -AsPlainText –Force
$cred=New-Object System.Management.Automation.PSCredential($uname,$pwd)
$Users=Get-NetUser -Domain "test.com" -DomainController 192.168.1.1 -Credential $cred
Set-ADObject -Domain "test.com" -DomainController 192.168.1.1 -Credential $cred -SamAccountName testc -PropertyName useraccountcontrol -PropertyXorValue 65536
(3)C#实现
使用命名空间 System.DirectoryServices
,详细代码已上传至 github,地址如下:https://github.com/3gstudent/Homework-of-C-Sharp/blob/master/Add_passwordneverexpires_user_byLDAP.cs
测试如下图
0x05 向指定用户删除密码永不过期属性的方法
有以下两种实现方法:userAccountControl 属性值同 65536 作按位异或运算( 运算符^
) 2.userAccountControl 属性值直接减去 65536
具体方法同 0x04 类似,不再重复介绍
0x06 小结
本文介绍了域用户具有密码永不过期属性的特征,分析枚举、添加和删除属性的原理,介绍不同条件下的多种实现方法,开源 c#实现代码。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论