programing

뷰 상태 디코딩 방법

subpage 2023. 6. 13. 22:18
반응형

뷰 상태 디코딩 방법

asp.net 페이지의 뷰 상태 내용을 봐야 합니다.뷰 상태 디코더를 찾아보니 프리즈 어니언의 뷰 상태 디코더가 있는데 페이지 URL을 요청합니다.내 뷰 상태는 포스트백 후에 형성되고 업데이트 패널의 작업의 결과이기 때문에 URL을 제공할 수 없습니다.뷰 상태 문자열을 복사하여 붙여넣고 안에 무엇이 있는지 확인해야 합니다.보기 상태의 내용을 볼 수 있는 도구나 웹 사이트가 있습니까?

다음은 온라인 ViewState 디코더입니다.

http://ignatu.co.uk/ViewStateDecoder.aspx

편집: 안타깝게도 위 링크가 비활성화되었습니다. 여기 다른 ViewState 디코더(댓글에서)가 있습니다.

http://viewstatedecoder.azurewebsites.net/

Fiddler를 사용하여 응답의 보기 상태를 잡고 왼쪽 아래 텍스트 상자에 붙여넣은 다음 디코딩합니다.

다음은 Scott Mitchell의 ViewState 기사(25페이지)의 ViewState 비주얼라이저 소스 코드입니다.

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
    }
}

텍스트 상자에서 보기 상태를 읽고 위의 코드를 사용하여 그래프로 표시할 수 있는 간단한 페이지가 있습니다.

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();
        }

다른 사람이 방금 언급했듯이, 그것은 Base64로 인코딩된 문자열입니다.과거에 이 웹 사이트를 사용하여 디코딩한 적이 있습니다.

http://www.motobit.com/util/base64-decoder-encoder.asp

JavaScript-ViewState-Parser:

파서는 암호화되지 않은 대부분의 보기 상태에서 작동해야 합니다..NET 버전 1에서 사용하는 직렬화 형식은 처리하지 않습니다. 이 버전은 너무 오래되어 실제 상황에서는 사용할 가능성이 거의 없기 때문입니다.

http://deadliestwebattacks.com/2011/05/29/javascript-viewstate-parser/


.NET 뷰 상태 구문 분석 중


2014년 현재 잘 작동하는 또 다른 디코더가 있습니다. http://viewstatedecoder.azurewebsites.net/

이것은 이그나투 디코더가 "직렬화된 데이터가 유효하지 않다"고 실패한 입력에 대해 작동했습니다(비록 바이너리 포맷의 직렬화된 데이터는 디코딩되지 않고 길이만 표시됨).

이것은 ViewState를 문자열에서 StateBag Code로 변환하는 다소 "네이티브" .NET 방식입니다.

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;
    }

URL 필드를 무시하고 보기 상태 문자열 상자에 보기 상태를 붙여넣으면 됩니다.

이전 버전이 있는 것 같습니다. ASP.NET 2.0에서 직렬화 방법이 변경되었으므로 2.0 버전을 가져옵니다.

파이썬에서 가장 좋은 방법은 이 링크를 사용하는 것입니다.

ASP.NET 뷰 상태를 디코딩하기 위한 작은 Python 3.5+ 라이브러리입니다.

다음을 합니다.pip install viewstate

>>> from viewstate import ViewState
>>> base64_encoded_viewstate = '/wEPBQVhYmNkZQ9nAgE='
>>> vs = ViewState(base64_encoded_viewstate)
>>> vs.decode()
('abcde', (True, 1))

Lachlan Keown이 만든 온라인 뷰 상태 뷰어:

http://lachlankeown.blogspot.com/2008/05/online-viewstate-viewer-decoder.html

일반적으로 머신 키가 있으면 ViewState는 암호 해독이 가능해야 합니다. 그렇죠?결국, ASP.net 은 그것을 해독해야 하며, 그것은 확실히 블랙박스가 아닙니다.

언급URL : https://stackoverflow.com/questions/22814/how-to-decode-viewstate

반응형