进化的抓包——fiddler plugin
Posted 搜狗测试
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进化的抓包——fiddler plugin相关的知识,希望对你有一定的参考价值。
前言
在测接口的过程中,少不了的就是去抓包,一来验证client-server的数据交换是否准确,二来,抓包也是在追查问题时的必要步骤;但是随着接口安全越来越被重视,各种对接口的加密方式,导致通过抓包来查看接口内容变得越来越麻烦,趁着放假研究了一下之前一直知道但又模糊的概念——fiddler plugin。
问题场景
以下几种场景,对需要抓包的测试同行们极不友好1、接口内容有各种加密,从最简单的base64,到aes,再到rsa。。这直接导致无法从抓到的包中直接查看请求内容;2、一些非明文传输协议,例如protobuf,需要用proto文件生成对应语言的库文件进行转换;3、一些非加密字段,但字段命名含义不明确或参数较多,需要对请求中内容进行翻译后展示;
解决方案
1、服务端打印明文查看
客户端指向测试服务器,测试服务器打印解释后的明文,通过远程工具查看log文件;
2、客户端增加debug log
3、fiddler插件
在fiddler中自定义插件进行解密,可直接看到解密结果
最优解
上述方案中1服务端测试常用;2客户端测试常用;但这两种都很麻烦而且测试中可用、但如果排查线上问题或使用正式版本的客户端就无法使用了;所以最优解肯定是直接在抓包工具中查看明文的方法3;
fiddler plugin开发步骤
先看下效果,选中要翻译的请求,切换到自定义选项卡,即可展示明文,如下图:
1、c#开发环境,新建项目(visual studio这里用的是2015,.net framework这里用的4.6)
2、项目添加fiddler引用
主要添加fiddler.exe,目的是引用fiddler提供的库
3、设置插件要求的fiddler最低版本
4、创建界面控件dv.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace SDKDecryption
{
public partial class DecryptionViewer : UserControl
{
public DecryptionViewer()
{
InitializeComponent();
}
private void DecryptionViewer_Load(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
public void setText(string content)
{
this.richTextBox1.Text = content;
}
public void clearText()
{
this.richTextBox1.Clear();
}
}
}
5、在主函数中关联界面控件,并实现处理逻辑
using Fiddler;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Standard;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace SDKDecryption
{
//实现fiddler内置接口Inspector2, IRequestInspector2, IBaseInspector2
public sealed class Decryption : Inspector2, IRequestInspector2, IBaseInspector2
{
private DecryptionViewer myControl = new DecryptionViewer();
private bool m_bReadOnly;
private byte[] m_entityBody;
private HTTPRequestHeaders m_Headers;
private JSONRequestViewer jsonRequestViewer;
public Decryption()
{
this.jsonRequestViewer = new JSONRequestViewer();
}
public void DoDecryption()
{
String path = this.m_Headers.RequestPath;
//可以打印log来调试
FiddlerApplication.Log.LogString("-------------test001"+"body"+this.m_entityBody+"len="+this.m_entityBody.Length);
if (this.m_entityBody == null || this.m_entityBody.Length == 0)
{
this.myControl.clearText();
}
else
{
//可以过滤请求uri包含*时再执行
if (path.Contains("test"))
{
FiddlerApplication.Log.LogString("-------------test002");
//此种方式才能将byte[]转换成常见的base64编码的字符串
String base64Body = System.Text.Encoding.Default.GetString(this.m_entityBody);
//将请求内容base64转码写入文本控件
myControl.setText(testresp);
}
else
{
String decodeBody = System.Text.Encoding.Default.GetString(this.m_entityBody);
myControl.setText(decodeBody);
}
}
}
//初始化fiddler请求body
public bool bReadOnly
{
get
{
return this.m_bReadOnly;
}
set
{
this.m_bReadOnly = value;
}
}
//初始化fiddler请求header
public HTTPRequestHeaders headers
{
get
{
FiddlerApplication.Log.LogString("headers get function.");
return m_Headers;
}
set
{
this.m_Headers = value;
}
}
//将处理完成的结果关联到界面控件
public override void AddToTab(TabPage o)
{
o.Text = "Proto2Json";
o.Controls.Add(this.myControl);
o.Controls[0].Dock = DockStyle.Fill;
}
public void Clear()
{
this.m_entityBody = null;
this.myControl.clearText();
}
public override int GetOrder() => 100;
}
}
6、编译成dll后,放到fiddler目录的Inspectors文件夹下,重启fiddler;
进一步优化
此次解决的是protobuf转json的问题,这里有两个问题:
1、c#不熟悉,写全套的转换逻辑比较费时;2、proto文件有更新的话,还需要重新修改插件源码并重新打包,替换dll;
为了解决这两个问题,想到了一个优化方案,原理见下图:
此处引入另一个服务B,提供一个protobuf转json的接口,fiddler插件tab页被点击触发时,将二进制请求body以http请求的形式post给服务B,由服务B将转换好的json返回给插件,再有插件写入文本控件中;这个服务B可以是任何你熟悉的语言,这样就完美解决了上述两个问题;当然此方法也可以用于其它需求,可以试fiddler本地插件更新起来更灵活;
以上是关于进化的抓包——fiddler plugin的主要内容,如果未能解决你的问题,请参考以下文章
有没有比 wireshark 和 fiddler 更方便的抓包工具