MasaのITC Life

夢は起業家!全てにおいて凡人だけど頑張ることだけはいっちょ前!

やってみた系/その他

【Linuxで実践】SYN Flood攻撃とSYN cookiesについて

投稿日:2020年2月27日 更新日:


今回はLinuxを用いて、

実際にSYN Flood攻撃をやって、

その対策に一つである、

SYN cookiesについて説明します。



まずはSYN Flood攻撃を

やってみましょう。



実践するにあたって私は、

次の環境を用いました。

Virtual Box上で動作するLinux2台
・Kali Linux2018.04 (Webサーバ:Apache)
・Ubuntu18.04 (クライアント側)


まずはSYN Flood攻撃について、

簡単に確認していきましょう。


TCP通信を始める前に、

クライアントとサーバは

3wayハンドシェークを行います。


3wayハンドシェークの手順は、

まずクライアントがSYNフラグを

セットしたTCPパケットを送ります。



それを受け取ったサーバは、

SYNとAckフラグをセットした

TCPパケットを送り返します。



クライアントはサーバから

それが送られてくると、

Ackフラグをセットして返信します。



図で表すと次のようになります。



サーバはクライアントから

SYNパケットを受け取ると、

syn_backlogキュー(バッファ)

その情報を一時的に確保します。



この状態はコネクションがまだ

未確立の状態でハーフオープンと

呼ばれれる状態に該当します。



そしてこの状態から

コネクション確立まで遷移すると、

SYN_Backlogキューにあった

コネクション情報はBacklogキューと

呼ばれるバッファに移されます。



ソケットプログラムで扱ったことが

ある方はご存知の通り、

listen()の引数で指定する値です。



listen()の引数で指定した値が、

バックログキューの長さに該当します。

ちなみにaccept()される直前では、

TCPコネクションが確立している状態です。



話しを戻しまして、SYN Flood攻撃は、

このSYN_Backlogというバッファを

攻撃者の手によって埋め尽くすことで、

正規クライアントがコネクション確立を

出来なくするDoS攻撃の一種です。



サーバはクライアントから

SYNパケットが送られてきたら、

Half-openの状態になり、

syn_backlogキューの情報を一時確保します。



攻撃者はこの仕組みを利用して、

多数のランダムIPアドレスからサーバへ

SYNパケットを乱打します。



これがSYN Flood攻撃です。



ではどのように対策すれば

良いのでしょうか。



今回はその一つである、

SYN cookiesについて説明します。

SYN cookies とは


SYN cookiesは、

SYN_Backlogがいっぱいになったら、

Half-openのコネクションを順に

解放してバッファを空ける仕組みです。



このSYN cookiesが有効であれば、

新しいコネクションの確立要求が来ても、

未確立のコネクションを削除することで、

対応できるようになります。



この値が無効であれば、普通、

SYN + Ack パケット対する

Ack パケットの返信がタイムアウトするまで

サーバはHalf-openを維持します。

つまりSYN Backlogキューを持ったままです。



SYN cookiesが有効であるか否かは、

次の場所で設定されています。

/proc/sys/net/ipv4/tcp_syncookies
1なら有効、0なら無効




それではこのsyn cookiesが

ONのときとOFFのときとで、

サーバにSYN Flood攻撃を

仕掛けてみましょう。

LinuxでSYN Flood攻撃をやる方法



まずSYNパケットを送信するのに、

hping3 というツールを使用します。

まずはhping3をインストールしましょう。

apt-get install hping3



インストールが出来たら、

例えば次のように打って

SYNパケットを送信します。

hping3 -c 1500 -d 120 -w 64 -p 80 --flood --rand-source X.X.X.X


-c:パケットカウント数

-d:データ長

-w:ウインドウサイズ

-p:送信先ポート番号

--flood:最高レートで送信する

--rand-source:送信元IPアドレスを偽造

x.x.x.x:送信先IPアドレス




サーバ側は listen() のポートを用意します。

私の場合は、Apacheを用いた

Webサーバを用意しました。



Apacheの場合は、

apt-get install apache2


インストールして、

service apache2 start


簡単にWebサーバを動かすことが出来ます。



未確立状態のコネクションは

次のコマンドで確認出来ます。

netstat -n | grep SYN_RECV



クライアント側で上述したhping3を

タイプしてSYNパケットを

送信し続ける状態にしておきます。

こんな感じです。



この状態でサーバ側で接続を確認した

画像がこちらになります。

netstat -n | grep 80 をうちました。




実はLinuxではデフォルト状態では、

SYN cookiesが有効になっています。

なのでどれだけSYNパケットを

送信してもSYN_Backlogキューは

いっぱいになりません。



なのでSYN Flood攻撃をしている中で、

正規クライアントが接続を試みても

コネクションの確立に成功します。



もしSYN Flood攻撃によって、

正規クライアントが接続できない

という状態を体験したい場合は、

syn cookiesを無効にする必要があります。



vimでもなんでもよいので、

/proc/sys/net/ipv4/tcp_syncookies


ここにある値を1から0にしてやります。



実際にこれを0にして、

正規クライアントがWebサーバに

アクセスすると、タイムアウトします。






これ以降はもう少し深堀します。

syn_cookiesの確認
cat /proc/sys/net/ipv4/tcp_syncookies

SYN_Backlogキューの確認
cat /proc/sys/net/ipv4/tsp_max_syn_backlog

listenに指定できる最大バックログキューの確認
cat /proc/sys/core/somaxconn


カーネル側でsys_backlogキューの

最大サイズが決められています。



これはあくまでカーネルが決めた

最大値に過ぎず、実はsyn_backlogには

実効値が存在します。



この実効値の計算には、

確立済みのコネクション用の

バッファであるバックログキューが

関係してきます。



このバックログキューの値は、

サーバを実装したプログラム中にある

listen()の引数に指定した値です。



サーバであればSOMAXCONNという

定義された値が入ることが多く、

これはカーネルによって決められた値です。

デフォルトでは↓の画像のように

128 (Debianの場合)がセットされています。


最後の行に、

netstat -n | grep SYN_RECV | wc -l


の出力として 97 が表示されています。



これはコネクション未確立の数を示します。

上の画像ではSYN Flood攻撃を仕掛けて、

数秒経過した後の数です。


この 97 という値は、

実験を行った環境において

Half-openのコネクションを

確保できる最大数を意味しています。



実はこの値は計算によっても

求めることが出来ます。



詳しい計算方法は下記のサイトに

大変分かりやすく記載されています。


参考:
https://wiki.bit-hive.com/linuxkernelmemo/pg/listen%20backlog%20%E3%80%903.6%E3%80%91
http://intrajp-computer.hatenadiary.jp/entry/2017/09/22/055158




今回は以上です。


最後まで読んでいただきありがとうございました。



-やってみた系/その他

Copyright© MasaのITC Life , 2023 All Rights Reserved Powered by STINGER.