So nach kurzer Recherche weiß ich nun worum es geht. Mit nachfolgendem Code kann man RapidShare Containter Dateien mit Endung .RSDF entschlüsseln. So wie ich das interpretiere benutzt Rapidshare dabei zwar eine starke AES Verschlüsselung aber im Grunde vollkommen falsch. Ein Beispiel wie man es nicht machen sollte.
1.) das Passwort scheint hardcoded zu sein, kein Wunder das Cracker dieses schnell gefunden haben.
2.) das Passwort wird nicht mit einem Zufallssalt und einer KDF (Schlüsselableitungsfunktion) in einen pseudozufälligen Sessionkey umgewandelt, naja ist bei einem hardcoded Passwort auch sinnfällig.
Punkte 1. und 2. und die Tatsache das jeder Rapidshare Link immer mit 'CCIF: http://rapidshare....'' anfdangen haben die Konsequenz, das im verschlüsseltenm Resultat immer die gleichen Bytefolgen zu sehen sind. Man kann also als Angreifer, mit dem Wissen das die Dateien immer gleich anfangen, sehr schnell erkennen das ein hardcoded Passwort ohne Preprocessing des Passwortes benutzt wurde. Dazu muß man nur ein par dieser RSDF Dateien analysieren.
3.) das eigentliche Datenformat ist kompliziert und ineffizient. Man hat binäre Daten die man zeilenweise verschlüsselt und in MIME64 umwandelt obwohl sie am Stück mit einem Cipher Objekt verschlüsselt werden. Man kann also nicht beliebig eine dieser Zeile entschlüsseln ohne alle vorherigen Zeilen zu entschlüsseln. Ergo macht es auch keinen Sinn die einzelnen Zeilen separat und denoch abhängig voneinander zu verschlüsseln und in MIME64 umzuwandeln. Man hätte auch gleich die Daten in einem Rutsch verschlüsseln können. Dies wäre weit effizienter (schätze mal das dahinter ein PHP Script bei RapidShare steckt
) Die zusätzliche Umwandlung dieser Daten in das HEX Format ergibt technologisch betrachtet keinen Nutzen. Das INet kann ohne Probleme MIME64 formatierte Daten übertragen. Problematisch könnten nur die Zeilenumbrüche innerhalb dieses MIME64 String sein, wahrscheinlich auch der Grund für die Konvertierung in das HEX Format. Nur ist es eben so das diese zusätzlichen Zeilenumbrüche erst dadurch entstanden sind weil man sinnloser weise die einzelnen Dateinamen eben zeilenweise verschlüsselt und in MIME64 umgewandelt hat. Dieses ineffektive Datenformat ist also entstanden weil der Programmierer schon am Anfang einen konzeptionellen Fehler gemacht hat.
An Hand dieses Datenformates kann ein Angreifer gut erkennen das in einer RSDF Datei X Links gespeichert wurden, denn es gibt X Zeilen getrennt durch Zeilenumbrüche. Nun muß man nur noch ein RSDF File anlegen in dem mehrmals ein Link auf exakt die gleiche Datei gespeichert wurde. Analysiert man dieses verschlüsselte RSDF File so gäbe es zwei Möglichkeiten. Jede der Zeilen im File besteht aus exakt dem gleichen MIME64 String oder die Strings unterscheiden sich zeilenweise. Träfe erster Fall zu so würden wir wissen das jede Zeile mit neuem Passwort und Cipher Objekt verschlüsselt wurde, also so wie es der OP gemacht hat. Träfe der zweite Fall zu dann wissen wir das zeileweise verschlüsselt wurde aber mit nur einem einmalig initialiserten Cipher Objekt, so wie es auch der Fall ist. Also allein an Hand einer beeinflussbaren RapidShare Container Datei können wir enorm viele Informationen erlangen wie was verschlüsselt wurde. Der nächste und finale Schritt ist es den verwendeten Cipher samt Mode usw. und das hardcoded Passwort per Reverse Engineering der Download Software zu knacken, wir wissen ja nun wonach wir suchen müssen.
Das verwendete Dateiformat lässt also viel zu viele Informationen nach aussen dringen die es einem Angreifer leicht machen es zu knacken. Das Dateiformat ist also eine kryptographische Unsicherheit.
Delphi-Quellcode:
procedure RSDFLoadFiles(AItems: TStrings; const AFileName: String);
const
Password = #$8C#$35#$19#$2D#$96#$4D#$C3#$18#$2C#$6F#$84#$F3#$25#$22#$39#$EB#$4A#$32#$0D#$25#$00#$00#$00#$00;
function DoCleanup(const Value: String): String;
begin
Result := System.Copy(Value, Pos('HTTP', AnsiUpperCase(Value)), MaxInt);
end;
var
I: Integer;
begin
AItems.BeginUpdate;
try
AItems.LoadFromFile(AFileName);
AItems.Text := TFormat_HEX.Decode(AItems.Text);
with TCipher_Rijndael.Create do
try
Mode := cmCFB8;
Init(Password);
for I := 0 to AItems.Count -1 do
AItems[I] := DoCleanup(DecodeBinary(AItems[I], TFormat_MIME64));
finally
Free;
end;
finally
AItems.EndUpdate;
end;
end;
Damit das funktioniert müsst ihr in DECFmt.pas folgendes ändern:
Delphi-Quellcode:
class function TFormat_HEX.DoDecode(
const Value; Size: Integer): Binary;
var
S: PChar;
D: PByte;
T: PChar;
I,P: Integer;
HasIdent: Boolean;
begin
Result := '
';
if Size <= 0
then Exit;
SetLength(Result, Size
div 2 +1);
T := CharTable;
D := PByte(Result);
S := PChar(@Value);
I := 0;
HasIdent := False;
while Size > 0
do
begin
P := TableFind(S^, T, 18);
if P < 0
then P := TableFind(UpCase(S^), T, MaxInt);
if P < 0
then
raise EDECException.CreateFmt(sInvalidStringFormat, [DECClassname(Self)]);
Inc(S);
if P >= 0
then
if P > 16
then
begin
if not HasIdent
and (P < 18)
then
begin
HasIdent := True;
I := 0;
D := PByte(Result);
end;
end else
begin
if Odd(I)
then
begin
D^ := D^
or P;
Inc(D);
end else D^ := P
shl 4;
Inc(I);
end;
Dec(Size);
end;
SetLength(Result, PChar(D) - PChar(Result));
end;
Der HEX String in einer RSDF Datei enthält am Ende ein '/n' bzw. eben ein #13#10 -> Carrige Return + Linefeed. Meine originale HEX Konvertierungsfunktion hat diese Steuerzeichen nicht rausgefiltert. Logisch betrachtet ein Fehler im
DEC.
Gruß Hagen