- das Passwort ist 18 Bytes lang
- es wird bei Nachrichten > 18 Bytes immer wiederholt angewendet
- die letzten 3 Bytes eines Ciphertext (verschl. Text) ist die Länge der Nachricht -> 2 Bytes als
ASCII + einem Abschlußbyte das nicht in
ASCII gespeichert wird. Eine Länge von 100 ist also so codiert '00'+$03, eine Länge von 16 dann so '16'+$02. Dh. der Algo analysiert das letzte Byte, ist es $01 dann gelten nur das vorletzte
ASCII Byte als Länge. Ist es $02 dann gelten die 2 vorherigen
ASCII Zeichen als Länge, ist es $03 dann wird 100 + die vorletzten
ASCII zeichen als Länge interpretiert, bei $04 müsste es also 200 +
ASCII Zeichen die Länge sein.
Das ist eindeutig ein Zeichen das in führeren Versionen der Software die Länge der Texte begrenzt war. Später würde das erweitert. Um kompatibel zu bleiben wurde diese verrückte Codierung benutzt.
- die ersten 2 Bytes des "Passwortes" (wenn man von Passwort überhaupt reden kann) unterscheiden sich zu den anderen 16 Bytes des Passwortes
- die restlichen 16 Bytes des Passwortes scheinen einfache Operationen mit dem Passwort zu sein
- eine Nachricht die kürzer als 18 Bytes ist wird expandiert. Dazu wird die Nachricht einfach solang an sich selber rangehangen bis sie größer 18 Zeichen ist und dann auf 18 Zeichen gekürzt
Alles in allem eindeutig ein Algo. der "Security trough Obscurity" benutzt statt mathem. sicher zu sein.
So im Grunde fertig, diese Infos reichen um den Algo + Passwort nachzubauen. Jetzt muß man nur noch eine Lookup Tabelle bauen in der alle 256 zeichen zu den 18 möglichen Positionen des Passwortes gespeichert sind. Also ein Array[0..17, Byte] of byte. Nun lässt man im Program alle 256 Zeichen verschlüsseln, also 256 mal die String "0000000000000" alle 18 Zeichen lang bis zum String "ZZZZZZZZZZZZZ". Aus der Datei werden diese Daten geladen und daraus baut man diese Lookup Tabelle. Fertig.
Gruß Hagen
[edit]
- Passwort ist -> !27Mdngi[yunbdtg*5
- man findest diesen String merhfach in der EXE.
- die Verschl. ist einfach XOR mit dem Passwort
Delphi-Quellcode:
function Decrypt(const Data: String): String;
const
Password: String = '!27Mdngi[yunbdtg*5';
var
Len,I,J: Integer;
begin
Result := TFormat_MIME64.Decode(Data);
Len := Length(Result);
Len := StrToInt(Result[Len -2] + Result[Len -1]) + (Ord(Result[Len]) - $02) * 100;
SetLength(Result, Len);
J := 1;
for I := 1 to Len do
begin
Result[I] := Char(Ord(Result[I]) xor Ord(Password[J]));
Inc(J);
if J > 18 then J := 1;
end;
end;
- Aus Decrypt('ZldVKAo9Dgx7ERwLEAARCX5QWUZSJAoKAgcIEBAPD AUYHllcREBSIxMBCwU+FzQ2Ag=='); wird -> GebenSie hierdenTexteindenSieanalysierenwollen
du hast uns also ein Leerzeichem im Text unterschlagen, du Sack
Fazit: ohne die Software zu debuggen, rein aus der Analyse der Daten die die Software speichert, haben wir das Teil in 40 Minuten Zeitaufand geknackt. Schade war zu einfach.
FazitFazit:
Der benutzte Angriff der Kryptoanalyse nennt sich "Choosen Plain Text Attack". Man kann also frei den Plaintext -> zu verschl. Nachricht, wählen und den CipherText -> verschl. Nachricht analysieren. Das wurde möglich weil
1.) eine simple XOR Verschl. benutzt wurde
2.) das Passwort immer wiederholt ohne Änderungen und direkt mit der Nachricht benutzt wurde, es gibt also eine direkte Abhängigkeit des Paswortes zur Verschlüsselung
3.) aus dem Passwort vor der Verschl. kein mit Zufall umgerchneter Sessionkey benutzt wurde
4.) die Nachricht vor der Verschl. nicht mit par Zufallbytes am Anfang expandiert wurde
Punkt 3.) und 4.) stellten sicher das wir aus den Mustern des CipherText die Lönge das Passwortes, den Aufbau des Cipher -> Block/Stromverschl. und die 3 Endebytes, erkennen konnten. Hätte man Punkt 3.) und 4.) benutzt mit einem guten Blockcipher hätten wir keinerlei Chancen gehabt.
[/edit]