Cでポピュラーな脆弱性とバッファオーバーフロー(後編)もいちど知りたい、セキュアコーディングの基本(3)(2/2 ページ)

» 2013年02月19日 20時20分 公開
[戸田洋三(JPCERT/CC) ,@IT]
前のページへ 1|2       

バッファオーバーフローを修正する

 問題のコードは、コピー先のメモリ領域を16バイトしか用意していないのに、それを超えるサイズのデータをコピーしてしまう危険がありました。なぜそんなことになったのでしょうか?

 コピーするデータはネットマスク情報という4バイトのデータであり、dhclientでは、ネットマスクを収めるのに十分なだけのメモリ領域を用意していました(構造体sturct iaddr)。この部分には問題はなさそうです。

 一方、コピーするデータサイズは、サブネットマスクオプションに記載されているサイズ情報を使っていました。問題はここにあります。ネットワークの向こう側からやってきた情報は攻撃者によって細工されている可能性があると考えなければなりません。RFC2132にも、サブネットマスクオプションのLenフィールドの値は固定長の4であると書いてあったことを思い出しましょう。

 今回のバッファオーバーフローの問題を修正するには、コピーするデータサイズを適切な値にする必要があります。実際のネットマスク情報は4バイトのはずですから、コピー長も明示的に4とすべきでしょう。

 ISC DHCP 4.1.0p1で修正した後のコードは以下のようになっています。

void script_write_params (client, prefix, lease)
	struct client_state *client;
	const char *prefix;
	struct client_lease *lease;
{
	int i;
	struct data_string data;
	struct option_cache *oc;
	struct envadd_state es;
	......
	memset (&data, 0, sizeof data);
	oc = lookup_option (&dhcp_universe, lease -> options, DHO_SUBNET_MASK);
	if (oc && evaluate_option_cache (&data, (struct packet *)0,
					 (struct lease *)0, client,
					 (struct option_state *)0,
					 lease -> options,
					 &global_scope, oc, MDL)) {
		if (data.len > 3) {
			struct iaddr netmask, subnet, broadcast;
			/*
			 * No matter the length of the subnet-mask option,
			 * use only the first four octets.  Note that
			 * subnet-mask options longer than 4 octets are not
			 * in conformance with RFC 2132, but servers with this
			 * flaw do exist.
			 */
			memcpy(netmask.iabuf, data.data, 4);
			netmask.len = 4;
			data_string_forget (&data, MDL);
			......
dhcp-4.1.0p1/client/dhclient.cより

 ここでは確かに、memcpy()の第3引数を固定長4としています。また、RFC2132に従って、サブネットマスクオプションの4バイトのみをコピーすることをコメント部分で明記しています。

「外部からの情報は信頼しない」という鉄則

 今回はISC DHCPに発見されたスタックバッファオーバーフローの脆弱性について見てみました。

 問題の源は、サーバから受け取った情報をそのまま信頼して、コピーするデータ長として使っていたことにあります。プログラムの外部から与えられた情報は信頼するな、というのがセキュアコーディングの原則です。

 ここではサブネットマスク情報のサイズが問題でした。あるいは、コピー長として使う前に、仕様(RFC2132)に沿った値(の範囲)であるかどうかを確認する「入力値検査」を行っていれば、異常な値を検出してエラー処理できたはずです。

 みなさんも開発作業においては、

  • 扱っているデータは信頼できるものか? それとも信頼できない(攻撃者によって細工されている可能性のある)ものか?
  • 外部から入力されたデータを使う前に、想定している範囲の値かどうかを検査する

の2点を意識してコーディングすることをお勧めします。

参考文献

Dynamic host Configuration Protocol

http://ja.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol

RFC2131: Dynamic host Configuration Protocol

http://tools.ietf.org/html/rfc2131

RFC2132: DHCP options and BOOTP Vendor Extensions

http://tools.ietf.org/html/rfc2132

DHCP Stack Overflow in 'dhclient' script_write_params()

https://www.isc.org/software/dhcp/advisories/cve-2009-0692

JVNVU#410676: ISC DHCP dhclient におけるバッファオーバーフローの脆弱性

https://jvn.jp/cert/JVNVU410676/

YouTube Exploiting dhclient flaw CVE-2009-0692

http://www.youtube.com/watch?v=6gx14VVuPV0

CERT C セキュアコーディングスタンダード ARR33-C. コピーは必ず十分なサイズの記憶領域に対して行われることを保証する

https://www.jpcert.or.jp/sc-rules/c-arr33-c.html


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。