misc.log

日常茶飯事とお仕事と

ASP.NETでやりとりされるViewstateの内容を読み解いてみたいがうまくいかない

※現時点ではまだ答えにたどり着いていません。下記内容は作業過程のメモです

Webアプリケーションが持つ、サーバーとの情報連携方法の1つに、ビューステート(Viwestate)と呼ばれる情報に値を載せてやりとりするという方法があります。ASP.NETで用いられるコントロールなども、たとえばボタンが押されて、サーバーに状態の変化がポストされて、再度同じページに戻ってくる「ポストバック」の際に前の状態をビューステートに入れて、状態を復元しているようです。

で、このビューステートはコントロールに限らず、自分でも情報を入れることができるのですが、ビューステートそのものはBase64エンコードされた文字列としてメッセージに載せられるようです。ということは、Base64自体は暗号化でも何でもなく、単に「文字列化」のエンコード手法なので、メッセージ自体を監視すれば簡単に復号してのぞき見できてしまいます。

ビューステートそのものをのぞき見する

たとえばGoogle Chromeの場合、F12を押すとWebページとWebサーバーとの間のやりとりを表示させることができます(下図)。

f:id:frontline:20131026174248j:plain

F12を押すと、Webページ下部に上図のような表示が登場します。上の方に「Elements」「Resources」…と見出しが並んでいるので、そこの「Network」を選択、さらにその下に表示される領域の見出しから「Response」や「Headers」を選択すると、そのページからサーバーに飛んだ情報や、返ってきた情報をのぞき見できます。

上図だと、「input」タグで囲まれた項目の1つに「__VIEWSTATE」という名前(name)がついた行がありますが、どうやらこれがビューステートの情報です。Base64エンコードされて文字列として表現されているので、原形はとどめておらず、そのままで人間が読むのは困難です(できないわけではないですが…)。

ビューステートをデコードしてみたい

では、何がやりとりされているのかをさらにデコードしてのぞき見できるのでは無いか??とおもったのですが……なんか上手くいきませんでした。

まずは、Base64エンコード、デコードできるツールをさくっと作ってしまいましょう。

f:id:frontline:20131026174648j:plain

    public partial class MainForm : Form
    {
        private System.Text.Encoding base64Encoder = System.Text.Encoding.GetEncoding("UTF-8");

        public MainForm()
        {
            InitializeComponent();
        }

        /// <summary>
        /// デコードボタン押下時処理。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ButtonDecode_Click(object sender, EventArgs e)
        {
            String result = base64Encoder.GetString(Convert.FromBase64String(TextDecode.Text));
            TextDecodeResult.Text = result;
        }

        /// <summary>
        /// エンコードボタン押下時処理。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ButtonEncode_Click(object sender, EventArgs e)
        {
            String result= Convert.ToBase64String(base64Encoder.GetBytes(TextEncode.Text));
            TextEncodeResult.Text = result;
        }

        /// <summary>
        /// Closeボタン押下時処理。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ButtonClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }

フォームにエンコード/デコード用テキストボックスと、ボタンを貼り付けて、エンコード、デコードはbase64Encoderを使えば簡単にできます。Base64の扱いは、以前書いたこれ(VB.NET)のC#版です。

Base64エンコーディングと、デコーディング
http://www.backyrd.net/entry/20120213/p3

で、先ほどのようにブラウザのF12ボタンで表示される情報から、ビューステート文字列を抜き出してデコードすればいいわけですよね…

f:id:frontline:20131026174900j:plain

あれ??化けてる。

もしかして暗号化されている?

このようにビューステート文字列自体は誰でも見られるので、すでにASP.NETなどでは暗号化するしくみが用意されているようです。また、SSLなどを使って通信路自体を暗号化してしまえば、のぞき見にも対応できます。

ですが、今はそれを手作業で読み解いてみようとしている訳なので、暗号化とか邪魔。というわけで、暗号化設定を強制的にOFFにしてみます。

暗号化の設定はASP.NETのページに配置されたコントロールごとにできるようですが、ページ全体の設定で指定を強制的に変更できるようです。

Page.ViewStateEncryptionMode Property(MSDN)
http://msdn.microsoft.com/en-us/library/system.web.ui.page.viewstateencryptionmode(v=vs.110).aspx

上記ページにあるように、ASP.NETのページ定義が記述された.aspxファイルの冒頭、Pageディレクティブに「ViewStateEncryptionMode」という属性を、「Never」で設定すると、暗号化をOFFにできるようです…。早速変更、ページを配置。

f:id:frontline:20131026175441j:plain

試してみますが…変わらない。

なんで????

宿題。ビューステートの読解方法

もう少し調べてみます。別に手作業で解読できることが何かにつながる訳では無いのですが、暗号化すべきなのか、どうなのかといった細かいセキュリティを考慮する時に、どれくらいの手間で盗聴ができるかという程度を把握していると人に説明がしやすいので。単にそれで試してみたくなっただけです。

続き

続きはこちら

ASP.NETでやりとりされるViewstateの内容を読み解いてみたいがうまくいかない(2)
http://www.backyrd.net/entry/20131031/1383150561

WEBアプリケーション・サーバー 設計・構築ノウハウ 第2版

WEBアプリケーション・サーバー 設計・構築ノウハウ 第2版