Example #1
0
 public static void AddHostnameRecord(Hostnames host, ObservableCollection <Hostnames> enumeratedHostnames, MainWindow UI)
 {
     App.Current.Dispatcher.Invoke((Action) delegate
     {
         if (enumeratedHostnames.Any(p => p.Hostname == host.Hostname && p.ipAddress.ToString() == host.ipAddress.ToString()))
         {
             //Could add some sexier code here to update/add/overwrite if not all values match
         }
         else
         {
             enumeratedHostnames.Add(host);
             UI.saveEnumeratedHostnames(null, Enums.SaveType.autoLog);
         }
     });
 }
 public static ServiceInterface getOrCreateServiceInterface(List <ServiceInterface> serviceInterfaces, MainWindow UI, ObservableCollection <Hostnames> enumeratedHostnames)
 {
     if (serviceInterfaces.Any(u => u.service == MicrosoftService.Skype))
     {
         UI.ThreadSafeAppendLog("[3]Selecting existing Skype interface...");
         IEnumerable <ServiceInterface> allSkype = serviceInterfaces.Where(x => x.service == MicrosoftService.Skype);
         foreach (ServiceInterface serv in allSkype)
         {
             if (serv.host.RealLync == true)
             {
                 serv.postCompromise.RealAddress = serv.host.Hostname;
                 return(serv);
             }
         }
     }
     else
     {
         //Don't already have service interface for skype - so create if we can
         if (enumeratedHostnames.Any(x => x.Service == MicrosoftService.Skype && x.RealLync == true))
         {
             Hostnames enumeratorHostname = (enumeratedHostnames.Where(x => x.Service == MicrosoftService.Skype && x.RealLync == true)).First();
             UI.ThreadSafeAppendLog("[3]Adding new enumerator with service: " + MicrosoftService.Skype);
             ServiceInterface serviceInterface = new ServiceInterface()
             {
                 host = enumeratorHostname, service = MicrosoftService.Skype, UI = UI, enumerator = new UsernameEnumeration(), sprayer = new PasswordSpray(), postCompromise = new PostCompromise()
                 {
                     RealAddress = enumeratorHostname.Hostname, UI = UI
                 }
             };
             serviceInterfaces.Add(serviceInterface);
             return(serviceInterface);
         }
         else
         {
             //error message comes from what calls this
             return(null);
         }
     }
     return(null);
 }
        public URLObject FindNTLMEndpoints(Hostnames host)
        {
            switch (host.Service)
            {
            case MicrosoftService.Skype:
                //Only do for real address - as we've already added this at validation
                UI.ThreadSafeAppendLog("[3]Adding Skype URLs...");
                //Load list of Lync related URLs
                addLinesFromFile("Lync", host.Hostname);
                return(DiscoverNTLM());

            case MicrosoftService.ADFS:
                //Load list of ADFS related URLs
                UI.ThreadSafeAppendLog("[3]Adding ADFS URLs...");
                addLinesFromFile("ADFS", host.Hostname);
                return(DiscoverNTLM());

            case MicrosoftService.Exchange:
                //Load list of Exchange related URLs
                UI.ThreadSafeAppendLog("[3]Adding Exchange URLs...");
                addLinesFromFile("Exchange", host.Hostname);
                return(DiscoverNTLM());

            case MicrosoftService.Exchange2007:
                //Load list of Exchange related URLs
                UI.ThreadSafeAppendLog("[3]Adding Exchange 2007 URLs...");
                addLinesFromFile("Exchange2007", host.Hostname);
                return(DiscoverNTLM());

            case MicrosoftService.RDWeb:
                //Load list of RDWeb related URLs
                UI.ThreadSafeAppendLog("[3]Adding RDWeb URLs...");
                addLinesFromFile("RDWeb", host.Hostname);
                return(DiscoverNTLM());
            }
            return(null);
        }
        private void ParseNTLM(string ntlmResponseString, Hostnames host, string url)
        {
            byte[] test = Convert.FromBase64String(ntlmResponseString);
            string hex  = BitConverter.ToString(test);

            //NEW - Thanks @ROSS
            int DOMAIN_SUPPLIED      = 0x1000;
            int WORKSTATION_SUPPLIED = 0x2000;
            int END_OF_LINE          = 0x0000;
            int NB_COMPUTER_NAME     = 0x0001;
            int NB_DOMAIN_NAME       = 0x0002;
            int DNS_COMPUTER_NAME    = 0x0003;
            int DNS_DOMAIN_NAME      = 0x0004;
            int DNS_FOREST_NAME      = 0x0005;

            byte[] bytesFirst7 = new byte[7];
            Array.Copy(test, 0, bytesFirst7, 0, 7);
            if (Encoding.ASCII.GetString(bytesFirst7) != "NTLMSSP")
            {
                UI.ThreadSafeAppendLog("[3]Not a valid NTLM response.");
            }
            else
            {
                UI.ThreadSafeAppendLog("[3]Valid NTLM response.");
                int offset  = 8;
                int version = BitConverter.ToInt32(test, offset);
                UI.ThreadSafeAppendLog("[3] NTLM Authentication Version: " + version);
                offset += 4;
                int flags = BitConverter.ToInt32(test, offset);
                offset += 4;

                //NTLM v1
                if (version == 1)
                {
                    if ((flags & DOMAIN_SUPPLIED) == DOMAIN_SUPPLIED)
                    {
                        int domainLength = BitConverter.ToInt16(test, offset);
                        offset += 2;

                        int domainOffset = BitConverter.ToInt32(test, offset);
                        offset += 4;
                        byte[] domain = new byte[domainLength];
                        Array.Copy(test, domainOffset, domain, 0, domainLength);
                        string domainString = Encoding.ASCII.GetString(domain);
                        UI.ThreadSafeAppendLog("[3]Domain: " + domainString);
                        host.NTLMDomain = domainString;
                    }
                    if ((flags & WORKSTATION_SUPPLIED) == WORKSTATION_SUPPLIED)
                    {
                        int workstationLength = BitConverter.ToInt16(test, offset);
                        offset += 2;
                        int workstationOffset = BitConverter.ToInt32(test, offset);
                        offset += 4;

                        byte[] workstation = new byte[workstationLength];
                        Array.Copy(test, workstationOffset, workstation, 0, workstationLength);
                        string workstationString = Encoding.ASCII.GetString(workstation);
                        UI.ThreadSafeAppendLog("[3]Workstation: " + workstationString);
                    }
                }
                else if (version == 2)
                {
                    offset = 40;
                    //Skip server challenge and reserved
                    //offset += 16;
                    int targetInfoLength = BitConverter.ToInt16(test, offset);
                    //Skip past length (which we have) and something that should also = length as well?!
                    //ThreadSafeAppendLog("[3]Target Info Length: " + targetInfoLength);
                    offset += 4;
                    int targetInfoOffset = BitConverter.ToInt32(test, offset);
                    //ThreadSafeAppendLog("[3]Target Info Offset: " + targetInfoOffset);
                    offset += 4;

                    byte[] TargetInfo = new byte[targetInfoLength];
                    Array.Copy(test, targetInfoOffset, TargetInfo, 0, targetInfoLength);
                    string testTargetInfo = BitConverter.ToString(TargetInfo);
                    //ThreadSafeAppendLog("[3]test string: " + testTargetInfo);
                    string test1Target = testTargetInfo.Replace("-", "");
                    string test2Target = test1Target.Replace("00", "");
                    //string targetInfoString = Encoding.ASCII.GetString(TargetInfo);
                    //ThreadSafeAppendLog("[3]Target Info: " + test2Target);

                    //Now need to go through and pull each bit
                    int flag_end           = 1;
                    int offset_Target_Info = 0;
                    while (flag_end != END_OF_LINE)
                    {
                        int AvLd = BitConverter.ToInt16(TargetInfo, offset_Target_Info);
                        flag_end = AvLd;

                        offset_Target_Info += 2;
                        int AvLength = BitConverter.ToInt16(TargetInfo, offset_Target_Info);
                        //ThreadSafeAppendLog("[3]AvLength: " + AvLength);
                        offset_Target_Info += 2;
                        if ((flag_end & NB_COMPUTER_NAME) == NB_COMPUTER_NAME)
                        {
                            //ThreadSafeAppendLog("[3]Flag: " + flag_end);
                            byte[] NBName = new byte[AvLength];
                            Array.Copy(TargetInfo, offset_Target_Info, NBName, 0, AvLength);
                            //ThreadSafeAppendLog("[3]NB AV LD: " + AvLd);
                            //ThreadSafeAppendLog("[3]NB AV Length: " + AvLength);
                            //ThreadSafeAppendLog("[3]NBLength: " + NBName.Length);
                            string NBNameHex      = BitConverter.ToString(NBName);
                            string test1NB        = NBNameHex.Replace("-", "");
                            string test2NB        = test1NB.Replace("00", "");
                            var    rtfBytesNBName = FromHex(test2NB);
                            string NBNameString   = Encoding.ASCII.GetString(rtfBytesNBName);
                            UI.ThreadSafeAppendLog("[3]NB Name String: " + NBNameString);
                            //string test2NB = test1NB.Replace("00", "");
                            //ThreadSafeAppendLog("[3]NETBIOS Computer Name: " + NBNameString);
                            offset_Target_Info += AvLength;
                        }
                        else if ((flag_end & NB_DOMAIN_NAME) == NB_DOMAIN_NAME)
                        {
                            byte[] NBDomainName = new byte[AvLength];
                            Array.Copy(TargetInfo, offset_Target_Info, NBDomainName, 0, AvLength);
                            string NBDomainNameHex      = BitConverter.ToString(NBDomainName);
                            string test1NBDN            = NBDomainNameHex.Replace("-", "");
                            string test2NBDN            = test1NBDN.Replace("00", "");
                            var    rtfBytesNBDomainName = FromHex(test2NBDN);
                            string NBDomainNameString   = Encoding.ASCII.GetString(rtfBytesNBDomainName);
                            host.NTLMDomain = NBDomainNameString;
                            UI.ThreadSafeAppendLog("[4]NTLM Domain name: " + host.NTLMDomain);
                            offset_Target_Info += AvLength;
                        }
                        else if ((flag_end & DNS_COMPUTER_NAME) == DNS_COMPUTER_NAME)
                        {
                            byte[] DNSComputerName = new byte[AvLength];
                            Array.Copy(TargetInfo, offset_Target_Info, DNSComputerName, 0, AvLength);
                            string DNSComputerNameHex      = BitConverter.ToString(DNSComputerName);
                            string test1DNSCN              = DNSComputerNameHex.Replace("-", "");
                            string test2DNSCN              = test1DNSCN.Replace("00", "");
                            var    rtfBytesDNSComputerName = FromHex(test2DNSCN);
                            string DNSComputerNameString   = Encoding.ASCII.GetString(rtfBytesDNSComputerName);
                            UI.ThreadSafeAppendLog("[2]Service Hostname: " + DNSComputerNameString);
                            //ThreadSafeAppendLog("[3]DNS Computer Name: " + DNSComputerNameString);
                            offset_Target_Info += AvLength;
                        }
                        else if ((flag_end & DNS_DOMAIN_NAME) == DNS_DOMAIN_NAME)
                        {
                            byte[] DNSDomainName = new byte[AvLength];
                            Array.Copy(TargetInfo, offset_Target_Info, DNSDomainName, 0, AvLength);
                            string DNSDomainNameHex      = BitConverter.ToString(DNSDomainName);
                            string test1DNSDN            = DNSDomainNameHex.Replace("-", "");
                            string test2DNSDN            = test1DNSDN.Replace("00", "");
                            var    rtfBytesDNSDomainName = FromHex(test2DNSDN);
                            string DNSDomainNameString   = Encoding.ASCII.GetString(rtfBytesDNSDomainName);
                            host.OAuthDomain = DNSDomainNameString;
                            UI.ThreadSafeAppendLog("[3]OAuth Domain name: " + host.OAuthDomain);
                            //ThreadSafeAppendLog("[3]DNS Domain Name: " + DNSDomainNameString);
                            offset_Target_Info += AvLength;
                        }
                        else if ((flag_end & DNS_FOREST_NAME) == DNS_FOREST_NAME)
                        {
                            byte[] DNSForestName = new byte[AvLength];
                            Array.Copy(TargetInfo, offset_Target_Info, DNSForestName, 0, AvLength);
                            string DNSForestNameHex      = BitConverter.ToString(DNSForestName);
                            string test1DNSFN            = DNSForestNameHex.Replace("-", "");
                            string test2DNSFN            = test1DNSFN.Replace("00", "");
                            var    rtfBytesDNSForestName = FromHex(test2DNSFN);
                            string DNSForestNameString   = Encoding.ASCII.GetString(rtfBytesDNSForestName);
                            UI.ThreadSafeAppendLog("[4] DNS Forest Name: " + DNSForestNameString);
                            //ThreadSafeAppendLog("[3]DNS Forest Name: " + DNSForestNameString);
                            offset_Target_Info += AvLength;
                        }
                        else
                        {
                            //ThreadSafeAppendLog("[3]Skipping");
                            offset_Target_Info += AvLength;
                        }
                        //ThreadSafeAppendLog("[3]Loop");
                    }
                    //ThreadSafeAppendLog("[3]Broken Out");
                }
            }
        }
        private void MakeNTLMRequests(Hostnames host, bool isADFS)
        {
            if (host.NTLMDomain == "" && host.OAuthDomain == "")
            {
                if (host.SprayURL.Url != "")
                {
                    if (host.SprayURL.Type == URLType.NTLM)
                    {
                        //So we already have NTLM spray URL - do it there as that's what we'll be hitting
                        //Make NTLM Auth Request
                        WebRequests NTLMWebRequest = CreateWebRequest(host.SprayURL.Url);
                        UI.ThreadSafeAppendLog("[3]Testing for NTLM authentication at URL: " + NTLMWebRequest.request.RequestUri + "...");
                        if (isADFS)
                        {
                            NTLMWebRequest.request.Headers.Add("Authorization", "Negotiate TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==");
                        }
                        else
                        {
                            NTLMWebRequest.request.Headers.Add("Authorization", "NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==");
                        }
                        HttpWebResponse     NTLMResponse = NTLMWebRequest.MakeGETRequest();
                        WebHeaderCollection headers      = WebRequests.GetResponseHeaders(NTLMResponse);
                        if (headers != null)
                        {
                            string ntlmResponse = headers.ToString();
                            //FOR DOMAIN INFORMATION - don't want to check has NTLM or Negotiate as we still just want to get the response even if we can't spray
                            UI.ThreadSafeAppendLog("[3]NTLM Response: " + ntlmResponse);
                            if (isADFS)
                            {
                                Match NTLMString = RegexClass.ReturnMatch(Regexs.NTLMResponseADFS, ntlmResponse);
                                if (NTLMString.Success)
                                {
                                    ParseNTLM(NTLMString.Value, host, host.SprayURL.Url);
                                }
                                else
                                {
                                    Match NTLMString2 = RegexClass.ReturnMatch(Regexs.NTLMResponse, ntlmResponse);
                                    if (NTLMString2.Success)
                                    {
                                        ParseNTLM(NTLMString2.Value, host, host.SprayURL.Url);
                                    }
                                }
                            }
                            else
                            {
                                Match NTLMString = RegexClass.ReturnMatch(Regexs.NTLMResponse, ntlmResponse);
                                if (NTLMString.Success)
                                {
                                    ParseNTLM(NTLMString.Value, host, host.SprayURL.Url);
                                }
                            }
                        }
                        else
                        {
                            UI.ThreadSafeAppendLog("[2]Null Resposne");
                        }
                    }
                }

                //Do yet ANOTHER test - have we cracked it above - if not - cycle through list of possibles...
                if (host.NTLMDomain == "" && host.OAuthDomain == "")
                {
                    foreach (string url in URLs)
                    {
                        //Do the check again in case the last one has now filled these in
                        if (host.NTLMDomain == "" && host.OAuthDomain == "")
                        {
                            //Make NTLM Auth Request
                            WebRequests NTLMWebRequest = CreateWebRequest(url);
                            UI.ThreadSafeAppendLog("[3]Testing for NTLM authentication at URL: " + NTLMWebRequest.request.RequestUri + "...");
                            if (isADFS)
                            {
                                NTLMWebRequest.request.Headers.Add("Authorization", "Negotiate TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==");
                            }
                            else
                            {
                                NTLMWebRequest.request.Headers.Add("Authorization", "NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==");
                            }
                            HttpWebResponse     NTLMResponse = NTLMWebRequest.MakeGETRequest();
                            WebHeaderCollection headers      = WebRequests.GetResponseHeaders(NTLMResponse);
                            if (headers != null)
                            {
                                string ntlmResponse = headers.ToString();
                                //FOR DOMAIN INFORMATION - don't want to check has NTLM or Negotiate as we still just want to get the response even if we can't spray
                                UI.ThreadSafeAppendLog("[3]NTLM Response: " + ntlmResponse);
                                if (isADFS)
                                {
                                    Match NTLMString = RegexClass.ReturnMatch(Regexs.NTLMResponseADFS, ntlmResponse);
                                    if (NTLMString.Success)
                                    {
                                        ParseNTLM(NTLMString.Value, host, url);
                                    }
                                    else
                                    {
                                        Match NTLMString2 = RegexClass.ReturnMatch(Regexs.NTLMResponse, ntlmResponse);
                                        if (NTLMString2.Success)
                                        {
                                            ParseNTLM(NTLMString2.Value, host, host.SprayURL.Url);
                                        }
                                    }
                                }
                                else
                                {
                                    Match NTLMString = RegexClass.ReturnMatch(Regexs.NTLMResponse, ntlmResponse);
                                    if (NTLMString.Success)
                                    {
                                        ParseNTLM(NTLMString.Value, host, url);
                                    }
                                }
                            }
                            else
                            {
                                UI.ThreadSafeAppendLog("[2]Null Resposne");
                            }
                        }
                        else
                        {
                            UI.ThreadSafeAppendLog("[4]Break");
                            break;
                        }
                    }
                }
            }
        }
Example #6
0
        public bool CheckFederated()
        {
            UI.ThreadSafeAppendLog("[2]Checking organisation federated status...");
            WebRequests checkFederated = CreateWebRequestFederated("https://login.microsoftonline.com/common/userrealm/?user=john.smith@" + targetDomain + "&api-version=2.1&checkForMicrosoftAccount=true");

            HttpWebResponse federatedWebResponse = checkFederated.MakeGETRequest();
            string          responseFederated    = WebRequests.GetResponseString(federatedWebResponse);

            JObject federatedResponse = JObject.Parse(responseFederated);

            string isFederated = (string)federatedResponse.SelectToken("NameSpaceType");
            string brandName   = (string)federatedResponse.SelectToken("FederationBrandName");

            UI.ThreadSafeAppendLog("[2][*]Organisation brand name: " + brandName);
            if (federatedResponse != null)
            {
                JToken interim = federatedResponse.SelectToken("TenantBrandingInfo[0]");
                if (interim != null)
                {
                    var signInDisabled = interim.SelectToken("KeepMeSignedInDisabled");
                    //bool signInDisabled = (bool)federatedResponse.SelectToken("TenantBrandingInfo[0].KeepMeSignedInDisabled");
                    UI.ThreadSafeAppendLog("[2][*]Organisation - cloud setting KeepMeSignedInDisabled: " + signInDisabled);
                }
            }


            if (isFederated == "Federated")
            {
                UI.ThreadSafeAppendLog("[2][*]Organisation is federated - password spraying needs to hit ADFS not O365 login...");
                string ADFSUrl = (string)federatedResponse.SelectToken("AuthURL");
                //Need to check and add ADFS record here
                //Strip out server name
                string ADFSUrlStripped = "";
                Match  match           = RegexClass.ReturnMatch(Regexs.ADFSAuthURL, ADFSUrl);
                if (match.Success)
                {
                    ADFSUrlStripped = match.Value;
                }
                if (ADFSUrlStripped != "")
                {
                    UI.ThreadSafeAppendLog("[2]Validating ADFS Auth URL: https://" + ADFSUrlStripped + "/adfs/ls/idpinitiatedsignon");
                    WebRequests ADFSValidationRequest = CreateWebRequest("https://" + ADFSUrlStripped + "/adfs/ls/idpinitiatedsignon");

                    HttpWebResponse     ADFSValidationRequestResponse = ADFSValidationRequest.MakeGETRequest();
                    string              responseADFSValidation        = WebRequests.GetResponseString(ADFSValidationRequestResponse);
                    WebHeaderCollection headersADFSValidation         = WebRequests.GetResponseHeaders(ADFSValidationRequestResponse);

                    if (headersADFSValidation != null)
                    {
                        if (headersADFSValidation.ToString().Contains("No authentication method configured for the URL in the request"))
                        {
                            UI.ThreadSafeAppendLog("[2]Server appears to have authentication disabled for: " + ADFSValidationRequest.url);
                        }
                        else if (responseADFSValidation.Contains("/adfs/"))
                        {
                            IPAddress[] ipaddrADFS;
                            IPHostEntry ipEntry;
                            ipEntry    = Dns.GetHostEntry(ADFSUrlStripped);
                            ipaddrADFS = ipEntry.AddressList;
                            Hostnames validADFS = new Hostnames()
                            {
                                O365 = "N", Hostname = ADFSUrlStripped, EnumURL = new URLObject()
                                {
                                    Url = "https://" + ADFSUrlStripped + "/adfs/ls/idpinitiatedsignon", Type = URLType.UserEnum
                                }, SprayURL = new URLObject()
                                {
                                    Url = "https://" + ADFSUrlStripped + "/adfs/ls/idpinitiatedsignon", Type = URLType.Oauth
                                }, Service = MicrosoftService.ADFS, ipAddress = ipaddrADFS.First()
                            };
                            //NOT GOT ANYTHING FOR O365 DISCOVERY HERE
                            CollectionUpdates.AddHostnameRecord(validADFS, UI.enumeratedHostnames, UI);
                            AddService.AddServiceToOptions(UI, validADFS.Service, true, true);
                        }
                    }
                }
                else
                {
                    UI.ThreadSafeAppendLog("[2]Unable to match ADFS URL...");
                }
                return(true);
            }
            else
            {
                UI.ThreadSafeAppendLog("[2][*]Organisation is not federated - password spraying can hit O365 login, and will provide details of MFA...");
                return(false);
            }

            //Need to properly JSON parse here - get NameSpaceType (if !null - if Federated
            //Also output - KeepMeSignedInDisabled and FederationBrandName

            //Basically - output - Federated/Managed/Whatever to UI - but is either true or false - Federated
            //Also output SignInDisabled and FederationBrandName - but don't need to add to any records anywhere

            //Also - pull AuthURL and add that record if Federated only
        }
Example #7
0
        public void Validate()
        {
            foreach (Hostnames host in toValidate)
            {
                bool breaker = false;
                switch (host.Service)
                {
                case MicrosoftService.ADFS:
                    //ENUM/SPRAY URLS ARE THE SAME - SO ONCE VALIDATED - ADD TO EACH
                    WebRequests         ADFSRequest  = CreateWebRequest("https://" + host.Hostname + "/adfs/ls/idpinitiatedsignon");
                    HttpWebResponse     adfsResponse = ADFSRequest.MakeGETRequest();
                    string              responseADFS = WebRequests.GetResponseString(adfsResponse);
                    WebHeaderCollection headersADFS  = WebRequests.GetResponseHeaders(adfsResponse);
                    if (areYouNginxOrNull(headersADFS))
                    {
                        breaker = true;
                        break;
                    }
                    if (headersADFS != null)
                    {
                        if (headersADFS.ToString().Contains("No authentication method configured for the URL in the request"))
                        {
                            UI.ThreadSafeAppendLog("[2]Server appears to have authentication disabled for: " + ADFSRequest.url);
                        }
                        else if (responseADFS.Contains("/adfs/"))
                        {
                            //NOT GOT ANYTHING FOR O365 DISCOVERY HERE
                            host.O365    = "N";
                            host.EnumURL = new URLObject()
                            {
                                Url = "https://" + host.Hostname + "/adfs/ls/idpinitiatedsignon", Type = URLType.UserEnum
                            };
                            host.SprayURL = new URLObject()
                            {
                                Url = "https://" + host.Hostname + "/adfs/ls/idpinitiatedsignon", Type = URLType.Oauth
                            };
                            CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                            AddService.AddServiceToOptions(UI, host.Service, true, true);
                        }
                    }
                    break;

                case MicrosoftService.Exchange:
                    //Validate USER ENUM
                    WebRequests         exchangeRequest  = CreateWebRequest("https://" + host.Hostname + "/owa/auth.owa");
                    HttpWebResponse     exchangeResponse = exchangeRequest.MakeGETRequest();
                    string              responseExchange = WebRequests.GetResponseString(exchangeResponse);
                    WebHeaderCollection headersExchange  = WebRequests.GetResponseHeaders(exchangeResponse);
                    if (areYouNginxOrNull(headersExchange))
                    {
                        breaker = true;
                        break;
                    }
                    if (headersExchange != null)
                    {
                        if (headersExchange.ToString().Contains("No authentication method configured for the URL in the request"))
                        {
                            UI.ThreadSafeAppendLog("[2]Server appears to have authentication disabled for: " + exchangeRequest.url);
                        }
                        else if (responseExchange.Contains("owa") || responseExchange.Contains("OutlookSession"))
                        {
                            if (responseExchange.Contains("outlook.office.com"))
                            {
                                //Check federated status and handle
                                if (CheckFederated())
                                {
                                    host.Federated = "Y";
                                }
                                else
                                {
                                    host.Federated = "N";
                                }
                                //Can refactor this...
                                //DEAL WITH O365 HERE
                                host.O365 = "Y";
                                //Change service to O365(?)
                                host.Service     = MicrosoftService.Office365;
                                host.OAuthDomain = UI.targetDomain;
                                host.EnumURL     = new URLObject()
                                {
                                    Url = "https://outlook.office365.com/autodiscover/autodiscover.json/v1.0/", Type = URLType.UserEnum
                                };

                                if (host.Federated == "Y")
                                {
                                    //host.OAuthURL = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token";
                                    CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                                    AddService.AddServiceToOptions(UI, host.Service, true, false);
                                }
                                else
                                {
                                    host.SprayURL = new URLObject()
                                    {
                                        Url = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token", Type = URLType.Oauth
                                    };
                                    CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                                    AddService.AddServiceToOptions(UI, host.Service, true, true);
                                }
                            }
                            else
                            {
                                //HOST should already have subdomain - IP address - can now add O365 N
                                host.O365    = "N";
                                host.EnumURL = new URLObject()
                                {
                                    Url = "https://" + host.Hostname + "/owa/auth.owa", Type = URLType.UserEnum
                                };
                            }
                        }
                    }
                    //VALIDATE PASS SPRAY SEPERATELY - MAY NOT HAVE ENUM - BUT DOES HAVE PASS SPRAYABLE POINT
                    WebRequests exchangeRequestSpray = CreateWebRequest("https://" + host.Hostname + "/Autodiscover");

                    HttpWebResponse     exchangeResponseSpray = exchangeRequestSpray.MakeGETRequest();
                    string              responseExchangeSpray = WebRequests.GetResponseString(exchangeResponseSpray);
                    WebHeaderCollection headersExchangeSpray  = WebRequests.GetResponseHeaders(exchangeResponseSpray);

                    if (areYouNginxOrNull(headersExchangeSpray))
                    {
                        breaker = true;
                        break;
                    }
                    if (headersExchangeSpray != null)
                    {
                        if (headersExchangeSpray.ToString().Contains("NTLM") || headersExchangeSpray.ToString().Contains("Negotiate"))
                        {
                            if (headersExchangeSpray.GetValues("request-id") != null)
                            {
                                if (host.O365 == "Y")
                                {
                                    //We need to create a second host with JUST spray URL and add that too
                                    Hostnames host2 = new Hostnames()
                                    {
                                        SprayURL = new URLObject()
                                        {
                                            Url = "https://" + host.Hostname + "/Autodiscover", Type = URLType.Oauth
                                        }, Service = MicrosoftService.Exchange, O365 = "N", Hostname = host.Hostname, ipAddress = host.ipAddress
                                    };
                                    CollectionUpdates.AddHostnameRecord(host2, UI.enumeratedHostnames, UI);
                                    //NEED TO MAKE ADD SERVICE INCLUDING WHICH TABS TAKE INTO ACCOUNT IF HOST HAS ENUM/SPRAY ENABLED - ACTUALLY NEED SEPERATE HOST IF
                                    //ONE WAS O365 AND ONE WAS ON-PREM
                                    AddService.AddServiceToOptions(UI, host2.Service, false, true);
                                }
                                else
                                {
                                    //Just add oauth to existing on-prem record which will be added at the end
                                    host.SprayURL = new URLObject()
                                    {
                                        Url = "https://" + host.Hostname + "/Autodiscover", Type = URLType.Oauth
                                    };
                                    CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                                    if (host.EnumURL != null)
                                    {
                                        AddService.AddServiceToOptions(UI, host.Service, true, true);
                                    }
                                    else
                                    {
                                        AddService.AddServiceToOptions(UI, host.Service, false, true);
                                    }
                                }
                            }
                            else if (host.EnumURL != null)
                            {
                                CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                                AddService.AddServiceToOptions(UI, host.Service, true, true);
                            }
                        }
                        else
                        {
                            UI.ThreadSafeAppendLog("[2]Server appears to have authentication disabled for: " + exchangeRequestSpray.url);
                        }
                    }
                    break;

                case MicrosoftService.Skype:
                    if (UI.enumeratedHostnames.Any(p => p.RealLync == true))
                    {
                        Hostnames tempHost = UI.enumeratedHostnames.Where(x => x.RealLync == true).First();
                        if (tempHost.SprayURL != null)
                        {
                            break;
                        }
                    }
                    //So - for any subdomains (will only be ones not already found) - validate
                    WebRequests lyncRequest = CreateWebRequest("https://" + host.Hostname);
                    lyncRequest.request.Accept = "text/xml";
                    HttpWebResponse     lyncResponse = lyncRequest.MakeGETRequest();
                    string              responseLync = WebRequests.GetResponseString(lyncResponse);
                    WebHeaderCollection lyncHeaders  = WebRequests.GetResponseHeaders(lyncResponse);
                    if (areYouNginxOrNull(lyncHeaders))
                    {
                        breaker = true;
                        break;
                    }
                    if (responseLync.Contains("Autodiscover"))
                    {
                        if (responseLync.Contains("online.lync.com"))

                        {
                            //Check federated status and handle
                            if (CheckFederated())
                            {
                                host.Federated = "Y";
                            }
                            else
                            {
                                host.Federated = "N";
                            }
                            //DEAL WITH O365 HERE
                            host.O365 = "Y";
                            //Change service to O365(?)
                            host.Service     = MicrosoftService.Office365;
                            host.OAuthDomain = UI.targetDomain;
                            host.EnumURL     = new URLObject()
                            {
                                Url = "https://outlook.office365.com/autodiscover/autodiscover.json/v1.0/", Type = URLType.UserEnum
                            };


                            if (host.Federated == "Y")
                            {
                                //host.OAuthURL = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token";
                                CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                                //So for O365 federated - can enum at Office but not spray
                                AddService.AddServiceToOptions(UI, host.Service, true, false);
                            }
                            else
                            {
                                host.SprayURL = new URLObject()
                                {
                                    Url = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token", Type = URLType.Oauth
                                };
                                CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                                AddService.AddServiceToOptions(UI, host.Service, true, true);
                            }
                        }
                        else
                        {
                            //HOST should already have subdomain - IP address - can now add O365 N
                            //Add that subdomain as not real (won't be as only lyncdiscover etc)
                            host.O365     = "N";
                            host.RealLync = false;
                            CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                            //So we now have lyncdiscover/internal and have added - so now pull real address and fqdn and add
                            //We also already have the response here
                            //Then - if we don't already have "real"...
                            if (UI.enumeratedHostnames.Any(p => p.RealLync == true))
                            {
                            }
                            else
                            {
                                //Match the response we've already got here
                                Match match = RegexClass.ReturnMatch(Regexs.SkypeRealAddress, responseLync);
                                if (match.Success)
                                {
                                    string realAddress = match.Value;
                                    UI.ThreadSafeAppendLog("[1][*] Skype Server Hostname: " + realAddress);
                                    //IP Lookup
                                    IPHostEntry ipEntry2 = Dns.GetHostEntry(realAddress);
                                    IPAddress[] ipAddr2  = ipEntry2.AddressList;
                                    foreach (IPAddress addr in ipAddr2)
                                    {
                                        Hostnames hostReal = new Hostnames()
                                        {
                                            Hostname = realAddress, ipAddress = addr, Service = MicrosoftService.Skype, O365 = "N", RealLync = true
                                        };
                                        //VALIDATE USER ENUM
                                        WebRequests lyncRequestReal = CreateWebRequest("https://" + realAddress + "/WebTicket/WebTicketService.svc/Auth");
                                        lyncRequestReal.request.Accept = "text/xml";
                                        HttpWebResponse     lyncResponseReal = lyncRequestReal.MakeGETRequest();
                                        WebHeaderCollection Headers          = WebRequests.GetResponseHeaders(lyncResponseReal);

                                        if (areYouNginxOrNull(Headers))
                                        {
                                            breaker = true;
                                            break;
                                        }
                                        if (Headers != null)
                                        {
                                            if (Headers.ToString().Contains("No authentication method configured for the URL in the request"))
                                            {
                                                UI.ThreadSafeAppendLog("[2]The server appears to have disabled authentication for the user enumeration URL: " + lyncRequestReal.url);
                                            }
                                            else if (Headers.GetValues("X-MS-Server-Fqdn") != null)
                                            {
                                                hostReal.EnumURL = new URLObject()
                                                {
                                                    Url = "https://" + realAddress + "/WebTicket/WebTicketService.svc/Auth", Type = URLType.UserEnum
                                                };
                                            }
                                        }
                                        //Seperately VALIDATE PASS SPRAY
                                        //So this isn't the actual pass spray URL - but will tell us the grant types - other option is to check ACTIVE pass spray WITH
                                        //Creds - gibberish and see if it says unsupported grant type - would solve if they just blocked /OAuth for some reason
                                        //But more active - requires adding and removing during validation active/not active
                                        WebRequests         lyncRequestSpray         = CreateWebRequest("https://" + realAddress + "/WebTicket/WebTicketService.svc/OAuth");
                                        HttpWebResponse     lyncRequestSprayResponse = lyncRequestSpray.MakeGETRequest();
                                        WebHeaderCollection HeadersSpray             = WebRequests.GetResponseHeaders(lyncRequestSprayResponse);

                                        if (areYouNginxOrNull(HeadersSpray))
                                        {
                                            breaker = true;
                                            break;
                                        }
                                        if (HeadersSpray != null)
                                        {
                                            if (HeadersSpray.ToString().Contains("password"))
                                            {
                                                if (HeadersSpray.GetValues("client-request-id") != null)
                                                {
                                                    UI.ThreadSafeAppendLog("[1][*] " + realAddress + ": " + addr.ToString());
                                                    hostReal.SprayURL = new URLObject()
                                                    {
                                                        Url = "https://" + realAddress + "/WebTicket/oauthtoken", Type = URLType.Oauth
                                                    };
                                                    CollectionUpdates.AddHostnameRecord(hostReal, UI.enumeratedHostnames, UI);
                                                    if (hostReal.EnumURL != null)
                                                    {
                                                        AddService.AddServiceToOptions(UI, hostReal.Service, true, true);
                                                    }
                                                    else
                                                    {
                                                        AddService.AddServiceToOptions(UI, hostReal.Service, false, true);
                                                    }
                                                }
                                                else if (hostReal.EnumURL != null)
                                                {
                                                    UI.ThreadSafeAppendLog("[1][*] " + realAddress + ": " + addr.ToString());
                                                    CollectionUpdates.AddHostnameRecord(hostReal, UI.enumeratedHostnames, UI);
                                                    AddService.AddServiceToOptions(UI, hostReal.Service, true, true);
                                                }
                                            }
                                            else
                                            {
                                                UI.ThreadSafeAppendLog("[2]It looks like the oauth endpoint has disabled password authentication: " + lyncRequestSpray.url);
                                            }
                                        }

                                        if (hostReal.EnumURL != null)
                                        {
                                            AddService.AddServiceToOptions(UI, hostReal.Service, true, true);
                                        }
                                        else if (hostReal.EnumURL == null && hostReal.SprayURL == null)
                                        {
                                            //Not sure we could hit here with Y - but just to check
                                            if (hostReal.O365 != "Y")
                                            {
                                                UI.ThreadSafeAppendLog("[2]No user enum or pass spray URL discovered for " + host.Hostname + " - attempting to find NTLM endpoints...");
                                                NTLMDiscovery domainInformation = new NTLMDiscovery();
                                                ObservableCollection <Hostnames> mySoloHostname = new ObservableCollection <Hostnames>();
                                                mySoloHostname.Add(hostReal);
                                                domainInformation.hostnamesForDomainInformationEnumeration = mySoloHostname;
                                                domainInformation.UI = UI;
                                                URLObject returnedSprayURL = domainInformation.FindNTLMEndpoints(hostReal);
                                                if (returnedSprayURL != null)
                                                {
                                                    hostReal.SprayURL = returnedSprayURL;
                                                    hostReal.O365     = "N";
                                                    CollectionUpdates.AddHostnameRecord(hostReal, UI.enumeratedHostnames, UI);
                                                    AddService.AddServiceToOptions(UI, hostReal.Service, false, true);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    break;

                case MicrosoftService.Office365:
                    WebRequests O365Request = CreateWebRequest("https://" + host.Hostname + "/autodiscover/autodiscover.json/v1.0/test.test@" + targetDomain + "?Protocol=Autodiscoverv1");
                    O365Request.request.AllowAutoRedirect = false;
                    HttpWebResponse O365WebResponse = O365Request.MakeGETRequest();
                    string          responseO365    = WebRequests.GetResponseString(O365WebResponse);

                    UI.ThreadSafeAppendLog("[4]O365 Response: " + responseO365);
                    if (responseO365.Contains("outlook.office365.com"))
                    {
                        //Check federated status and handle
                        if (CheckFederated())
                        {
                            host.Federated = "Y";
                        }
                        else
                        {
                            host.Federated = "N";
                        }

                        host.O365 = "Y";
                        //Hard code - we manually set up this record - but as this is also needed for lyncdiscover cloud hosted etc...
                        host.EnumURL = new URLObject()
                        {
                            Url = "https://outlook.office365.com/autodiscover/autodiscover.json/v1.0/", Type = URLType.UserEnum
                        };
                        //FOR NOW - NOT SETTING NTLMDOMAIN - O365 WILL ALWAYS BE HITTING THE @DOMAIN.COM ANYWAY?
                        host.OAuthDomain = UI.targetDomain;


                        if (host.Federated == "Y")
                        {
                            //host.OAuthURL = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token";
                            CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                            AddService.AddServiceToOptions(UI, host.Service, true, false);
                        }
                        else
                        {
                            host.SprayURL = new URLObject()
                            {
                                Url = "https://login.microsoftonline.com/organizations/oauth2/v2.0/token", Type = URLType.Oauth
                            };
                            CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                            AddService.AddServiceToOptions(UI, host.Service, true, true);
                        }
                    }
                    break;

                case MicrosoftService.RDWeb:
                    WebRequests         rdWebRequest      = CreateWebRequest("https://" + host.Hostname + "/RDWeb/Pages/en-US/login.aspx");
                    HttpWebResponse     rdWebResponse     = rdWebRequest.MakeGETRequest();
                    string              responseRDWeb     = WebRequests.GetResponseString(rdWebResponse);
                    WebHeaderCollection responseRDHeaders = WebRequests.GetResponseHeaders(rdWebResponse);
                    if (areYouNginxOrNull(responseRDHeaders))
                    {
                        breaker = true;
                        break;
                    }
                    if (responseRDHeaders != null)
                    {
                        if (responseRDHeaders.ToString().Contains("No authentication method configured for the URL in the request"))
                        {
                            UI.ThreadSafeAppendLog("[2]The server appears to have disabled authentication for the URL: " + rdWebRequest.url);
                        }
                        else
                        {
                            if (responseRDWeb.Contains("RD Web Access"))
                            {
                                //NOT GOT ANYTHING FOR RDWEB O365
                                host.O365    = "N";
                                host.EnumURL = new URLObject()
                                {
                                    Url = "https://" + host.Hostname + "/RDWeb/Pages/en-US/login.aspx", Type = URLType.UserEnum
                                };
                                host.SprayURL = new URLObject()
                                {
                                    Url = "https://" + host.Hostname + "/RDWeb/Pages/en-US/login.aspx", Type = URLType.Oauth
                                };
                                CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                                AddService.AddServiceToOptions(UI, host.Service, true, true);
                            }
                        }
                    }


                    break;
                }
                if (breaker)
                {
                }
                else
                {
                    //At the end of doing that host - if we don't have either - ONLY IF NOT EITHER - do NTLM
                    Hostnames tempHost2 = null;
                    if (UI.enumeratedHostnames.Any(p => p.RealLync == true))
                    {
                        tempHost2 = UI.enumeratedHostnames.Where(x => x.RealLync == true).First();
                    }
                    if (tempHost2 != null)
                    {
                        if (tempHost2.SprayURL != null)
                        {
                        }
                        else
                        {
                            if (host.EnumURL.Url == "" && host.SprayURL.Url == "")
                            {
                                //Not sure we could hit here with Y - but just to check
                                if (host.O365 != "Y")
                                {
                                    UI.ThreadSafeAppendLog("[2]No user enum or pass spray URL discovered - attempting to find NTLM endpoints...");
                                    NTLMDiscovery domainInformation = new NTLMDiscovery();
                                    ObservableCollection <Hostnames> mySoloHostname = new ObservableCollection <Hostnames>();
                                    mySoloHostname.Add(host);
                                    domainInformation.hostnamesForDomainInformationEnumeration = mySoloHostname;
                                    domainInformation.UI = UI;
                                    URLObject returnedSprayURL = domainInformation.FindNTLMEndpoints(host);
                                    if (returnedSprayURL != null)
                                    {
                                        host.SprayURL = returnedSprayURL;
                                        host.O365     = "N";
                                        CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                                        AddService.AddServiceToOptions(UI, host.Service, false, true);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (host.EnumURL.Url == "" && host.SprayURL.Url == "")
                        {
                            //Not sure we could hit here with Y - but just to check
                            if (host.O365 != "Y")
                            {
                                UI.ThreadSafeAppendLog("[2]No user enum or pass spray URL discovered - attempting to find NTLM endpoints...");
                                NTLMDiscovery domainInformation = new NTLMDiscovery();
                                ObservableCollection <Hostnames> mySoloHostname = new ObservableCollection <Hostnames>();
                                mySoloHostname.Add(host);
                                domainInformation.hostnamesForDomainInformationEnumeration = mySoloHostname;
                                domainInformation.UI = UI;
                                URLObject returnedSprayURL = domainInformation.FindNTLMEndpoints(host);
                                if (returnedSprayURL != null)
                                {
                                    host.SprayURL = returnedSprayURL;
                                    host.O365     = "N";
                                    CollectionUpdates.AddHostnameRecord(host, UI.enumeratedHostnames, UI);
                                    AddService.AddServiceToOptions(UI, host.Service, false, true);
                                }
                            }
                        }
                    }
                }
            }
        }