Fiddler自定义脚本实现批量替换请求头

前言

在写爬虫分析网页时最常用的软件便是Fiddler,它能很方便的对HTTP、HTTPS请求进行拦截、修改、重发等。通常其默认功能便可以满足我们日常需要,但在某次使用Fiddler抓小程序HTTPS包时,需要帮其它微信用户进行小程序的操作,而微信只能单点登录,又不方便在测试时频繁让别人在这边登录微信,因此就需要在获取他人的小程序的Token后,将自己小程序的所有请求批量替换Token,最终实现只需要登录自己微信便可以操作其它微信账户的小程序。

Fiddler Script

脚本介绍

运行Fiddler软件,然后在工具栏->Rules->Customize Rules打开自定义规则脚本:

https://cdn.jsdelivr.net/gh/wefantasy/FileCloud/img/20210405094903.png
打开自定义规则脚本

Fiddler规则中所有操作都在Handlers类中定义完成,其默认已有很多变量和函数,其中最常用的函数主要有两个:OnBeforeRequestOnBeforeResponse。Fiddler在发送每个请求的过程中都会调用该类的一些方法——OnBeforeRequest(不可用response类对象,因为它未被创建)函数会在每个请求前被调用,OnBeforeResponse(可用request类对象,但对它的修改毫无意义)会在每个响应前被调用,之后我们所有需求都将会在这两个函数内完成。1

常用规则2

  1. 替换响应json里面部分参数后返回
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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);
 }
  1. 修改request的Body里面的部分参数
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
if(oSession.uriContains("http://www.baidu.com"))
{
	// 获取Request 中的body字符串
	var strBody=oSession.GetRequestBodyAsString();
	// 用正则表达式或者replace方法去修改string,将false改为true
	strBody=strBody.replace("false","true");
	// 弹个对话框检查下修改后的body 
	FiddlerObject.alert(strBody);
	// 将修改后的body,重新写回Request中
	oSession.utilSetRequestBody(strBody);
}
  1. 修改request的cookie并将请求改为红色
1
2
3
4
5
6
7
8
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;
    oSession["ui-color"] = "red";
}
  1. 保存某个接口的数据到本地
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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();
}

批量替换Token

  1. 自定义替换函数
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
static function ChangeData(oSession: Session){
	if (oSession.HostnameIs("test.com") && 1) {
		var requestBodyStr=oSession.GetRequestBodyAsString();
        // 替换电话15877778888为15888889999
		if(requestBodyStr.Contains("mobile")){
			var requestBodyStr2 = requestBodyStr.Replace("mobile=15877778888","mobile=15888889999")
			FiddlerObject.log("电话 "+requestBodyStr+" 替换为 "+requestBodyStr2);
			oSession.utilSetRequestBody(requestBodyStr2)
		}
        // 替换Token
		if(oSession.RequestHeaders.Exists("token")){
			var token = oSession.RequestHeaders.FindAll("token");
			var tokenNew = "Some Token";
			oSession.RequestHeaders.Remove("token")
			oSession.oRequest.headers.Add("token", tokenNew);
			FiddlerObject.log("token "+token[0]+" 替换为 "+tokenNew);
		}
		
	}
}
  1. 在OnBeforeRequest调用自定义函数(第一行添加以下代码):
1
2
3
4
static function OnBeforeRequest(oSession: Session) {
	ChangeData(oSession)
	......
}

参考


  1. 树桐robot. Fiddler 之修改请求或响应. 掘金. [2019-12-30] ↩︎

  2. 派大星. Fiddler高级使用——规则编写. 派大星的博客. [2019-03-11] ↩︎