Eigenes Passwort in Python "hacken"?

3 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

Hi,

um dir vielleicht noch einen interessanten Denkansatz zu geben, der hier noch nicht erwähnt wurde - und etwas, dass du beim schreiben von Code durchaus im Kopf haben solltest: Das ist ein klassisches Szenario für eine 'Timing Attack'.

Wenn in Python (und den meisten anderen Sprachen) zwei strings verglichen werden, dann werden in wirklichkeit alle chars des strings nacheinander verglichen. Es wird genau genommen erst geguckt ob die strings gleich lang sind, wenn ja wird über jedes Zeichen des ersten strings iteriert und mit dem Zeichen, an gleicher stelle, des zweiten Strings verglichen. Sobald ein Zeichen abweicht wird der Vergleich beendet und als 'false' evaluiert.

userpw == passwort

ist in echt ziemlich genau das gleiche wie:

def str_equals(userpw, passwort):
    if len(userpw) != len(passwort):
        return False

    for c1, c2 in zip(userpw, passwort):
        if c1 != c2:
            return False

    return True

Gut, aber wie kann man das exploiten?
Ganz einfach: Je mehr Zeichen verglichen werden, desto länger dauert der Vergleich.

Wenn du (in deinem Fall wo das korrekte Passwort "geheim" ist) "aasd" eingegeben hättest, würde er sofort abbrechen, da die beiden strings noch nicht mal gleich lang sind. Hättest du "asddsa" eingegeben würde es schon ein bisschen länger dauern, da er zumindest das erste Zeichen vergleicht. "gehopp" würde noch länger dauern, da er erst beim vierten Zeichen abbricht.

Du kannst bruteforcen - aber anstatt blind zu raten, kannst du gucken wie lange das Programm braucht, um festzustellen, dass dein eingegebenes Passwort falsch war. Zu erst änderst du die Länge des geratenen Passworts, bis das Programm ein bisschen länger braucht um festzustellen, dass das Passwort falsch ist. Das verrät dir, dass die Länge nun stimmen muss. Dann änderst du so lange das erste Zeichen bis die Zeit noch ein bisschen länger wird, wenn das passiert weißt du, dass der erste Buchstabe richtig ist. Und so weiter.

Um zu verdeutlichen was das bedeutet: Dein Passwort "geheim" besteht aus 6 Zeichen. Würden wir ganz naiv jede mögliche Kombination ausprobieren, und es wären nur Buchstaben und Zahlen möglich, dann gäbe es 36 mögliche Zeichen. Das bedeutet 6³⁶ verschiedene Möglichkeiten (= 10314424798490535546171949056 verschiedene Passwörter). Dadurch, dass wir allerdings an jeder Stelle feststellen können ob das Zeichen richtig ist, sind es auf einmal keine 6³⁶ Möglichkeiten mehr, sondern lediglich 6*36 (= 216). Bedeutet, wir müssen im schlechtesten Fall 216 mal raten - statt 10314424798490535546171949056 mal.

Und genau das ist der Grund, warum es sichere Funktionen für stringvergleiche gibt, etwa https://docs.python.org/3/library/hmac.html#hmac.compare_digest

Viele Grüße

Gute Antwort. Allerdings sind es 36 hoch 6 = 2.176.728.336 Möglichkeiten für ein PW aus 6 Zeichen mit Kleinbuchstaben und Ziffern.

1

Natürlich geht das.

Wenn du weißt, dass das Passwort zufallsgeneriert ist, dann solltest du Bruteforce anwenden. Python ist aber eher langsam, weswegen ein dafür gedachtes Programm besser wäre.

Wenn das Passwort, wie bei dir, nicht zufallsgeneriert ist, dann lade dir ein Dictionary herunter (es gibt sehr viele im Internet). Dann öffne die Datei mit Python und iteriere durch alle Wörter in der Datei. Bei deinem Programm wird immer nach einem Input gefragt, der eingegeben werden muss, dadurch dauert das noch länger. Normarlerweise hat man den Hash-Wert eines Passworts, den du knacken willst. Statt deiner Schleife, die immer nach einem Input fragt, solltest du lieber sowas machen:

for password in alledeinepasswörterausdemdictionary:

if hashlib.sha512(password).hexdigest()==dein_hash_wert: print(password); break

hashlib.sha512 musst du dann durch die Hash-Funktion ersetzen, die benutzt wurde.

Python ist zwar eine gute Sprache für's Hacken, aber (im Vergleich zu anderen Programmen und Sprachen) eher langsam. Deswegen solltest du für das Knacken von Passwörtern ein dafür gedachtes Programm benutzen.

Viel Glück!

Hört sich kompliziert an und um das zu verstehen muss ich wohl noch ein bisschen üben. Ich wollte einfach mal sehen wie sowas funktioniert, aber damit warte ich dann halt noch ein bisschen xD. Danke trotzdem.

0

Aus meinen Buch "Hacken mit Python und Kali-Linux":

import sys, hashlib, time

ts = time.time()
if len(sys.argv) != 3:
    print("USAGE:")
    print("./" + sys.argv[0] + " [HASHFILE] [WORDLIST] \n")
    sys.exit()

hashes = []
with open(sys.argv[1], "r") as hashfile:
    for line in hashfile:
        hashes.append(line.strip())

print("Start cracking ...")
with open(sys.argv[2], "r") as wordlist:
    for line in wordlist:
        line = line.strip('\n')
        md5_hash = hashlib.md5(line.encode()).hexdigest()
        
        if md5_hash in hashes:
            print(md5_hash + " == " + line)

td = time.time() - ts
print("Done in " + str(td) + " sec.")

Je nach dem wie die Passwort-Hashes abgespeichert wurden (md5, SHA256, ...) muss die Zeile md5_hash = hashlib.md5(line.encode()).hexdigest() angepasst werden. Im Internet ist MD5 noch sehr weit verbreitet...

Woher ich das weiß:Beruf – Softwareentwickler seit 2001 (Web, Win. und Linux)

Was möchtest Du wissen?