SHOEISHA iD

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

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

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

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

Linuxのcrontabコマンドの脆弱性をつぶす

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


修正コード

 Fedoraのリポジトリで実際に行われた修正を見てみましょう。

修正された edit_cmd()
static void edit_cmd(void) {

......省略......

  fclose(f);
  if (fflush(NewCrontab) < OK) {
    perror(Filename);
    exit(ERROR_EXIT);
  }
+ if (swap_uids() == -1) {
+   perror("swapping uids");
+   exit(ERROR_EXIT);
+ }
  /* Set it to 1970 */
  utimebuf.actime = 0;
  utimebuf.modtime = 0;
  utime(Filename, &utimebuf);
+ if (swap_uids_back() == -1) {
+   perror("swapping uids");
+   exit(ERROR_EXIT);
+ }
again:
  rewind(NewCrontab);
  if (ferror(NewCrontab)) {
      fprintf(stderr, "%s: error while writing new crontab to %s\n",
                      ProgramName, Filename);
    fatal:
      unlink(Filename);
      exit(ERROR_EXIT);
  }

......省略......

done:
}

 行頭に「+」をつけた部分が修正によって追加された部分です。プロセスの権限を一般ユーザ権限に落としてからutime()を実行しています。プロセスの実行権限を一般ユーザ権限に落しておけば、symlink攻撃を受けたとしても、システムファイルまでいじられる危険がなくなるというわけです。もちろん、当該ユーザの権限でいじれるものについては、これでは保護できていないことに注意が必要です。この修正は、symlink攻撃に対処するための最小限の修正だけを行なったものと理解すべきでしょう。

 そもそもこのコードには、以下のような問題点があります。

  • 一時ファイルのタイムスタンプをわざわざ0に設定している

    タイムスタンプは編集作業によって更新されるので、ファイルが更新されたかどうかをチェックするには、生成時点のタイムスタンプを保存しておくだけでいいはずです。

  • utime()によるファイル名文字列を使ったファイル操作

    ファイルの中身をコピーするためにFILEポインタを使い、タイムスタンプを設定するためにファイル名文字列を使っています。ファイル名文字列を使ったファイル操作を行う場合には、今回のような競合状態が発生する危険があることに注意する必要があります。ファイル名文字列を使った操作は最小限にすること、また、ファイルをopenしたら、そのときに得られたFILEポインタやファイル記述子だけを使って操作を行うように心がけましょう。ファイルのタイムスタンプを設定するにはファイル名文字列を使ってutime()関数を使うしかありませんが、幸いにも今回のコードではタイムスタンプを設定する必要はありません。編集前のタイムスタンプを保存し、編集後のタイムスタンプと比較するような形にしたほうがより安全になります。

  • root権限の使用(setuid root)

    個々のユーザのcrontab(5)ファイルを保護するために、パーミション設定によるディレクトリの保護と、crontab(1)コマンドにおける権限管理を行なっていました。しかし、root権限はそのシステム上でなんでもできてしまうので、できるだけ使わないほうが望ましいのです。このような場合は、専用のユーザアカウントをひとつ設けて権限管理を行うことで、Cronに脆弱性があった場合でもシステムの他の部分への侵害を最小限に止めることが期待できます。

よりセキュアなcrontab(1)コマンド

 Vixie Cronバージョン4、あるいはDebian/GNU Linuxや*BSDなどに取り込まれているCronのコードを調べてみると、上記に説明したような形で、よりセキュアなコードになっていることが分かります。また、権限管理もroot権限を使う代わりに、crontabという専用グループを設ける形で行っています。2種類のコードを比較してみることをお勧めします。

 今回紹介した、ファイルの扱いやプロセスの権限管理に関連したガイドラインとして、セキュアコーディングスタンダードには、POS02-CFIO01-Cといったレコメンデーションがあります。こちらもぜひ参考にしてみてください。

参考情報

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

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
実例で学ぶ脆弱性対策コーディング連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/5360 2010/08/19 12:03

イベント

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

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

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

メールバックナンバー