Autodiscover Redirect

Autodiscover entwickelt sich weiter und bei einigen PowerShell-Tests ist mit was komisches und zugleich interessantes aufgefallen. Gezielte Abfragen nach dem EWS-Zugangspunkt funktionieren anonym oft in beide Richtungen über Weiterleitungen. Aber nicht immer.

Dieser Artikel bezieht sich auf Autodiscover V2, wie es z.B. schon von Outlook, IOS und Microsoft Teams genutzt wird.

Autodiscover liefert EWS-Endpunkt

Auch wenn in den meisten Fällen heute Autodiscover immer noch von Outlook genutzt wird um einen Zugang per RPC/HTTP oder MAPI/HTTP zu finden, so ist auch EWS eine gängige Schnittstelle zum Zugriff auf Informationen. Skype for Business nutzt EWS zum Zugriff auf Termine und Outlook MAC nutzt sogar komplett EWS. Auch Exchange Online migriert Postfächer "über EWS und den MRSPROXY in die Cloud und zurück. Insofern ist eine Abfrage per Autodiscover nichts Ungewöhnliches um den Zugangspunkt zu finden.

Wenn ich nu mal Die Auflösung per Service Connections Point weglasse und mich auf "autodiscover.<maildomain> beschränke, dann kann ich einfach per PowerShell Einzeiler den Autodiscover-Endpunkt ermitteln.

Invoke-RestMethod `
   -Uri ‘https://autodiscover.netatwork.de/autodiscover/autodiscover.json?Email=onpremUser@netatwork.de&Protocol=EWS’
 
Protocol Url
-------- ---
EWS      https://owa.netatwork.de/EWS/Exchange.asmx

Sie können den Test sehr einfach mit ihrer Mailadresse gegen ihren Exchange Server machen.

Wie sie im HTTP-Request gut sehen können erfolgt die Anfrage anonym und kann quasi gegen jeden Firma erfolgen. Indirekt ist damit eine Verifizierung von Mailadressen möglich. Wenn Sie nämlich eine falsche Adresse angeben, dann liefert der Aufruf einen Fehler

Invoke-RestMethod `
   -Uri ‘https://autodiscover.netatwork.de/autodiscover/autodiscover.json?Email=noUser@netatwork.de&Protocol=EWS’

{
   "ErrorCode":"UserNotFound",
   "ErrorMessage":"The given User is not found"
}

Die Meldung ist OnPremises die gleiche, wenn sie eine andere nicht vorhandene Domäne verwenden. Wenn Sie die Mailadresse einer Verteilergruppe nutzen, dann erhalten Sie den gleichen Fehler. Für Räume es erhalten sie wieder Daten und sie können auch problemlos eine sekundäre SMTP-Adresse abfragen.

Autodiscover und TargetAddress

Wer nun Exchange OnPremises zusammen mit Office 356 nutzt, liest überall, dass in der Umgebung die Autodiscover-Auflösung erst immer mal über die On-Premises-Umgebung läuft und der lokale Exchange Server dann die Zugriffe entsprechend über eine Umleitung oder passende Antwort steuert. Dazu nutzt der Exchange Server das Feld "TargetAddresse" bei einem Postfach in der Cloud sieht das dann wie folgt aus

Invoke-RestMethod -Uri ‘https://autodiscover.netatwork.de/autodiscover/autodiscover.json?Email=cloudUser@netatwork.de&Protocol=EWS’
 
Protocol Url
-------- ---
EWS      https://outlook.office365.com/EWS/Exchange.asmx

Hier liefert der Exchange Server bei der Abfrage nach EWS direkt die URL zurück, über die ein Zugriff auf das Postfach per EWS möglich ist. In dem Beispiel ist das ein Postfach in Office 365. Die "TargetAddresse" verweist bei dem AD-Objekt auf cloudUser@netatwork.onmicrosoft.com. Im Hintergrund sehen wir aber zwei HTTP-Requests. Der erste Zugriff geht auf Autodiscover aber ergibt einen Redirect.

 

Invoke-Webrequest folgt diesem Redirect und holt die Antwort von Office 365.

Auch diese Anfragen sind alle "anonym".

Warnung in Outlook

Wenn Outlook sich per Autodiscover mit der primären Exchange Umgebung verbindet und diese den Client dann aber über die TargetAddress zu einer anderen Topologie umleitet, warnt Outlook den Anwender und bittet ihn die Umleitung zu bestätigen.

Das ist prinzipiell eine gute Idee, damit nicht ein Angreifer z.B. die Anfrage ohne HTTPS abfängt und auf seinen Webserver umleitet und Outlook sich dann dort versucht sich anzumelden. So könnte ein Angreifer z.B. Zugangsdaten erlangen. Die Warnung ist natürlich kontraproduktiv, wenn die Umleitung gewollt und erforderlich ist. Hier können Sie als Administrator und Anwender aber Outlook derart einstellen, dass bestimmte Umleitungsziele als "vertrauenswürdig" erscheinen. Das erfolgt über Einträge in der Registrierung.

Hier die Einträge in meinem Computer. Neben meiner eigenen Domäne sind hier durch Office selbst schon bestimmte Systeme vordefiniert. Es ist gut zu sehen, dass die Einträge je Office Version getrennt vorzunehmen sind und Outlook 2010 noch weniger Adressen mitgebracht hat.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_User\Software\Microsoft\Office\14.0\Outlook\AutoDiscover\RedirectServers]
"autodiscover-s.outlook.com"=hex(0):
"autodiscover.outlook.com"=hex(0):
"autodiscover.msxfaq.de"=hex(0):

[HKEY_CURRENT_User\Software\Microsoft\Office\15.0\Outlook\AutoDiscover\RedirectServers]
"autodiscover-s.outlook.com"=hex(0):
"autodiscover.hotmail.com"=hex(0):
"autodiscover.msxfaq.de"=hex(0):
"autodiscover-s.partner.outlook.cn"=hex(0):
"autodiscover-s.outlook.de"=hex(0):
"autodiscover-s.office365.us"=hex(0):

[HKEY_CURRENT_User\Software\Microsoft\Office\16.0\Outlook\AutoDiscover\RedirectServers]
"autodiscover-s.outlook.com"=hex(0):
"autodiscover.hotmail.com"=hex(0):
"autodiscover-s.partner.outlook.cn"=hex(0):
"autodiscover-s.outlook.de"=hex(0):
"autodiscover-s.office365.us"=hex(0):
"autodiscover.msxfaq.de"=hex(0):

In einem Firmennetzwerk sollten Sie die passenden Ziele natürlich per Gruppenrichtlinie verteilen.

Autodiscover in Office 365

Wenn Sie eine Domäne zu 100% in Office 365 anlegen, dann gibt Microsoft für Exchange folgende Einträge vor:

Sie sehen hier den CNAME für Autodiscover, der auf autodiscover.outlook.com geht. Also frage ich erst mal Office 365 zu Informationen über ein Postfach in der Cloud:

Invoke-RestMethod -Uri ‘https://autodiscover.outlook.com/autodiscover/autodiscover.json?Email=User1@uclabor.de&Protocol=EWS’
Invoke-RestMethod : Der Remoteserver hat einen Fehler zurückgegeben: (502) Ungültiges Gateway.

Schaut man sich den Wireshark-trace an, dann sieht man, dass diese Adresse gar nicht per HTTPS erreichbar ist. Es ist nur eine "Redirect-Seite", die man besser per HTTP anspricht

Invoke-RestMethod -Uri ‘http://autodiscover.outlook.com/autodiscover/autodiscover.json?Email=User1@uclabor.de&Protocol=EWS’

Protocol Url
-------- ---
EWS      https://outlook.office365.com/EWS/Exchange.asmx

Dann sehe ich in Fiddler zuerst die Umleitung auf die HTTPS-Seite mit dem richtigen Hostnamen.

Im zweiten Request kommen dann, wieder ohne Anmeldung, die Daten

Ich kann natürlich auch direkt diese Seite aufrufen:

Invoke-RestMethod `
   -Uri ‘https://autodiscover-s.outlook.com/autodiscover/autodiscover.json?Email=User1@uclabor.de&Protocol=EWS’

Protocol Url
-------- ---
EWS      https://outlook.office365.com/EWS/Exchange.asmx

Besser ist aber die Nutzung von autodiscover.outlook.com mit der Umleitung.

Rückweg von Office 365

Bislang wurde immer gesagt, dass "Autodiscover.<maildomain>" zwingend auf die lokale Umgebung verweisen muss damit der Client erst den Server fragt und dann ggfls. zu Office 365 umgeleitet wird. Mit dem PowerShell-Befehl ist es natürlich nicht schwer die normale DNS-Auflösung einfach mal zu umgehen und direkt den Host zu fragen, den Microsoft in einem Office 365 Setup für "autodiscover" vorsieht.

Für jedes on-premises Postfach  gibt es natürlich einen entsprechenden Gegenpart in Office 365, damit auch die Cloud den Weg zu den Empfängern findet, die noch on-premises sind. Mich hat schon interessiert, wie Office 365 mit so einer fehlgeleiteten Anfragen umgeht.

Invoke-RestMethod -Uri ‘http://autodiscover.outlook.com/autodiscover/autodiscover.json?Email=onprem@netatwork.de&Protocol=EWS’
Protocol Url
-------------- ---
EWS EWS      https://owa.netatwork.de/EWS/Exchange.asmx

Anscheinend ist es für Office 365 überhaupt kein Problem auf Ziele zurück zu verweisen, die nicht in der Cloud sind.

Anonyme Anfragen?

Bislang war ich "freundlich" und habe nur meine eigenen Dienste und Tenants benutzt. Aber alles Anfragen waren zu dem Zeitpunkt noch "anonym". Da juckt es ja gerade zu in den Fingern mal andere Mailadressen auszuprobieren, und die Reaktion auszuwerten.

Mailadresse Ergebnis

gibtesnicht@ibm.com

"Der Remotename konnte nicht aufgelöst werden: 'autodiscover.ibm.com'"

Microsoft macht noch einen Redirect

Aber da es den Host nicht gibt, kommt die PowerShell nicht weiter

gibtesnicht@polycom.com

Umleitung von Office 365 auf on-premises aber dort mangels Authentication geblockt. Es scheint aber keine Preauthentication durch einen Reverse-Proxy zu sein, denn der würde wohl nicht mit Headern wie "X-FEServer" o.ä. antworten.

Ein Rückschluss auf die Exchange Version ist nicht möglich

gibtesnicht@microsoft.com

Es hat den Anschein, dass es diese Adresse tatsächlich geben könnte. Ich sehe drei Umleitungen und keinen Fehler.

Und die letzte liefert dann die Exchange Online URL

Aber diese Antwort leitet in die Irre, wie ich weiter unten noch genauer beschreibe.

admin@bertelsmann.com

Auch von der Bertelsmann/Arvato-Gruppe ist bekannt, dass Sie Office 365 und Exchange nutzen. DNS-Einträge wie Autodiscover und die "ms=xxxx" Einträge zur Cloud Bestätigung verraten so etwas. Hier bekomme ich anonym auch eine Antwort mit der on-premises URL.

admin@rwe.com

Über verschiedene Presseveröffentlichungen und letztlich auch über die DNS-Einträge ist bekannt, dass RWE auch Exchange Online nutzt. Die Antwort hier hier wieder eine andere:

Invoke-RestMethod : The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

Auch hier wieder die bekannten Redirects auf s-outlook und dann zu einem angenommenen OnPremise.Host

Der dann aber mit einem 404 antwortet und gar keine Authentifizierung anbietet

Ich weiß, dass eine gültige Adresse auf die Cloud auflöst. Da ich aber nicht weiß, ob es dort einen Hybrid-Mode gibt und welche Adressen dann noch "lokal" sind, gibt es keine gesicherte Aussage zur Funktion.

gibtesnicht@netatwork.de

Daher habe ich diesen Test auch noch mal mit einer nicht gültigen Adresse bei Net at Work widerholt und habe hier die gleiche Antwort bekommen:

Die Cloud sendet die Anfrage auf den on-premise Server und der meldet einfach dass es die Adresse nicht gibt.

Diese Verhalten können Sie aber nur bis CU4 oder CU5 so sehen. Spätestens seit CU6 verrät Exchange dies nicht mehr.

admin@carius-mantke.de

Diese Domain ist definitiv nicht in Office 365 registriert. Die Antwort von Office 365 verrät dies aber nicht sondern verweist den Client zu "autodiscover.<maildomain>.

Der 502 wird von Fiddler generiert, weil der Host nicht auflösbar ist

 Anscheinend leitet Office 365 jeden Client um, wenn es die Domäne nicht gibt.

Das Ergebnis ist etwas durchwachsen. Es scheint nicht überall möglich zu sein über eine anonyme Anfrage mehr Details über das Zielsystem eines Postfachs zu ermitteln. Ob das nun ein Reverse-Proxy davor verhindert oder eine Abhängigkeit der Exchange Version oder Konfiguration ist, kann ich im Moment nicht ermitteln.

Sie dürfen aber dennoch nun nicht dazu übergehen den "Eintrag für "autodiscover.<maildomain>" direkt auf Office 365 zu leiten. Die Cloud leitet Zugriff auf on-premises Postfächer nämlich auch weiterhin auf "autodiscover.<maildomain>" weiter womit wir dann eine Endlosschleife für Weiterleitungen hätten. Die Postfächer auf lokalen Servern wären dann per Autodisover nicht erreichbar.

Vielleicht helfen Sie mir dabei, einfach mal eine Abfrage an ihre Mailadresse zu senden und ein paar Worte zur dahinter liegenden Infrastruktur (Reverse-Proxy, Frontend, Backend) zu machen.

Exchange CU Abhängigkeiten

Zusammen mit Ingo Gegenwarth haben wir entdecken dürfen/müssen, dass die Antwort auf "ungültige" Adressen sich von Exchange CU zu CU unterscheidet. Es ist dabei aber wohl egal, ob die Domäne in der Liste der Accepted Domains steht oder nicht. Maßgeblich wohl nur, ober der Benutzer im Active Directory gefunden wird oder nicht. Ich habe folgenden test gemacht

#Wenn der Server HTTPS erlaubt
Invoke-RestMethod -Uri ‘https://autodiscover.<domain>/autodiscover/autodiscover.json?Email=unvalid@example.com&Protocol=EWS’

# ansonsten HTTP und auf Redirect hoffen
Invoke-RestMethod -Uri ‘https://autodiscover.<domain>/autodiscover/autodiscover.json?Email=unvalid@example.com&Protocol=EWS’

# Interne tests gegen den FQDN gehen auch
Invoke-RestMethod -Uri ‘https://<serverfqdn>/autodiscover/autodiscover.json?Email=unvalid@example.com&Protocol=EWS’

Meine Testserie ergab folgendes Bild.

Wenn jemand noch andere Build-Versionen hat, kann er mir gerne Infos zukommen lassen. Ich denke aber dass die Änderung von Microsoft beabsichtigt war. Entwickler, die aber AutodiscoverV2 nutzen, müssen ggfls. ihren Code intelligenter machen, da sie nicht mehr auf einen 404 hoffen können.

Exchange Version Ergebnis auf Anfragen für nicht vorhandene Empfänger

2016 CU4 (15.1.669.32)

HTTP/1.1 404 Not Found

Invoke-RestMethod : {"ErrorCode":"UserNotFound","ErrorMessage":"The given User is not
found"}

2016 CU5

noch nicht getestet

2016 CU6

HTTP/1.1 200 OK
EWS-Url ist die des angefragten Systems und nicht die zur Maildomain passende Gegenstelle

2016 CU7

HTTP/1.1 200 OK
EWS-Url ist die des angefragten Systems und nicht die zur Maildomain passende Gegenstelle

2016 CU8

HTTP/1.1 200 OK
EWS-Url ist die des angefragten Systems und nicht die zur Maildomain passende Gegenstelle

2016 CU9

HTTP/1.1 200 OK
EWS-Url ist die des angefragten Systems und nicht die zur Maildomain passende Gegenstelle

Irgendwo hat Microsoft sich wohl entschieden, bei einer Anfrage nach einem ungültigen Benutzer diese Information nicht mehr mit einem 404 zu beantworten sondern einfach mit einem 200OK und als URL die EWS-Url der lokalen Installation zurück zu liefern. Nur wenn Sie Exchange Online nach einem ungültigen Benutzer fragen, dann bekommen Sie ein Redirect zur On-premises-Installation die dann wieder je nach Version antwortet.

Schaut man auf dem Server dann etwas genauer in den Autodiscover-Logs nach, dann findet man Meldungen wie...

RequestedProtocol=EWS;
   ExecuteOnPremEndFlow=OnPrem;
      GetOnPremUser=Start Ad lookup;
      TryGetEmailRedirectResponse=UserNotFound;
   GetOnPremUser=Start Ad lookup;
      TryGetEmailRedirectResponse=FoundRandomUser;
      TryGetEmailRedirectResponseUserFound=UserMailbox 

Anscheinend hat Microsoft absichtlich den Code so geändert, dass eine anonyme Anfrage nach einem ungültigen Konto nicht mehr mit einem "404 not found" beantwortet wird, sondern pauschal die EWS-Url's geliefert wird. Ein möglicher Angreifer muss dann erst einen authentifizierten Zugriff auf EWS starten um dann zu erkennen, dass die Mailadresse gar nicht stimmt. Das ist so auch im Code (ILSpy kann sowas aus einer DLL extrahieren) zu sehen:

private AutoDiscoverV2Response ExecuteOnPremEndFlow(AutoDiscoverV2Request request)
   {
      this.logger.AppendGenericInfo("ExecuteOnPremEndFlow", "OnPrem");
      IADMailboxRecipient onPremUser = this.tenantRepository.GetOnPremUser(request.EmailAddress);
      if (onPremUser == null)
      {
         this.logger.AppendGenericInfo("TryGetEmailRedirectResponse", "UserNotFound");
         if (!this.flightSettings.IsAntiFarmingEnabled())
         {
            ExTraceGlobals.LatencyTracer.TraceDebug(0L, "ExecuteOnPremEndFlow-NoAntiFarming-UserNotFound");
            throw AutoDiscoverResponseException.NotFound();
         }
         IAutodMiniRecipient nextUserFromSortedList = this.tenantRepository.GetNextUserFromSortedList(request.EmailAddress);
         if (nextUserFromSortedList != null)
         {
            this.logger.AppendGenericInfo("TryGetEmailRedirectResponse", "FoundRandomUser");
            AutoDiscoverV2Response result;
            if (this.TryGetEmailRedirectResponse(request, nextUserFromSortedList, out result))
            {
               return result;
            }
         }
         return this.GetResourceUrlResponse(this.flightSettings.GetHostNameFromVdir(null, request.Protocol), request.Protocol);
      }

Er sucht erst nach dem Empfänger und wenn "onPremUser == null" ist, dann wprde er schon einen Redirect suchen. Aber dann kommt die Abfrage auf "!this.flightSettings.IsAntiFarmingEnabled()" wenn dies nicht gesetzt ist, dann sendet der Server einen 404. Ansonsten nimmt er einfach den nächsten Empfänger in der Liste und liefert dessen EWS-URL aus. Wenn es keinen weiteren User gibt, dann wird eben die URL des virtuellen Verzeichnisses genommen.

Ob das ein guter Programmierstiel ist, darüber lässt sich streiten. Ich hätte mit dann einfach einen Fehler gewünscht, dass "Farming" unterbunden ist und die Anfrage immer langsamer werden lassen. So muss der Client bei einer vom Anwender falsch eingegebenen Adresse erst eine Anmeldung am Dienst versuchen und den dortigen Fehler abfragen, was sicher auch auf dem Backend eine zusätzliche Authentifizierung bedeutet.

Die Frage stellt sich dann aber, wie man den Parameter "flightSettings.IsAntiFarmingEnabled" setzen kann. Google und Co sind auf den Begriffen blind.

Anonym ist keine Sicherheitslücke!

Muss den Exchange auf eine anonyme Anfrage so ausführlich Antwort geben und ist das nicht eine Sicherheitslücke? Schließlich könnte ich ja über den Weg z.B. ermitteln ob Mailadresse "gültig" sind und im gleichen Schritt erfragen, ob diese schon in der Cloud sind. Das ist ein Wissen, was ich als Betreiber vielleicht nicht so einfach verfügbar machen will.

Auf der anderen Seite war es noch nie ein echtes Geheimnis, wo ein Postfach vermutlich liegt. Über den MX.Record kann zumindest der Mailserver ermittelt werden und wenn die verschiedenen SMTP-Stationen keinen Header-Firewall haben, dann sende ich einfach eine Mail an so eine Adresse und schaue mir die Rückantworten an. Über die "Received by"-Zeilen bekomme ich schon die ein oder andere Information über das Zielsystem und das Postfach. Wenn ich dann dem Anwender noch eine Mail mit externen Links sende und er diese nachlädt, weiß ich noch mehr über seinen Client.

Natürlich könnte ich die Autodiscover-Anfrage auch mit einer Authentifizierung versehen. Der legitime Anwender kann ja seine Anmeldedaten übermitteln, eher er eine Antwort bekommt. Allerdings müsste dann jeder Client auch die entsprechenden Anmeldeverfahren unterstützen. Klar ist die Übermittlung von "Benutzername/Kennwort" einfach aber wie gehen Sie mit Conditional Access und Modern Authentication um, d.h. Zertifikate, ADFS-Tokens etc. Nur weil Benutzer A wissen möchte, wie er an die Informationen von Benutzer B kommt, kann sich Benutzer A ja nicht noch automatisch am generischen Autodiscover-Dienst anmelden. Jede Dialogbox, die vom Anwender die Eingabe eines Kennworts verlangt, ist nicht nur störend für den Anwender sondern auch ein Sicherheitsrisiko. Der Anwender muss ja unterscheiden, ob die Box nun eine legitime Abfrage ist oder ein Schadcode der Zugangsdaten abfischen will.

Ein zweiter Aspekt ist die Federation zwischen Firmen. Die Zusammenarbeit wird immer enger und es könnte durchaus erwünscht sein, dass bestimmte Informationen vom Anwender selbst auch anderen Personen zur Verfügung gestellt werden sollen. Ich denke da z.B. daran, einen Lesezugriff auf meinen Kalender an jemand zu delegieren, der nicht Mitglied der Firma ist. z.B. könnte meine Ehefrau so sehr einfach meine nächsten Termine bei sich integrieren. Auf jeden Fall müsste ein System erst einmal per Autodiscover ermitteln, wo es die Anfrage überhaupt hinstellen muss. Der Zugriff auf die Information ist eigentlich nur schützenswert und nicht wo sie verortet ist. Eine Bank hat ja auch einen "Tresor" mit Schlössern aber überall stehen die Wegweiser, wie man zur Bank kommt.

Insofern ist Autodiscover eher das Verkehrsschild, das den Weg zu einem Ziel weist. Der Schutz der Information muss aber immer auf der Information selbst erfolgen. Nur dort kann letztlich bestimmt werden, welcher Zugriff (Kein, Lesen, Lesen/Schreiben, u.a.) erlaubt ist und welche Aktionen ausgelöst werden, wenn ein Angriff passiert. Dann haben Sie nämlich wirklich auch das Ziel erkannt. Autodiscover selbst ist ja nur der erste Schritt.

Weitere Links