RustでARPポイズニングツールを実装するとこうなる

RustでARPポイズニングツールを実装するとこうなる


Rusの力を借りてARPポイズニングツールを実装します。
以前c言語でツールを実装しました。

これをRustで作るとどのような形になるのかに興味がありました。

ARPポイズニングの原理については上に挙げた記事に簡単に書かれているので、
今回は主に実装を中心に書きたいと思います。


実現するために必要なもの

Rustで実現するためにひとまずドキュメントを読みました。
https://docs.rs/pnet/0.22.0/pnet/index.html
そこで関連しそうなものをもつけました。

  • MutableEthernetPacket
  • MutableArpPacket


おそらくこれらを使うことになるでしょう。
pnetを使うことはわかっていました。


またRustに限らず低レイヤのパケットを扱うにはRawSocketにアクセスする必要があります。
この方法に関しては以前に記事にしました。


この記事ではパケットをキャプチャするプログラムを作りました。

インターフェースを取得してデータリンク層までアクセスしたわけですが、
今回も同じようにデータリンク層にアクセスします。

他にも細かいところで必要なものが出てくると思いますがそれは後々カバーできるでしょう。

あとはスプーフィングを実現するプログラムを書いていくだけです。

実装


まずはCargo.tomlに依存クレートを記載します。


お馴染みのpnetです。
このpnetにはしばらくお世話になるとおもいます。


まず必要なモジュールをインポートします。


どれが何に使われるかはある程度見当がつくと思います。

次はパケットを作成します。
この部分が一番の悩みどころでした。


main関数の頭で引数を取得します。
取得する引数は5個です。(ファイル名をいれて6個)

  1. インターフェース名
  2. 送信元Macアドレス
  3. 宛先Macアドレス
  4. 送信元IPアドレス
  5. 宛先IPアドレス


あとはこれらの引数をつかってパケットを作成していきます。
make_ethernet_packetとmake_earp_packetがその処理をします。
この関数にそれぞれMutableEthernetPacketとMutableArpPacketのインスタンスを渡します。

パケットを作り終わったらインターフェースを取得します。
これは以前の記事でやりました。


そしていよいよパケットの送信です。
MutableEthernetPacketのpacket関数でパケットを[u8]にしたものを取得し、
パケットを送信する処理そしてくれるsend_packet関数に渡します。


ソースコード全体はこのようになりました。

動作確認


対象ホストのARPテーブルを書き換えることができていたら成功です。


ソースコードのクオリティはともかくテクニックの実現はできているようですね。

Rustのベストプラクティス


今回は一種のハッキングツールを作りました。
Rustはまだ参考書も圧倒的に少なくベストプラクティスもあまり確立されていないように思えます。
こういう時にドキュメント読んで進んで何かを作ってみることは重要なことだと思います。

ただベストプラクティスが確立されていな状態で我流で作ると、
行儀の悪い作り方をしているか不安になります。

一日でも早くRustの作法が固まればいいなと思います。