Fiddler学习

2019-01-29

Fiddler的介绍

Fiddler是强大的抓包工具,它的原理是以web代{过}{滤}理服务器的形式进行工作的,使用的代{过}{滤}理地址是:127.0.0.1,端口默认为8888,我们也可以通过设置进行修改。
代{过}{滤}理就是在客户端和服务器之间设置一道关卡,客户端先将请求数据发送出去后,代{过}{滤}理服务器会将数据包进行拦截,代{过}{滤}理服务器再冒充客户端发送数据到服务器;同理,服务器将响应数据返回,代{过}{滤}理服务器也会将数据拦截,再返回给客户端。
Fiddler可以抓取支持http代{过}{滤}理的任意程序的数据包,如果要抓取https会话,要先安装证书。

Fiddler脚本

Fiddler 包含了一个脚本文件可以自动修改Http Request 和Response.这样我们就不需要手动地下”断点”去修改了,实际上它是一个脚本文件CustomRules.js
位于: C:\Documents and Settings[your user]\My Documents\Fiddler2\Scripts\CustomRules.js 下,你也可以在Fiddler 中打开CustomRules.js 文件, 启动Fiddler, 点击菜单Rules->Customize Rules…
Fiddler Script 的官方帮助文档必须认真阅读, 地址是:http://www.fiddler2.com/Fiddler/dev/ScriptSamples.asp

脚本场景1

场景1:一个付费验证,是否付费会返回一个json。里面有一个时间戳和一个false。如果时间戳和客户端不一致,则为破解失败。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if (oSession.fullUrl.Contains("http://www.baidu.com"))
{

// 获取Response Body、Request Body中JSON字符串,转换为可编辑的JSONObject变量
var responseStringOriginal = oSession.GetResponseBodyAsString();
var responseJSON = Fiddler.WebFormats.JSON.JsonDecode(responseStringOriginal);
var requestStringOriginal=oSession.GetRequestBodyAsString();
var requestJSON = Fiddler.WebFormats.JSON.JsonDecode(requestStringOriginal);
){ //请求参数中,若type为1,对返回值做如下修改

responseJSON.JSONObject['付费'] = "true";
// 重新设置Response Body
var responseStringDestinal = Fiddler.WebFormats.JSON.JsonEncode(responseJSON.JSONObject);
oSession.utilSetResponseBody(responseStringDestinal);
}
}
}

脚本场景2

场景2:我想要修改request的Body里面的部分参数,每次下完断点,修改完再提交,总会网络超时或者APP超时。这该怎么办?难道只能靠手速?

1
2
3
4
5
6
7
if(oSession.uriContains("http://www.baidu.com"))
{
var strBody=oSession.GetRequestBodyAsString();// 获取Request 中的body字符串
strBody=strBody.replace("false","true");// 用正则表达式或者replace方法去修改string,将false改为true
FiddlerObject.alert(strBody);// 弹个对话框检查下修改后的body
oSession.utilSetRequestBody(strBody);// 将修改后的body,重新写回Request中
}

脚本场景3

场景3:我想要修改cookie,改成一个付费过的cookie,但是需要实时生成,不能靠手速。这该怎么办?

1
2
3
4
5
6
  if (oSession.HostnameIs('www.baidu.com') && oSession.uriContains('pagewithCookie') && oSession.oRequest.headers.Contains("Cookie")) 
{
var sCookie = oSession.oRequest["Cookie"];
// 用replace方法或者正则表达式的方法去操作cookie的string
sCookie = sCookie.Replace("付费=false", "付费=true");
oSession.oRequest["Cookie"] = sCookie;

脚本场景4

场景4:我想要知道他到底有没有请求具体哪个网址,用查找速度太慢了。过滤也很慢。

1
2
3
if (oSession.HostnameIs("www.baidu.com")) {
oSession["ui-color"] = "red";
}

脚本场景5

场景5:我想要自动保存某个接口的数据到本地,怎么才能实现?

1
2
3
4
5
6
7
8
9
10
11
12
if (oSession.fullUrl.Contains("www.baidu.com/playurl/v1/") ){  
oSession.utilDecodeResponse();//消除保存的请求可能存在乱码的情况
var fso;
var file;
fso = new ActiveXObject("Scripting.FileSystemObject");
//文件保存路径,可自定义
file = fso.OpenTextFile("D:\\Sessions.txt",8 ,true, true);
//file.writeLine("Response code: " + oSession.responseCode);
file.writeLine("Response body: " + oSession.GetResponseBodyAsString());
file.writeLine("\n");
file.close();
}

Fiddler插件

just trust me是hook了安卓框架验证机制,更加棒~

过安卓验证机制

目前有非常多的APP,都为了防止被抓包,不仅仅是只用了https这么简单。而使用fiddler抓不到包,本质原因在于wifi代{过}{滤}理!很多APP会检测你是否用了wifi代{过}{滤}理,如果设置了,则APP无法正常使用。这样就会从根本上杜绝被抓包

那么,我们要怎么做才能防止这种情况的发生呢?
比较笨的一种办法依旧是使用xposed上的just trust me,依旧hook相关函数,即可破解该策略。

目前有非常多的APP,都为了防止被抓包,不仅仅是只用了https这么简单。而使用fiddler抓不到包,本质原因在于wifi代{过}{滤}理!很多APP会检测你是否用了wifi代{过}{滤}理,如果设置了,则APP无法正常使用。这样就会从根本上杜绝被抓包

那么,我们要怎么做才能防止这种情况的发生呢?
比较笨的一种办法依旧是使用xposed上的just trust me,依旧hook相关函数,即可破解该策略。

—————————————————————————————————————————————————————————
等等,我发现用了trust me过后,还是抓不到包,这到底是怎么回事!!!
非常简单,他们就是利用了本地服务器中转,这样的话Fiddler是抓不了包的。比如著名APP:麻花影视、电视家

那么,有没有办法能抓到这种操作的包呢?当然是有的。
这边只能透露几点,不能正大光明地公布,否则大量非法分子就可以破解非常多的APP了。
提示:Fiddler的本质其实就是代{过}{滤}理服务器,那么,如果是代{过}{滤}理服务器,所有的请求是不是都会走这台服务器呢?那是肯定的。

Request区域

那么每一个数据都是什么意思呢?
请求方式:GET/POST等
协议: HTTP/1.1(通常都是这个)

  1. Cache 头域
    if-Modified-since:缓存
      if-None-Match:可提高性能(在Response中添加ETag信息,客户端再次请求资源,Request中加入if-None-Match(ETag的值),服务器验证ETag,若没改变返回状态码304,有改变,返回状态码200)
      Pragma:防止页面被缓存
      Cache-Control:Response—Request遵循的缓存机制
      public:可以被任何缓存所缓存
      private:内容只缓存在私有缓存中
      no-cache:所有内容都不会被缓存
  2. Client 头域
    User-Agent: 告知服务器客户端使用的操作系统与浏览器的名称和版本
      Accept: 浏览器端可以接受的媒体、文件类型
      Accept-Encoding: 指定压缩方法,是否支持压缩,支持什么压缩方法(gzip、deflate)
      Accept-Language: 浏览器申明自己的接收语言
      Accept-chareset:浏览器申明自己接收的字符集。如gb2312,UTF_8
  3. Cookies 头域
    有的请求不发送Cookies,有的请求有Cookies。
      目的:将cookie值发送给服务器
  4. Entity头域
    Content-Length:发送给HTTP服务器的数据长度
      Content-Type:决定文件接收方将以什么形式、什么编码读取此文件
  5. Security 头域:
    Upgrade-Insecure-Requests: 1(默认,这个是自己协商的)
  6. Transport 头域:
    Host: 发送请求时,该报头域是必需的。主要用于指定被请求资源的Internet主机和端口号,通常从HTTP URL 中提取出来
      Proxy-Connection: 当网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接是否关闭。keep-alive表示不会关闭,客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接;close表示关闭,客户端再次访问这个服务器上的网页,需要重新建立连接。
      connection:Keep—alive TCP连接不会关闭
      connection:close 一个Request完成后,TCP连接关闭
  7. Miscellaneous头域
    Referer:提供了Request的上下文信息,告诉服务器我是从哪个链接过来的
      A——>B(B的服务器从Referer中统计有多少用户是从A过来的)

Response

  1. Cache头域
    Date:生成消息的具体时间和日期
      Expires:浏览器在指定过期时间内使用本地缓存
  2. Cookie/Login头域
    P3P:用户跨域设置cookie,可以解决iframe跨域访问cookie的问题
      Set-Cookie:重要的header,用于把cookie发送到客户端浏览器,每一个写入cookie都会生成一个set-cookie
  3. Entity头域
    ETag:与if-None-Match配合使用
      Last-Modified:用于指示资源的最后修改日期和时间
      Content-Type:Web服务器告知浏览器自己响应对象的类型和字符集
      Content-Length:指明实体正文长度,以字节方式存储的十进制数字表示。在数据下行中,要预先在服务器中缓存所有数据,然后所有数据一并发给客户端
      Content-Encoding:Web服务器表明自己用了什么压缩方式(gzip、deflate)压缩响应中的对象
      Content-Language:服务器告知浏览器自己响应的对象语言
  4. Miscellaneous头域
    Server:指明HTTP服务器的软件信息
      X-Powered-By:表明网站是用什么技术开发的
      X-AspNet-Version:如果网站是用Asp/Net开发的,这个header用来表明Asp/Net的版本
  5. Transport头域
    connection:Keep—alive TCP连接不会关闭
      connection:close 一个Request完成后,TCP连接关闭
  6. Location头域
    Location:用于重定向一个新的位置,包括新的URL地址

HTTP认证过程

  1. 客户端发送HTTP Request给服务器;
    1. Request中未包含Authorization header,服务器会返回一个401错误给客户端,且在Response中的header“www-Authenticate”中添加信息;
    2. 客户端将用户名和密码以base64加密后,放在Authorization中发送给服务器,认证成功;
    3. 服务器将Authorization header中的用户名和密码去除,进行验证。如果验证通过,将根据请求发送资源给客户端;
      HTTP OAuth认证:OAuth对于http来说,就是放在Authorization header中的不是用户名密码,而是一个token(令牌)。
        客户端的使用:客户端若要跟“使用基本认证的网站”进行交互,将用户名密码加载Authorization header中即可。