Code: Alles auswählen
;"Helle" K.Helbing 21.3.2019
;binäre Passwortsuche in Datei "pwned-passwords-sha1-ordered-by-hash-v4.txt"
;von "https://haveibeenpwned.com/Passwords" die Passwort-Datei "pwned-passwords-sha1-ordered-by-hash-v4.7z" runterladen und entpacken
;s.a. c´t 5/2019
;getestet mit Windows7/64, PB 5.70 LTS (x64)
;wer Langeweile hat oder besonders ordentlich ist kann auch die Variablen sauber verwalten. Dieser Test läuft auch so... :-)
FileSeekKonst.q = 64 ;Konstanter Offset für FileSeek
Offset_DP_HA.q = 40 ;Abstand Doppelpunkt - Anfang HashWert
If OpenWindow(0, 0, 0, 600, 600, "Passwort-Überprüfung", #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
TextGadget(1, 10, 10, 230, 15, "Select das Passwort-Text-File:")
ExplorerTreeGadget(2, 10, 30, 580, 565, "*.TXT", #PB_Explorer_NoDriveRequester)
SetActiveGadget(2)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
End
EndIf
Until EventType() = #PB_EventType_LeftDoubleClick And GetGadgetState(2) = #PB_Explorer_File
File$ = GetGadgetText(2)
FreeGadget(1) : FreeGadget(2)
If ReadFile(0, File$, #PB_Ascii)
LenFileOri.q = Lof(0)
Buffer.q = AllocateMemory(128, #PB_Memory_NoClear)
Repeat ;für noch ein Passwort
Adresse.q = 0
Passwort$ = InputRequester("Passwort-Eingabe", "Bitte hier das zu suchende Passwort eingeben:", "", #PB_InputRequester_Password)
TA = ElapsedMilliseconds()
UseSHA1Fingerprint()
SHA1_Uni$ = UCase(StringFingerprint(Passwort$, #PB_Cipher_SHA1, -1, #PB_UTF8)) ;in der TXT-Datei werden Großbuchstaben verwendet. Die Passwörter in der Datei wurden als UTF8 gehasht!
SHA1$ = Space(40)
PokeS(@SHA1$, PeekS(@SHA1_Uni$), -1, #PB_Ascii)
;Startwerte
SuchQuad1.q = PeekQ(@SHA1$) ;die 40 Byte von SHA1$ in 5 Integer-Quads kopieren. Zuerst wird nach SuchQuad1 gesucht
!mov rax,[v_SuchQuad1] ;ist hier mit ASM einfacher
!bswap rax ;notwendig wegen Größen-Vergleich!
!mov [v_SuchQuad1],rax
;für neuere CPUs eine Instruktion weniger:
;!mov rax,[v_SuchQuad1]
;!movbe [v_SuchQuad1],rax
SuchQuad2.q = PeekQ(@SHA1$ + 8)
SuchQuad3.q = PeekQ(@SHA1$ + 16)
SuchQuad4.q = PeekQ(@SHA1$ + 24)
SuchQuad5.q = PeekQ(@SHA1$ + 32)
LenFileOld = LenFileOri
LenFile = LenFileOld
LenFile >> 1 ;1.Halbierung für binäre Suche
FilePos.q = LenFile
LenFileOld >> 1
While LenFile > Offset_DP_HA
FileSeek(0, FilePos - FileSeekKonst)
Gelesen.q = ReadData(0, Buffer, 128)
For j = 0 To Gelesen - 1
If PeekB(Buffer + j) = $3A ;Suche nach Doppelpunkt ":"
If j > Offset_DP_HA
Break
EndIf
EndIf
Next
FindQuad1.q = PeekQ(Buffer + j - Offset_DP_HA)
!mov rax,[v_FindQuad1]
!bswap rax ;notwendig wegen Größen-Vergleich!
!mov [v_FindQuad1],rax
If FindQuad1 = SuchQuad1
FindQuad2.q = PeekQ(Buffer + j - Offset_DP_HA + 8)
FindQuad3.q = PeekQ(Buffer + j - Offset_DP_HA + 16)
FindQuad4.q = PeekQ(Buffer + j - Offset_DP_HA + 24)
FindQuad5.q = PeekQ(Buffer + j - Offset_DP_HA + 32)
If FindQuad2 = SuchQuad2 And FindQuad3 = SuchQuad3 And FindQuad4 = SuchQuad4 And FindQuad5 = SuchQuad5
TE = ElapsedMilliseconds() - TA
Adresse = FilePos + j - FileSeekKonst - Offset_DP_HA
Adresse$ = "Das eingegebene Passwort wurde gefunden an Adresse " + Str(Adresse) + #LFCR$ + "($" + Hex(Adresse) + ")"
j + 1
Wieoft$ = ""
While PeekB(Buffer + j) <> $0D
Wieoft$ + Chr(PeekB(Buffer + j))
j + 1
Wend
Anzahl$ = "Lt. Liste wurde dieses Passwort " + Wieoft$ + "mal verwendet."
Warntext$ = "Ergebnis ist aber eigentlich negativ! Passwort sollte nicht verwendet werden!"
Abfrage = MessageRequester("Ergebnis positiv!", Adresse$ + " in " + Str(TE) + " ms!" + #LFCR$ + Anzahl$ + #LFCR$ + Warntext$ + #LFCR$ + #LFCR$ + "Nochmal?", #PB_MessageRequester_YesNo)
If Abfrage = #PB_MessageRequester_No
Break 2
EndIf
Break
EndIf
EndIf
LenFile >> 1 ;nächste Halbierung
If FindQuad1 > SuchQuad1 ;1.Hälfte nur Quad1 zu testen sollte ausreichen
FilePos = LenFileOld - LenFile
Else ;2.Hälfte
FilePos = LenFileOld + LenFile
EndIf
LenFileOld = FilePos
Wend
If Adresse = 0
Abfrage = MessageRequester("Ergebnis negativ!", "Passwort nicht gefunden!" + #LFCR$ + "Ist aber eigentlich positiv!" + #LFCR$ + #LFCR$ + "Nochmal?", #PB_MessageRequester_YesNo)
If Abfrage = #PB_MessageRequester_No
Break
EndIf
EndIf
ForEver ;noch ein Passwort
CloseFile(0)
FreeMemory(Buffer)
Else
MessageRequester("Fehler!", "Kann Passwort-Datei nicht einlesen!")
EndIf
EndIf
Schon lustig, was alles so gefunden werden kann. Sogar "purebasic" ist 15x vertreten . Gut vertreten ist z.B. auch "a....loch" (22278mal!!!); das kenne ich noch von Arbeit...
Viel Spaß!
Helle
Edit 21.03.2019: Adresse-Berechnung wieder an richtige Stelle gesetzt