RyanDing

用编码抒写未来

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  41 随笔 :: 0 文章 :: 1243 评论 :: 52万 阅读

     上周完成了一个从ASP.NET WebForm 开发的站点抓包的功能。该功能要求使用该网点内的帐号通过我们自己的程序获取网站内的数据。其间使用了HttpWebRequest 进行抓包。具体的抓包过程就不重点讨论了。旨在和大家分享一下我在抓包过程中对ViewState 在 ASP.NET WebForm 中的作用有了进一步的了解。如果存在不足之处,希望您能指出。

     为了模拟Http POST/GET 我们用VS建立两个工程,截图如下:

注:第一个工程是一个简单的ASP.NET Web Form 程序,第二个是模拟Web Form 的 WinForm 程序。

WebApplication1 执行如下:

两个服务器端控件 DropDownList 和 Button 服务器端相应事件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
 
        }
 
 protected void Button1_Click(object sender, EventArgs e)
        {
            if (DropDownList1.SelectedValue == "Two")
            {
                lblInfor.Text = "Two";
            }
            else
            {
                lblInfor.Text = "One";
            }
        }

 

功能代码非常简单,Button1被单击后显示dropdownlist 的文本值:

Webform介绍完,剩下就是用WinForm 通过HTTP POST/GET来模拟Web Form 程序,程序运行界面如下:

这里的OnePost 与TwoPost 分别模拟WebForm中 Post 按钮Click功能。

贴出模拟的核心代码:PostByWebRequest 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
private void PostByWebRequest(string strPostValue)
   {
       try
       {
           string URI = "http://localhost:2026/webform1.aspx/";
           HttpWebRequest request = WebRequest.Create(URI) as HttpWebRequest;
           request.Method = "GET";
           request.KeepAlive = true;
           request.CookieContainer = cookieContainer;
           HttpWebResponse response = request.GetResponse() as HttpWebResponse;
           System.IO.Stream responseStream = response.GetResponseStream();
           System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.UTF8);
           //返回的页面html文本
           string srcString = reader.ReadToEnd();
           //VeiwState               
           string viewStateFlag = "id=\"__VIEWSTATE\" value=\"";
           int len1 = srcString.IndexOf(viewStateFlag) + viewStateFlag.Length;
           int len2 = srcString.IndexOf("\"", len1);
           string viewState = srcString.Substring(len1, len2 - len1);
           //EventValidation               
           string eventValidationFlag = "id=\"__EVENTVALIDATION\" value=\"";
           len1 = srcString.IndexOf(eventValidationFlag) + eventValidationFlag.Length;
           len2 = srcString.IndexOf("\"", len1);
           string eventValidation = srcString.Substring(len1, len2 - len1);
 
           //编码
           viewState = System.Web.HttpUtility.UrlEncode(viewState);
           eventValidation = System.Web.HttpUtility.UrlEncode(eventValidation);
 
           //这里可以通过抓包工具获得poststring.记得中文需要UrlEncode编码。
           string formatString = "DropDownList1={0}&Button1={1}&__VIEWSTATE={2}&__EVENTVALIDATION={3}";
           string postString = string.Format(formatString, strPostValue,
               "Do PostBack", viewState, eventValidation);
 
           byte[] postData = Encoding.UTF8.GetBytes(postString);
 
           URI = "http://localhost:2026/webform1.aspx/";
           //POST
           request = WebRequest.Create(URI) as HttpWebRequest;
           request.Method = "POST";
           request.KeepAlive = false;
           request.ContentType = "application/x-www-form-urlencoded";
           request.CookieContainer = cookieContainer;
           request.ContentLength = postData.Length;
 
           System.IO.Stream outputStream = request.GetRequestStream();
           outputStream.Write(postData, 0, postData.Length);
           outputStream.Close();
 
           response = request.GetResponse() as HttpWebResponse;
           responseStream = response.GetResponseStream();
           reader = new System.IO.StreamReader(responseStream, Encoding.UTF8);
           srcString = reader.ReadToEnd();
       }
       catch (Exception ex)
       {
           string msg = ex.Message;
           MessageBox.Show(ex.Message);
       }
   }

PostByWebRequest函数调用如下:

OnePost 按钮单击执行:   PostByWebRequest("One");

TwoPost 按钮单击执行:   PostByWebRequest("Two");

注:如果在PostByWebRequest函数的第31行,不传入ViewState或EVENTVALIDATION,WinForm内的两个按钮均不能成功模拟WebForm。最终模拟的正确效果是:预先在WebForm 的 Button_Click内设置断点,接着点击WinForm内的两个按钮,VS会自动截获到该断点设置。说明我们顺利模拟了WebForm的POST的机制。如果点击TwoPost 按钮时,WebForm 服务器端不但会执行Post按钮事件还会执行DropDownlist 的SelectedIndexChanged事件。为什么会执行到DropDownlist 的SelectedIndexChanged事件呢?这一切都归功于ViewState。它记录了WebForm的表单内容从而做出了相应的处理。所以WebForm 的 ViewState 机制还是很强大的。让我们用事件机制去开发Web程序。同时ViewState机制让我们的web form 程序更难被“爬虫”获取程序内容,想用程序Post WebForm 就必须传入传入ViewState 。否则POST不会返回正确的页面内容。

posted on   ryanding  阅读(12922)  评论(40编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
点击右上角即可分享
微信分享提示