この脆弱性により、攻撃者はBINDリゾルバのDNSキャッシュを破壊し、正規ユーザーを気付かれないまま悪意のあるIPアドレスへリダイレクトさせることができます。
この攻撃は信頼を悪用することに依存しています。被害者はリゾルバを信頼し、リゾルバ(BIND)は権威サーバから受け取った回答を信頼します。この欠陥は、BIND が DNS レスポンスの ADDITIONAL セクションで提供された要求外のデータを、それがまったく別の、要求されていないドメインに属するデータであっても処理してキャッシュすることに起因します。
セットアップ: 攻撃者は特定のドメイン(例: poc.lab)に対する悪意のある権威DNSサーバを制御します。攻撃者は、標的のリゾルバ(BIND)がこのドメインを問い合わせるのを待ちます。
インジェクション: リゾルバが攻撃者のサーバに poc.lab を問い合わせると、攻撃者は poc.lab に対する正規の回答を返しますが、ADDITIONAL セクションには別のドメイン(この例では www.hacker.com ですが、facebook.com のような任意の正規ドメインでも構いません)に対する要求外の回答を悪意のあるIPアドレスに向けて含めます。
ポイズニング: この脆弱性により、リゾルバは要求外の "Additional" レコードを受け入れ、それをキャッシュに保存します。リゾルバは、攻撃者がその要求外のドメインに対して権限を持っていないことを検証しません。
被害者の問い合わせ: その後、被害者がリゾルバに要求外のドメイン(www.hacker.com)を問い合わせると、リゾルバはキャッシュからポイズニングされたレコードを返し、被害者を攻撃者が制御する悪意のあるIPアドレスへリダイレクトします。
[!IMPORTANT]
この PoC の重要ポイント
間接攻撃: 被害者は攻撃者と直接通信することはありません。
信頼アンカーの侵害: 被害者のマシンは正常に動作しています。嘘をついているのはインフラストラクチャ(DNS)です。
メカニズム: このエクスプロイトは、Additional セクションの処理を利用して、要求されたことのないレコードを注入します。
[!CAUTION]
この PoC は教育目的のみで提供されています。この情報をシステム侵害に不正利用することは違法かつ非倫理的です。ネットワークやシステム上で脆弱性をテストまたは悪用する前に、必ず許可を取得してください。
このデモでは、次の仮想マシン(VM)を使用します:
以下のコマンドは、CVE-2025-40778 の脆弱性を実証するために、Debianベースのシステムに BIND 9.21.12 をセットアップするためのものです。
[!NOTE] このデモでは、この脆弱性の影響を受けるバージョンの1つである BIND 9.21.12 を使用します。
影響を受ける他の既知のバージョン範囲は以下のとおりです:
- 9.11.0 – 9.16.50
- 9.18.0 – 9.18.39
- 9.20.0 – 9.20.13
- 9.21.0 – 9.21.12
以下のコマンドは、必要な依存関係をインストールし、BIND 9.21.12 のソースコードをダウンロードしてコンパイルし、システムにインストールします。
sudo apt install -y build-essential pkg-config perl meson ninja-build libssl-dev libuv1-dev liburcu-dev libcap-dev liblmdb-dev libnghttp2-dev
cd /usr/local/src
sudo wget -O bind-9.21.12.tar.xz https://isc.mirrorservice.org/bind/9.21.12/bind-9.21.12.tar.xz
sudo tar -xf bind-9.21.12.tar.xz
cd bind-9.21.12
sudo meson setup build --prefix=/usr/local --sysconfdir=/etc --localstatedir=/var
sudo ninja -C build
sudo ninja -C build install
echo /usr/local/lib/x86_64-linux-gnu | sudo tee /etc/ld.so.conf.d/bind9-local.conf
sudo ldconfig
ldconfig -p | grep 'libdns-9.21.12' || true
/usr/local/sbin/named -v
以下は最後のコマンドの期待される出力です:
> student@student:/usr/local/src/bind-9.21.12$ /usr/local/sbin/named -v
BIND 9.21.12 (Development Release) <id:9bafc35>
BINDサーバを起動する前に、namedサービスを実行するための専用ユーザーとグループを作成する必要があります:
sudo groupadd --system named 2>/dev/null || true
sudo useradd --system --no-create-home --home /nonexistent --shell /usr/sbin/nologin --gid named named 2>/dev/null || true
このBINDインストールにはデフォルトの設定ファイルが付属していないため、必要なディレクトリを手動で作成する必要があります:
sudo mkdir -p /etc/bind
sudo mkdir -p /var/cache/bind
sudo mkdir -p /var/log/named
sudo mkdir -p /var/run/named
sudo chown -R named:named /var/cache/bind /var/log/named /var/run/named
sudo chmod 750 /var/cache/bind /var/log/named /var/run/named
次のステップとして、以下の内容でメイン設定ファイル /etc/bind/named.conf を作成します:
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.logging";
include "/etc/rndc.key";
オプション設定については、以下の内容でファイル /etc/bind/named.conf.options を作成します:
options {
directory "/var/cache/bind";
recursion yes;
allow-recursion { 192.168.174.0/24; };
allow-query { 192.168.174.0/24; };
listen-on { 192.168.174.131; 127.0.0.1; };
listen-on-v6 { none; };
dnssec-validation no;
forwarders {
1.1.1.1;
8.8.8.8;
};
minimal-responses no;
// for manual start
pid-file "/var/run/named/named.pid";
};
ドメイン poc.lab のフォワードゾーンを設定して、クエリを標準ポート53の攻撃者のDNSサーバ 192.168.174.130 に転送するには、/etc/bind/named.conf.local ファイルを次のように編集する必要があります:
zone "poc.lab" {
type forward;
forward only;
forwarders { 192.168.174.130; };
};
ロギング設定として、以下の内容を含むファイル /etc/bind/named.conf.logging を作成します:
logging {
channel queries_file {
file "/var/log/named/queries.log" versions 3 size 20m;
severity info;
print-time yes;
print-category yes;
};
channel default_stderr {
stderr;
severity info;
print-time yes;
print-category yes;
};
category queries { queries_file; };
category default { default_stderr; };
};
最後に、RNDCを設定する必要があります:
sudo /usr/local/sbin/rndc-confgen -a -c /etc/bind/rndc.key
sudo chown root:named /etc/bind/rndc.key
sudo chmod 640 /etc/bind/rndc.key
まず、ポート53が他のサービスによって使用されていないことを確認する必要があります(この例では systemd-resolved を無効にする必要がありました):
sudo systemctl disable --now systemd-resolved || true
sudo ss -lunp | grep ':53' || true # To verify that port 53 is free
最後に、以下のコマンドでBINDサーバを起動できます:
sudo /usr/local/sbin/named -g -u named -c /etc/bind/named.conf
[!TIP]
BINDが正しく実行されていることを確認するには、次のコマンドを使用できます:
ss -lunpt | grep :53
被害者マシンでは、DNSリゾルバとしてBINDサーバを使用するように設定する必要があります。また、競合を避けるために systemd-resolved を無効化する必要があります:
sudo systemctl disable --now systemd-resolved
次に、以下のコマンドを使用して静的DNSサーバを設定できます:
sudo rm -f /etc/resolv.conf
sudo nano /etc/resolv.conf
> nameserver 192.168.174.129
> options timeout:1 attempts:1
sudo chattr +i /etc/resolv.conf #block overwrites
攻撃者マシンでは、リポジトリに含まれるスクリプト(attacker.py)を実行する必要があります。
このシナリオでは、攻撃者は poc.lab ドメインを制御しています。攻撃者は、このドメインまたは任意のサブドメインを問い合わせられたとき、自分のIPアドレスを指す要求外の回答レコード(www.hacker.com)を追加します。
被害者が poc.lab ドメインを問い合わせると、BINDサーバはリクエストを攻撃者のDNSサーバに転送します。攻撃者は、BINDサーバのキャッシュをポイズニングする要求外の回答レコードを返します。被害者が www.hacker.com にアクセスすると、正規のIPアドレスの代わりに攻撃者のIPアドレスへリダイレクトされます。
以下は、被害者が両方のドメインを問い合わせるデモです:
student@student:~/Desktop$ dig www.poc.lab +noall +answer
www.poc.lab. 60 IN A 192.168.174.99
student@student:~/Desktop$ dig www.hacker.com +noall +answer
www.hacker.com. 60 IN A 192.168.174.130
上記のとおり、www.hacker.com に対する被害者のDNSクエリは攻撃者のIPアドレス(192.168.174.130)を返します。
[!NOTE]
このビデオは、説明した脆弱性のデモです: https://drive.google.com/file/d/1PATD0tUqw8-BipfSf6TkQQfnJBvV110Z/view?usp=sharing