为了账号安全,请及时绑定邮箱和手机立即绑定

进化的抓包——fiddler plugin

前言

在测接口的过程中,少不了的就是去抓包,一来验证client-server的数据交换是否准确,二来,抓包也是在追查问题时的必要步骤;但是随着接口安全越来越被重视,各种对接口的加密方式,导致通过抓包来查看接口内容变得越来越麻烦,趁着放假研究了一下之前一直知道但又模糊的概念——fiddler plugin。

问题场景

以下几种场景,对需要抓包的测试同行们极不友好1、接口内容有各种加密,从最简单的base64,到aes,再到rsa。。这直接导致无法从抓到的包中直接查看请求内容;2、一些非明文传输协议,例如protobuf,需要用proto文件生成对应语言的库文件进行转换;3、一些非加密字段,但字段命名含义不明确或参数较多,需要对请求中内容进行翻译后展示;

解决方案

1、服务端打印明文查看

客户端指向测试服务器,测试服务器打印解释后的明文,通过远程工具查看log文件;

2、客户端增加debug log

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

3、fiddler插件

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

最优解

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

fiddler plugin开发步骤

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

https://img1.sycdn.imooc.com//5e5e0d8600019c7e10800819.jpg

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

https://img1.sycdn.imooc.com//5e5e0d870001c77810800751.jpg

2、项目添加fiddler引用

https://img1.sycdn.imooc.com//5e5e0d87000133c310800910.jpg

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

https://img1.sycdn.imooc.com//5e5e0d8700013ec410800551.jpg

3、设置插件要求的fiddler最低版本

https://img1.sycdn.imooc.com//5e5e0d8800018a9010800268.jpg


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;

为了解决这两个问题,想到了一个优化方案,原理见下图:

https://img1.sycdn.imooc.com//5e5e0d880001d45d10800561.jpg

此处引入另一个服务B,提供一个protobuf转json的接口,fiddler插件tab页被点击触发时,将二进制请求body以http请求的形式post给服务B,由服务B将转换好的json返回给插件,再有插件写入文本控件中;这个服务B可以是任何你熟悉的语言,这样就完美解决了上述两个问题;当然此方法也可以用于其它需求,可以试fiddler本地插件更新起来更灵活;


 spacer.gifhttp://m.imooc.com/act/june2021
spacer.gif http://m.imooc.com/act/rain2021?act_navBgClear=1

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
软件测试工程师
手记
粉丝
51
获赞与收藏
91

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 1
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消