labunix's blog

labunixのラボUnix

「NTP増幅」攻撃の対策について

■「NTP増幅」攻撃の対策について

 「NTP増幅」手法のDDoS攻撃、もっと強大化する恐れも
 http://www.itmedia.co.jp/enterprise/articles/1403/13/news069.html

 400GbpsのDDoS攻撃発生、「NTP増幅」で過去最大規模に
 http://www.itmedia.co.jp/enterprise/articles/1402/13/news043.html

■「CVE-2013-5211」
 「ntp_request.c」の「MON_GETLIST」コマンドによるリクエストの応答に不備がある

$ w3m -dump "http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-5211" 2>&1 | grep -A 5 "^Overview"
Overview

The monlist feature in ntp_request.c in ntpd in NTP before 4.2.7p26 allows
remote attackers to cause a denial of service (traffic amplification) via
forged (1) REQ_MON_GETLIST or (2) REQ_MON_GETLIST_1 requests, as exploited in
the wild in December 2013.

■wheezyのntpdのバージョンの確認

# ntpq -c rv | grep version
version="ntpd 4.2.6p5@1.2349-o Sat May 12 09:54:55 UTC 2012 (1)",

# ntpd --version
ntpd 4.2.6p5
ntpd 4.2.6p5@1.2349-o Sat May 12 09:54:55 UTC 2012 (1)

# apt-get update >/dev/null && apt-cache show ntp | grep Version
Version: 1:4.2.6.p5+dfsg-2

■該当箇所

# apt-get source ntp

# tar ztvf ntp_4.2.6.p5+dfsg.orig.tar.gz  | grep ntp_request.c
-rw-r--r-- peter/peter   74603 2011-12-01 11:55 ntp-4.2.6p5/ntpd/ntp_request.c

# tar zxvf ntp_4.2.6.p5+dfsg.orig.tar.gz  ntp-4.2.6p5/ntpd/ntp_request.c
ntp-4.2.6p5/ntpd/ntp_request.c

# grep MON_GETLIST ntp-4.2.6p5/ntpd/ntp_request.c 
	{ REQ_MON_GETLIST,	NOAUTH,	0, 0,	mon_getlist_0 },
	{ REQ_MON_GETLIST_1,	NOAUTH,	0, 0,	mon_getlist_1 },

■認証なしの他のリクエスト

# grep "REQ.*NOAUTH" ntp-4.2.6p5/ntpd/ntp_request.c 
	{ NO_REQUEST,		NOAUTH,	 0,	0 }
	{ REQ_PEER_LIST,	NOAUTH,	0, 0,	peer_list },
	{ REQ_PEER_LIST_SUM,	NOAUTH,	0, 0,	peer_list_sum },
	{ REQ_PEER_INFO,    NOAUTH, v4sizeof(struct info_peer_list),
	{ REQ_PEER_STATS,   NOAUTH, v4sizeof(struct info_peer_list),
	{ REQ_SYS_INFO,		NOAUTH,	0, 0,	sys_info },
	{ REQ_SYS_STATS,	NOAUTH,	0, 0,	sys_stats },
	{ REQ_IO_STATS,		NOAUTH,	0, 0,	io_stats },
	{ REQ_MEM_STATS,	NOAUTH,	0, 0,	mem_stats },
	{ REQ_LOOP_INFO,	NOAUTH,	0, 0,	loop_info },
	{ REQ_TIMER_STATS,	NOAUTH,	0, 0,	timer_stats },
	{ REQ_GET_RESTRICT,	NOAUTH,	0, 0,	list_restrict },
	{ REQ_MON_GETLIST,	NOAUTH,	0, 0,	mon_getlist_0 },
	{ REQ_MON_GETLIST_1,	NOAUTH,	0, 0,	mon_getlist_1 },
	{ REQ_AUTHINFO,		NOAUTH,	0, 0,	get_auth_info },
	{ REQ_TRAPS,		NOAUTH, 0, 0,	req_get_traps },
	{ REQ_GET_CTLSTATS,	NOAUTH,	0, 0,	get_ctl_stats },
	{ REQ_GET_KERNEL,	NOAUTH,	0, 0,	get_kernel_info },
	{ REQ_GET_CLOCKINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32), 
	{ REQ_GET_CLKBUGINFO, NOAUTH, sizeof(u_int32), sizeof(u_int32),
	{ NO_REQUEST,		NOAUTH,	0, 0,	0 }

■回避方法があるからなのか、debianでの優先度は「low」

 CVE-2013-5211
 https://security-tracker.debian.org/tracker/CVE-2013-5211

■要はmonlistコマンドを外部から受け付けなければ「CVE-2013-5211」には該当しない。
 また、「ntpd 4.2.7p26」以降ならば対策済み。

 ntpd の monlist 機能を使った DDoS 攻撃に関する注意喚起
 http://www.jpcert.or.jp/at/2014/at140001.html

 ntpd の脆弱性に関連して、さくら VPS の設定を確認した件
 http://hyper-text.org/archives/2014/02/sakura_vps_ntpd.shtml

■デフォルトはすべてのパケットを無視する。
 許可リストがその後にあるので、外部からは受け付けない。

 ※「noquery」は「ntpq」や「ntpdc」を拒否するので、
  「default noquery」でも良い。

# grep ignore /etc/ntp.conf
restrict -4 default ignore
restrict -6 default ignore

■nmapのntpスクリプト

# dpkg -L nmap | grep ntp
/usr/share/nmap/scripts/ntp-monlist.nse
/usr/share/nmap/scripts/ntp-info.nse

■「ntpdc -c sysinfo」の無効について
 以下のように「defalt ignore」と同様のルールをlocalhostに適用すると、
 「nmap」の「ntp-info」スクリプトも時刻情報も取得出来なくなる。

# sed -i s/"restrict 127.0.0.1"/"& ignore"/ /etc/ntp.conf

# grep 127.0.0.1 /etc/ntp.conf 
restrict 127.0.0.1 ignore

# ntpdc -c sysinfo
localhost: timed out, nothing received
***Request timed out

# nmap -sU -pU:123 -Pn -n --script=ntp-info localhost

Starting Nmap 6.00 ( http://nmap.org ) at 2014-03-16 00:53 JST
Nmap scan report for localhost (127.0.0.1)
Host is up.
PORT    STATE         SERVICE
123/udp open|filtered ntp

Nmap done: 1 IP address (1 host up) scanned in 7.14 seconds

■「noquery」にすると、時刻参照のみが出来る。
 ※外部からの時刻情報の参照を許可するなら、こちら。

# sed -i s/"\(restrict 127.0.0.1\) ignore"/"\1 noquery"/ /etc/ntp.conf

# grep 127.0.0.1 /etc/ntp.conf
restrict 127.0.0.1 noquery

# nmap -sU -pU:123 -Pn -n --script=ntp-info localhost

Starting Nmap 6.00 ( http://nmap.org ) at 2014-03-16 00:56 JST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00025s latency).
PORT    STATE SERVICE
123/udp open  ntp
| ntp-info: 
|_  receive time stamp: Sun Mar 16 00:56:29 2014

Nmap done: 1 IP address (1 host up) scanned in 5.17 seconds

■localhostの制限を元に戻す

# sed -i s/"\(restrict 127.0.0.1\) .*"/"\1"/ /etc/ntp.conf
# grep "restrict 127.0.0.1" /etc/ntp.conf 
restrict 127.0.0.1

■許可されている範囲での「MON_GETLIST」コマンド
 「-n」オプションをつければいくらか速い。

# time ntpdc -n -c monlist
remote address          port local address      count m ver rstr avgint  lstint
===============================================================================
192.168.0.10            2371 192.168.0.88        5106 3 4    180    585     463
133.243.238.164          123 192.168.1.253       2999 4 4    100    996     680
172.16.64.253           1026 192.168.0.88        1687 3 3    180   1771    3528
192.168.0.254            123 192.168.0.88          37 3 1    180  79994   17134
192.168.0.77             123 192.168.0.88          23 4 4    100 129951  175292
192.168.0.90             123 192.168.0.88          12 3 4    180 249023  696755

real	0m0.011s
user	0m0.000s
sys	0m0.004s

■名前解決までしようとすると、急激に遅くなる。

# time ntpdc -c monlist
remote address          port local address      count m ver rstr avgint  lstint
===============================================================================
192.168.0.10            2371 192.168.0.88        5106 3 4    180    585     504
ntp.nict.jp              123 192.168.1.253       2999 4 4    100    996     721
172.16.64.253           1026 192.168.0.88        1687 3 3    180   1771    3569
192.168.0.254            123 192.168.0.88          37 3 1    180  79995   17175
localntp1.localdomain    123 192.168.0.88          23 4 4    100 129953  175333
localntp2.localdomain    123 192.168.0.88          12 3 4    180 249027  696796

real0m15.081s
user0m0.004s
sys0m0.004s

■nmapでは以下のようになる。
 「Public Servers」以外は、上位のFWで制御しているのは言うまでも無い。

 File ntp-monlist
 http://nmap.org/nsedoc/scripts/ntp-monlist.html

# nmap -sU -pU:123 -Pn -n --script=ntp-monlist localhost

Starting Nmap 6.00 ( http://nmap.org ) at 2014-03-15 23:41 JST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00015s latency).
PORT    STATE SERVICE
123/udp open  ntp
| ntp-monlist: 
|   Target is synchronised with 133.243.238.164
|   Alternative Target Interfaces:
|       192.168.0.88    192.168.1.253   
|   Private Servers (1)
|       192.168.0.77    
|   Public Servers (1)
|       133.243.238.164 
|   Private Clients (5)
|       127.0.0.1       192.168.0.90    192.168.0.254   172.16.64.253   
|_      192.168.0.10    

Nmap done: 1 IP address (1 host up) scanned in 0.17 seconds

■system flagsから「monitor」の表示がなければ良い。
 「bclient」フラグがあって、実際に使っているなら設計を考え直した方が良い。

# ntpdc -c sysinfo | grep flags
system flags:         auth monitor ntp kernel stats 

■「disable monitor」による対処
 ※ローカルも信用しないというポリシーならば。

# man ntp.conf | grep -A 1 "disable \["
       disable [auth | bclient | calibrate | kernel | monitor | ntp  |  pps  |
       stats]

# echo "disable monitor" | tee -a /etc/ntp.conf ;/etc/init.d/ntp restart
disable monitor
[ ok ] Stopping NTP server: ntpd.
[ ok ] Starting NTP server: ntpd.

# ntpdc -c sysinfo | grep flags
system flags:         auth ntp kernel stats 

■対処後のローカルからのチェック

# ntpdc -c monlist 
***Server reports data not found

■nmapからも「open」しか判別出来なくなった。
 FWを通る端末からは「123/usp filter ntp」になる。

# nmap -sU -pU:123 -Pn -n --script=ntp-monlist localhost

Starting Nmap 6.00 ( http://nmap.org ) at 2014-03-16 00:40 JST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00015s latency).
PORT    STATE SERVICE
123/udp open  ntp

Nmap done: 1 IP address (1 host up) scanned in 0.14 seconds

■まとめ
 前提として、許可範囲の制限が適切に設定されているというのは、NTPに限らない。

■私の環境は内部のIPv4専用なので、IPv6では待ち受けていない。
 IPv6を使用していないなら、IPv4に制限する方法も検討した方が良い。

# grep OPTS /etc/default/ntp
NTPD_OPTS='-4 -g'

■外部から時刻情報を参照させない設定は下記
 参照を許可する内部のアドレスリストを適切に設定していること。
 ※IPv6の有効/無効に関わらず設定はする。

restrict -4 default ignore
restrict -6 default ignore

disable monitor

■外部から時刻情報のみを参照させる設定
 参照を許可する内部のアドレスリストを適切に設定していること。
 ※IPv6の有効/無効に関わらず設定はする。

restrict -4 default noquery
restrict -6 default noquery

disable monitor

■RHEL系の記事ですが、設定ポリシーの参考になります。

 NTP設定
 http://d.hatena.ne.jp/incarose86/20110505/1312522379