在Safari、IE和iOS设备上使用Fiddler信任证书并捕获流量

7
我可以帮您进行翻译。这段内容是关于设置 Fiddler 代理的,具体操作可以参考此链接:gist here
代码如下:
public class ProxyConfig
    {
        private readonly string _secureEndpointHostname = IPAddress.Any.ToString();
        private readonly int _secureEndpointPort = 4555;
        private readonly int _port = 18882;

        private static readonly ICollection<Session> AllSessions = new List<Session>();

        private static Fiddler.Proxy _secureEndpoint;

        private static readonly LoggerCnx Logger = new LoggerCnx();
        private Action<string> onRequest;

        public ProxyConfig()
        {
        }

        public ProxyConfig(Action<string> onRequest)
        {
            this.onRequest = onRequest;
        }

        public void SetupProxyListener()
        {
            FiddlerApplication.SetAppDisplayName("FiddlerCoreProxyApp");

            // This is a workaround for known issue in .NET Core - https://github.com/dotnet/coreclr/issues/12668
            CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");

            // Simply echo notifications to the console.  Because Fiddler.CONFIG.QuietMode=true 
            // by default, we must handle notifying the user ourselves.
            //Fiddler.FiddlerApplication.OnNotification += delegate (object sender, NotificationEventArgs oNEA) { System.Diagnostics.Debug.WriteLine("** NotifyUser: " + oNEA.NotifyString); };
            FiddlerApplication.Log.OnLogString += delegate (object sender, LogEventArgs oLEA) { Logger.Info("** LogString: " + oLEA.LogString); };

            FiddlerApplication.BeforeRequest += delegate (Session session)
            {

                if (!CertMaker.rootCertIsTrusted())
                {
                    CertMaker.trustRootCert();
                }

                if (onRequest != null)
                {
                    onRequest(session.fullUrl);
                }

                // In order to enable response tampering, buffering mode MUST
                // be enabled; this allows FiddlerCore to permit modification of
                // the response in the BeforeResponse handler rather than streaming
                // the response to the client as the response comes in.
                session.bBufferResponse = false;
                lock (AllSessions)
                {
                    AllSessions.Add(session);
                    Logger.Info("Session: " + session.fullUrl);
                }
                session["X-AutoAuth"] = "(default)";

                if ((session.oRequest.pipeClient.LocalPort == _secureEndpointPort) && (session.hostname == _secureEndpointHostname))
                {
                    session.utilCreateResponseAndBypassServer();
                    session.oResponse.headers.SetStatus(200, "OK");
                    session.oResponse["Content-Type"] = "text/html; charset=UTF-8";
                    session.oResponse["Cache-Control"] = "private, max-age=0";
                    session.utilSetResponseBody("<html><body>Request for httpS://" + _secureEndpointHostname + ":" + _secureEndpointPort.ToString() + " received. Your request was:<br /><plaintext>" + session.oRequest.headers.ToString());
                }
            };

            Logger.Info($"Starting {FiddlerApplication.GetVersionString()}...");
            CONFIG.IgnoreServerCertErrors = true;
            CONFIG.bCaptureCONNECT = true;

            FiddlerApplication.Prefs.SetBoolPref("fiddler.network.streaming.abortifclientaborts", true);

            FiddlerCoreStartupFlags startupFlags = FiddlerCoreStartupFlags.Default;

            startupFlags = (startupFlags | FiddlerCoreStartupFlags.DecryptSSL);
            startupFlags = (startupFlags | FiddlerCoreStartupFlags.AllowRemoteClients);
            startupFlags = (startupFlags & ~FiddlerCoreStartupFlags.MonitorAllConnections);
            startupFlags = (startupFlags & ~FiddlerCoreStartupFlags.CaptureLocalhostTraffic);

            FiddlerApplication.Startup(_port, startupFlags);

            Logger.Info("Created endpoint listening on port {0}", _port);

            Logger.Info("Starting with settings: [{0}]", startupFlags);
            Logger.Info("Gateway: {0}", CONFIG.UpstreamGateway.ToString());

            // Create a HTTPS listener, useful for when FiddlerCore is masquerading as a HTTPS server
            // instead of acting as a normal CERN-style proxy server.
            _secureEndpoint = FiddlerApplication.CreateProxyEndpoint(_secureEndpointPort, true, _secureEndpointHostname);
            if (null != _secureEndpoint)
            {
                Logger.Info("Created secure endpoint listening on port {0}, using a HTTPS certificate for '{1}'", _secureEndpointPort, _secureEndpointHostname);
            }
        }
    }

该软件的目的是捕获并分析来自Windows、Mac OS X、Android和iOS浏览器(主要是Chrome、Firefox和Safari,包括桌面设备和移动设备)的流量。

到目前为止,它似乎可以在以下设备上运行:

  • Windows浏览器:Chrome、Firefox。但不支持IE和Edge
  • Android:Chrome
  • Mac OS:Chrome、Firefox。但不支持Safari
  • iOS:无法运行

在我的日志文件中,我看到Fiddler记录了一些错误,这些错误出现在不能正常工作的浏览器上(适用于所有设备)。以下是一个HTTPS请求的示例:

2018-02-14 17:25:50.3860 | INFO | ** LogString: !SecureClientPipeDirect failed: System.IO.IOException Authentication failed because the remote party has closed the transport stream. for pipe (CN=*.optimizely.com, O=DO_NOT_TRUST_BC, OU=Created by http://www.fiddler2.com)

根据我最近几天阅读的内容,试图找出解决方案,原因可能是设备上不信任证书。

测试正在使用BrowserStack进行,使用他们提供的名为BrowserStack Local的功能。有关详细信息,请单击此处此处

现在我的问题可以分为桌面和移动设备:

  • 为什么Chrome和Firefox能够进行HTTPS请求,而IE、Edge和Safari无法做到?
  • 特别针对iOS,这里有一个iOS Fiddler文档此处,指定了配置设备所需的步骤。然而,正如我已经提到的,我没有使用内部iOS设备,而是由BrowserStack提供的物理设备。有没有办法在iOS设备上以编程方式信任证书(iOS 9.x、iOS 10.x、iOS 11.x)?

有没有任何解决方法可供我使用?

编辑:FiddlerCore和BrowserStack Local的日志在这里。


我看不出这个问题与 [tag: c#] 或编程总体有何关联。 - Camilo Terevinto
2
Fiddler是一个基于.NET/C#的代理工具,我正在寻找提供的要点中的缺陷/错误/增强项,以帮助我解决问题。我不明白为什么这与C#或编程无关。 - Cosmin
你能试一下以下代码吗?ServicePointManager .ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true; - FaizanHussainRabbani
@FaizanRabbani 我已经添加了证书验证回调,但是没有看到任何变化。 - Cosmin
我会使用类似Wireshark或Fiddler的嗅探工具,将好的结果与坏的结果进行比较。通常只需要添加一个标头即可解决问题。检查HTTP消息并比较标头。检查请求和响应的HTTP版本是否为HTTP 1.0(流模式)或HTTP 1.1(分块模式)。 - jdweng
显示剩余5条评论
1个回答

4
从你的第二个问题开始,官方Telerik论坛上有一篇关于IOS设备的讨论,其中写道:(链接)

SSL2不应该被启用,而且在Fiddler中也没有启用,除非你特别设置自己的证书。

如果你已经正确配置了你的iOS设备来信任Fiddler的根证书,那么除了证书固定以外,HTTPS拦截将在客户端中正常工作。尽管Chrome的证书固定在桌面上不起作用,在iOS上他们忽略了可信证书存储库,因此Fiddler的拦截将无法工作。但是大多数网站和应用程序都不使用证书固定。如果一个网站或应用程序使用了固定,那么除了越狱设备之外,就没有其他解决方法了。这不是Fiddler所特有的限制——每个HTTPS解密代理都有完全相同的限制。

我想这也回答了你的第一个问题,IE也会像我记得的那样使用证书固定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接