かさやぬすの日記

後で思い出したいことを書く

C言語で"生"のパケットを送信する!その2【ARPキャッシュポイズニング】

こんにちは!まさです。

前回ARPキャッシュポイズニングについて大まかに説明しました。

f:id:kasayanus:20180724213214p:plain

その中で、この攻撃を成立させるためにはニセのARPリプライを送る必要があることを述べました。

今回は具体的なARPパケットの作り方と送信のプログラムについて説明します。

今回はC言語のpcapライブラリというものを使っていきます。

C言語を使う理由としては、

ARPプロトコルOSI参照モデルネットワーク層(第三層)に位置する非常に低レイヤーなプロトコルである。

MACアドレスを詐称するためデータリンク層(第二層)のヘッダー情報を書き換える必要がある。

以上の2つが主な理由です。

では実際にパケットを送信するまでのプログラムを以下に示します。
数字をのせた行については後で説明します。

#include <pcap.h>//pcapライブラリインクルード

char* device="イーサネットデバイス名を入力";//①
pcap_t *pcap_handle; //パケット送信用ハンドラー
char errbuf[PCAP_ERRBUF_SIZE];//エラーメッセージ格納用の変数

int main(int argc,char** argv)
{
  u_char* packet={0x00};//②送信するパケットの内容(16進数)
  pcap_handle=pcap_open_live(device,8192,1,0,errbuf);//③ハンドルのオープン
  pcap_sendpacket(pcap_handle,packet,100);//④パケットを送信

}

コードの①〜④を説明します。
① PCが使っているイーサネットバイスを入力します。これはipconfigやifconfig、ip aなどのコマンドによって確認してください。

② pcapライブラリで送信するパケットは16進数の配列で表される"生"のパケットです。ここではサンプルでは{0x00}を送信していますが、
宛先の情報も書かれていないのでこのパケットには意味がありません。
(u_char型はunsigned charの略です。)

pcap_t* pcap_open_live(char* device , int snaplen ,int promisc ,int to_ms,char* errbuf)
パケット送信用のハンドルをオープンします。引数は、デバイス名、取得したいパケットの最大長、デバイスをプロミスキャスモードにするかどうかのフラグ、読み込みタイムアウト時間(0を永遠に待ち続ける。)、エラーメッセージ格納バッファ


int pcap_sendpacket(pcap_handle* handle,u_char* packet,int size)

これが一番重要なパケット送信関数です。引数はハンドル、送信パケット、送信パケットサイズです。
注意してほしいのは、引数に宛先やポートを指定していないことです。
ここが他の言語に備わっているようなソケット通信とは違うところです。
pcapライブラリは生のパケットを送ります。つまりパケットそのものに宛先などの情報を書かなければならないのです。


生のパケットには、ヘッダーと言われるパケットそのものの種類や宛先、送信元などの情報を記載するための各プロトコルごとに決まった書式があります。
もちろんARPプロトコルにも独自のARPヘッダーというものが存在します。

今回はpcapライブラリの関数を使ったパケットの送信の仕方について説明しました。
次回は実際に送信する偽のパケットのARPヘッダを生成していきたいと思います。


ARPキャッシュポイズニングを実装その1
ARPキャッシュポイズニングを実装その3