进化的抓包——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

在客户端增加debug log的打印,测试时通过androidios的开发ide进行查看;

3、fiddler插件

在fiddler中自定义插件进行解密,可直接看到解密结果

最优解

上述方案中1服务端测试常用;2客户端测试常用;但这两种都很麻烦而且测试中可用、但如果排查线上问题或使用正式版本的客户端就无法使用了;所以最优解肯定是直接在抓包工具中查看明文的方法3;

fiddler plugin开发步骤

先看下效果,选中要翻译的请求,切换到自定义选项卡,即可展示明文,如下图:

1、c#开发环境,新建项目(visual studio这里用的是2015,.net framework这里用的4.6)

进化的抓包——fiddler plugin

2、项目添加fiddler引用

进化的抓包——fiddler plugin

主要添加fiddler.exe,目的是引用fiddler提供的库

进化的抓包——fiddler plugin

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 更方便的抓包工具

fiddler——一款莱斯的抓包工具

了解fiddler:实现简单的抓包测试

常用的抓包工具:fiddler 随笔

全网最全fiddler使用教程和fiddler如何抓包(fiddler手机抓包)-笔者亲测

全网最全fiddler使用教程和fiddler如何抓包