Wireshark で Lua Dissector を使用する方法
世界最高のネットワーク パケット キャプチャ ツールの 1 つである Wireshark を使用すると、特定の情報のパケットをキャプチャできます。 したがって、これらのパケットをオフラインとリアルタイムの両方で分析できます。 このアプリは、ネットワークを流れるデータを綿密に監視する方法として考えてください。 さまざまな問題や異常を検出できます。
パケットのデータの特定の部分を解析する場合は、パーサーを使用できます。 名前の通りこのプロセスによりコードが「断片化」され、注意が必要な一部の領域を削除できるようになります。 このチュートリアルでは、Lua スクリプト言語を使用して Wireshark でスプリッタを作成および使用する方法について説明します。
Contents
始める前に – ディセクターについて知っておくべきこと
スプリッターはパーツを迅速に分析する方法を提供しますが、 Wireshark ではデータ パケットの数が増加しますが、効率的に動作するには特定のプロトコルに従う必要があります。 これらのプロトコルは次のとおりです。
- 作成するすべての Dissector は、他のプロトコルで定義されたペイロード タイプを処理するために登録する必要があります。 この登録を完了するには 「Proto」オブジェクトを逆コンパイラに割り当てる必要があります。 以下に表示されます
- Wireshark 経由で Dissector を呼び出すと、アプリから 3 つの内容を受け取ります。
- TVB オブジェクト – データ パケットからの TVB バッファー。
- TreeItem オブジェクト – データ ツリー内の単一ノードを表すツリーのルート。
- Pinfo オブジェクト – パケット データをログに記録します。
- データ パケットが一致する場合にのみ dissector を実行できます。 ディセクターテーブル 「Proto」オブジェクトに設定したもの。
- 関数を介してスプリッターの使用を強制することで、この要件を回避できます。 「として復号化されました」が、それでも次の場合にのみディセクターを強制できます。 ディセクターテーブルここで、オブジェクト「Proto」を有効なタイプに設定します。
LUA を使用したディセクターのセットアップ
Wireshark は C プログラミング言語で記述され、使用されるため、ほとんどのパーサーも C で記述されます。ただし、Lua を使用することもできます。このスクリプト言語は C よりも単純です。 そのため、初心者や、より軽い言語を使用してシャードを作成したい人にとって、よりアクセスしやすくなっています。
たとえコードがより単純であっても。 ただし、Lua を使用したときに得られるスプリッターは、通常、C を使用して生成したスプリッターよりも遅くなります。ただし、Lua を使用して Wireshark スプリッターを構築する場合は、次の手順に従う必要があります。
ステップ 1 – Wireshark で Lua を構成する
これまで Wireshark で Lua を使用したことがない場合は、Lua をセットアップする必要があります。
- 「ヘルプ」をクリックし、続いて「Wireshark について」をクリックします。
- 「フォルダ」をクリックします
- 次のいずれかを選択して、実行中の Lua スクリプトを作成します。
- ユニバーサル Lua プラグイン
- プライベート Lua プラグイン
- 個人的
アクティブ化されたときスクリプトに変更を加えるたびに、Wireshark を起動するたびに、スクリプトの準備が整います。 変更を有効にするには、Wireshark を再起動して変更を登録するか、「Ctrl + Shift + L」を押してすべての Lua スクリプトをリロードする必要があります。
ステップ 2 – ディセクターを作成するための基本的な手順
すでに Lua に精通している場合は、次の手順を使用して、Wireshark で実行される独自のフォークされたスクリプトを作成できます。
- スプリッターのプロトコルを宣言します。 プロトコル ツリーで使用する長い名前と、分割の表示フィルター名として機能する短い名の両方を定義する必要があります。
- 次の 3 つのフィールドを作成します。 適切なタイプを使用して:
- 質問 – 質問の種類を表示します。
- 回答 – 回答の種類を表示します。
- MessageType – パケットが質問または回答を求めているかどうかを示します。
- Wireshark がフィールドを表示する方法を認識できるようにフィールドを登録します。 登録フィールドがない場合 「Lua エラー」メッセージが表示されます。これは通常、ツリー エントリの ProtoField が無効であることを示します。
- 前述の Pinfo を含む抽出関数を作成します。 (パケットに関する情報が含まれます) とツリー リスト。 (サブツリーに追加するチャートを作成します。)また、TCP の上に「バッファ」を作成する必要があります。
- Wireshark がスプリッターを使用する必要があるプロトコルとポートの両方を指定します。たとえば、プロトコルを「TCP」に設定し、使用するポート番号を設定できます。
ステップ 3 – ディセクターを Wireshark に追加する
さて、解剖器は電気のない電球のようなもので、存在しますが、電力を供給できるまでは役に立ちません。 言い換えるとスプリッタはまだ Wireshark に追加されていないため、次の手順に従って手動で追加して機能させる必要があります。
- 「ヘルプ」をクリックし、「Wireshark について」メニューに移動します。
- 「フォルダー」タブを選択して、Lua ファイルのパスのリストを見つけます。
- 「Personal Lua Plugin」を選択し、必要に応じてディレクトリを作成します。
- 作成した Lua ファイルをコピーして「Personal Lua Plugins」ディレクトリに貼り付け、Wireshark をリロードして Dissector を開きます。
キャッチしたパケットの一部を開いて、新しいフラグメンテーションをテストすることをお勧めします。Wireshark は、フラグメンテーション用に選択した長い名前を示すメッセージを送信する必要があります。 メッセージの種類に関する情報も含まれます。 (質疑応答)と試験結果。
いくつかのサンプルコード
これまでにスプリッターを構築したことがない場合。 (または Lua を初めて使用する場合) ワイヤーシャーク 試してみる便利なサンプル抽出ツールを提供します。
local p_multi = Proto("multi", "MultiProto");
local vs_protos = {
[2] = "mtp2",
[3] = "mtp3",
[4] = "alcap",
[5] = "h248",
[6] = "ranap",
[7] = "rnsap",
[8] = "nbap"
}
local f_proto = ProtoField.uint8("multi.protocol", "Protocol", base.DEC, vs_protos)
local f_dir = ProtoField.uint8("multi.direction", "Direction", base.DEC, { [1] = "incoming", [0] = "outgoing"})
local f_text = ProtoField.string("multi.text", "Text")
p_multi.fields = { f_proto, f_dir, f_text }
local data_dis = Dissector.get("data")
local protos = {
[2] = Dissector.get("mtp2"),
[3] = Dissector.get("mtp3"),
[4] = Dissector.get("alcap"),
[5] = Dissector.get("h248"),
[6] = Dissector.get("ranap"),
[7] = Dissector.get("rnsap"),
[8] = Dissector.get("nbap"),
[9] = Dissector.get("rrc"),
[10] = DissectorTable.get("sctp.ppi"):get_dissector(3), -- m3ua
[11] = DissectorTable.get("ip.proto"):get_dissector(132), -- sctp
}
function p_multi.dissector(buf, pkt, tree)
local subtree = tree:add(p_multi, buf(0,2))
subtree:add(f_proto, buf(0,1))
subtree:add(f_dir, buf(1,1))
local proto_id = buf(0,1):uint()
local dissector = protos[proto_id]
if dissector ~= nil then
-- Dissector was found, invoke subdissector with a new Tvb,
-- created from the current buffer (skipping first two bytes).
dissector:call(buf(2):tvb(), pkt, tree)
elseif proto_id < 2 then
subtree:add(f_text, buf(2))
-- pkt.cols.info:set(buf(2, buf:len() - 3):string())
else
-- fallback dissector that just shows the raw data.
data_dis:call(buf(2):tvb(), pkt, tree)
end
end
local wtap_encap_table = DissectorTable.get("wtap_encap")
local udp_encap_table = DissectorTable.get("udp.port")
wtap_encap_table:add(wtap.USER15, p_multi)
wtap_encap_table:add(wtap.USER12, p_multi)
udp_encap_table:add(7555, p_multi)
ポストディセクターと連鎖ディセクター
スプリッターの使用法をもう少し詳しく調べてみるとよいでしょう。 Lua での操作をマスターしたら、Wireshark にはバック スプリッターとチェーン スプリッターという 2 つの追加の分割タイプが用意されています。 より多くの機能があるのは
解剖後これは、パケットに対して実行するすべてのディセクターの最終チェックのようなものです。 Wireshark が他のスプリッタを呼び出したときに通知を受け取るようにサインアップしています。 使用する必要があるものはすべてまた、これを使用して「プロトコル」列と「データ」列をフィルタリングすることもできます。
チェインディセクターも同様の機能を実行します。 ここでの主な利点は、チェーンされたディセクターがすべてのパケットを実行する必要がないことです。 元のパーサーが再度実行されるのを待たずに結果を取得します。
ルアで解剖
Wireshark はすでに C (自然言語) でパーサーを作成する機能を提供しているため、Lua でパーサーを作成する必要性も感じないかもしれません。少し Lua スクリプトを使用するとパーサーの作成が簡単になることがわかるかもしれません。 C ベースの分類子と比較して、プロセスを実行するときの読み込み時間は長くなりますが、いずれにしても、オプションがあることは便利です。
以上のことを踏まえて、皆様のご意見を伺いたいと思います。 Wireshark でスプリッターをどのくらいの頻度で使用しますか? 以前に C で作成してみたことがありますか? Lua でスプリッターを作成するメリットは何だと思いますか? 以下のコメントセクションでお知らせください。