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

标签 c# ios ssl fiddler fiddlercore

我已经像在 gist here 中一样设置了我的 Fiddler 代理.

代码:

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
  • 安卓:Chrome
  • Mac 操作系统: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 的功能。关于它的详细信息是herehere .

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

  • 为什么 Chrome 和 Firefox 能够发出 HTTPS 请求,而 IE、Edge 和 Safari 却不能?
  • 专门针对 iOS,有适用于 iOS 的 Fiddler 文档 here指定配置设备所需的步骤。但是,正如我已经提到的,我使用的不是内部 iOS 设备,而是 BrowserStack 提供的物理设备。有没有办法以编程方式信任 iOS 设备(iOS 9.x、iOS 10.x、iOS 11.x)上的证书?

是否有任何我可以使用的解决方法?

编辑: FiddlerCore and BrowserStack Local logs are here.

最佳答案

从你的第二个问题开始,官方Telerik上有关于IOS设备的讨论。论坛声明:

SSL2 shouldn't ever be enabled, and it isn't enabled in Fiddler unless you go out of the way to shoot yourself in the foot.

If you've properly configured your iOS device to trust Fiddler's root certificate, then HTTPS interception will work properly in clients except where certificate pinning is in use. While Certificate Pinning in Chrome won't matter on the Desktop, on iOS they ignore the Trusted Certificates store and as a consequence Fiddler interception will not work. But most sites and apps do not use pinning. If a site or app uses pinning, there's no workaround short of jailbreaking the device. This isn't a limitation unique to Fiddler-- every HTTPS-decrypting proxy has exactly the same limitation.

我想这会回答您的第一个答案,而且 IE 正在使用证书固定,正如我记得的那样。

关于c# - 在 Safari、IE 和 iOS 设备上使用 Fiddler 信任证书并捕获流量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48792458/

相关文章:

SSL 信任链验证

java - setUseClientMode 是什么意思

python wsgi :ssl-error Can't connect to HTTPS URL because the SSL module is not available

ios - Alamofire 请求错误 : NSURLErrorDomain Code -1005 The network connection was lost

ios - 使用反余弦的线之间的绝对角度

ios - 从 url 创建缩略图

c# - 计算量大导致栈溢出错误

c# - 找不到 VSCode Unity OmniSharp .NETFramework

c# - 来自 List<String> 的 FromSqlRaw 参数可以安全地避免 SQL 注入(inject)

c# - 删除或替换,当我从字符串中删除子字符串时,哪个更好?