一般我们都是利用WebRequest这个类来向服务器进行数据的POST,不过很多情况下相应的服务器都有验证,看你是不是登陆,是不是来自同一个域,这些都简单,我们可以更改其属性来达到欺骗服务器。不过如果服务器做了CSRF控制,那我们怎么办?

不熟悉CSRF的可以问下G哥此为何物,这里简单介绍下。CSRF常规来讲是在表单页里放一个隐藏域,然后在表单提交的时候服务器验证POST过来的NAVEVALUE里面是不是包含此域,同时如果包含验证其值。

问题来了,在这种情况下我们POST到服务器的数据怎么写,虽然我们可以查看HTML来得知这个NAME是什么以及它的VALUE是什么,但是这个VALUE一般情况下每刷一次都是会发生变化的。那好了在我们POST的时候怎么来得到它呢?

网上常见的那些WebRequest方法肯定不行,因为它们都是用这个类先获得一个Stream,在这个Stream里面写入我们要POST到服务器的数据,可这个时候我们还不知道这个CSRF的值呢,POST过去肯定出错。理论上来讲我们要先GET一次,然后自己办法解析GET到的这个HTML,得到CSRF的值,可是接下来我们再去WebRequest.Creat打算去POST的时候,此时相当于又重新访问了一遍,它的CSRF值已经变了,看来此路不通啊。

好在我们还有WebClient可以利用,WebClient可以让我们保持一个实例即可,而WebRequest只有通过静态方法创造出来,不能通过变化URL来达到使用同一个的目的,此处可能也是在NET4里微软推出全新HttpClient的目的,用来一统HTTP访问接口的江湖。

好了,我们现在需要做的就是继承WebClient,重写相应方法,代码如下:

 public class CookieAwareWebClient : WebClient
{
public string Method;
public CookieContainer CookieContainer { get; set; }
public Uri Uri { get; set; } public CookieAwareWebClient()
: this(new CookieContainer())
{
} public CookieAwareWebClient(CookieContainer cookies)
{
this.CookieContainer = cookies;
this.Encoding = Encoding.UTF8;
} protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = this.CookieContainer;
(request as HttpWebRequest).ServicePoint.Expect100Continue = false;
(request as HttpWebRequest).UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.5 Safari/537.36";
(request as HttpWebRequest).Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
(request as HttpWebRequest).Headers.Add(HttpRequestHeader.AcceptLanguage, "zh-CN,zh;q=0.8,en;q=0.6,nl;q=0.4,zh-TW;q=0.2");
(request as HttpWebRequest).Referer = "some url";
(request as HttpWebRequest).KeepAlive = true;
(request as HttpWebRequest).AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
if (Method == "POST")
{
(request as HttpWebRequest).ContentType = "application/x-www-form-urlencoded";
}
}
HttpWebRequest httpRequest = (HttpWebRequest)request;
httpRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
return httpRequest;
} protected override WebResponse GetWebResponse(WebRequest request)
{
WebResponse response = base.GetWebResponse(request);
String setCookieHeader = response.Headers[HttpResponseHeader.SetCookie]; if (setCookieHeader != null)
{
//do something if needed to parse out the cookie.
try
{
if (setCookieHeader != null)
{
Cookie cookie = new Cookie();
cookie.Domain = request.RequestUri.Host;
this.CookieContainer.Add(cookie);
}
}
catch (Exception)
{ }
}
return response;
}
}

可以看出,其实最关键的还是利用好CookieContainer这个类。接下来就是如何使用了,我们需要首先访问一次登陆页面,拿到HTML然后正则也好替换也好,拿到这个CSRF的VALUE,然后再将其POST相应的服务器。

 var cookieJar = new CookieContainer();
CookieAwareWebClient client = new CookieAwareWebClient(cookieJar); // the website sets some cookie that is needed for login, and as well the 'lt' is always different
string response = client.DownloadString("url for get");
string regx = "<input type=\"hidden\" id=\"lt\" name=\"lt\" value=\"(?<PID>\\S+?)\" />";
// parse the 'lt' and cookie is auto handled by the cookieContainer
string token = Regex.Match(response, regx).Groups[].Value;
string urlforlogin = "url for login";
string postData =
string.Format("username={0}&password={1}&lt={2}", "user", "pass", token);
client.Method = "POST";
response = client.UploadString("url for login", postData); client.Method = "GET";

到此我们就可以结束,后期就是变化不同的URL去DownloadString了,俗称爬虫,接下来就可以根据不同的业务做不同的数据分析了。

如何利用WebClient模拟登陆CSRF控制的网站的更多相关文章

  1. 使用ApiPost测试接口时需要先登录怎么办?利用Cookie模拟登陆!

    ApiPost简介: ApiPost是一个支持团队协作,并可直接生成文档的API调试.管理工具.它支持模拟POST.GET.PUT等常见请求,是后台接口开发者或前端.接口测试人员不可多得的工具 . 下 ...

  2. 通过Javascript模拟登陆Windows认证的网站

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>模拟登陆</title ...

  3. 利用selenium模拟登陆

    第一部:利用selenium登陆 导入selenium库 from selenium import webdriver 明确模拟浏览器在电脑中存放的位置,比如我存在当前目录 chromePath = ...

  4. python3下scrapy爬虫(第六卷:利用cookie模拟登陆抓取个人中心页面)

    之前我们爬取的都是那些无需登录就要可以使用的网站但是当我们想爬取自己或他人的个人中心时就需要做登录,一般进入登录页面有两种 ,一个是独立页面登陆,另一个是弹窗,我们先不管验证码登陆的问题 ,现在试一下 ...

  5. Shell 利用 curl 模拟登陆

    -b 参数 指定使用cookie文件 -c是往cookie文件中写cookie -d 是指定此次登录所需的参数,通过httpfox查看 -L 指定页面自动跳转 #curl -c ck.txt --us ...

  6. 如何模拟登陆添加了CSRF保护的网站

    上次写了篇文章,内容是如何利用WebClient模拟登陆CSRF控制的网站,回复中有人还是不理解,现在另开一篇,打算说说用Python如何来登陆. 开写之前,先说下为什么webrequest不行,常规 ...

  7. python模拟登陆 pixiv

    ##---author:wuhao##在QQ群看到有群友在模拟登陆 pivix.cn 这个网站,闲来无事,我也写了一个测试一下,起初我把它想的复杂了,认为我需要获取服务器返回过来的Set-Cookie ...

  8. 【教程】手把手教你如何利用工具(IE9的F12)去分析模拟登陆网站(百度首页)的内部逻辑过程

    [前提] 想要实现使用某种语言,比如Python,C#等,去实现模拟登陆网站的话,首先要做的事情就是使用某种工具,去分析本身使用浏览器去登陆网页的时候,其内部的执行过程,内部逻辑. 此登陆的逻辑过程, ...

  9. 利用Python与selenium自动化模拟登陆12306官网!

    近年来,12306的反爬越来越来严重,从一年前的 获取tk参数后到现在增加了 JS.CSS等加密方式! 目前大部分人利用的登陆方式都是利用selenium ,此文也不例外. 环境:        Wi ...

随机推荐

  1. Java 继承内部类

    大家有没有想过内部类究竟能不能被继承呢? public class Main { public static void main(String[] args){ Outer outer = new O ...

  2. Java Web开发——HTML CSS JavaScript 杂记

    HTML是一种在互联网上常见的网页制作标注性语言,并不能算作一种程序设计语言.因为它相对程序设计语言来说缺少了其应所有的特征.对于网站设计人员来说,只使用HTML是不够的,需要在页面中引入CSS样式. ...

  3. PHP库函数积累,持续更新

    1. gethostbyname($server_name) 作用:根据给定的域名获取对应的ip 示例:echo gethostbyname("www.baidu.com"); 2 ...

  4. Mybatis源码分析之插件的原理

    MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用. 默认情况下,可以使用插件来拦截的方法调用包括: Executor (update, query, flushStatements, ...

  5. 【欧拉回路】UVA - 10054 The Necklace

    题目大意: 一个环被切割成了n个小块,每个小块有头尾两个关键字,表示颜色. 目标是判断给出的n个小块能否重构成环,能则输出一种可行解(按重构次序输出n个色块的头尾颜色).反之输出“some beads ...

  6. 关于 DP 的一些题目

    DP 是真的好玩. 口胡一段话题解: DP 题集 1 DP 题集 2

  7. 使用抽象bean

    定义抽象类Abstract=“true”抽象bean不能实例化,一个类可以创建多个bean. 抽象bean的配置和一般bean的配置基本一样只是在增加了Abstract=“true”抽象bean是一个 ...

  8. POJ 2185 kmp

    题目链接:http://poj.org/problem?id=2185 题意:给出一个R*C(10000 * 75)的矩形字符串,然你求最小的不严格重复矩阵,比如,ABA,最小的重复矩阵是AB,经过复 ...

  9. POJ poj 2155 Matrix

    题目链接[http://poj.org/problem?id=2155] /* poj 2155 Matrix 题意:矩阵加减,单点求和 二维线段树,矩阵加减,单点求和. */ using names ...

  10. 【BZOJ 2144】 2144: 跳跳棋 (倍增LCA)

    2144: 跳跳棋 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 642  Solved: 307 Description 跳跳棋是在一条数轴上进行的 ...