blog.atwork.at

news and know-how about microsoft, technology, cloud and more.

Password Security lokal und in der Cloud - Password Hash Sync Security

Sicherheit ist eine Vertrauensfrage, die jedes Unternehmen für sich selbst beantworten und lösen muss. In letzter Zeit bekommen wir immer mehr Fragen zum Thema Password (Hash) Sync in Azure Active Directory Connect. Hierzu gibt es viele Unklarheiten wie das genau funktioniert oder warum eine Synchronisation von Passwörtern trotzdem als sehr sicher angesehen werden kann.

Hier liefern wir Hintergrund-Informationen, wie Passwort-Sicherheit in AD, AAD Connect und AAD funktioniert.

Dieser Artikel entstand bereits vor einiger Zeit aus der Idee von Martina Grom, Toni Pohl und Christoph Wilfing um über die Sicherheitsaspekte von Password Sync in die Cloud zu informieren. Nun ist dieser Artikel aktueller denn je. Christoph hat diesen Artikel geschrieben, ergänzt von Teilen und Kommentaren der anderen Autoren.

Natürlich gibt es Security-Experten, die darüber im Detail beschrieben haben, wie der Synchronisationsprozess genau aussieht und welche Algorithmen und Methoden hierbei zum Einsatz kommen. Ein aktueller und sehr umfangreicher Artikel von Michael Grafnetter hierzu findet sich u.a. in How Azure Active Directory Connect Syncs Passwords.

Ich bin kein Kryptographie-Experte und auch nicht in der Lage die Details und Methoden der Verschlüsselung selbst umzusetzen, dafür gibt es eigene Experten. Trotzdem will ich versuchen einen Überblick zu geben welche Methoden bei Microsoft verwendet werden um das Passwort des Users zu schützen. Dazu wollen wir uns hier die einzelnen Bereiche und deren Sicherheit ansehen.

1. Active Directory (Security on premises)

Unsere Geschichte beginnt im Active Directory (AD) auf einem Windows Server System. Ein User wird angelegt und erhält ein Passwort. Dieses wird anschließend im Active Directory gespeichert. Natürlich nicht im Klartext.

Das bedeutet, ein Passwort wird im AD als NT-Hash abgelegt. Der Artikel "Passwords Technical Overview-How passwords are stored in Windows" ist zwar aus 2012, gilt aber noch bis heute. Im Wesentlichen ist das Password ein MD4 Hash. Microsoft selbst beschreibt die verwendete Verschlüsselungsmethode als "The NT hash is simply a hash". Sinngemäß wird das Passwort (falls es zu kurz ist, mit NULL Bytes aufgefüllt), in zwei Teile zerlegt, verschlüsselt, wieder zusammengefügt und daraus ein Hash berechnet.

Ich darf an dieser Stelle erinnern: MD5 Hashes wurden vor einiger Zeit aus Zertifikaten verbannt. Das war 2008 als auf dem 25. Chaos Computer Congress eine Kollision einer Intermediate CA hergezeigt wurde (ebenso ein sehr spannendes Thema). Nicht umsonst gibt es hier eine aufsteigende Versionsnummer... Man kann also sagen, dass die Passwort-Verschlüsselung im AD heutzutage nicht mehr unbedingt zeitgemäß ist.

2. Azure Active Directory Connect (Synchronisation)

AAD Connect verwendet nun den NT-Hash im Active Directory und will diesen in das AAD synchronisieren. (Infos zu, AAD Connect Tool finden sich hier.)

Natürlich wird dieser NT-Hash aus dem AD aber nicht 1:1 ins AAD gespeichert, sondern vorher erneut lokal gehashed - also verschlüsselt. Also wir hashen einen Hash. Das kann man sich etwa wie diese russische Matryoshka Puppe vorstellen, Grafik von https://en.wikipedia.org/wiki/Matryoshka_doll.

image

Als Hashing Algorithmus kommt hier PBKDF2 zum Einsatz. Dieser Hashing Algorithmus ist in der RFC2898 beschrieben und ist somit kein proprietärer Mechanismus, sondern ein weltweiter Standard.

Der einzige Zusatz ist, dass neben ein wenig Herumrechnerei, ein sogenannter SALT dazugepackt wird. Ein SALT - wie der Name schon sagt - kann als das Salz des Lebens verstanden werden. Salz macht das Leben interessanter. Um einen SALT zu erklären muss ich ein wenig ausholen.

Hashing ist ein rechnerisch aufwändiger Prozess. Das bedeutet man braucht sauschnelle CPUs (GPUs sind aber besser geeignet) damit man viele Hashes ausrechnen kann. Wozu macht man das?

Der Grund ist einfach: Mit hoher Rechenkapazität können Brute Force Attacken ausgeführt werden. Brute Force Attacken sind nichts anderes als Auszuprobieren, ob ein beliebiger String den vorhandenen Hash ergibt. Findet man einen String der denselben Hash erzeugt wie der Hash des Passworts den wir haben, dann haben wir das Passwort gefunden.

Jetzt hat sich jemand überlegt, "das könnte man doch einfach mal alles ausrechnen und eine Table in einer Datenbank daraus machen". Also, String (Passwort) => Hash, dann klauen wir noch den Hash eines Passworts und machen einen SQL Table Lookup und schon haben wir das Passwort im Klartext. Das ist irgendwie eine nahe liegende Idee. Nachdem diese "Rainbow Tables" modern geworden sind hat man für einiges an Geld ein Backup von einem SQL Table mit 300GB bekommen und konnte in kürzester Zeit (wenigen Minuten/Sekunden) Passwörter von - je nachdem bis zu 10 oder 15 Stellen - einfach "nachschauen". Das ist natürlich nicht im Sinne der Sicherheit...

Genau hier kommt unser SALT ins Spiel. Der SALT ist der Sand (eigentlich das Salz) im Getriebe eines Rainbow Tables. Der SALT ist ein völlig zufälliger Wert der bei der Berechnung des Hashes einfliesst und damit auch aus gleichen Ausgangspasswörter unterschiedliche Hashes erzeugt.

Klar was ich meine? Machen wir ein einfaches Beispiel zur Nachvollziehbarkeit um ein Kennwort mit einem SALT zu verschlüsseln (Grafik zum Vergrößern anklicken).

image

Wie man sieht verwende ich die Hashing Funktion eines Powershell Modules. Obwohl der SALT sich nur durch eine einzige Stelle unterscheidet, ist der resultierende Hash vollkommen unterschiedlich! Damit kann ich gleichzeitig den SALT jederzeit mitgeben. Jede Rainbow Table müsste jetzt _nochmal_ gerechnet werden um den zufälligen SALT zu berücksichtigen und damit ist der Vorteil des Rainbow Tables hinfällig.

An dieser Stelle danke an DSInternals für das PowerShell Modul zur Verschlüsselung. Die Verwendung ist einfach: Das Modul herunterladen und mit Install-Module -Name DSInternals in einer Powershell 5.0 installieren. Die Verwendung erfolgt dann wie oben gezeigt.

AAD Connect verwendet ebenso eine solche Methode. Und zwar zweimal. Damit haben wir den Hash eines Hashes eines Passworts den wir per SSL über die Leitung transportieren und an einen Microsoft Server in der Cloud übertragen.

Eine Eigenheit, die AAD Connect an dieser Stelle besitzt: Das Tool verwendet _niemals_ einen SSL Proxy Server für die Übertragung. Dies habe ich selbst mehrfach getestet und ausprobiert. Der AAD Connect Server verbindet sich _FIX_ direkt auf die Ziel IP der Microsoft Server und verwendet den gesetzten System Proxy nicht. Warum ist auch klar: Man könnte mit einem SSL Proxy einfach den SSL Tunnel aufbrechen und den "Hash eines Hashes eines Passworts" per MITM-Attacke auslesen. Das wird unterbunden.

Ich nenne dieses "Passwort" jetzt weiter einfach "HHP". Mit einer selbst erstellten Abkürzung wird alles besser und es klingt gleich viel wichtiger.

3. Azure Active Directory (Cloud)

Im Azure Active Directory (AAD) angekommen wird der HHP abgelegt und bei einer Authentifizierung durch Portal oder Client neu berechnet und mit dem gespeicherten HHP verglichen. Somit ist klar: Das Kennwort liegt immer nur zweifach verschlüsselt vor. Ist der berechnete Hash gleich dem gespeicherten Hash, hat der User das richtige Passwort angegeben und wird angemeldet.

In unserem Beispiel von oben würde der Vergleich sinngemäß also etwa so aussehen:
IF "ad37ea7d..." == "ad37ea7d..." THEN LOGIN OK

Die erste Frage des Kunden lautet dann oft: Aber bitte, dann muss ich das Passwort ja auf der Webseite eintippen. Ja richtig. Wie das genauso auch bei Facebook, Google+, Xing oder anderen Web Services der Fall ist. Natürlich wird das Passwort _NIEMALS_ im Klartext über die Leitung geschickt, Anmeldungen werden ausschließlich über SSL verschlüsselt angeboten und niemals über den HTTP Port 80, zB: beim Login mit einem AAD Konto: https://login.microsoftonline.com/...

Die zweite Frage: Kann aus dem HHP das Kennwort zurückgerechnet werden? Nein. Ohne SALT gar nicht, oder nur mit sehr viel Rechenleistung (und Zeit). Hier gilt: Je mehr Stellen das Kennwort hat, umso mehr Zeit wird für Berechnen und eventuelle Brute Force Attacken gegen das Anmeldeservice benötigt.

Die Ablage des Passworts selbst erfolgt auf den gesicherten Servern von Microsoft Azure. Diese sind natürlich in einem geschützten Rechenzentrum hinter besonders dicken und fetten Firewalls versteckt. Was in den Microsoft Rechenzentren alles genau im Einsatz ist mir nicht bekannt, man kann sich aber unter folgenden Links einen Überblick verschaffen:

Wem das nicht reicht, der kann natürlich gern noch eins drauf setzen:

4. MFA-Multi Factor Authentication

Multi Factor bedeutet immer, dass ein Passwort allein nicht genug ist um sich anzumelden. Wir kennen das von den klassischen Tokens die man früher am Schlüsselbund hatte. Die zeigen alle 60-90 Sekunden einen neuen 6 stelligen Code an der dann zusätzlich zum Passwort angegeben wird. Man will damit erreichen, dass ein gestohlenes Passwort allein nicht ausreicht. Man muss auch etwas besitzen um zu beweisen, dass man der Benutzer ist der man vorgibt zu sein. Microsoft geht dabei einen Schritt weiter und bietet allen Office 365 Kunden kostenlos einen zusätzlichen Faktor an. Dies kann nun sein:

  • MFA Applikation auf dem SmartPhone - Aufforderung zur Bestätigung
  • MFA Applikation auf dem SmartPhone - Aufforderung zur Bestätigung inklusive Angabe eines PINs
  • MFA Applikation auf dem SmartPhone - Mehrstelliger Code
  • Anruf auf einer definierten Telefonnummer
  • Anruf auf einer definierten Telefonnummer inklusive Angabe eines PINs
  • ...und sicher noch eine Variante die mir nicht einfällt...

In Kombination mit dieser Funktionalität versucht Azure auch auf gewisse nicht mögliche Szenarien zu reagieren. Ein simples Beispiel, das mir selbst passiert ist war: Ich melde mich auf meinem Notebook in Österreich auf einer Portal Seite an und setze das Hackerl für "Privater Computer - frage nicht erneut nach dem Second Factor". Damit kann ich mich bequem mehrfach anmelden und muss nicht ständig meinen Soft Token am Handy bemühen. Ich wähle mich in ein Kunden VPN ein und bin damit plötzlich quasi in Deutschland. Beim nächsten Versuch auf das Portal zuzugreifen werde ich erneut nach MFA gefragt mit dem Hinweis, dass mein letzter Zugriff aus einem anderen Land war. Um sicherzugehen, dass ich noch ich bin, werde ich erneut nach MFA gefragt (obwohl ich das auf diesem PC deaktiviert habe).

Azure versucht damit zu erkennen ob ein Zugriff valide sein kann oder nicht. Nicht vernünftig klingt etwa, dass ein Mitarbeiter in wenigen Minuten von Österreich nach Deutschland reist und sich dort erneut anmeldet. Das Ganze funktioniert ähnlich wie Kreditkartenunternehmen eine Betrug (Fraud) erkennen. Physische Kartenzahlungen werden blockiert sofern eine unrealistische Reisezeit zwischen den Orten liegt.

Im Office 365 Reportcenter existieren sogar eigene Security-Reports, die solche und weitere verdächtige Versuche aufzeigen (neben den Statistiken von erfolgreichen und erfolglosen Logins u.v.m.).

5. Windows Hello

Mit Windows 10 geht Microsoft in der Authentifizierung noch einen Schritt weiter: Die Anmeldung an einem Windows Gerät kann durch Erkennen der Person erfolgen, sofern man die entsprechende Hardware besitzt: Ein Fingerprint Reader oder eine Webcam und natürlich Windows 10.

Get Started with Windows 10 informiert über die wichtigsten Eckpunkte und beschreibt das Service wie folgt: "Windows Hello ist ein Teil von Windows 10 und ermöglicht eine neue Art der Anmeldung an Geräten, Apps, Onlinediensten und in Netzwerken, die einfacher, benutzerfreundlicher und sicherer ist als ein Kennwort ist".

Im Hintergrund nutzt Windows Hello die Technologie "Microsoft Passport" für Anmeldeinformationen. Damit können biometrischen Authentifizierung wie Gesichts- oder Iriserkennung und Fingerabdruck oder auch ein PIN sicher (also verschlüsselt) gespeichert werden. Es wird kein "Bild" am Computer gespeichert, sondern eine Art berechnetes Diagramm. Diese Informationen bleiben ausschließlich am eigenen Computer gespeichert. Wie beim HHP ist kein "Zurückberechnen" möglich, also kann aus dem Diagramm kein Bild berechnet werden. Die Windows Hello und Datenschutz: FAQ geben Auskunft über die Details von Hello.

Fazit

Was ich leider immer wieder in Unternehmen höre ist: "Doppelt gehashed oder nicht, AzureAD Connect mit Password Sync ist unsicher, wir wollen ADFS."

Nun stellen Sie sich einmal folgende Fragen:

  • Windows Active Directory hashed sein Kennwort mit einem Hashing-Algorithmus der seit Jahren als Unsicher gilt und Rainbow Table Attacken ermöglicht um in wenigen Minuten selbst komplexe Passwörter zu hacken. Vertrauen Sie diesem Mechanismus mehr, als einem aktuellen Hashing-Algorithmus mit gehärteten Abwehrmechanismen (SALT!) gegen diverse BruteForce Attacken?
  • ADFS benötigt aktiven Zugriff vom Internet auf einen Ihrer eigenen Server...
  • Haben sie IDS Systeme um zu erkennen ob dieser Server gehackt wurde?
  • Wie oft monitoren Sie diese Server-Umgebung und Ihre Firewall?
  • Können Sie (automatisiert) DDOS Attacken blocken?
  • Verwenden Sie Lockout Policies? Wenn ja: Ich sperre Ihnen jeden User im Unternehmen in wenigen Sekunden... wie viel Schaden richtet das an?
  • Verwenden sie Extranet Lockout? Wenn nein: Dann sollten sie sich dieses Feature bald ansehen um den hoffentlich eingesetzten WAP Server vor Massen Lockout Ihrer User über AD FS zu schützen.
  • ...und es gibt noch viele weitere Fragen zum Thema Security...

Man sieht, in Wahrheit ist das schwächste Glied in der ganzen Password-Security-Kette das (lokale) Active Directory. Aber jeder IT-Security-Beauftragte will sein HHP nicht im AAD (in der Cloud) haben... Ob das noch zeitgemäß ist?

Wir hoffen, dieser Artikel hilft, das Thema Passwort Security etwas näher zu beleuchten und sich selbst und für das eigene Unternehmen zu überlegen, wie Security gehandhabt wird und ob die Sicherheit von AAD Connect und Sicherheitsmechanismen in der Cloud helfen können, Ihr Unternehmen sicherer zu machen.

Comments (6) -

  • Helmut

    7/26/2017 6:48:05 AM |

    Danke für die Ausführliche Darstellung. Ein Punkt der mir noch unklar ist:

    Jeder User gibt lediglich sein Passwort ei. Wo kommt der SALT her?
    Wenn dieser automatisch vom System beim User generiert wird, wie kommt dieser zur Verifizierung in die Cloud?
    Wenn dieser automatisch generiert wird, woher wissen die Systeme, wenn der User erst 6 Monate später auf die Dokumente zugreifen will, noch den korrekten SALT?
    Das bedeutet auch, dass das Passwort als Hach vom MD4 und der Hash vom SALT
    sowohl beim On-Prem AD und in der Cloud AD liegen müssen?
    Wie kann MS Ihren Aufgaben nachkommen und die Dateien in der Clound nach Malware
    dursuchen wenn der User der Dokumenteneigner ist? Dazu müsste MS ja Passwort und
    den HHP haben und auch verwenden?

    Mfg
    Helmut Klarer

  • Christoph Wilfing

    7/26/2017 5:35:11 PM |

    Hallo Herr Klarer,

    es freut mich, wenn der Artikel hilfreich war.

    Der SALT ist normalerweise eine möglichst lange (128bit) Zeichenkette die beim setzen des Passworts (bzw. in diesem Fall beim ersten lesen) erzeugt wird und gemeinsam mit dem Passwort gespeichert wird. Dieser SALT wird jetzt an das Klartextpasswort angehängt, anschließend der HASH erzeugt. Sieht dann in etwa so aus:

    <PWHash><SALT> => Hashfunktion => <PwHashDerGespeichertWird>

    der so entstandene Hash wird gemeinsam mit dem SALT (welcher im Klartext bleibt!) gespeichert in etwa so:

    <Salt128bit>;<PwHashDerGespeichertWird>

    (der Semikolon wurde von mir jetzt als Trennzeichen angenommen, könnte aber natürlich ein beliebiges Zeichen sein um das Ende des SALTs zu erkennen.)

    Der Salt selbst bleibt dabei im Klartext. Man könnte jetzt meinen das widerspricht dem Sinn. Aber der Sinn des SALTs ist Rainbow Tables zu verhindern. Und dafür muss nur garantiert sein, das für jeden User der SALT ein anderer ist und verändert auch den entstandenen Hash. Selbst wenn zwei User das gleiche Passwort verwenden wird durch den Random generierten SALT der PWHash definitiv unterschiedlich und somit jeder Rainbow Table unbrauchbar.

    Was die Frage des Malware scans betrifft - das Passwort dient der Verification des Users sprich beweist wer der User ist, es definiert nicht, worauf dieser User zugriff hat. Es besteht ein wesentlicher Unterschied zwischen Authorisierung und Authentifizierung. Die oben genannten Methoden dienen der Authentifzierung, nicht der Authorisierung.
    Sie können sich das vorstellen wie den BackupMode eines NTFS File Systems. Sobald ich berechtigt bin den Backup Mode zu verwenden kann ich unabhängig davon wem das Dokument gehört dieses auch angreifen. Das Problem das sie ansprechen trifft sie nur bei ARM (Azure Rights Management) - dort werden die Dokumente auch verschlüsselt ohne das ein System darauf Zugriff hat und somit verhindert es auch einen erfolgreichen Malware Scan.

    MfG
    Christoph Wilfing

  • Helmut

    7/27/2017 8:35:11 AM |

    Guten Morgen Herr Wilfing,

    Danke für die rasche Antwort. Das Prinzip ist mir soweit klar.

    Analog zum on-Prem AD: Wenn ich mich am AAD anmelde, wird das Passwort per MD4 in einen Hash umgerechnet. Damit benötigt der AAD zur Verifikation den Hash lokal, damit der „einfache“ PW Hash nicht über die Leitung / Internet geht. Damit muss ich mich zuvor als User am AAD „registrieren“ damit der AAD aus dem PW den Hash generieren und lokal ablegen kann.

    Damit der PW Hash nicht über das Internet geht, abgefangen wird und per Rainbow-Table zurück gerechnet werden kann wird jetzt das SALZ hinzugefügt und der HHP übertragen.

    Damit die Authentifizierung funktioniert, muss links und rechts (AD und AAD) derselbe PW Hash und SALT verfügbar sein. D.h. beim Ersten Anmelden auf dem AAD  muss am lokalen PC das SALZ generiert und zeitgleich im AAD und im AD gespeichert werden.

    Soweit korrekt?

    Was mir jetzt nicht klar ist:
    Wenn ich mich am OS/Windows anmelde, fragt mein OS den AD ab. Dieser hat nur den MD4Hash. Mein OS muss also das PW in den einfachen MD4 Hash umrechnen und mit dem Hash vergleichen den das AD zurück sendet. Das Passwort wird hier niemals übertragen.

    Wenn ich jetzt ein Netzlaufwerk anlege, muss ähnliches passieren. Mein lokales OS sendet einen User Request und wartet auf den Response Hash (PWHash) vom entfernten OS. Passt er, wird das Laufwerk angelegt, wenn nicht, kommt das Anmeldefenster. Das Passwort wird hier niemals übertragen.


    Bei einem Cloud mit AAD muss es dann ähnlich funktionieren. Nur dass hier anstelle des PW Hash der HHP (Hash+Salt) als Response vom entfernten OS (oder hier AAD) zurückkommt. Passt er, wird die Verbindung/Filetransfer akzeptiert, wenn nicht, kommt das Anmeldefenster. Das Passwort wird hier niemals übertragen.



    Wo liegt jetzt der Unterschied ob ich den einfachen PWHash oder den HHP abfange und mich als der User ausgebe? Ich kann zwar nicht auf das Passwort zurückreichen, aber egal, ich kann mich als User ausgeben da ich das HHP habe und das PW sowieso nicht abgefragt wird, sondern nur die Hashes..

    Lg & Danke
    Helmut

  • Christoph Wilfing

    7/27/2017 2:10:47 PM |

    Hallo,

    sie sprechen hier ein ganz anderes Problem an. Das Problem das sie sehen nennt sich Pass_the_hash (https://en.wikipedia.org/wiki/Pass_the_hash) hat aber nichts mit dem Hash ansich zu tun, sondern mit der darunterliegenden Authentifizierungsarchitektur.

    Wir schützen mit dem SALT im Hash den Hash davor per Brute Force zurück gerechnet zu werden. Der Schutz des Hashes davor gestolen zu werden obliegt der dazwischen liegenden Übertragungstechnologie. (SSL/TLS, Certificate Pinning,...)

    MfG
    Christoph Wilfing

  • Helmut

    7/31/2017 7:42:53 AM |

    Hallo,

    Da ich als Betreiber nicht nur die einzelne Teilmodule, sondern das „Gesamte“ betrachten muss, bin ich aufgrund des Artikels fälschlicherweise der Meinung aufgesessen, dass es eine Möglichkeit gibt das gesamte System „Externe Daten“ bzw. “Cloundtransfer“ sicher zu gestalten. Es hilft mir leider nichts wenn Dokumente und Informationen, statt aus der Linken, aus der rechten Tasche entwendet werden… Damit ist das Gesamtkonstrukt Cloud für mich noch immer „unsicher“.

    Die Tatsache das MS die On-Prem Security nicht nachgezogen hat (um die Leute auf Cloud zu leiten?) wird sicher dazu führen, dass die Linux und Samba Community langfristig die Oberhand gewinnen wird.

    Eine Betrachtung in Teilbereiche ist sicher ein guter Weg, da die Gesamtkomplexität mittlerweile fast unüberschaubar ist. Danke für ihre sehr hilfreichen Erklärungen für diesen Teilaspekt!

  • Christoph Wilfing

    7/31/2017 8:02:57 AM |

    Hallo,

    Das Thema würde ich gern offline mit ihnen nochmal besprechen, da ich denke das wir hier von zwei verschiedenen Themen sprechen. Sie können mich gern unter meinen Kontaktdaten (cw (AT) atwork.at) kontaktieren.

    Um kurz ihre Frage zu beantworten - 'die Cloud' ist sehr wohl der sichere Teil. das Problem ist ihre onPremises Umgebung. DORT liegt der Hash aus meist kompatibility Gründen unsalted herum. (und diese compatibility Gründe sind übrigens meist SMB von Third Party Herstellern die unter anderem neuere Verschlüsselungsalgos nicht supporten.) Ohne dabei mit dem Finger zeigen zu wollen (und verstehen sie mich nicht falsch, ich mag Linux sehr!) aber die leider sehr verbreitete Ansicht Linux muss ja nicht gepatched werden führt nunmal auch dazu, das wir die Security auf Windows Seite nicht stramm ziehen dürfen ohne diese Systeme auszusperren. (und das würde wiederum zur klassischen Meinung - Windows sperrt alle anderen aus führen).

    Wie gesagt - ich bitte sie mich direkt zu kontaktieren um das genau zu erläutern, da ich keinerlei Fingerpointing oder Flameware auf unserem Blog starten möchte.

    Danke!

    MfG
    Christoph Wilfing

Loading