asp.net - valido - viewstate[]
Cómo decodificar viewstate (10)
Aquí está el código fuente de un visualizador ViewState del artículo de Scott Mitchell sobre ViewState (25 páginas)
using System;
using System.Collections;
using System.Text;
using System.IO;
using System.Web.UI;
namespace ViewStateArticle.ExtendedPageClasses
{
/// <summary>
/// Parses the view state, constructing a viaully-accessible object graph.
/// </summary>
public class ViewStateParser
{
// private member variables
private TextWriter tw;
private string indentString = " ";
#region Constructor
/// <summary>
/// Creates a new ViewStateParser instance, specifying the TextWriter to emit the output to.
/// </summary>
public ViewStateParser(TextWriter writer)
{
tw = writer;
}
#endregion
#region Methods
#region ParseViewStateGraph Methods
/// <summary>
/// Emits a readable version of the view state to the TextWriter passed into the object''s constructor.
/// </summary>
/// <param name="viewState">The view state object to start parsing at.</param>
public virtual void ParseViewStateGraph(object viewState)
{
ParseViewStateGraph(viewState, 0, string.Empty);
}
/// <summary>
/// Emits a readable version of the view state to the TextWriter passed into the object''s constructor.
/// </summary>
/// <param name="viewStateAsString">A base-64 encoded representation of the view state to parse.</param>
public virtual void ParseViewStateGraph(string viewStateAsString)
{
// First, deserialize the string into a Triplet
LosFormatter los = new LosFormatter();
object viewState = los.Deserialize(viewStateAsString);
ParseViewStateGraph(viewState, 0, string.Empty);
}
/// <summary>
/// Recursively parses the view state.
/// </summary>
/// <param name="node">The current view state node.</param>
/// <param name="depth">The "depth" of the view state tree.</param>
/// <param name="label">A label to display in the emitted output next to the current node.</param>
protected virtual void ParseViewStateGraph(object node, int depth, string label)
{
tw.Write(System.Environment.NewLine);
if (node == null)
{
tw.Write(String.Concat(Indent(depth), label, "NODE IS NULL"));
}
else if (node is Triplet)
{
tw.Write(String.Concat(Indent(depth), label, "TRIPLET"));
ParseViewStateGraph(((Triplet) node).First, depth+1, "First: ");
ParseViewStateGraph(((Triplet) node).Second, depth+1, "Second: ");
ParseViewStateGraph(((Triplet) node).Third, depth+1, "Third: ");
}
else if (node is Pair)
{
tw.Write(String.Concat(Indent(depth), label, "PAIR"));
ParseViewStateGraph(((Pair) node).First, depth+1, "First: ");
ParseViewStateGraph(((Pair) node).Second, depth+1, "Second: ");
}
else if (node is ArrayList)
{
tw.Write(String.Concat(Indent(depth), label, "ARRAYLIST"));
// display array values
for (int i = 0; i < ((ArrayList) node).Count; i++)
ParseViewStateGraph(((ArrayList) node)[i], depth+1, String.Format("({0}) ", i));
}
else if (node.GetType().IsArray)
{
tw.Write(String.Concat(Indent(depth), label, "ARRAY "));
tw.Write(String.Concat("(", node.GetType().ToString(), ")"));
IEnumerator e = ((Array) node).GetEnumerator();
int count = 0;
while (e.MoveNext())
ParseViewStateGraph(e.Current, depth+1, String.Format("({0}) ", count++));
}
else if (node.GetType().IsPrimitive || node is string)
{
tw.Write(String.Concat(Indent(depth), label));
tw.Write(node.ToString() + " (" + node.GetType().ToString() + ")");
}
else
{
tw.Write(String.Concat(Indent(depth), label, "OTHER - "));
tw.Write(node.GetType().ToString());
}
}
#endregion
/// <summary>
/// Returns a string containing the <see cref="IndentString"/> property value a specified number of times.
/// </summary>
/// <param name="depth">The number of times to repeat the <see cref="IndentString"/> property.</param>
/// <returns>A string containing the <see cref="IndentString"/> property value a specified number of times.</returns>
protected virtual string Indent(int depth)
{
StringBuilder sb = new StringBuilder(IndentString.Length * depth);
for (int i = 0; i < depth; i++)
sb.Append(IndentString);
return sb.ToString();
}
#endregion
#region Properties
/// <summary>
/// Specifies the indentation to use for each level when displaying the object graph.
/// </summary>
/// <value>A string value; the default is three blank spaces.</value>
public string IndentString
{
get
{
return indentString;
}
set
{
indentString = value;
}
}
#endregion
}
}
Y aquí hay una página simple para leer viewstate desde un cuadro de texto y graficarlo usando el código anterior
private void btnParse_Click(object sender, System.EventArgs e)
{
// parse the viewState
StringWriter writer = new StringWriter();
ViewStateParser p = new ViewStateParser(writer);
p.ParseViewStateGraph(txtViewState.Text);
ltlViewState.Text = writer.ToString();
}
Necesito ver el contenido del viewstate de una página asp.net. Busqué un decodificador viewstate, encontré el decodificador ViewState de Fridz Onion pero me pide que la url de una página obtenga su viewstate. Como mi viewstate se forma después de una devolución de datos y se produce como resultado de una operación en un panel de actualización, no puedo proporcionar una url. Necesito copiar y pegar la cadena viewstate y ver qué hay adentro. ¿Existe alguna herramienta o sitio web que pueda ayudar a ver el contenido de viewstate?
Aquí hay otro decodificador que funciona bien a partir de 2014: http://viewstatedecoder.azurewebsites.net/
Esto funcionó en una entrada en la que falló el decodificador Ignatu con "Los datos serializados no son válidos" (aunque deja descifrados los datos seriados de BinaryFormatter, mostrando solo su longitud).
Aquí hay un decodificador ViewState en línea:
http://ignatu.co.uk/ViewStateDecoder.aspx
Editar: desafortunadamente, el enlace de arriba está muerto - aquí hay otro decodificador de ViewState (de los comentarios):
Como otra persona acaba de mencionar, es una cadena codificada en base64. En el pasado, he usado este sitio web para decodificarlo:
Esta es una manera "nativa" de .NET de convertir ViewState de cadena en StateBag. El código está a continuación:
public static StateBag LoadViewState(string viewState)
{
System.Web.UI.Page converterPage = new System.Web.UI.Page();
HiddenFieldPageStatePersister persister = new HiddenFieldPageStatePersister(new Page());
Type utilClass = typeof(System.Web.UI.BaseParser).Assembly.GetType("System.Web.UI.Util");
if (utilClass != null && persister != null)
{
MethodInfo method = utilClass.GetMethod("DeserializeWithAssert", BindingFlags.NonPublic | BindingFlags.Static);
if (method != null)
{
PropertyInfo formatterProperty = persister.GetType().GetProperty("StateFormatter", BindingFlags.NonPublic | BindingFlags.Instance);
if (formatterProperty != null)
{
IStateFormatter formatter = (IStateFormatter)formatterProperty.GetValue(persister, null);
if (formatter != null)
{
FieldInfo pageField = formatter.GetType().GetField("_page", BindingFlags.NonPublic | BindingFlags.Instance);
if (pageField != null)
{
pageField.SetValue(formatter, null);
try
{
Pair pair = (Pair)method.Invoke(null, new object[] { formatter, viewState });
if (pair != null)
{
MethodInfo loadViewState = converterPage.GetType().GetMethod("LoadViewStateRecursive", BindingFlags.Instance | BindingFlags.NonPublic);
if (loadViewState != null)
{
FieldInfo postback = converterPage.GetType().GetField("_isCrossPagePostBack", BindingFlags.NonPublic | BindingFlags.Instance);
if (postback != null)
{
postback.SetValue(converterPage, true);
}
FieldInfo namevalue = converterPage.GetType().GetField("_requestValueCollection", BindingFlags.NonPublic | BindingFlags.Instance);
if (namevalue != null)
{
namevalue.SetValue(converterPage, new NameValueCollection());
}
loadViewState.Invoke(converterPage, new object[] { ((Pair)((Pair)pair.First).Second) });
FieldInfo viewStateField = typeof(Control).GetField("_viewState", BindingFlags.NonPublic | BindingFlags.Instance);
if (viewStateField != null)
{
return (StateBag)viewStateField.GetValue(converterPage);
}
}
}
}
catch (Exception ex)
{
if (ex != null)
{
}
}
}
}
}
}
}
return null;
}
JavaScript-ViewState-Parser:
- http://mutantzombie.github.com/JavaScript-ViewState-Parser/
- https://github.com/mutantzombie/JavaScript-ViewState-Parser/
El analizador debería funcionar con la mayoría de los ViewStates no encriptados. No maneja el formato de serialización utilizado por .NET versión 1 porque esa versión está muy desactualizada y, por lo tanto, es poco probable que se encuentre en una situación real.
http://deadliestwebattacks.com/2011/05/29/javascript-viewstate-parser/
Análisis de .NET ViewState
Un vistazo a spirited en ViewState, parte I:
http://deadliestwebattacks.com/2011/05/13/a-spirited-peek-into-viewstate-part-i/
Un vistazo a spirited en ViewState, parte II:
http://deadliestwebattacks.com/2011/05/25/a-spirited-peek-into-viewstate-part-ii/
Normalmente, ViewState debería poder descifrarse si tiene la clave de máquina, ¿verdad? Después de todo, ASP.net necesita descifrarlo, y ciertamente no es una caja negra.
Puede ignorar el campo de URL y simplemente pegar viewstate en el cuadro de texto Viewstate.
Parece que tienes una versión anterior; los métodos de serialización cambiaron en ASP.NET 2.0, así que tome la versión 2.0
Use Fiddler y tome el estado de la vista en la respuesta y péguelo en el cuadro de texto de la esquina inferior izquierda, luego decodifique.
Viewstate Viewer en línea hecho por Lachlan Keown:
http://lachlankeown.blogspot.com/2008/05/online-viewstate-viewer-decoder.html