Доверяйте сертификатам и собирайте трафик с помощью Fiddler на устройствах Safari, IE и iOS

Я настроил прокси-сервер 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
  • Android: Chrome
  • Mac OS: Chrome, Firefox. Safari не работает
  • iOS: нет

В моих файлах журналов я вижу следующие ошибки, зарегистрированные Fiddler в браузерах, которые не работают (для всех устройств). Пример запроса HTTPS:

2018-02-14 17: 25: 50.3860 | ИНФОРМАЦИЯ | ** LogString:! SecureClientPipeDirect не удалось: System.IO.IOException Аутентификация не удалась, поскольку удаленная сторона закрыла транспортный поток. для трубы (CN = *. optimizely.com, O = DO_NOT_TRUST_BC, OU = Создано http://www.fiddler2.com < / а>)

Из того, что я прочитал за последние пару дней, пытаясь найти решение для этого, причиной могут быть сертификаты, которым не доверяют на устройстве.

Тесты выполняются в BrowserStack с использованием предоставляемой ими функции под названием BrowserStack Local. Подробности об этом здесь и здесь.

Теперь мои вопросы можно разделить на настольные и мобильные:

  • Почему Chrome и Firefox могут делать HTTPS-запросы, в то время как IE, Edge и Safari не могут этого сделать?
  • В частности, для iOS есть здесь документация Fiddler для iOS, в которой указаны необходимые шаги. для настройки устройства. Однако, как я уже упоминал, я использую не собственные устройства iOS, а физические, предоставленные BrowserStack. Есть ли способ программно доверять сертификату на устройстве iOS (iOS 9.x, iOS 10.x, iOS 11.x)?

Есть ли какие-нибудь обходные пути, которые я мог бы использовать?

РЕДАКТИРОВАТЬ: локальные журналы FiddlerCore и BrowserStack здесь.


person Cosmin    schedule 14.02.2018    source источник
comment
Я не понимаю, как этот вопрос связан с c # или программированием в целом.   -  person Camilo Terevinto    schedule 14.02.2018
comment
Fiddler - это прокси-инструмент на основе .NET / C #, и я ищу недостатки / ошибки / улучшения в предоставленной сути, которые помогут мне решить проблему. Я не понимаю, почему это не связано с C # или программированием.   -  person Cosmin    schedule 14.02.2018
comment
Можете попробовать подписаться? ServicePointManager .ServerCertificateValidationCallback + = (отправитель, сертификат, цепочка, sslPolicyErrors) = ›true;   -  person FaizanHussainRabbani    schedule 14.02.2018
comment
Вы пробовали добавить [User-Agent]? msdn.microsoft.com/en-us/library /ms537503(v=vs.85).aspx   -  person jdweng    schedule 14.02.2018
comment
@FaizanRabbani Я добавил обратный вызов для проверки сертификата, но не заметил никаких изменений.   -  person Cosmin    schedule 15.02.2018
comment
@jdweng Пытался добавить User-Agent, но все равно не работал (добавлен для iOS): session.oRequest["User-Agent"] = "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0_1 like Mac OS X) AppleWebKit/604.2.10 (KHTML, like Gecko) Version/11.0 Mobile/15A8391 Safari/604.1"; session.oRequest["Connection"] = "keep-alive";   -  person Cosmin    schedule 15.02.2018
comment
Я бы использовал сниффер, например wirehark или fiddler, и сравнил бы хорошие результаты с плохими. Обычно нужно добавить просто заголовок. Проверьте сообщения http и сравните заголовки. Проверьте, получаете ли вы http 1.0 (режим потока) или http1.1 (режим фрагмента) как для запроса, так и для ответа.   -  person jdweng    schedule 15.02.2018
comment
Настройка | ServicePointManager .ServerCertificateValidationCallback | полезно только поместить внутрь приложения client, которое вы хотите (опасно) игнорировать действительность сертификата сервера. Это бесполезно в FiddlerCore.   -  person EricLaw    schedule 15.02.2018
comment
@Cosmin, посмотри, поможет ли это telerik .com / forum /   -  person Tarun Lalwani    schedule 18.02.2018
comment
@EricLaw В качестве примечания, все шаги отсюда уже были выполнены (до этого сообщения SO), но все еще безуспешно.   -  person Cosmin    schedule 19.02.2018


Ответы (1)


Начиная с вашего второго вопроса, здесь на официальном Telerik, в которых говорится:

SSL2 никогда не должен быть включен, и он не включен в Fiddler, если вы не сделаете все возможное, чтобы выстрелить себе в ногу.

Если вы правильно настроили свое устройство iOS для доверия корневому сертификату Fiddler, перехват HTTPS будет работать правильно на клиентах, за исключением случаев, когда используется закрепление сертификата. Хотя закрепление сертификатов в Chrome не имеет значения на рабочем столе, на iOS они игнорируют хранилище доверенных сертификатов, и, как следствие, перехват Fiddler не будет работать. Но большинство сайтов и приложений не используют закрепление. Если на сайте или в приложении используется закрепление, нет никакого обходного пути, кроме взлома устройства. Это ограничение не является уникальным для Fiddler - каждый прокси-сервер, расшифровывающий HTTPS, имеет точно такое же ограничение.

Я думаю, это ответит на ваш первый ответ, так как IE использует закрепление сертификатов, насколько я помню.

person Barr J    schedule 21.02.2018