Archive: Month 9, Year 2015

Altes Passwort bei Google wieder verwenden

29.09.2015 yahe legacy security

Wer kennt es nicht? Man hat ein Passwort bei einem Dienst vergessen, lässt es zurücksetzen und das neue Passwort, das man setzen möchte, entspricht genau dem Passwort, das man eigentlich vergessen hatte. Einige Dienste weisen einen darauf hin, dass man das Passwort schon einmal verwendet hatte, lassen das Setzen des Passworts dann aber doch zu.

Google verhindert erneute Passwortnutzung

Anders sieht das jedoch bei Google aus: Dort wird die erneute Verwendung eines bereits verwendeten Passworts vehement abgelehnt. Das geht sogar soweit, dass das Passwort abgelehnt wird, obwohl man es zwischenzeitlich mehrfach gewechselt hat. Doch auch das Gedächtnis von Google hat irgendwo seine Grenzen, genauer gesagt bei 100 Passworten. So oft muss man sein Passwort ändern, um eine bereits verwendetes Passwort wieder verwenden zu können.


Java-Anwendung sauber beenden mit addShutdownHook

21.09.2015 yahe code java legacy

Bei einfachen Java-Anwendungen macht man sich typischerweise wenig Gedanken um das saubere Beenden aller Prozesse. Man geht davon aus, dass der Nutzer weiß, was er tut, wenn er auf Beenden klickt und fragt zur Not vorher nochmal nach, ob er tatsächlich fortfahren will. Anders sieht das jedoch aus, wenn man mehrere Threads verwaltet, wie das zum Beispiel bei Serveranwendungen der Fall ist. Dann möchte man vor dem tatsächlichen Beenden lieber doch noch die einen oder anderen Aufräumarbeiten durchführen, zum Beispiel Logdateien flushen, laufende Serveranfragen beantworten oder temporäre Dateien wegräumen. Die JVM-Runtime bietet für solche Fälle die Möglichkeit, sogenannte Shutdown-Hooks via "Runtime.getRuntime().addShutdownHook()" zu registrieren. Wenn die JVM beendet wird, werden die registrierten Hooks ausgeführt. Im Grunde sind es Threads, deren "run()"-Methode aufgerufen wird.

Im folgenden Beispiel habe ich mal eine kleine Vorlage gebastelt, in der man sieht, wie man das ganze verwenden kann. In der Methode "startupMain()" implementiert man alle Initialisierungen, die beim Programmstart ausgeführt werden sollen, in der Methode "runMain()" führt man dann die tatsächliche Anwendung aus, während in der Methode "shutdownMain()" notwendige Deinitialisierungen durchgeführt werden können:

public class Main extends Object implements Runnable {

    // singleton instance
    protected static Main fInstance = null;

    static {
        // create singleton instance
        fInstance = new Main();
    }

    // prevent external instantiation
    protected Main() {
        super();
    }

    public static Main getInstance() {
        return fInstance;
    }

    public static void main(String[] args) {
        Main lMain = Main.getInstance();

        // call startup code
        lMain.startupMain(args);

        // register shutdown code
        Runtime.getRuntime().addShutdownHook(new Thread(lMain));

        // call main code
        lMain.runMain();
    }

    @Override
    public void run() {
        // call shutdown code
        shutdownMain();
    }

    public synchronized void startupMain(String[] aArguments) {
        // startup code
        // ...
    }

    public synchronized void shutdownMain() {
        // shutdown code
        // ...
    }

    public void runMain() {
        // main code
        // ...
    }

}

Als Test habe ich mir eine einfache Anwendung geschrieben, die beim Starten das Wort "start", während des Laufens in einer Endlosschleife das Wort "sleep" und beim Beenden das Wort "stop" schreibt. Die drei Methoden sehen dabei wie folgt aus:

    public synchronized void startupMain(String[] aArguments) {
        // startup code
        // ...
        System.out.println("start");
    }

    public synchronized void shutdownMain() {
        // shutdown code
        // ...
        System.out.println("stop");
    }

    public void runMain() {
        // main code
        // ...
        while (true) {
            System.out.println("sleep");
            try {
                Thread.sleep(1000);
            }
            catch (Exception e) {}
        }
    }

Nach dem Starten verwende ich den Linuxbefehl "kill -SIGINT <Prozess-ID>" um die Anwendung wieder zu beenden. Dabei wird vor dem tatsächlichen Beenden noch der Shutdown-Hook ausgeführt. Ich habe ein kleines Video bei Youtube hochgeladen, das das ganze mal demonstriert.

Wie ihr seht, kann man mit einfachen Mitteln Java-Anwendungen sauber und ordentlich beenden. Es ist übrigens auch möglich, mehrere Shutdown-Hooks zu registrieren. Da jedoch deren Ausführungsreihenfolge nicht definiert ist, ist anzuraten, nur einen Shutdown-Hook für die gesamte Anwendung zu verwenden und in diesem zur Not weiteren Cleanup-Code aufzurufen. Da der Shutdown-Hook ein Thread ist, müsst ihr euch zudem um Themen wie Threadsicherheit kümmern.


Simples Failover-Cluster mit Floating IP realisieren

18.09.2015 yahe administration legacy linux security

Immer wieder kommt es vor, dass der Wunsch aufkommt, die Verfügbarkeit eines internen Dienstes zu erhöhen. Mitunter ist das das allererste Mal, dass die Beteiligten sich überhaupt mit dem Thema Clustering auseinandersetzen müssen. Leider herrscht immer noch die Meinung vor, dass Clustering ein komplexes Thema sei, das man am besten weit nach hinten schiebt. Dabei wird es umso einfacher, je früher man sich darum Gedanken macht. Denn dann kann man seine Anwendungen von vorne herein darauf vorbereiten, in einem Cluster lauffähig zu sein.

An dieser Stelle würde ich gern einmal eine simple Lösung zeigen, wie es möglich ist, ohne Einsatz eines Loadbalancers ein einfaches Failover-Cluster mit einer Floating IP (auch als virtuelle IP bezeichnet) zu realisieren.

In einer einfachen Form gibt es zwei Maschinen im Netzwerk, die die gleiche Aufgabe erfüllen und sich eine gemeinsame IP-Adresse teilen. Wenn eine der beiden Maschine startet, prüft sie, ob die gemeinsame IP-Adresse bereits verwendet wird. Ist das nicht der Fall, dann nimmt sie sich die IP-Adresse. Startet nun die zweite Maschine, so bekommt diese mit, dass die IP-Adresse bereits verwendet wird und schaltet sich in einen Wartezustand. In diesem prüft sie regelmäßig, ob die IP-Adresse noch verwendet wird. Sobald das nicht mehr der Fall ist, übernimmt sie die IP-Adresse und nutzt sie selbst.

Dieses Vorgehen kann man noch entsprechend gegen fälschliche IP-Adressübernahmen absichern. Beispielsweise sollte man mehr als nur einmal prüfen, ob die IP-Adresse noch verwendet wird, bevor man sie übernimmt. Ebenso kann man sich Protokolle überlegen, damit mehr als nur zwei Knoten im Failover-Cluster existieren können (z.B. durch die Einführung einer Knotengewichtung oder durch dynamische Reihenfolgen). Durch den Einsatz von STONITH-Mechanismen kann man zudem dafür sorgen, dass Clusterknoten mit einer Fehlfunktion das Cluster nicht stören, indem man sie gewaltsam aus dem Cluster entfernt. Aber für unser simples Beispiel geht es auch erstmal ohne.

Um einen einfachen, für den Client transparenten, Failover hinzukriegen, brauchen wir unter Linux die zwei Tools "ip" und "arping". Das "ip"-Tool ist standardmäßig vorhanden und wird dazu verwendet, die Floating IP an ein Netzwerkinterface zu binden (z.B. "eth0"). Das "arping"-Tool muss man hingegen erst installieren. Dabei ist Vorsicht geboten, denn es gibt zwei verschiedene Implementierungen, wobei uns nur die aus den "iputils" der Linux Foundation interessiert, denn nur diese kennt den Parameter "-U" für "Unsolicited ARP Requests" (auch "Gratuitous ARP Messages" oder "ARP Announcements" genannt). Sinn und Zweck dieser ARP Requests ist es, den angeschlossenen Systemen mitzuteilen, dass IP-Pakete, die an die Floating IP gerichtet werden, nun an ein anderes Gerät zu routen sind.

Die folgenden beiden Befehle sind unter Linux ausreichend, um eine IP-Adresse zu übernehmen (wobei ihr "<IP>" durch die Floating IP und "<Interface>" durch den Namen des Netzwerkinterfaces ersetzen müsst):

sudo /bin/ip addr add <IP>/32 dev <Interface>
sudo /usr/bin/arping -U -c 5 -q -I <Interface> <IP>

Ich habe mir testweise ein PHP-Skript geschrieben, das die oben beschriebene Funktionalität ausführt. Beim ersten Starten prüft es, ob die Floating IP ("192.168.123.10") in Verwendung ist und übernimmt diese. Der zweite Aufruf bekommt mit, dass die Floating IP in Verwendung ist und versetzt sich in den Wartemodus. Wenn die IP-Adresse frei werden sollte, übernimmt das wartende PHP-Skript die IP-Adresse. Ein Screencapture des Tests habe ich bei Youtube hochgeladen. Der permanent laufende Ping rechts oben zeigt, dass trotz des Herunterfahrens des ersten Rechners die IP-Adresse weiterhin verwendbar bleibt. Im CURL-Aufruf rechts unten sieht man, dass die HTTP-Anfragen zwar über dieselbe IP-Adresse gestellt, jedoch von verschiedenen Servern beantwortet werden.

Mit dem gleichen Know-how kann man übrigens auch Angriffe auf Netzwerkdienste fahren, indem man die Pakete, die an den Dienst gerichtet sind, über den eigenen Rechner umleitet.


Accounts auf Windows 7 Loginseite verstecken

15.09.2015 yahe administration legacy security windows

Zur Einschulung meines Neffen habe ich ihm einen aufgearbeiteten Computer geschenkt. Als Sechsjähriger sollte er natürlich nur einen begrenzten Zugriff auf Systemfunktionen (Administration, Softwareinstallation, etc.) haben, was über einen eingeschränkten Account realisiert werden sollte. Gleichzeitig sollte es aber möglich sein, dass er den Rechner einschaltet kann und beim Hochfahren sofort in seinen Account eingeloggt wird. Das wiederum funktioniert nur, wenn es auf der Loginseite nur einen Account gibt, der ohne Passwort angelegt wurde. Also musste eine Lösung her, in einem eingeschränkten Account viel Administration unterbinden zu können und gleichzeitig nur einen Account auf der Windows-Loginseite zu haben.

Mein erster Schritt war, den vorhandenen, aber nicht sichtbaren, Administratoraccount in Windows 7 zu aktivieren. Dazu gebt ihr in das Suchfeld des Startmenüs die Buchstaben "cmd" ein. In der Liste darüber sollte euch die Kommandozeile als Ergebnis angezeigt werden. Macht einen Rechtsklick auf den Eintrag mit der Kommandozeile und führt sie als Administrator aus. In der Kommandozeile gebt ihr dann folgenden Befehl ein:

net user administrator /active:yes

Nun kann man sich als Administrator am System einloggen und ihm zum Beispiel ein Passwort geben. Weiterhin kann man nun den einzuschränkenden Account ordentlich konfigurieren (z.B. die Jugendschutzoptionen aktivieren). Leider hat man nun auf der Windows-Loginseite auch den Administrator-Account, der den automatischen Login verhindert. Um diesen wieder zu verstecken, können wir ein wenig Registry-Magie einsetzen. Wir erstellen uns eine "hide-admin.reg"-Datei mit folgendem Inhalt:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList]
"Administrator"=dword:00000000

Ebenso erstellen wir uns eine "show-admin.reg"-Datei mit diesem Inhalt:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList]
"Administrator"=dword:00000001

Dazu basteln wir uns noch zwei Batch-Dateien. Zuerst die "hide-admin.bat"-Datei:

runas /user:administrator "regedit hide-admin.reg"

Als zweites noch die "show-admin.bat"-Datei:

runas /user:administrator "regedit show-admin.reg"

Wenn wir nun mit dem eingeschränkten Account eingeloggt sind und den Administrator-Account auf der Windows-Loginseite verstecken wollen, rufen wir einfach die "hide-admin.bat"-Datei per Doppelklick auf. In der sich öffnenden Kommandozeile werden wir nach dem Passwort des Administrator-Accounts gefragt, das wir noch mit Enter bestätigen. Anschließend ist der Administrator-Account auf der Windows-Loginseite versteckt und beim Hochfahren loggt sich das System automatisch in den eingeschränkten Account ein.

Sollten wir nun administrative Aufgaben wahrnehmen müssen, rufen wir einfach im eingeschränkten Account die "show-admin.bat"-Datei auf, geben das Administrator-Passwort ein und bestätigen mit Enter. Anschließend können wir den Benutzer wechseln, die administrativen Aufgaben erledigen (z.B. Updates installieren, Software installieren, Konfigurationsänderungen vornehmen, etc.), danach wieder in den eingeschränkten Account wechseln und den Administrator-Account wieder verstecken.


Interview bei Spreadaudio

07.09.2015 yahe legacy publicity security

Ich wollte kurz darauf hinweisen, dass ich mit @AaronTeleK von Spreadaudio ein Interview geführt habe, das nun veröffentlicht wurde. In dem Gespräch zum Thema IT-Sicherheit geht es einmal querbeet von sicheren Passwörtern, über Virenscanner und Firewalls bis hin zur Ende-zu-Ende-Verschlüsselung. Wer mal reinhören will, findet auf der Webseite von Spreadaudio eine Aufzeichnung des gesamten Interviews.


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)