Spielchen mit RSA-Schlüsseln

Als Einstiegshürde für ein CTF (Capture the Flag) dient gerne mal ein RSA Schlüsselpaar, von dem nur der öffentliche Teil bekannt ist. Also kein unrealistischer Ansatz, lediglich die Schlüssellängen sollten entsprechend klein sein.

Vorbereiten der Challenge

Diese Schritte werden vom Spielleitder durchgeführt. Wichtig ist eine geeignete, nicht zu lange Schlüssellänge zu wählen. Hier wählen wir 256 Bit als Schlüssellänge. Das sollte die Teilnehmer vor keine Probleme stellen.

Generieren des Schlüsselpaars

Der wesentliche Schritt bei der Erzeugung eines RSA-Schlüsselpaars ist die Wahl von 2 Primzahlen p und q, deren Produkt n (der RSA-Modulus) die gewünschte Schlüssellänge besitzt.

Dank OpenSSL ist es einfach ein RSA-Schlüsselpaar zu erzeugen:

openssl genrsa -des3 -out private.pem 256
openssl rsa -in private.pem -outform PEM -pubout -out public.pem

Daraus ergibt sich als Public Key beispielsweise:

-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhALRUOO0rvPEA282wqL4VF5GibnA1kcux
LHdIOcT807+DAgMBAAE=
-----END PUBLIC KEY-----

Den privaten Schlüssel private.pem können wir nun löschen, da wir diesen zum Einen nicht mehr benötigen und zum Anderen ja rekonstruieren wollen.

Verschlüsseln der Probedatei

Eine Probedatei lesbar.txt wird mit dem öffentlichen Schlüssel mit OpenSSL verschlüsselt:

openssl rsautl -encrypt -inkey public.pem -pubin -in lesbar.txt -out geheim.txt

Das Ergebnis der Verschlüsselung ist eine Datei, die nur unlesbare binäre Daten enthält. Sie kann hier heruntergeladen werden: geheim.txt. Diese Datei und der öffentliche Schlüssel gehen an die Teilnehmer.

Lösen der Challenge

Diese Schritte werden durch die Teilnehmer durchgeführt.

Knacken der Schlüssel

Zunächst müssen wir aus dem öffentlichen Schlüssel die beiden Parameter  n (Modulus) und e (Exponent) extrahieren:

from Crypto.PublicKey import RSA

public_key = RSA.importKey(open('public.pem', 'r').read())
print 'n =', public_key.n
print 'e =', public_key.e

Dazu verwenden wir die Bibliothek pycrypto (Debian: python-crypto). Ausgegeben werden die beiden oben genannten Werte, in unserem Beispiel also:

n = 815651207903382691105573612057017618852
    64115611526254943458542612275141001091
e = 65537

Nun muss der Modulus faktorisiert werden (n ist das Produkt der beiden Primzahlen p und q). Dazu kann das msieve von Jason Papadopoulos verwendet werden.

Für unsere Zahl n liefert msieve auf einem Core2Duo T7400 nach knapp 10 Minuten die beiden Primfaktoren:

p = 264446414907090989475638551039611206507
q = 308437234133027923039636551098640509513

Alternativ können wir auch factordb.com verwenden, wenn die Zahl dort bereits faktorisiert vorliegt.

Nun müssen wir aus p und q den privaten Exponenten d berechnen:

d = 1/e mod (p-1)*(q-1)

oder mit Python und dem Modul gmpy2:

import gmpy2

p = 264446414907090989475638551039611206507
q = 308437234133027923039636551098640509513
e = 65537
d = gmpy2.invert(e,(p-1)*(q-1))

Aus den Werten n,e und d wird nun der private Schlüssel erstellt und ausgegeben:

from Crypto.PublicKey import RSA
key = RSA.construct((n,e,d))
print key.exportKey()

In unserem Beispiel ergibt das:

-----BEGIN RSA PRIVATE KEY-----
MIGrAgEAAiEAtFQ47Su88QDbzbCovhUXkaJucDWRy7Esd0g5xPzTv4MCAwEAAQIh
ALFDhX4nG6FxbaChww6vnyzjasWei1L/rUg3aG/c6MaxAhEA6ArZu41/pzoKRlXH
MfYqSQIRAMbyhuPv26I/S0+zokene2sCEDxkfpDK3huHBp+RubtuJ0kCECAEWecG
6+7Rhto9y4kCkB8CEQCSSbMXMjOybMpz3gCOQYeS
-----END RSA PRIVATE KEY-----

Wir speichern den privaten Schlüssel wieder in der Datei private.pem ab.

Entschlüsseln der Probedatei

Wurde alles richtig durchgeführt, so kann man mit folgender OpenSSL Anweisung die Probedatei entschlüsseln:

openssl rsautl -decrypt -inkey private.pem -in geheim.txt -out lesbar.txt

Der genaue Inhalt von lesbar.txt wird hier jedoch nicht verraten.

Abschluss

Man erkennt hier am Zeitaufwand zur Faktorisierung eines 256 Bit Schlüssels bereits, dass die Sicherheit von RSA auf genau dieser Schwierigkeit basiert. In der Praxis verwendet man daher Schlüssellängen von mindestens 2000 Bit (siehe dazu die Technische Richtilinie des BSI: Kryptographische Verfahren: Empfehlungen und Schlüssellängen (Seite 39, Kapitel 3.5 – RSA).

Mounten von Partitionen aus Image-Dateien

Ist das Backup einer SD-Karte nur als Image-Datei vorhanden und keine Zeit erst wieder auf SD-Karte zu schreiben? Dateimanager kann Image-Dateien nicht direkt einbinden? Hier die Lösung:

  1. Auslesen der Partitionen und ihrer Startsektoren:
    fdisk -l ${QUELLDATEI}

    (Hier in der Spalte Start nach dem Anfang der Partition suchen, unter Units steht die Größe der Sektoren)

  2. Einbinden der gewählten Partition:
    mount ${QUELLDATEI} /mnt -o offset=$((${ANFANGSSEKTOR}*${SEKTORGRÖßE}
  3. Und fertig!

 

Probleme mit Windows Update KB3033929 (SHA2 Einführung)

Auch bei meinem Desktop hat KB3033929 zu Problemen geführt. Windows 7 befindet sich auf der ersten Festplatte, Linux auf der zweiten. Natürlich wird Grub zum Booten verwendet. Leider befand sich kein Windows Boot Loader mehr auf keiner der beiden Platten.

Woher bekommt man jetzt wieder ein direkt bootfähiges Windows 7?

  1. Die meisten Webseiten empfehlen die Windows 7 Installations Medien zu verwenden um das System zu reparieren. Gut, müsste man suchen und die richtigen Medien erwischen. Meine war „inkompatibel“.
  2. Diverse Linux-Tools wie install-mbr führten auch nicht zum Erfolg.
  3. Zum Glück konnte ich das Windows noch starten und das Programm EasyBCD installieren. Wie auf der Hersteller Web-Seite beschrieben, kann das Tool einen Windows 7 MBR schreiben.

Nach dem Anwenden von EasyBCD kann das Windows wieder nativ von der ersten Festplatte gestartet werden und ebenso von der zweiten Festplatte via Grub.

Problem gelöst!

UUID für Device direkt abfragen

UUIDs werden unter Linux verwendet um Partition eindeutig zu identifizieren. Klassischerweise dient das Kommando blkid zum Abfragen der entsprechenden Information:

/dev/sda1: UUID="612adf0a-1780-ad4c-3fb6-082ee5593158" TYPE="linux_raid_member" 
/dev/sda2: UUID="950bb587-ea1d-4dbf-bd6f-7c9d1c234175" TYPE="swap"              
/dev/sda3: UUID="313669c6-3d82-132e-3fb6-082ee5593158" TYPE="linux_raid_member" 
/dev/sdb1: UUID="612adf0a-1780-ad4c-3fb6-082ee5593158" TYPE="linux_raid_member" 
/dev/sdb2: UUID="bd6fa3c7-37cc-455e-acea-0aaa1fb44290" TYPE="swap"              
/dev/sdb3: UUID="313669c6-3d82-132e-3fb6-082ee5593158" TYPE="linux_raid_member"

Will man nun zu einem Device nun nur die UUID abfragen, so hilft folgendes Kommando:

blkid -o value -s UUID /dev/sdb1

Dabei wird lediglich die UUID ausgegeben:

612adf0a-1780-ad4c-3fb6-082ee5593158

Somit kann man in Skripten problemlos mit UUIDs arbeiten.

nmon: Einschränken auf ausgewählte Festplatten bzw. Partitionen

nmon is bei der Anzeige von Festplattendaten nicht wählerisch und zeigt (zumindest unter Linux, AIX war grade nicht zur Hand ;) ) jeweils Daten zur Gesamtplatte (z.B.  /dev/sda) als auch zu einzelnen Partitionen (z.B. /dev/sda1 und /dev/sda3) an. Soweit ist das kein Problem, nur summiert nmon die einzelnen Werte auf, was zu unsinnig hohen Werten führt, wenn in der Summe sowohl die Festplatte als auch einzelne Partitionen summiert werden.

Nun gilt es also nmon auf ausgewählte Festplatten oder einzelne Partitionen zu beschränken. Das Handbuch (nmon -h) ergibt:

-g <filename> User Defined Disk Groups [hit g to show them]
 - file = on each line: group_name <disks list> space separated
 - like: database sdb sdc sdd sde
 - upto 64 disk groups, 512 disks per line
 - disks can appear more than once and in many groups

Also sieht eine entsprechende Datei für meinen Fall (3 Festplatten, jeweils eine relevante Partition) so aus:

Data1 sda3
Data2 sdb1
Data3 sdc1

Wie in der Hilfe beschrieben, wird nmon nun mit der Datei als Parameter gestartet:

nmon -g disks.dat

Anschließend zeigt nmon nach Druck auf ‚g‚ die entsprechenden Statistiken an.

SuperGRUB2Disk: Booten eines USB-Stick über CD-Rom

Folgendes Szenario/Problem stellte sich:

  • Laptop bzw. Rechner
  • das BIOS erkennt (theoretisch) USB Festplatten/Sticks
  • das Booten von USB wurde per BIOS gesperrt
  • das Booten von CD-Rom ist noch erlaubt

Man kann sich nun zu recht fragen, warum ist booten von CD-Rom noch erlaubt? Das bleibt ein Geheimnis des Besitzers des Rechners.

Die Frage ist nun, kann man diese Einschränkung umgehen? Wenn ja, wie?

Die Antwort lautet: Es kann gehen. USB Festplatten/Sticks dürfen nicht ganz deaktiviert sein, sie müssen zumindest erkannt werden (d.h. sie tauchen nicht im Boot-Menu des Rechners auf). Mit Hilfe der SuperGRUB2Disk und deren Funktion „Detect any OS“ kann man das Betriebsystem (bevorzugt Linux) auf der USB Festplatte erkennen lassen und dieses Starten.

Voilà, booten von USB mit einem kleinen Umweg. Sicher nicht im Sinne des Besitzers, aber manchmal hilfreich für Notfälle wie Datenrettungen, etc.

MacFusion unter OS X 10.8 benutzen

MacFusion ist ein UI-Frontend zum Einbinden von entfernten Server ins lokale Dateisystem des Macs. Dabei kann man auf die Verzeichnisse und Dateien völlig analog zugreifen. Der manuelle Schritt zum Up- oder Download entfällt somit.

Leider verweist die Startseite von MacFusion noch auf das MacFUSE-Projekt bei Google, welches leider nicht mehr aktiv entwickelt wird. Unter OS X 10.8 bekommt man damit wohl auch Probleme mit der 64-bit Tauglichkeit.

Zum Glück gibt es FUSE for OS X. Es handelt sich dabei um den Nachfolger von MacFUSE und bietet eine Kompatibilitätsschicht zu MacFUSE an.

Anschließend kann man mit MacFusion graphisch seine entfernten Server per SSHFS bequem ins lokale Dateisystem einbinden.

 

 

Verwendung eines speziellen SSH-Keys für rsync

Will man bei rsync einen speziellen SSH-Key verwenden um sich zu einem Server zu verbinden, so kann man das mit der rsync-Option -e verwenden:

rsync -e "ssh -i PRIVATE-KEYFILE" SOURCE TARGET

Und schon wird dieser ausgewählte Schlüssel für diese SSH-Verbindung verwendet und nicht der eventuell vorhandene Standardschlüssel.