私はブラウザのメモリにフックする方法を学ぼうとしています。 Fridaツール は、これの良いスタートです。私の目標は、TLSハンドシェイクの最後に確立されたクライアントランダム、サーバーランダム、対称のセッションキーを抽出することです。 SSLKEYLOGFILE
環境を設定することで、クライアントのランダムキーとマスターキーを抽出できますが、サーバーのランダムキーは出力されません。
Firefoxのソースコードを確認した後、_<firefox src/security/nss/lib/ssl/ssl3conn.c>
_の関数static void ssl3_RecordKeyLog(sslSocket *ss)
のサーバーランダムキーを出力することで、簡単に修正できます。
ただし、これは私のプロジェクトでは実行可能なソリューションではありません。これは、展開能力が低下するためです。つまり、新しい更新があるたびにFirefoxをコンパイルすることは、通常、ブラウザーコードに変更を加えて再配布することはお勧めできません。
これを行うより良い方法はありますか?より具体的には、これらの2つのオプションのいずれかが実行可能ですか?私はブラウザのアーキテクチャについてあまり知識がありません。
A. Firefox拡張機能でネイティブC++呼び出しを使用して、ファイル_src/security/nss/lib/ssl/ssl3conn.c
_からこの関数/任意の関数を呼び出します。
B.この関数がブラウザーで呼び出されるたびに、ブラウザーフックを使用して自分のコードを呼び出す。
コンテキスト:サーバーランダム、クライアントランダム、マスターシークレットの3つの値を使用して、TLSセッションで使用される暗号化キーの生成にさらに使用されるキーブロックを生成します。
私はwiresharkにこの機能があることを知っており、最小限の変更でキーを出力できますが、キー生成のような単純なプロセスでホストコンピューターのリソースを多く消費するため、wiresharkを使用したくありません。
独自のlibpcapコードを記述してトラフィックを解析できますが、これを最後のオプションとして保持したいと思います。
あなたはfridaでこれを試してみたいかもしれません:
import frida
import sys
session = frida.attach("firefox.exe")
script = session.create_script("""
"use strict";
const PR_Read = Module.findExportByName("nss3.dll", "PR_Read");
Interceptor.attach(PR_Read, {
onEnter: function (args) {
let length = args[2].toInt32();
let buffer = Memory.readByteArray(args[1], length - 1);
console.log(buffer);
}
});
""")
script.load()
sys.stdin.read()
私はこのコードを試していませんが、PR_Write(firefoxが出力するもの)でクライアントランダムとマスターキーを取得できたように見えるので、おそらくPR_Read(これはサーバーの応答)。
出典:
私がそれを見つけた方法: