C# FiddlerCore 抓取

原文: C# FiddlerCore 抓取

本文目的

记录FiddlerCore怎样实现如下功能:html

抓取本机的请求响应web

抓取本机局域网内其它设备的请求响应浏览器

情景介绍

C#调用FiddlerCore,开发出软件,本软件能够抓取本机(运行本软件的电脑)上的http/https请求响应,能够抓取同一局域网内设备(如本机局域网ip为192.168.1.2,路由器ip为192.168.1.1,同一路由器下还链接了一部手机,其ip为192.168.1.3,那么,这个手机的http/https也是能够抓取的)。缓存

添加引用

须要的库文件:
BCMakeCert.dll
CertMaker.dll
FiddlerCore4.dll


服务器

FiddlerCore4.pdb
FiddlerCore4.xml
app

 
 
 
 
  
  
           
  
  
  • 1
using Fiddler;

初始化FiddlerCore

 
 
 
 
  
  
           
  
  
  • 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
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
//https代理 Proxy oSecureEndpoint; //主机名 string sSecureEndpointHostname = "localhost"; //假装https服务器(别人这么说,我也没搞明白这个技术细节) int iSecureEndpointPort = 8877; //代理端口 int iStartPort = 8888; //FiddlerCore抓取到的会话不会缓存,因此,要本身维护一个会话列表,来保存所关心的请求 List<Session> oAllSessions = new List<Session>(); //初始化Fiddler private void InitFiddler() { //这个名字随便 FiddlerApplication.SetAppDisplayName("test"); //绑定事件处理————当发起请求以前 FiddlerApplication.BeforeRequest += On_BeforeRequest; //绑定事件处理————当会话结束以后 FiddlerApplication.AfterSessionComplete += On_AfterSessionComplete; //-----------处理证书----------- //伪造的证书 X509Certificate2 oRootCert; //若是没有伪造过证书并把伪造的证书加入本机证书库中 if(null== CertMaker.GetRootCertificate()) { //建立伪造证书 CertMaker.createRootCert(); //从新获取 oRootCert = CertMaker.GetRootCertificate(); //打开本地证书库 X509Store certStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine); certStore.Open(OpenFlags.ReadWrite); try { //将伪造的证书加入到本地的证书库 certStore.Add(oRootCert); } finally { certStore.Close(); } } else { //之前伪造过证书,而且本地证书库中保存过伪造的证书 oRootCert = CertMaker.GetRootCertificate(); } //----------------------------- //指定伪造证书 FiddlerApplication.oDefaultClientCertificate = oRootCert; //忽略服务器证书错误 CONFIG.IgnoreServerCertErrors = true; //信任证书 CertMaker.trustRootCert(); //看字面意思知道是啥,但实际起到啥做用。。。鬼才知道,官方例程里有这句,加上吧,管它呢。 FiddlerApplication.Prefs.SetBoolPref("fiddler.network.streaming.abortifclientaborts", true); //启动代理服务————启动参数1:捕捉https;启动参数2:容许局域网其余终端连入本代理 FiddlerApplication.Startup(iStartPort, FiddlerCoreStartupFlags.DecryptSSL | FiddlerCoreStartupFlags.AllowRemoteClients | FiddlerCoreStartupFlags.Default, null); //建立https代理 oSecureEndpoint = FiddlerApplication.CreateProxyEndpoint(iSecureEndpointPort, true, oRootCert); }

实现事件处理

 
 
 
 
  
  
           
  
  
  • 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
//封包发送以前事件————基于这个Session oS能够作不少不少事 private void On_BeforeRequest(Session oS) { oS.bBufferResponse = false; Monitor.Enter(oAllSessions); if (oS.fullUrl.ToLower().Length >= 0) { oAllSessions.Add(oS); } Monitor.Exit(oAllSessions); if (oS.oRequest.pipeClient.LocalPort == iSecureEndpointPort && oS.hostname == sSecureEndpointHostname) { oS.utilCreateResponseAndBypassServer(); oS.oResponse.headers.SetStatus(200, "Ok"); oS.oResponse["Content-Type"] = "text/html; charset=UTF-8"; oS.oResponse["Cache-Control"] = "private, max-age=0"; oS.utilSetResponseBody("<html><body>Request for httpS://" + sSecureEndpointHostname + ":" + iSecureEndpointPort.ToString() + " received. Your request was:<br /><plaintext>" + oS.oRequest.headers.ToString()); } } //封包响应结束事件————一样,基于这个Session oS能够作不少不少事 private void On_AfterSessionComplete(Session oS) { string respStr = ""; respStr = oS.GetResponseBodyAsString(); if (oS.bHasResponse && respStr.Length > 0) { Invoke(new Action(() => { textBox1.AppendText($"{oS.fullUrl}\r\n"); })); } if (oAllSessions.Count > 300) { Monitor.Enter(oAllSessions); oAllSessions.Clear(); Monitor.Exit(oAllSessions); GC.Collect(); } }

启动、中止

到这里,程序已经准备好了。如今咱们来启动它。函数

冷启动

程序刚运行起来,从未将自身做为系统代理。这时,只须要调用InitFiddler就好了。this

完全中止

因为本程序将自身设置为系统代理了,当本程序退出时,若是你没有作善后处理,那么系统代理还在Internet选项——>链接——>局域网设置——>代理服务器的设置里躺着,可因为你的程序已经退出了,这个系统代理指向的是一个没有在工做的代理,那么此路不一样,你可能会浏览器打不开网页,经过本机代理上网的其余设备也没法发起http请求。所以,当你肯定再也不抓取请求的时候,要作善后处理。spa

 
 
 
 
  
  
           
  
  
  • 1
FiddlerApplication.Shutdown();

关于这个,官方有段建议
Shuts down the FiddlerCore proxy and disposes it. Note: If there’s any traffic in progress while you’re calling this method, your background threads are likely to blow up with ObjectDisposedExceptions or NullReferenceExceptions. In many cases, you’re better off simply calling oProxy.Detach() and letting the garbage collector clean up when your program exits.
意思是:当你调用这个方法的时候,若是存在任何正在处理的通讯,那么你的后台线程颇有可能带着ObjectDisposedExceptions异常或NullReferenceExceptions异常而崩溃。
在的大多数状况下,你最好只是简单地调用一下oProxy.Detach() 而后当你的程序退出时让GC来处理。


.net

热启动、中止

有时候,程序可能须要暂停一下抓取,但并不彻底退出程序,只是暂时不让它做为代理了。这时候有两种方法:

方式一:解绑事件处理函数

 
 
 
 
  
  
           
  
  
  • 1
  • 2
  • 3
  • 4
//解绑事件处理————当发起请求以前 FiddlerApplication.BeforeRequest -= On_BeforeRequest; //解绑事件处理————当会话结束以后 FiddlerApplication.AfterSessionComplete -= On_AfterSessionComplete;

这种方式只是再也不介入请求和响应了,实际上,全部的会话仍是经过本程序的代理走的流量。

方式二:解除系统代理

暂停代理

 
 
 
 
  
  
           
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
if(FiddlerApplication.oProxy.IsAttached) { FiddlerApplication.oProxy.Detach(); oSecureEndpoint.Detach(); }

这种方式是将本程序的代理完全解除,当代理解除以后,全部的请求都将再也不走本程序。

当你须要再启动代理的时候,从新设置一下代理便可:
重设代理

 
 
 
 
  
  
           
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
if(!FiddlerApplication.oProxy.IsAttached) { FiddlerApplication.oProxy.Attach(); oSecureEndpoint.Attach(); }

终端设置

如今程序已经准备好拦截抓取了,就等着连入请求了。

抓取本机请求

通常状况下,浏览器的代理设置都默认为使用IE代理设置,若是不是,须要手动设置一下:
代理服务器IP设置为localhost或127.0.0.1
端口设置为8888,也就是iStartPort = 8888指定的端口号

抓取非本机请求

这种场景,我只实验成功了抓取同一局域网内的终端请求。

保证目标终端与代理机处于同一网段

若是你的软件运行的计算机(咱们称它为代理机)链接在一台192.168.1.1的路由器下,那么你的代理机的局域网IP应该是192.168.1.X,那么你必需要将要抓取的终端(它能够是同一局域网内的另外一台计算机,能够是经过WiFi上网的手机、iPad等,咱们称它为目标终端)经过网线或者WiFi链接到同一个路由器下。

下载证书

在目标终端上,打开浏览器,输入网址,格式为:代理机的局域网IP:代理端口,好比192.168.1.5:8888
这时,会看到一个网页,这是FiddlerCore生成的一个网页,提供伪造证书下载的页面:


Fiddler Echo Service

GET / HTTP/1.1
Host: localhost:8888
Proxy-Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8
DNT: 1
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: _ga=GA1.1.1679095215.1533305166








This page returned a HTTP/200 response
Originating Process Information: 360se:3664
To configure Fiddler as a reverse proxy instead of seeing this page, see Reverse Proxy Setup
You can download the FiddlerRoot certificate



注意这个页面最下方的You can download the FiddlerRoot certificate带有一个超连接,这个链接就能够下载伪造的证书。

安装证书

这个就不说了,不一样的系统、设备,安装证书的方法不尽相同,百度一下就知道了。

设置代理

同上,不一样系统设备的设置方法不尽相同,百度之。
但重要的参数不能填错:
代理服务器ip就填代理机的IP
代理端口就填你FiddlerApplication.Startup时给的端口,也就是代码中的iStartPort,8888


真正开始抓取

启动软件,打开目标机上的浏览器、app等,看看你软件里的On_BeforeRequestOn_AfterSessionComplete 能干些啥事吧~

待实现

截至写本文的时候,我依然没搞定将Fiddler做为广域网代理服务器来抓取来自外网IP的代理数据。而网上有资料说这个功能也是能够实现的。之后再试验一下吧。
我想缘由应该是跨请求跨路由器网段了,须要作端口映射、防火墙设置之类的东西吧。固然,只是暂时猜想,真正缘由还有待查明。

项目合做

本人在爬虫、网页自动化以及验证码识别方面经验还算丰富,有合适的项目的话,能够联系我 QQ:116703690

相关文章
相关标签/搜索