Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi SSL Key Log mit Indy erstellen (https://www.delphipraxis.net/198231-ssl-key-log-mit-indy-erstellen.html)

Codehunter 16. Okt 2018 11:22

SSL Key Log mit Indy erstellen
 
Hallo!

Diverse Webbrowser können ja ein SSL-Keylogfile schreiben. Aktiviert wird das über die Systemvariable %SSLKEYLOGFILE%=PfadZurDatei. Die Datei sieht so aus:
Code:
CLIENT_RANDOM 0123456789012345678901234567890123456789012345678901234567890123 012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901
CLIENT_RANDOM 0123456789012345678901234567890123456789012345678901234567890123 012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901
CLIENT_RANDOM 0123456789012345678901234567890123456789012345678901234567890123 012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901
CLIENT_RANDOM 0123456789012345678901234567890123456789012345678901234567890123 012345678901234567890123456789012345678901234567890123456789012301234567890123456789012345678901
Zwecks Debugging würde ich mir gerne mit Wireshark die Kommunikation anschauen, die ich mit meinem Indy-HTTP-Client durchführe. Wireshark greift auf diese Datei zurück, um verschlüsselte Pakete zu dekodieren.

Ich vermute (!!!) man muss da mit einem SSL-Interceptor arbeiten, wenn man an diese Informationen kommen und in das Logfile schreiben will. Was ich nicht weiß: Die beiden Hex-Zeichenfolgen, die pro Zeile im Logfile jeweils einen Schlüssel bilden, wo finde ich die bei Indy?

Grüße
Cody

EDIT: Dank MDN bin ich schon etwas schlauer und weiß nun, das es sich beim ersten Hex-Wert um das "client_random" und beim zweiten um das "secret" handelt. Aber nach wie vor weiß ich nicht, wie/wo ich beim Verbindungsaufbau mit Indy diese Infos abfangen kann.

Codehunter 16. Okt 2018 13:27

AW: SSL Key Log mit Indy erstellen
 
Problem gelöst:
Delphi-Quellcode:
procedure TForm1.IdSSLIOHandlerSocketOpenSSL1StatusInfoEx(ASender: TObject;
  const AsslSocket: PSSL; const AWhere, Aret: Integer; const AType,
  AMsg: string);
var
  I, J, K, L: Integer;
  B: Byte;
  C: AnsiChar;
  LClientRandom, LMasterSecret, LLogLine: string;
begin
  if Assigned(AsslSocket) and
     Assigned(AsslSocket^.session) and
     Assigned(AsslSocket^.s3) then
  begin
    J := 0;
    L := Length(AsslSocket^.session^.master_key) - 1;
    for I := 0 to L do begin
      B := AsslSocket^.session^.master_key[I];
      J := J + B;
      LMasterSecret := LMasterSecret + Format('%x', [B]);
      if (I = L) and (J > 0) then begin
        L := Length(AsslSocket^.s3^.client_random) - 1;
        for K := 0 to L do begin
          C := AsslSocket^.s3^.client_random[K];
          B := Ord(C);
          LClientRandom := LClientRandom + Format('%x', [B]);
          if K = L then begin
            LLogLine := 'CLIENT_RANDOM ' + LClientRandom + ' ' + LMasterSecret;
          end;
        end;
      end;
    end;
  end;
end;
Diese Procedure wird von Indy mehrfach aufgerufen. Die Variable LLogLine wird aber letztlich nur dann gefüllt, wenn beide Informationen (Master Secret und Client Random) zur Verfügung stehen. Müsste so funktionieren für TLS 1.1 .. 1.3 und SSLv3.

Codehunter 3. Dez 2018 16:52

AW: SSL Key Log mit Indy erstellen
 
Update: Hier eine verbesserte Version. Zum einen lese und schreibe das MasterKeyFile nun per Stream mit fmShareDenyNone, sodass gleichzeitige Zugriffe zwischen Wireshark und meinem Programm keine AV mehr produzieren. Zweitens habe ich einen Bug in Indy entdeckt, der m.M.n. in der Header-Deklaration steckt. Innerhalb von PSSL.S3 sind die Master-Secret und Client-Random um ein Byte verschoben. Dadurch klappte die Entschlüsselung mittels Wireshark beim aktuellen Indy nicht mehr. Drittens hatte ich noch einen Bug drin in der Hexformatierung, der nur zufällig und sporadisch zu korrekten NSS-Exports führte. Das ist nun auch behoben.
Delphi-Quellcode:
procedure TForm1.DoSSLStatusInfoEx(ASender: TObject;
  const AsslSocket: PSSL; const AWhere, Aret: Integer; const AType,
  AMsg: string);
var
  I, K, L: Integer;
  B: Byte;
  C: AnsiChar;
  LClientRandom, LMasterSecret, LLogLine: AnsiString;
  LMode: Word;
  S3: Pssl3_state;
  FS: TFileStream;
begin
  if Assigned(AsslSocket) and
     Assigned(AsslSocket^.session) and
     Assigned(AsslSocket^.s3) and
     (FMasterSecretFile <> '') then
  begin
    L := Length(AsslSocket^.session^.master_key) - 1;
    for I := 0 to L do begin
      B := AsslSocket^.session^.master_key[I];
      LMasterSecret := LMasterSecret + Format('%2.2x', [B]);
      if (I = L) and (LMasterSecret <> StringOfChar('0', (L+1)*2)) then begin
        L := Length(AsslSocket^.s3^.client_random) - 1;
        for K := 0 to L do begin
          S3 := AsslSocket^.s3;

          Dec(PByte(S3)); // <-- Bug irgendwo zwischen OpenSSL-DLL und Indy, Speicher von ASslSocket.S3 um ein Byte verschoben
          C := s3^.client_random[K];
          B := Ord(C);
          LClientRandom := LClientRandom + Format('%2.2x', [B]);
          if K = L then begin
            LLogLine := 'CLIENT_RANDOM ' + LClientRandom + ' ' +
                        LMasterSecret + sLineBreak;
            if LLogLine <> FLastMasterSecretLine then begin
              LMode := (fmOpenReadWrite or fmShareDenyNone);
              if not FileExists(FMasterSecretFile) then begin
                LMode := fmCreate or LMode;
              end;
              FS := TFileStream.Create(FMasterSecretFile, LMode);
              try
                FS.Position := FS.Size;
                FS.Write(LLogLine[1], Length(LLogLine));
                Exit;
              finally
                FLastMasterSecretLine := LLogLine;
                FreeAndNil(FS);
              end;
            end;
          end;
        end;
      end;
    end;
  end;
end;

Codehunter 4. Dez 2018 09:42

AW: SSL Key Log mit Indy erstellen
 
Liste der Anhänge anzeigen (Anzahl: 2)
Hier noch nachgereicht die beiden "Beweisfotos" für den Speicherfehler innerhalb von Indy. Die Tatsache, dass Wireshark mit der nach der Pointer-Linksverschiebung erzeugten NSS-Datei TLS 1.2 entschlüsseln kann, müsste eigentlich Beweis genug sein dass es sich um einen Bug in Indy handelt ;-)

Codehunter 16. Feb 2019 21:03

AW: SSL Key Log mit Indy erstellen
 
Kleiner Nachtrag: Mittlerweile wurde der erwähnte Bug in Indy behoben. Daher sollte die Zeile
Delphi-Quellcode:
Dec(PByte(S3));
nun überflüssig sein und kann auskommentiert werden.

baka0815 23. Dez 2021 13:39

AW: SSL Key Log mit Indy erstellen
 
Was gut funktioniert ist https://www.telerik.com/fiddler/fiddler-classic, hier kann man auch SSL/TLS-Traffic analysieren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:20 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz