Cでポピュラーな脆弱性とバッファオーバーフロー(後編):もいちど知りたい、セキュアコーディングの基本(3)(2/2 ページ)
前回の説明に続き、今回はISC DHCPのソースコードをサンプルにして、スタックバッファオーバーフローが生じる仕組みと修正方法について説明します。
バッファオーバーフローを修正する
問題のコードは、コピー先のメモリ領域を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); ......
ここでは確かに、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
Copyright © ITmedia, Inc. All Rights Reserved.