Steffen Peters: Daten von einer Passwort-geschützten Seite herunterladen

Hallo Leute,

auf einer Webseite werden uns monatlich CSV-Dateien zum Download zur Verfügung gestellt. Den Download und die anschließende Verarbeitung würde ich gerne automatisieren. Allerdings sagt der Hersteller, dass er mittelfristig nur den Zugriff über Browser zur Verfügung stellen kann. Daher möchte ich das nun über ein geeginetes PHP-Script realisieren, weiß aber nicht so recht, wie ich das anstellen soll. Die URL für das Anmeldefenster lautet

https://vault.firma.net/index.php/s/RK2zA8ogRArFB1F?path=%2F2022%2F9

Es wird dann nur noch das Passwort abgefragt. Wenn ich ein Passwort eingebe, dann werden mir die CSV-Dateien angezeigt, die ich markieren und über einen Download-Button herunterladen kann.

Die HTML-Form ruft sich selber auf und der Payload der Anmeldung sieht wie folgt aus:

requesttoken: eine ziemliche lange Zeichenkette (ca. 90 zeichen)
sharingToken: die ID, die hinter dem /s/ steht
password: das eingegebene Passwort im Klartext

Ohne die Parameter hinter der index.php wird zu index.php/login geleitet. Hier kann ich sogar per GET-Parameter den Benutzernamen vorgeben und möglicherweise vielleicht sogar das Passwort (index.php/login?user=ABC&password=test), aber ich kenne tatsächlich meinen Benutzernamen nur in der kodierten Form.

Kann ein automatischer Download hier überhaupt (wenn auch mit Aufwand) funktionieren? Ist hier cUrl ein aussichtsreicher Ansatz?

Euer Steff

  1. Die URL für das Anmeldefenster ergibt den Fehler: Verbindung fehlgeschlagen

    Womöglich wird diese kryptische URL täglich / stündlich / ... neu generiert?

    Damit ist wohl ein automatischer Zugriff ausgeschlossen.

    1. Hallo,

      nein, die URL ändert sich nicht. Natürlich habe ich hier nicht die Original-Domain gepostet, daher auch der Zugriffsfehler bei Dir.

      Ich hab gerade nochmal geschaut. Sobald angemeldet, kann ich auch die Dateien direkt per One-Click herunterladen. Der Link lautet: /index.php/s/RK2zA8ogRArFB1F?path=%2F2022%2F9&openfile=3118427

      Dafür muss ich aber erstmal die Anmeldung hinbekommen.

      1. Lieber Steffen,

        Sobald angemeldet, kann ich auch die Dateien direkt per One-Click herunterladen.

        also dann: Mit cURL den Login nachbilden. Wie Du schon beschrieben hast, holst Du Dir das HTML-Dokument (via cURL!) mit dem Loginformular. Dann extrahierst Du alle Eingabe-Elemente (<input> und <select>) und ermittelst ihre bisherigen Werte.

        Wenn Du diese Liste an Schlüssel-Wert-Paaren hast, kannst Du Deine Login-Daten hinzufügen. Wenn Du Deinen Benutzernamen nur in der kodierten Form kennst, kannst Du ihn bestimmt dekodieren. Anschließend holst Du Dir mit cURL und den ganzen POST-Werten das HTML-Dokument, welches nach erfolgreicher Anmeldung gesendet werden sollte.

        Erzähl doch, wie es läuft!

        Liebe Grüße

        Felix Riesterer

  2. Lieber Steffen,

    Es wird dann nur noch das Passwort abgefragt. Wenn ich ein Passwort eingebe, dann werden mir die CSV-Dateien angezeigt, die ich markieren und über einen Download-Button herunterladen kann.

    ist das Eingeben des Passworts von einer weiteren Aktion begleitet? Also das Betätigen eines Buttons oder dergleichen? Wird durch diese Aktion ein HTTP-Request ausgelöst? Mit welcher Methode (GET|POST)?

    requesttoken: eine ziemliche lange Zeichenkette (ca. 90 zeichen)
    sharingToken: die ID, die hinter dem /s/ steht
    password: das eingegebene Passwort im Klartext
    

    Sind das POST-Daten?

    Man kann einen Login-Vorgang via PHP nachbilden. Ob man allerdings erreicht, was man will, ist fraglich, weil es an einigen Faktoren scheitern kann. Prinzipiell ist zu prüfen, ob

    • das Login-Formular für den jeweiligen Request spezielle Tokens bereit stellt, um XSS-Attacken zu blockieren. Diese müssen von Deinem PHP-Script beachtet und bei weiteren Requests wieder mitgeliefert werden.
    • Cookie-Daten für ein Session-Management zum Einsatz kommen. Auch diese müssen behandelt werden, wie ein Browser das auch tut.

    Ohne die Parameter hinter der index.php wird zu index.php/login geleitet. Hier kann ich sogar per GET-Parameter den Benutzernamen vorgeben und möglicherweise vielleicht sogar das Passwort (index.php/login?user=ABC&password=test), aber ich kenne tatsächlich meinen Benutzernamen nur in der kodierten Form.

    Login per GET? Allen Ernstes? Das klingt reichlich schrottig. Die Übertragung des Passwortes (und im Idealfall auch des Benutzernames) will man nicht in der URL sehen können. Das steht ja dann im Klartext in den Log-Dateien!

    Kann ein automatischer Download hier überhaupt (wenn auch mit Aufwand) funktionieren?

    Wenn es Dir gelingt, das HTML-Dokument nach dem Login per PHP abzugreifen und zu analysieren, um dann den CSV-Download zu simulieren, ja.

    Ist hier cUrl ein aussichtsreicher Ansatz?

    Also cURL ist nur ein Werkzeug. Es kann HTTP-Requests durchführen. Dein PHP-Script wird sich dieses Werkzeugs sicherlich bedienen wollen, damit Du via PHP die Login-Seite laden kannst, um den Login korrekt durchführen zu können, und auch um die Seite nach dem Login herunterzuladen, damit Du die CSV-Links findest. Auch die Downloads der CSV-Dateien kannst Du mit cURL umsetzen.

    Liebe Grüße

    Felix Riesterer

    1. Hallo Felix,

      sorry, ich hatte versäumt zu erwähnen, dass es POST-Daten ist. Und ja, ich muss das Kennwort eingeben und dann auf den Einloggen-Button klicken.

      Ich hatte mir gedacht, dass ich zuerst die Login-Seite abrufe, dort die diversen hidden-Inputs ziehe und damit dann den POST-Request nachbaue, um mich anzumelden. Ein einfacher Zugriffstest über wget hat leider nicht funktioniert. Die drei POST-Data-Felder habe ich mittels der Option "--post-data" übergeben. wget meldete zunächst, dass das Zertifikat abgelaufen wäre, obwohl der Browser es offenbar akzeptiert. Mit der Option "--no-check-certificate" konnte ich das ignorieren. Aber wget wird offenbar abgefangen, denn ich erhalte "405 Method not allowed".

      1. wget meldete zunächst, dass das Zertifikat abgelaufen wäre, obwohl der Browser es offenbar akzeptiert. Mit der Option "--no-check-certificate" konnte ich das ignorieren.

        Das ist SEHR merkwürdig. Stimmte denn der Hostname? Etwas wie „www“ vergessen?

        Aber wget wird offenbar abgefangen, denn ich erhalte "405 Method not allowed".

        Naja. Ich mach ja auch sowas (und noch krasseres) wenn mir Requests nicht gefallen. Das können hier „malformed“ Daten sein, Daten welche nicht zusammenpassen oder, ganz einfach, der von cUrl oder wget gesendete USER-AGENT. Auch den kann man manipulieren.

        Wie schon geschrieben: Du musst hier offenbar Reengineering betreiben und alle header und Daten analysieren, die rein- und rausgehen. In der Regel schaffen das die Entwicklungstools.

        Falls da aber auch noch Javascript mitmischt - in dem es mittels sorgfälig minifizierter und verdunkelter Skripte aus irgendwelchen Daten (z.B. AUCH aus dem Datum) irgendwelche Hashs baut - kann das „spaßig“ werden.

        Irgendwann kommt man an eine Grenze an welcher $andererAnbieter mit seinem $hoeherenPreis im Hinblick auf $PreisDesGefummels der Günstigere ist.

        Zudem könnte es ja auch sein, dass der derzeitige Anbieter der Daten genau dann, wenn Dein Programm läuft, etwas umbaut und Du von vorn anfangen musst. Dieses Risiko ist nicht kalkulierbar.

        Wähle lieber einen Lieferant, der Dir Zusicherungen gibt und vor allem (s)eine API offen legt.

        1. Hallo Raketenwilli,

          Wähle lieber einen Lieferant

          was man oft liebend gern täte, aber wegen [$grundX, $grundY, $grundZ] nicht kann. Je nach eigener Bedeutung als Kunde kann man dann maulen, zähneknirschen oder versuchen, den Lieferanten zu erpressen.

          Meinereiner hat je nach Lieferant schon alles davon getan, mal mit, mal ohne Erfolg (als Kunde sind wir durchaus beachtlich, aber Microsoft oder IBM lachen auch dann noch, wenn - um mal ein Beispiel aus einer anderen Branche zu bringen - AUDI oder Porsche Druck machen wollen.

          Rolf

          --
          sumpsi - posui - obstruxi
  3. Hallo Steffen,

    heißt also: Der Browser ruft mit GET ein Formular zur Passworteingabe ab. Der GET URL enthält deine User-ID bereits in verschlüsselter Form.

    Das so erhaltende Formular wird dann gePOSTet und schickt das Passwort im Klartext (was bei https okay ist), einen Wert aus dem Formular (das Request-Token) und einen Wert aus der URL (das Sharing-Token).

    D.h. dein erster Schritt ist das Auslesen des Passwort-Formulars, um an das Request-Token heranzukommen, um damit den POST Request zusammenzubauen.

    Und dann? Vermutlich bekommst Du als Antwort auf diesen POST zwei Dinge:

    • einen Keks
    • einen Redirect auf die Downloadseite.

    Den Keks musst Du bei allen Folge-Requests mitliefern, um den Login aufrechtzuerhalten. Den Redirect musst Du verstehen, die Downloadseite holen und dann deren Inhalt durchwühlen, um die Download-Links zu extrahieren.

    Ich habe keine Ahnung von cURL, aber ich glaube, damit könnte ein Standardtool überfordert sein. Eine Keksdose gibt's in cURL, aber einen Screen Scraper?

    Eigentlich schreit das nach einem FTP Server (den gibt's auch mit Transportsicherheit) oder einem REST Service.

    Rolf

    --
    sumpsi - posui - obstruxi
  4. Die URL für das Anmeldefenster lautet

    https://vault.firma.net/index.php/s/RK2zA8ogRArFB1F?path=%2F2022%2F9
    

    Nein. Lautet sie nicht.

    Die Domain „firma.net“ steht zum Verkauf. Bitte benutze die Domain „example.org“ für Beispiele sonst verwirrst Du eine Menge Leute und bringst womöglich Dritte in juristische Schwierigkeiten.

    1. Hallo,

      Die Domain „firma.net“ steht zum Verkauf. Bitte benutze die Domain „example.com“ für Beispiele

      alternativ example.net oder example.org, oder auch *.example oder *.test.

      sonst verwirrst Du eine Menge Leute und bringst womöglich Dritte in juristische Schwierigkeiten.

      Und dich selbst noch dazu.

      Einen schönen Tag noch
       Martin

      --
      Wer nicht genießt, wird ungenießbar.
      (Mottospruch auf einem T-Shirt)