SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

実例で学ぶ脆弱性対策コーディング

Samba smbclient―書式指定文字列に潜む脆弱性

実例で学ぶ脆弱性対策コーディング 第4回

  • X ポスト
  • このエントリーをはてなブックマークに追加

コードに潜む脆弱性の解説

 今回のコードに潜む脆弱性は書式指定文字列に関する脆弱性です。talloc_asprintf_append()の使い方に問題があります。この関数の型を確認してみましょう。

char *talloc_asprintf_append(char *s, const char *fmt, ...);

 「...」という部分は何かを省略しているわけではなく、実際にこのように記述します。そう、printf()を代表とする可変引数関数です。プロトタイプ宣言と一緒に引用したコメントにも書いてあるように、talloc_asprintf_append()は、第2引数の書式指定文字列を使って第3引数以降で指定されるデータを整形した文字列を、第1引数のsが示す文字列の後ろに連結した文字列を生成します。

 talloc_asprintf_append()の呼び出しでは、第2引数のfnameはユーザーが入力した文字列から取ってきています。ここにはユーザーが指定したファイル名が入っているわけですが、talloc_asprintf_append()では、第2引数は書式指定文字列だと想定しています。

 では、ユーザーが「get aa%sbb」のような入力を行って書式指定子「%s」を含むファイル名を与えたらどうなるでしょうか? talloc_asprintf_append()はその後ろに「%s」にはめこむべき文字列引数が置いてあるものとしてアクセスしにいくでしょう。しかし、実際の呼び出しは第2引数までしかありません。このコードでは、スタックに残されていたデータを勝手に「%s」の部分にはめこんで処理することになります。

 この問題は「書式指定文字列の脆弱性」として知られています。一般にプログラムで使われている書式指定文字列を自由に操作できる場合、スタックに積まれている値を調べることが可能です。また、メモリアドレスを指定してその値を調べたり、さらには任意のメモリアドレスに指定した値を書き込んだり、入力に潜ませたコードを実行させることが可能になることもあります。

 今回紹介したコードでは、smbclientプログラムへの入力を処理する部分の問題であり、コマンドラインからsmbclientを起動して使う通常の使用では問題にならないと思われます。しかし、自動化スクリプトやWebアプリケーションのなかからsmbclientを呼び出しているようなケースの場合、外部からの攻撃に悪用される危険性は十分に考えられます。

 Sambaでは3.2.13でこの問題を修正しています。修正はいたって簡単。書式指定文字列を明示的に与えるだけです。

samba-3.2.13 における修正
-    remote_name = talloc_asprintf_append(remote_name, fname);
+    remote_name = talloc_asprintf_append(remote_name, "%s", fname);

 この修正により、書式指定文字列として解釈されるのは「%s」となり、fnameはそこにはめこまれるためにだけ使われるようになります。

 なお、cmd_get()から呼び出される関数のなかで、d_printf()もtalloc_asprintf_append()と同様の可変引数関数として定義されており、書式指定文字列を引数に取ります。

int d_printf(const char *format, ...);

 しかし、実際の呼び出しでは、外部入力に左右されない文字列リテラルを書式指定文字列として引数に渡しているため、悪用される心配はありません。

終わりに

 書式指定文字列の問題は、1999年ころから広く知られるようになり、printf()やsyslog()関数を使う多くのアプリケーションがこぞって修正を行いました。

 今回のような問題を作りこまないようにするには、プログラム中で使われる書式指定文字列を外部からの入力で操作されないようにすることが必要です。セキュアコーディングスタンダードでは、「FIO30-C.ユーザーからの入力を使って書式指定文字列を組み立てない」というルールがあります。こちらも一度眺めてみてください。

参考文献

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
実例で学ぶ脆弱性対策コーディング連載記事一覧

もっと読む

この記事の著者

戸田 洋三(JPCERT コーディネーションセンター)(トダ ヨウゾウ(JPCERT コーディネーションセンター))

リードアナリストJPCERTコーディネーションセンター東京工業大学情報理工学研究科修士課程修了。学生時代は、型理論および証明からのプログラム抽出を研究。その後、千葉大学総合情報処理センターのスタッフとして、学内ネットワークの運営、地域ネットワーク、IPマルチキャストの実験ネットワークであるJP-MB...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5229 2010/06/22 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング