DNS増幅(DNS増幅)

少し前に、最近このトピックの関連性を考慮に入れて問題(およびその解決策)に遭遇しました。また、現在この災害に苦しんでいる人の数を考慮して、情報を1つの記事にまとめることにしました。 たぶん他の誰かがそれを役に立つと思うでしょう。

画像

開始する





数週間前、DNSサーバーに向けられた奇妙なアクティビティに気付きました。 Linuxゲートウェイを使用しているため、バインドDNSサーバーがそこにインストールされているとすぐに言います。 アクティビティでは、さまざまなIPアドレスからの1秒あたりのUDPパケットが、サーバーのポート53(DNS)でストリーミングされていました。



10:41:42.163334 IP 89.149.221.182.52264> MY_IP.53:22912+ NS?。 (17)

10:41:42.163807 IP MY_IP.53> 89.149.221.182.52264:22912拒否-0/0/0(17)



ログからわかるように、サーバーは失敗で応答しました。 当然、どの種類のIPアドレスがDNSをつついているのだろうと思っていました。 whoisでいくつかのアドレスを見たところ、これらは大規模なホスティング会社であると判断し、それらのいくつかのテクニカルサポートで私のサーバーへの攻撃を阻止する要求を書きました。 応答として、このタイプの攻撃はブロックできないという事実に言及しており、彼ら自身がこの異常な活動に苦しんでいるという返信を受け取りました。 すべてを自分で処理することにしました。



DNS増幅(DNS増幅)。 理論



攻撃の種類自体は新しいものではありません。2006年に知られていましたが英語の詳細はこちら確認できますが 、比較的最近使用され始めました。 2009年1月から2月に、いくつかのオンライン出版物が、このタイプのDDOSのサイバー犯罪者による大規模な使用に関する情報を公開しました。

簡単に言えば、利益の本質は、攻撃者が(通常は短い)要求を脆弱なDNSサーバーに送信し、それが非常に大きなパケットで要求に応答することです。 要求を送信するときに送信元IPアドレスとして被害者のコンピューターのアドレス(IPスプーフィング)を使用すると、脆弱なDNSサーバーは、その操作を完全に麻痺させるまで被害者のコンピューターに大量の不要なパケットを送信します。



練習する



このタイプの攻撃は、古い(パッチが適用されていない)または不適切に構成されたDNSサーバーで最も効果的です。DNSサーバーは、既に述べたように、サイバー犯罪者による大きなパケットでの短い要求に応答します。

このような相互作用の例を次に示します(ところで、これらは攻撃者が最も頻繁に使用する要求です)。

次のコマンドでリクエストをNSサーバーに送信します

#dig @SERVER_IP NS





ここで、SERVER_IPはサーバーのIPアドレスです。 その結果、サーバーポート53のログオンで次のようになります。

11:08:47.994604 IP MY_IP.47816> SERVER_IP.53:5655+ NS?。 (17)

つまり 送信したいリクエストの17バイトだけです。

応答として、同じログに次のように表示されます:

11:08:47.995853 IP 192.168.100.254.53> 192.168.100.100.47816:5655 13/0/6 NS C.ROOT-SERVERS.NET。、[|ドメイン]

つまり サーバーは、ルートDNSサーバーのアドレスの形式でヒントを返しました。これは既に360バイトです。 これらはDNS要求とDNS応答の長さであり、合計パケット長はそれぞれ60バイトと402バイトです。 増幅は明らかです。



どうする



もちろん、最初に、実行しているプラ​​ットフォームに関係なく、DNSサーバーのバージョンの関連性を確認します。 次に、サーバーが十分に安全に構成されており、全員への「左」要求に応答しないことを確認します。 これに関する多くのマニュアルと推奨事項をネット上で見つけることができます。 ここでは、さっき見つけたドキュメントを1つだけ説明します。



他に何ができますか?



私の場合、特別なことはもうありませんでした。 引用した最初のログを見ると、攻撃者が17バイトの長さでリクエストを送信し、同じ長さ(17バイト)のREJECTを受信して​​いることは明らかです。 ゲインは発生しません。 しかし、どうやら「ddos-ers」は、リストからこの脆弱性の影響を受けないDNSサーバーのアドレスを削除することを特に急いでいるわけではなく、それらを悩まし続けています...この状況は私には向いていません。 誰かが私のサーバー上の私のアドレスから不必要なトラフィックを受け取るのは不愉快です(たとえ私が責任を負わなくても)。

最初は、送信者のアドレスをブラックリストに入れ始めましたが、そこには存在しませんでした。古いアドレスからの攻撃は止まりましたが、ますます現れました。 より洗練されたフィルタリング方法を使用し、Linuxサーバーでiptablesモジュールを使用することが決定されましたが、これまで到達できませんでした。 いわば、1石で2羽の鳥を殺します。攻撃者は-1を行い、2つのiptablesモジュールを扱います。



文字列モジュール



もちろん、ポート53(DNS)を完全に閉じることはできませんでした。必要なクライアントがたくさんいます。 DNSクエリの内容でパケットをフィルタリングし、攻撃者のクエリを含むパケットを削除することにしました。すべてのクエリには「NS」が含まれていました。 iptables文字列モジュールはこのタスクに適しています。これにより、パッケージの内容を調べることができます。

フィルタリングの対象を理解するために、wiresharkを使用して攻撃者のパッケージを見てみましょう。

画像

ここここでは、それぞれUDPパケットの構造とDNSフレームの形式について読むことができます。 簡潔にするために、パケットの最初の14バイトがイーサネットプロトコルデータ(赤で表示)で占有され、20バイトのIPプロトコルヘッダー(青で表示)があり、8バイトがUDPヘッダー(緑で表示)であると言います。 DNSプロトコルデータ(黄色で表示)。 DNSフレームの最初の12バイトはヘッダーで占められ、その後、最後にDNSクエリフィールドが開始されます(つまり、クエリ自体がオレンジ色で表示されます)。 54番目(14 + 20 + 8 + 12)バイトから始まる攻撃者によって送信されたパケットには、次のデータが含まれています:00 00 02 00 01(16進コード)。これは、前述の「NS」要求に対応します。 したがって、54バイトから始まるこれらのバイトを含むパケットを選択する必要があります。 次のようになります。



iptables -A INPUT --in-interface eth1 --protocol udp --dport 53 --match state --state NEW --match string --algo kmp --hex-string "|00 00 02 00 01|" --from 40 --to 45 --jump DROP







少し説明します。

--in-interface-パケットをキャッチするインターフェイスを示します。 攻撃が行われている外部インターフェイスのみを配置する必要があります(ネットワーク内のユーザーを侵害する必要はありません)。

--match state --state NEW-連続したすべてのトランザクションをチェックせず、パケットを開始するだけであるように、NEW状態でのみパケットをキャッチします(ポート53で送信できるものが分からない)。

次に楽しい部分があります-私たちはスティングモジュールを使用します。 次のパラメーターを使用します。

--algo-検索アルゴリズムを示します。実際には重要ではありません。kmpを指定しましたが、bmを指定することもできます。

--hex-string-探している16進形式の文字列が書き込まれます。

-40から-40バイトから開始しています(54からではなく、文字列が検索を開始し、それに応じてIPプロトコルの最初のバイトからのカウントダウン、つまりイーサネットプロトコルがスローされ、長さが14バイトであることに注意してください(上の図)。合計54-14 = 40);

--to 45-それぞれ最大45バイトのパケットを検索します。



最近のモジュール





これはすでに停止している可能性があります。 パッケージはもはやバインドに到達しませんが、DNSサーバーへのNSクエリへのアクセスを誰もが禁止しているという考えにまだ安心できなかったので、最近、もう1つのiptablesモジュールを使用することにしました。

このモジュールを使用すると、特定の条件に応じてIPアドレスの動的テーブルを作成し、これらのテーブルの許可ルールと拒否ルールを設定できます。

最近の単純な2行の例を考えてみましょう。



iptables -A INPUT --protocol tcp --match state --state NEW --dport 22 --match recent --update --seconds 30 --name SSHT --jump DROP

iptables -A INPUT --protocol tcp --match state --state NEW --dport 22 --match recent --set --name SSHT --jump ACCEPT






2番目のルールから始めましょう。 ポート22(SSH)でログイン(ログイン、-state NEWを使用しているため)しようとすると、スキップ(--jump ACCEPT)されますが、IPアドレスはSSHTという名前のテーブルに分類されます。 このアドレスから再度接続しようとすると、最初のルールが機能し始めます。その意味は、テーブル内の(--update)レコードを更新すると同時に、このレコードが最後にインストール/更新されたタイミングをチェックすることです。 レコードが30秒前(--seconds 30)より前にインストール/更新された場合、-jump DROPがトリガーされ、パケットは破棄されます。 したがって、パケットの送信頻度が30秒で1パケットを超えると、SSHポートでクラッシュしようとするブルートフォーサーは破棄されます。

ニーズに合わせて最近使用してみましょう。

iptables -A INPUT --in-interface eth1 --protocol udp --dport 53 --match state --state NEW --match string --algo kmp --hex-string "|00 00 02 00 01|" --from 40 --to 45 --match recent --name DNST --update --seconds 600 --jump DROP

iptables -A INPUT --in-interface eth1 --protocol udp --dport 53 --match state --state NEW --match string --algo kmp --hex-string "|00 00 02 00 01|" --from 40 --to 45 --match recent --name DNST --set --jump ACCEPT







したがって、外部インターフェイスへのNS要求は、10分間に1回まで許可されます。



これらのルールをサーバーの/ proc / net / xt_recentに追加すると、DNSTファイルが表示され、攻撃者のIPアドレスが記録され始めました。 そして、DNSサーバーは挑発への応答を停止しました。

14:10:19.011818 IP 89.149.221.182.40320> MY_IP.53:23508+ NS?。 (17)

14:10:25.243499 IP 89.149.221.182.64984> MY_IP.53:25306+ NS?。 (17)

14:11:08.832827 IP 89.149.221.182.15864> MY_IP.53:48029+ NS?。 (17)

14:11:15.063058 IP 89.149.221.182.30959> MY_IP.53:64444+ NS?。 (17)



数日間のルールの後、攻撃者からのパケット数は数回減少しました。 今では、毎分2〜3パケットを取得しますが、これらはファイアウォールによってすぐに破棄されます。



UPD:コードの最後のブロックで、私は急いでエラーを書きました。すでに修正しました。



All Articles