Category: thoughts

Vermeiden. Erkennen. Beheben.

21.08.2017 yahe legacy security thoughts

Bereits seit einiger Zeit orientiere ich mich bei der Auswahl von Sicherheitsmaßnahmen an einer Einteilung, die ich bereits im Artikel über die aktive Verteidigung gegen Kryptotrojaner einmal verwendet hatte: Vermeiden. Erkennen. Beheben.

Bisher war ich davon ausgegangen, dass es sich dabei um ein gängiges Modell handelt, schließlich wird es in vielen Bereichen eingesetzt, in denen es um Fehlervermeidung geht. Bezogen auf das Management der Informationssicherheit habe ich jedoch keine relevanten Quellen ausfindig machen können, die sich mit dieser Klassifizierung von Sicherheitsmaßnahmen beschäftigt. Aus diesem Grund habe ich mir überlegt, einfach einmal aufzuschreiben, was ich mit den drei Punkten meine und wie deren Anwendung einem helfen kann, die Absicherung der eigenen Informationssicherheit ganzheitlicher zu gestalten.

tl;dr

Anstatt sich im risikoorientierten Sicherheitsmanagement nur mit der Frage zu beschäftigen, wie man Schäden vermeidet, sollte man in seinen Prozessen auch die Frage berücksichtigen, wie man entstandene Schäden erkennt und wie man diese entstandenen Schäden behebt.

Grundsätzliches

Sicherheitsmanagement, wie es heutzutage praktiziert wird, ist primär risikoorientiert. Man baut sich einen Pool an potentiellen Bedrohungen auf; prüft, ob ein spezifisches Asset Schwachstellen hat, die durch eine Bedrohung zu tatsächlichen Gefährdungen werden; bewertet das daraus entstehende Risiko und überlegt sich, wie man mit diesem Risiko umgehen möchte. Möglichkeiten sind die Übernahme des Risikos, man lebt also damit, dass das Risiko existiert; man transferiert das Risiko auf jemand anderen, z.B. indem man eine Versicherung abschließt; man vermeidet das Risiko, z.B. indem man eine andere technische Lösung wählt; oder man reduziert das Risiko, indem man Maßnahmen ergreift, die dabei helfen, die Eintrittswahrscheinlichkeit oder die Auswirkung zu verringern.

Wie man erkennt, beschränkt sich diese Form der Betrachtungsweise primär auf die Vermeidung von Schäden. Was fehlt, ist die Betrachtung von Maßnahmen, die dabei helfen, eingetretene Schäden zu erkennen und diese zu beheben. Meiner Erfahrung nach führt diese einseitige Herangehensweise dazu, dass sich Unternehmen darauf versteifen, Gefahren abzuwehren und sich zu wenig damit auseinander setzen, was passiert, wenn ein Schaden trotzdem eintreten sollte. Erst in jüngerer Zeit scheint es hier ein Umdenken zu geben. Nachdem sogar Sicherheitsunternehmen wie z.B. Antivirenhersteller und Sicherheitsbehörden gehackt werden, entsteht langsam das Mantra "es stellt sich nicht die Frage, ob man gehackt wird, sondern wann".

Die Klassifizierung von Sicherheitsmaßnahmen in die Kategorien Vermeidung, Erkennung und Behebung, wobei Mehrfachklassifizierungen je nach Nutzungsart durchaus möglich sind, kann dabei helfen, einen ganzheitlichen Ansatz des Sicherheitsmanagements zu etablieren.

Vermeiden

Meiner Erfahrung nach handelt es sich bei der Vermeidung von Schäden um den Maßnahmenkomplex, den Unternehmen als erstes betrachten, wenn sie sich mit dem Thema Sicherheits- oder Risikomanagement beschäftigen. Als ich begonnen habe, mich mit der IT-Security zu beschäftigen, ist man häufig noch davon ausgegangen, dass es ausreichend ist, genügend technische Maßnahmen zu ergreifen, um sich vollständig abzusichern. Das Nutzen von Verschlüsselung, der Einsatz von Antivirenscannern und Firewalls, das Nutzen von RAIDs, das Erstellen von Backups, sowie das regelmäßige Patchen von Anwendungen waren die klassischen zu ergreifenden Maßnahmen. Wie bereits weiter oben beschrieben, führen auch die klassischen Risikomanagementmethoden dazu, sich primär mit Maßnahmen zur Vermeidung von Schäden zu beschäftigen.

Erkennen

Die Erkennung von Schäden ist, so zumindest meine Erfahrung, selten vom Gedanken des Risikomanagements getrieben, dafür aber umso häufiger vom Gedanken der operativen Funktionstüchtigkeit. Die klassische Erkennungsmethode ist der Einsatz einer Monitoringlösung im IT-Umfeld. Diese beschränkt sich jedoch sehr häufig auf Themen wie die Verfügbarkeit von Services und der Ressourcenauslastung von Hardware.

Nur selten wird sie genutzt, um regelmäßig nach veränderten Dateien, unzulässigen Netzwerkverbindungen, unbekannten Prozessen oder bekannten Prozessen mit unbekannten Parameterlisten zu scannen. Hintergrund dürfte auch sein, dass sich das Erkennen von Verfügbarkeitsproblemen recht einfach standardisieren lässt, während Verhaltensmuster von Systemen und Anwendungen sehr unterschiedlich sein können und eines individuelles Profiling bedürfen. Das führt dazu, dass solche komplexeren Erkennungen in Form von IDS- und IPS-Lösungen erst dann zum Einsatz kommen, wenn das gesamte Sicherheitsmanagement des Unternehmens einen gewissen Reifegrad erreicht hat.

Eine andere klassische Maßnahme ist die Einführung einer zentralen Logging-Infrastruktur, die es prinzipiell ermöglicht, durch das Analysieren einer Vielzahl von Systemevents einen möglichen Schaden zu erkennen. Aber auch hier müssen erst im Zuge einer SIEM-Lösung entsprechende Trigger definiert werden, bevor ein tatsächlicher Nutzen aus der Maßnahme gezogen werden kann.

Doch auch abseits der Technik sollte man sich im Zuge seines Risikomanagements immer die Frage stellen, welche Maßnahmen ergriffen werden, um das Eintreten eines Schadens überhaupt erkennen zu können.

Beheben

Nachdem man sich Gedanken gemacht hat, wie man eingetretene Schäden erkennt, besteht die schlussendliche Arbeit darin, sich zu überlegen, wie man den Schaden wieder beheben kann. Eine klassische Maßnahme zur Behebung von Schäden ist das Wiedereinspielen von Backups oder das Neuaufsetzen von kompromittierten Systemen. Doch evtl. muss je nach Anwendung granularer vorgegangen werden oder es ergibt sich die Möglichkeit, die Behebung einzelner Schäden automatisiert durchzuführen.

Meiner Erfahrung nach bestehen viele Maßnahmen zur Behebung von Schäden im ersten Schritt aus spontanen Ideen, die im tatsächlichen Ernstfall umgesetzt werden. Diese verfestigen sich anschließend durch die Formulierung von Wiederherstellungsplänen oder, gröber gefasst, durch Notfallpläne im Zuge der Etablierung eines Notfallmanagements. Die erstellten Pläne stützen sich anfangs oft vor allem auf händische Prozesse. Erst bei zunehmender Reife werden manuelle Arbeiten durch automatisierte Tasks abgelöst. Denn auch hier müssen viele individuelle Aspekte berücksichtigt werden.

Auch abseits der Technik sollte man sich Gedanken über die Behebung von Schäden machen. Wie reagiert man als Unternehmen, wenn essentielle Ressourcen nicht zur Verfügung stehen oder wie würde man beim Abhandenkommen sensibler Daten vorgehen?

Praxisbeispiel

Um diese Dreiteilung an Maßnahmen einmal im Zusammenspiel zu zeigen, möchte ich einmal Antivirensoftware als plakatives Beispiel wählen, unabhängig von der Diskussion über deren tatsächlichen Nutzen.

Wir beginnen mit der Hauptaufgabe von Antivirensoftware, dem Erkennen von Viren. Im ersten Schritt wird man nur einzelne Dateien geprüft haben und diese Maßnahme Stück für Stück erweitert haben; um das Scannen ganzer Ordner, um das Scannen des ganzen Systems und schlussendlich auch um das Scannen des Bootsektors. Die Erkennung erfolgte früher allein auf Basis einer Virensignatur, sprich, der Information darüber, wie der kompilierte Quelltext des Virus aussieht.

Als man Viren erkennen konnte, stellte sich die Frage, wie man mit ihnen umgeht, sprich, wie das Beheben eines Virenbefalls aussehen könnte. Man könnte sie z.B. in Quarantäne schieben, sie direkt löschen oder, mit entsprechend viel Wissen über den Virus, diesen evtl. sogar aus einer infizierten Datei entfernen.

Als man nun weiter fortschritt, Festplatten größer und die Scans damit zeitaufwändiger wurden, kam man evtl. nicht mehr dazu, regelmäßig alle Dateien händisch zu prüfen. Trotzdem war es wichtig, zu verhindern, dass eine virenverseuchte Datei geöffnet oder verteilt wird. Also begann man damit, Dateien noch vor einem tatsächlichen Zugriff zu prüfen. Das Live-Scannen von Dateien half, das Ausführen von Viren zu vermeiden, optimierte gleichzeitig aber auch das Erkennen von Viren.

Viren wurde intelligenter und polymorph, ihr Quelltext änderte sich regelmäßig, sodass einfache Virensignaturen nicht mehr in der Lage waren, diese zu erkennen. Erst durch die Einführung von Heuristiken kam Antivirensoftware dazu, auch diese neuen, komplexeren Viren überhaupt erkennen zu können.

Das Internet hielt Einzug und verdrängte Wechseldatenträger als primäres Einfallstor für Viren. Die Hersteller von Antivirensoftware gingen mit und begannen, sich in den Datenkanal einzuklinken. Man wollte Viren bereits erkennen können, noch bevor sie auf der Festplatte des Nutzers gespeichert werden. Das sollte auch vermeiden, dass Nutzer überhaupt die Möglichkeit haben, irgendetwas mit der virenverseuchten Datei anstellen zu können.

Im Businessumfeld sind die Risiken, die von einem Virenbefall ausgehen, sogar noch größer, als in anderen Bereichen. Virenschreiber haben es vor allem auch auf diesen Bereich abgesehen, mitunter sogar mit speziell entwickelten Viren. Aber auch Antivirenhersteller haben dies erkannt und bieten spezifische Lösungen für solche Unternehmen an. Eine Lösung ist, Anwendungen vor ihrem Download auf einen Nutzerrechner in einer VM einer Scanning-Appliance gezielt zur Ausführung zu bringen, um ein verdächtiges Verhalten dieser Anwendung bereits im Vorfeld erkennen zu können. Hiermit will man die Ausführung eines Virus auf einem Nutzerrechner vermeiden.

Fazit

Wie man am Beispiel der Antivirensoftware gut erkennen kann, kann die Klassifizierung von Maßnahmen in die Themenfelder Vermeidung, Erkennung und Behebung dabei helfen, diese besser in einem gesamtheitlichen Sicherheitsansatz zu begreifen. Je nach Reifegrad des Sicherheitsmanagements im eigenen Unternehmen sollte man sich einmal ansehen, in welchem der drei Themenkomplexe noch Nachholbedarf bzgl. der geplanten und umgesetzten Maßnahmen besteht.


Aktive Verteidigung gegen Krypto-Trojaner

29.02.2016 yahe code legacy security thoughts

Mit Locky sieht die IT-Welt derzeit einen der koordiniertesten Trojanerangriff der jüngeren Zeit. Während er sich Anfangs als Schläfer getarnt haben soll, findet er inzwischen auf unterschiedlichsten Wegen sein Ziel: als Word- oder Excel-Dokument mit schädlichem Makro; als JavaScript-Datei, die sich z.B. als angebliches Sipgate-Fax tarnt; oder gar als altmodische und als ausgestorben geglaubte Batch-Datei. Bei den Opfern des Verschlüsselungstrojaners handelt es sich auch um größere Organisationen wie Krankenhäuser und ein Fraunhofer-Institut. Man ging zeitweise von 5000 Neuinfektionen pro Stunde aus.

Die Vorschläge für Gegenmaßnahmen sehen derzeit noch eher mager aus. Die einen raten zur Symptombekämpfung durch Backups, deaktivierte Makros und Virenscannern. Andere wiederum versuchen, den Krypto-Trojaner anhand seiner Funktionsweise zu erkennen und so eine Anti-Malware-Software auf Heuristikbasis zu entwickeln.

Um sich erfolgreich gegen solch einen Trojanerangriff zur Wehr zu setzen, muss man jedoch an mehreren Baustellen aktiv werden und anstatt unterschiedlichste Teilmaßnahmen einzuführen, sollte man sich überlegen, welche Kombination von Maßnahmen zu einem ganzheitlichen Schutz führen kann. Die folgende Auflistung soll dabei eine kleine Hilfestellung für einen aktiven Umgang mit solch einem Infektionsrisiko bieten. Das folgende Dreiergespann aus Vermeidung, Erkennung und Behebung ist auch in der Medizin durchaus weit verbreitet.

Zuerst einmal sollte man natürlich das Thema Vermeidung betrachten. Hierzu zählen Dinge wie das Deaktivieren der Makrofunktion in Office-Anwendungen und die Aufklärung von Mailnutzern darüber, dass Office-Anhänge von außen nicht zu öffnen und ZIP-Dateien von außen nicht zu entpacken sind. Auch das Deaktivieren von JavaScript auf exponierten Arbeitsplätzen oder gar der Wechsel auf ein Betriebssystem mit konsequenter Trennung von Ausführungsrechten und Dateinamen kann eine Option darstellen.

Anschließend sollte man sich darum kümmern, eine Erkennung eines erfolgreichen Angriffs zu ermöglichen. Erst, wenn eine Infektion erkannt werden kann, kann sie im Anschluss auch behoben werden. Leider ist es noch häufig so, dass eine Erkennung lediglich durch Virenscanner erfolgt. Diese sind jedoch so spezifisch an einzelne Schädlinge und deren Verhalten angepasst, dass neue Generationen häufig für längere Zeit unentdeckt bleiben. Anstatt Verhaltensmuster der Schädlinge zu untersuchen, ist es daher sinnvoller, Standardverhaltensmuster seiner Mitarbeiter zu aggregieren und Abweichungen von diesem Standardverhalten in einem Sicherheitsmonitoring zu sammeln. So ist es möglich, auch neue Schädlinge anhand eines vom Durchschnitt abweichenden Verhaltens zu erkennen. Beispielsweise könnte zum Erkennen eines Krypto-Trojaners die durchschnittliche Anzahl an neu erstellten, bearbeiteten und gelöschten Dateien pro Tag herhalten. Während ein typischer Büroarbeiter eher selten viele Dateien gleichzeitig anlegt und gleichzeitig viele Dateien löscht, ist genau das das Hauptgeschäft von Krypto-Trojanern. Solch eine Erkennung von Abweichungen kann mit Canaries ergänzt werden. Dabei handelt es sich um Dateien, die extra als Opfer für einen Verschlüsselungstrojaner bereitgestellt werden und deren Bearbeitung als ein eindeutiges Indiz für das Vorhandensein eines Krypto-Trojaners dienen kann. Das Ziel der Erkennung ist es, von einem Problem zu erfahren, noch bevor der Nutzer etwa Ungewöhnliches feststellt.

Abschließend muss das Thema der Behebung betrachtet werden. Hierzu zählen an erster Stelle regelmäßige Backups. Das häufig kommunizierte Mantra, Dateien auf einem externen Datenträger zu sichern und diesen anschließend wieder vom Computer zu trennen, stellt in den meisten Umgebungen keinen ausreichenden Schutz dar. Denn während des Backups kann auch der externe Datenträger befallen und verschlüsselt werden. Der eigentliche Wunsch hinter solch einer Aussage ist vielmehr, eine Sicherung zu erstellen, die von einer eventuellen Infektion nicht beeinflusst werden kann. Sinnvolle Varianten können hierbei extern durchgeführte Backups sein, die nicht vom infizierten Nutzer angestoßen und demnach auch nicht vom infizierten Nutzer modifiziert werden können. Auch lokale Backups unter der Hoheit eines anderen Systemnutzers stellen eine Möglichkeit dar. Noch sinnvoller als ein einfaches Backup ist eine Versionierung, die zwar mehr Speicherplatz benötigt, dafür aber auch eine selektive Wiederherstellung von Dateiinhalten unterschiedlichster Zeitpunkte ermöglicht.

Die Implementierung eines entsprechenden Schutzes ist auch mit einfachen Tools möglich, wobei speziell entwickelte Werkzeuge wesentlich mehr Komfort bieten können. Im Folgenden soll eine Erkennung und Behandlung eines Krypto-Trojaner-Angriffs mit Hilfe von Mercurial dargestellt werden. Anbei folgt ein beispielhaftes Skript zur Erkennung von Abweichungen in der Bearbeitung von Dateien. Das Script ermittelt Abweichungen von der durchschnittlichen Menge an erstellten/gelöschten/bearbeiteten Dateien. Zudem prüft es separat die Veränderung eines Canaries. Das Script ist nur als Proof-of-Concept eines dateiorientierten, Host-basierten, sowie Anomalie-basierten Intrusion Detection Systems zu verstehen.

#!/usr/bin/php
<?php
  // user-defined values
  define("CHECKFOLDER", "/testpit/");
  define("CHECKCANARY", CHECKFOLDER . "data/do-not-edit.txt");
  define("STATUSFILE",  CHECKFOLDER . "status/status");

  // deviation of user behaviour from previously collected behaviour
  define("DEVIATIONVALUE", 0.5); // default deviation of 50% is allowed

  // generated values
  define("CHECKDATE", date("Ymd-His"));

  // concatenated actions
  define("ADDREMOVECMD", "hg addremove -R \"" . CHECKFOLDER . "\" -X \"" . CHECKCANARY . "\"");
  define("COMMITCMD",    "hg commit -R \"" . CHECKFOLDER . "\" -X \"" . CHECKCANARY . "\" -m \"" . CHECKDATE . "\"");
  define("STATUSCMD",    "hg status -R \"" . CHECKFOLDER . "\"");

  // static definitions
  define("ADDEDHINT",     "A");
  define("MISSINGHINT",   "!");
  define("MODIFIEDHINT",  "M");
  define("NOTTRACKEDHINT","?");
  define("REMOVEDHINT",   "R");

  define("HINTDELIMITER",       " ");
  define("STATISTICSDELIMITER", ":");

  function check_filename($line, $filename) {
    $result = false;

    $parts = explode(HINTDELIMITER, $line, 2);
    if ((false !== $parts) && (2 === count($parts))) {
      $result = (0 == strcasecmp(CHECKFOLDER . $parts[1], $filename));
    }

    return $result;
  }

  function check_hint($line, $hint) {
    $result = false;

    $parts = explode(HINTDELIMITER, $line, 2);
    if ((false !== $parts) && (2 === count($parts))) {
      $result = (0 == strcasecmp($parts[0], $hint));
    }

    return $result;
  }

  function get_statistics_text($additions, $deletions, $modifications) {
    return (CHECKDATE . STATISTICSDELIMITER . ADDEDHINT . STATISTICSDELIMITER . $additions .
                        STATISTICSDELIMITER . MODIFIEDHINT . STATISTICSDELIMITER . $modifications .
                        STATISTICSDELIMITER . REMOVEDHINT . STATISTICSDELIMITER . $deletions);
  }

  function check_statistics($additions, $deletions, $modifications) {
    $result = true;

    // with any modification there's nothing to check
    if (0 < ($additions + $deletions + $modifications)) {
      // read statistics and execute statistics checkvg_additions_count     = 0;
      $avg_additions_count     = 0;
      $avg_additions_value     = 0;
      $avg_deletions_count     = 0;
      $avg_deletions_value     = 0;
      $avg_modifications_count = 0;
      $avg_modifications_value = 0;

      if (is_file(STATUSFILE)) {
        $statistics = file(STATUSFILE, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        if ((false !== $statistics) && (0 < count($statistics))) {
          // calculate average additions, deletions and modifications from statistics data
          foreach ($statistics as $line) {
            $parts = explode(STATISTICSDELIMITER, $line, 7);
            if ((false !== $parts) && (7 === count($parts))) {
              // check if value is integer and bigger than 0
              if (is_numeric($parts[2]) && (0 < $parts[2])) {
                $avg_additions_value += $parts[2];
                $avg_additions_count++;
              }
              if (is_numeric($parts[6]) && (0 < $parts[6])) {
                $avg_deletions_value += $parts[6];
                $avg_deletions_count++;
              }
              if (is_numeric($parts[4]) && (0 < $parts[4])) {
                $avg_modifications_value += $parts[4];
                $avg_modifications_count++;
              }
            }
          }
        }
      }

      // there's nothing wrong when nothing happened
      if (0 < $additions) {
        // when actions has never been seen then that's a deviation
        if (0 === $avg_additions_count) {
          $result = false;
        } else {
          // more additions than expected
          if (((1.0 + DEVIATIONVALUE) * ($avg_additions_value / $avg_additions_count)) < $additions) {
            $result = false;
          }
        }
      }

      // there's nothing wrong when nothing happened
      if (0 < $deletions) {
        // when actions has never been seen then that's a deviation
        if (0 === $avg_deletions_count) {
          $result = false;
        } else {
          // more deletions than expected
          if (((1 + DEVIATIONVALUE) * ($avg_deletions_value / $avg_deletions_count)) < $deletions) {
            $result = false;
          }
        }
      }

      // there's nothing wrong when nothing happened
      if (0 < $modifications) {
        // when actions has never been seen then that's a deviation
        if (0 === $avg_modifications_count) {
          $result = false;
        } else {
          // more modifications than expected
          if (((1 + DEVIATIONVALUE) * ($avg_modifications_value / $avg_modifications_count)) < $modifications) {
            $result = false;
          }
        }
      }
    }

    // add new result to statistics
    file_put_contents(STATUSFILE,
                      get_statistics_text($additions, $deletions, $modifications) . "\n",
                      FILE_APPEND | LOCK_EX);

    return $result;
  }

  function main() {
    $additions     = 0;
    $deletions     = 0;
    $modifications = 0;

    $canary_found = false;

    // retrieve information about file changes
    exec(STATUSCMD, $output);

    // accept file changes right away
    exec(ADDREMOVECMD);
    exec(COMMITCMD);

    // iterate through file changes
    foreach ($output as $line) {
      // check if the canary file is part of the modifications
      if (check_filename($line, CHECKCANARY)) {
        $canary_found = true;
      } else {
        // check if a file has been added
        if (check_hint($line, ADDEDHINT) || check_hint($line, NOTTRACKEDHINT)) {
          $additions++;
        } else {
          // check if a file has been deleted
          if (check_hint($line, MISSINGHINT) || check_hint($line, REMOVEDHINT)) {
            $deletions++;
          } else {
            // check if a file has been modified
            if (check_hint($line, MODIFIEDHINT)) {
              $modifications++;
            }
          }
        }
      }
    }

    if (0 < ($additions + $deletions + $modifications)) {
      // accept file changes
      exec(ADDREMOVECMD);
      exec(COMMITCMD);
    }

    // print result
    print(get_statistics_text($additions, $deletions, $modifications) . "\n");

    // the canary has been modified
    if ($canary_found) {
      //!!! do something
      print("ALERT! CANARY HAS BEEN MODIFIED!\n");
    }

    // check if the modifications do not match the statistics
    if (!check_statistics($additions, $deletions, $modifications)) {
      //!!! do something
      print("ALERT! BEHAVIOUR DOES NOT MATCH STATISTICS!\n");
    }
  }

  // execute application
  main();

?>

Bei jedem Aufruf ermittelt das Script mit Hilfe von Mercurial, welche Dateien in einem Repository/Ordner hinzugefügt, entfernt oder bearbeitet wurden. Sollte sich darunter die Canary-Datei befinden, wird Alarm geschlagen. Zudem wird eine statistische Analyse durchgeführt. In diesem einfachen Beispiel gilt als Abweichung, wenn mehr als 150% der durchschnittlichen Dateioperationen erkannt wurden. Wird solch eine Abweichung erkannt, wird ebenfalls Alarm geschlagen. Durch die Verwendung von Mercurial ließen sich zudem zu jeder Zeit alle bearbeiteten Dateien rekonstruieren.

In einem realen Umfeld könnte solch eine Analyse natürlich noch viel tiefergreifend sein. So könnten beispielsweise folgende Prüfungen mit einfließen, um Anomalien besser erkennen zu können:

  • Es könnte die Uhrzeit der Dateibearbeitung mit in die Analyse einfließen. In Kombination mit der Auswertung von Arbeitsplänen und/oder Anwesenheitszeiten ließen sich bessere Modelle erstellen. So sollte es seltener der Fall sein, dass Dateien eines Mitarbeiters bearbeitet werden, der gar nicht anwesend ist.
  • Es könnte die Relation der Dateibearbeitungen untereinander betrachtet werden. Beispielswiese werden Büromitarbeiter wesentlich mehr Dateien erstellen und bearbeiten als löschen, da Arbeitsergebnisse selten wieder vernichtet werden.
  • Es könnte das ursprüngliche Dateidatum mit berücksichtigt werden. Beispielsweise ist es eher unüblich, dass Dateien ab einem bestimmten Alter noch einmal bearbeitet werden. Stattdessen werden sie eher als Referenz vorgehalten, anstatt als aktives Arbeitsdokument zu fungieren.

Je besser das erstellte Modell ist, mit dem das Verhalten der Systemnutzer abgeglichen wird, desto schneller erkennt man in Ausnahmesituationen einen potentiellen Angreifer. Nicht immer müssen das externe Angreifer sein. Auch interne Mitarbeiter, die ein ungewöhnliches Verhalten an den Tag legen, können auf diese Weise unter Umständen identifiziert werden. Es muss nicht einmal zwingend eine böse Absicht hinter diesem Verhalten stecken, evtl. stellt ein Mitarbeiter einfach eine Ausnahme zur üblichen Regel dar.

Generell sollte man sich bei solch einer Angriffserkennung auf Basis von Abweichungsermittlungen daran gewöhnen, auch False Positives zu erhalten. Diese sind durchaus wünschenswert, da sie einerseits zeigen, dass die durchgeführten Analysen tatsächlich einen Effekt haben und einem andererseits Verbesserungspotentiale in den erstellten Anomaliemodellen aufzeigen.


3D-Barcodes mit Farbfiltern auslesen...

18.01.2016 yahe legacy thoughts

Bereits vor einer ganzen Weile hatte ich mal mit Licht und Farbfiltern herum experimentiert. Damals hatte ich mit Hilfe von Farbfiltern das Licht aufgespalten, das von einer RGB-LED emittiert wurde und dabei auch erwähnt, dass man auf Basis dieser Bündelung Daten übertragen könne.

Einige Zeit später war ich auf der Suche nach einer Möglichkeit, Binärdaten über ein Druckerzeugnis zu übertragen. Dabei denkt man heutzutage natürlich erst einmal an 2D-Barcodes (z.B. Aztec-Codes, Matrix-Codes oder die allseits bekannten QR-Codes). Leider reichte deren Datendichte nicht aus. In ähnlichen Fällen werden deshalb gelegentlich 3D-Barcodes (z.B. der "HCCB"-Code von Microsoft) eingesetzt. Diese funktionieren, indem zusätzlich zu den beiden Dimensionen Höhe und Breite noch die dritte Dimension der Farbe eingeführt wird. Allerdings benötigen solche 3D-Barcodes typischerweise mehrere Dinge:

  1. Eine Lizenz, um das Verfahren nutzen zu dürfen.
  2. Stark angepasste Lesegeräte und/oder Erkennungsalgorithmen.

In dem Moment dachte ich an das Experiment mit den Farbfiltern zurück. Wenn man es hinbekäme, die Komplexität des Barcode-Lesens und die Komplexität des gesteigerten Farbraums voneinander zu trennen, könnte man einfach reproduzierbare Barcodes erzeugen, die gleichzeitig mit vorhandenen Standardmitteln lesbar wären. Geboren war der kombinierte Farb-Barcode.

kombinierter Farb-Barcode

Herstellen lässt er sich recht einfach:

  1. Man nimmt sich zwei normale 2D-Barcodes und legt diese übereinander.
  2. Pixel, die in beiden Barcodes vorkommen, werden schwarz gefärbt.
  3. Pixel, die in keinem der beiden Barcodes vorkommen, werden weiß gefärbt.
  4. Pixel, die nur im ersten Barcode vorkommen, werden mit einer Farbe A eingefärbt.
  5. Pixel, die nur im zweiten Barcode vorkommen, werden mit einer Farbe B eingefärbt.

Gedanken machen muss man sich nun darum, wie man die Barcodes wieder getrennt bekommt. Dafür ist es wichtig, Farbe A und Farbe B richtig zu wählen. Diese beiden Farben müssen eine Beziehung zueinander haben, die sich wie folgt beschreiben lässt:

  1. Wenn Farbe A durch einen Farbfilter der Farbe B betrachtet wird, muss ein möglichst starker Farbkontrast entstehen.
  2. Wenn Farbe B durch einen Farbfilter der Farbe A betrachtet wird, muss ein möglichst starker Farbkontrast entstehen.

Glücklicherweise hatte ich Farbfilter zuhause, die diese beiden Bedingungen erfüllen, rote und blaue:

roter und blauer Farbfilter

Wichtig für einen produktiven Einsatz ist, dass die Farbfilter und die für den Druck verwendeten Farben aufeinander abgestimmt werden. Im Haushaltsgebrauch wird man das nicht unbedingt hinbekommen, weshalb das Auslesen des Barcodes im selbstgebastelten Umfeld wohl mehr Geduld erfordert, als es im professionellen Umfeld der Fall wäre.

gedruckter Farb-Barcode

Um nun den Inhalt der Barcodes auslesen zu können, platziert man einen Farbfilter vor der Kamera und scannt den Code. Anschließend tauscht man den Farbfilter vor der Kamera aus und scannt den Code erneut (sogenanntes "shuttern"). Eine Alternativmöglichkeit ist, zwei Kameras gleichzeitig zu verwenden, die jeweils einen der Farbfilter fest zugeordnet bekommen. So ist es möglich, trotz doppelter Datendichte die Lesegeschwindigkeit konstant zu halten.

Farb-Barcode mit Farbfilter Farb-Barcode mit Farbfilter

Wie man erkennt, geschehen beim Aufnehmen des Barcodes durch die Farbfilter nun mehrere Dinge:

  1. Schwarze Pixel bleiben unverändert und stellen die Kontrastfarbe dar.
  2. Weiße Pixel werden eingefärbt und stellen die Grundfarbe dar.
  3. Pixel in der Farbe des Filters werden herausgefiltert und stellen die Grundfarbe dar.
  4. Pixel in der Gegenfarbe des Filters werden verstärkt und stellen die Kontrastfarbe dar.

Durch Einsatz der Farbfilter und dem Effekt der Kontraständerung der Gegenfarbe entstehen zwei unterschiedliche Barcode-Abbildungen auf Basis eines einzigen Farb-Barcodes. Jeder QR-Code-Leser, der einen automatischen Kontrastabgleich vornimmt, kann diese Barcodes bereits lesen. Zur Verbesserung der Barcode-Erkennung können nach dem Einsatz des Filters noch zwei Schritte unternommen werden, um das Leseergebnis zu verbessern. Im ersten Schritt kann eine Überführung in ein Graustufenbild erfolgen, um den Bias des Farbsensors abzumildern. Denn wie man in den Ausgangsbildern erkennt, ist der Kontrast im Blaufilter-Bild wesentlich schlechter erkennbar als im Rotfilter-Bild.

Farb-Barcode mit Farbfilter als Graustufenbild Farb-Barcode mit Farbfilter als Graustufenbild

Im zweiten Schritt kann mit Hilfe eines Schwellwertabgleichs der tatsächlich benötigte Bildinhalt gut herausgefiltert werden. GIMP bietet hierfür beispielsweise ein einfach zu verwendendes Werkzeug, das einem eindeutig anzeigt, welche Schwellwerte von Interesse sind:

Schwellwertabgleich Schwellwertabgleich

Die daraus entstehenden Barcodes sollten nun wirklich von jedem Barcode-Scanner gelesen werden können:

Farb-Barcode mit Farbfilter als Graustufenbild nach Schwellwertfilter Farb-Barcode mit Farbfilter als Graustufenbild nach Schwellwertfilter

Um zu zeigen, dass das Auslesen auch mit Standardmitteln funktioniert, habe ich einen prototypischen Versuch unternommen und zuhause einen Farb-Barcode ausgedruckt, eine normale QR-Code-App auf meinem iPhone installiert und einen Farbfilter vor die Kamera gehalten. Den Versuch, die beiden Ebenen des 3D-Barcodes aufzunehmen habe ich als Video bei Youtube hochgeladen. Ja, es funktioniert nicht perfekt, aber weder Licht, Druckerfarbe, Farbfilter noch die verwendete App sind in irgendeiner Form aufeinander abgestimmt. Das sollte man beim Betrachten des Videos im Hinterkopf behalten.

Einsatz finden kann solch ein Verfahren in meinen Augen in zwei Situationen:

  1. In Situationen, in denen in einem Barcode mehr Daten gespeichert werden müssen, als in einen konventionellen Barcode passen.
  2. In Situationen, in denen in einem Barcode Daten für mehrere Empfänger gespeichert werden sollen. Möglich wäre beispielsweise das Szenario, dass zwei Verarbeitungsschritte Informationen aus einem Barcode lesen sollen. Der Barcode-Leser des ersten Verarbeitungsschritts erhält einen blauen Farbfilter, dessen zu lesende Daten werden in rot encodiert. Der Barcode-Leser des zweiten Verarbeitungsschritts erhält einen roten Farbfilter, dessen zu lesende Daten werden in blau encodiert. Bei gut abgestimmten Filtern und Druckfarben sind die Barcode-Leser nun optisch nicht mehr in der Lage, die falschen Daten vom Farb-Barcode auszulesen.

TeamViewer: Ein Konzept macht noch keine Sicherheit

01.07.2014 yahe legacy security thoughts

Heute hatte ich das Vergnügen, die Bekanntschaft mit dem TeamViewer zu machen, einem Tool, das es ermöglicht, VPN-Verbindungen durch restriktive Firewalls hindurch aufzubauen. Das ganze funktioniert mit einer User-ID und einem Passwort, was gerade dazu einlädt, diese einfache Lösung zu verwenden. Aber wie genau funktioniert das dann? Und wie sicher ist der Verbindungsaufbau und die darüber übertragenen Daten?

Einen ersten Anhaltspunkt gibt die Menge der Konfiguration. Annähernd null, ziemlich wenig für eine typische VPN-Verbindung. Die Verwendung einer User-ID lässt den Schluss zu, dass ein zentraler Server beim Verbindungsaufbau involviert ist. Weiteren Aufschluss über die Vorgänge beim Verbindungsaufbau gibt das Dokument mit den "Teamviewer Sicherheitsinformationen". Dort wird lang und breit erklärt, wie viele Zertifizierungen man hat, dass man tollen ISO-Standards entspricht, europäische Server verwendet, viel Wert auf den Schutz personenbezogener Daten legt und Technologien einsetzt, die so ähnlich bereits anderswo erfolgreich eingesetzt werden. Ein Statement interessiert mich dabei besonders:

Wie später im Abschnitt „Verschlüsselung und Authentifizierung“ beschrieben, können auch wir als Betreiber der Routingserver den verschlüsselten Datenverkehr nicht einsehen.

Allerdings stellt sich die Frage, ob das wirklich so ist. Sehen wir uns im ersten Schritt die Registrierung der Schlüssel an. Diese werden von Client A und Client B generiert und der Public Key des Clients an Server S übertragen. Die Schlüssel werden für die Übertragung mit dem öffentlichen Masterschlüssel von Server S verschlüsselt. Da jedoch Server und Masterschlüssel unter der Kontrolle von TeamViewer sind, stellt das kein Hindernis dar. Eine weitere Validierung findet laut dem Dokument nicht statt.

TeamViewer: Key Ceremony

Kommen wir also zum eigentlichen Verbindungsaufbau zwischen zwei Clients. Die Authentisierung der Clients via SRP lasse ich an dieser Stelle außen vor, da diese nur zwischen einem Client und dem Server stattfindet, aber nicht unter den Clients.

Als erstes erfragt Client A von Server S den Public Key von Client B. Die Anfrage ist mit dem öffentlichen Masterschlüssel von Server S verschlüsselt. Der Public Key von Client B wird vom Server S an Client A geschickt, verschlüsselt mit dem Public Key von Client A und signiert mit dem Masterschlüssel von Server S. Beide Daten sind TeamViewer natürlich bekannt. Nun erzeugt Client A einen symmetrischen AES-256-Schlüssel, verschlüsselt ihn mit dem Public Key von Client B, den er von Server S erhalten hat und signiert ihn mit seinem eigenen Private Key. Dieses Paket X wird nun an Server S geschickt, damit dieser es an den Client B weiterleitet. Nach dem Erhalt fragt Client B den Public Key von Client A bei Server S an. Die Anfrage ist wiederum mit dem öffentlichen Masterschlüssel von Server S verschlüsselt. Server S antwortet mit dem Public Key von Client A, den er mit dem öffentlichen Schlüssel von Client B vor der Übertragung verschlüsselt und mit seinem eigenen Masterschlüssel signiert. Nun prüft Client B die Signatur von Paket X mit dem erhaltenen Public Key von Client A und kann anschließend den symmetrischen AES-256 Schlüssel mit seinem eigenen Private Key entschlüsseln.

TeamViewer: Connection Establishment

Damit haben nun Client A und Client B einen gemeinsamen, symmetrischen AES-256 Schlüssel und können diesen verwenden, um verschlüsselt untereinander zu kommunizieren. Da TeamViewer die privaten Schlüssel der Clients nicht kennt, können sie auch nicht den ausgetauschten symmetrischen Schlüssel in Erfahrung bringen. Oder etwa doch? Hier schlägt nun nämlich ein großes Problem zu: der zentrale Server. Die Clients müssen diesem blind vertrauen. Während des Schlüsselaustauschs ist er jedoch in solcher einer Machtposition, dass überhaupt nicht ersichtlich ist, ob er tatsächlich keinen Zugriff auf den symmetrischen AES-256 Schlüssel hat.

Nehmen wir uns mal folgendes Szenario: Der Client A möchte gern eine Verbindung zu Client B aufbauen und muss dazu dessen öffentlichen Schlüssel erfragen. Der zentrale Server S könnte nun mit einem öffentlichen Fake-Schlüssel für Client B antworten, zu dem der Server auch den passenden privaten Fake-Schlüssel kennt. Der Client A würde nun mit diesem öffentlichen Fake-Schlüssel den symmetrischen AES-256 Schlüssel verschlüsseln und mit seinem privaten Schlüssel signieren. Dieses Paket X würde der Client A nun an den Server schicken, damit dieser es an Client B weiterleitet. Anstatt es jedoch einfach weiterzuleiten, entschlüsselt Server S den symmetrischen AES-256 Schlüssel mit dem passenden privaten Fake-Schlüssel für Client B, verschlüsselt den symmetrischen AES-256 Schlüssel mit dem tatsächlichen öffentlichen Schlüssel von Client B, signiert das ganze mit einem privaten Fake-Schlüssel für Client A und schickt dieses neue Paket Y erst dann an Client B weiter. Nach dem Erhalt fragt Client B den Public Key von Client A bei Server S an. Dieser antwortet jedoch stattdessen mit dem öffentlichen Fake-Schlüssel für Client A. Die Signatur des Paket Y passt mit dem erhaltenen öffentlichen Fake-Schlüssel überein, der symmetrische AES-256 Schlüssel ist mit dem korrekten öffentlichen Schlüssel von Client B verschlüsselt, also muss das erhaltene Paket Y ja valide sein und der enthaltene Schlüssel kann verwendet werden.

TeamViewer: Possible MITM Attack

Praktischerweise bestimmt nun auch noch TeamViewer, ob eine direkte TCP-/UDP-Verbindung aufgebaut wird oder ob die Routingserver von TeamViewer verwendet werden. Dank des unsicheren Schlüsselaustauschs können die Routingserver den symmetrischen AES-256-Schlüssel verwenden, um den gesamten Traffic zwischen Client A und Client B zu entschlüsseln. Die Aussage aus dem Dokument, dass dieses Mitlesen nicht möglich sei, ist also schlichtweg falsch.

Ob es Absicht ist, dass TeamViewer sämtliche Datenverbindungen mitlesen kann? Ich weiß es nicht. Es ist jedoch auffällig, dass sie bei der Authentisierung zwischen Client und Server ein relativ komplexes, Diffie-Hellmann-ähnliches Verfahren einsetzen, während sie beim Austausch des symmetrischen Schlüssels nicht auf ein Verfahren setzen, das aus einem gemeinsamen Geheimnis einen sicheren Sitzungsschlüssel erzeugt.

Die Entscheidung, ob man einer zentralen Instanz Zugriff auf sämtliche übertragenen Daten geben möchte, sollte an dieser Stelle jeder für sich selbst treffen.


Das blendfreie Fernlicht...

21.04.2011 yahe legacy thoughts

In den langen Wintermonaten ist mir etwas aufgefallen: Seid ihr schon mal im Dunkeln durch den Wald gefahren und wurdet plötzlich von einem entgegenkommenden Auto mit Fernlicht geblendet? Mir ist das in der vergangenen Zeit häufiger passiert. Dabei habe ich mir etwas überlegt: Warum kann man keine "Abblendscheiben" entwickeln?

Das ganze stelle ich mir in etwa so vor, wie bei gefärbten Scheiben. Der Farbeindruck bei diesen Scheiben entsteht dadurch, dass bestimmte Wellenlängen des sichtbaren Lichtes reflektiert werden und nur noch bestimmte Wellenlängen durchgelassen werden. Man könnte doch nun einfach Glühbirnen (z.B. LED-Birnen) herstellen, die Licht mit einer bestimmten Wellenlänge emitieren. Gleichzeitig könnte man Glas herstellen, das genau diese Wellenlänge reflektiert. Beleuchtet ein Fernlicht nun einen Fahrer hinter solch einer Scheibe, so würde der Fahrer im Auto nicht geblendet werden, aber trotzdem die besser ausgeleuchtete Umgebung sehen können. Möglich ist das dadurch, dass die beleuchtete Umgebung das Licht des Fernlichts nicht 1:1 zurückwirft, sondern die Wellenlänge des Lichtes beim Zurückwerfen ändert.

Es ist nur eine fixe Idee, aber probieren könnte man es doch mal, oder? Inspiriert wurde ich übrigens vom Kobaltglas, das in der Lage ist, gelbes Licht wegzufiltern und das deshalb in der Chemie bei der Flammenprobe für die Unterscheidung verschiedener Metalle verwendet wird.


Search

Links

RSS feed

Categories

administration (40)
arduino (12)
calcpw (2)
code (33)
hardware (16)
java (2)
legacy (113)
linux (27)
publicity (6)
review (2)
security (58)
thoughts (21)
windows (17)
wordpress (19)