実行順序から解き明かす、sudoコマンドの脆弱性(CVE-2019-14287)が発生した理由OSS脆弱性ウォッチ(16)(2/2 ページ)

» 2019年11月18日 05時00分 公開
[面和毅OSSセキュリティ技術の会]
前のページへ 1|2       

【Case3】「UID」が指定されている場合

1.UIDが#で指定されている場合は、/etc/passwdを確認してUIDからユーザー名に変換します。例えば/etc/passwdが下記のようになっている場合があるとします。

jsosug:x:1000:1000:,,,:/home/jsosug:/bin/bash

 この場合、下記のようにすると、まず/etc/passwdを参照して「#1000->jsosug」と変換してから処理を行います。

test@localhost:~$ sudo -u#1000 /bin/cat /home/jsosug/hidden

 以降は【Case1】【Case2】のときと全く同じになり、下記のように表示されます。

test@localhost:~$ sudo -u#1000 /bin/cat /home/jsosug/hidden
This is hidden file.
test@localhost:~$

2.一方で、UIDが/etc/passwdに載っていない場合には、そのままUIDをユーザー名として処理していきます。例えば「UID=10000」が/etc/passwdに登録されていないときに下記を実行すると、「#10000」をそのままユーザー名として処理を行います。

test@localhost:~$ sudo -u#10000 /bin/cat /home/jsosug/hidden

 そのため、【Case1】【Case2】のときと同様の処理になります。【Case2】の4.のようにsudoersがALLで許可されていれば、下記のようにuidをdetails->uid(今回の場合は引き渡されたUIDである#10000)、details->euid(今回の場合は引き渡されたUIDである#10000)を使ってsetresuid()を呼び出します。

203 #if defined(HAVE_SETRESUID)
204 	if (setresuid(details->uid, details->euid, details->euid) != 0) {
205     	sudo_warn(U_("unable to change to runas uid (%u, %u)"),
206         	(unsigned int)details->uid, (unsigned int)details->euid);
207     	goto done;
208 	}

3.ここで、UIDを10000として「/bin/cat /home/jsosug/hidden」を実行します。当然、/home/jsosugはUID=10000に許可を与えていないので、下記のようになり、エラーとなります。

test@localhost:~$ sudo -u#1000 /bin/cat /home/jsosug/hidden
/bin/cat: /home/jsosug/hidden: 許可がありません
test@localhost:~$

今回の脆弱性の説明

 今回の脆弱性では、sudoersにALLが設定されており、かつUIDとして#-1を与えたときの挙動から問題が発生しています。

1.UIDに#-1(または実質的に同じなである「4294967295」)を与えると、【Case3】のような挙動になります。また、ALLが設定されているため、一足飛びに下記が呼び出されます。

203 #if defined(HAVE_SETRESUID)
204 	if (setresuid(details->uid, details->euid, details->euid) != 0) {
205     	sudo_warn(U_("unable to change to runas uid (%u, %u)"),
206         	(unsigned int)details->uid, (unsigned int)details->euid);
207     	goto done;
208 	}

 ここで、setresuidの動作が問題となります。Linux Manページにある通り、uid、euidに-1を与えることは特別なことを意味しており、値が変更されません。

-rwsr-xr-x 1 root root 586560 10月 30 10:49 /bin/sudo

 上記でSUIDビットが立っていてrootで動作しているため、結果としてsudoコマンドの実行は、UID="#-1"を与えるとrootで動作してしまうことになり、下記のようにアクセスできてしまいます。

test@localhost:~$ sudo -u#-1 /bin/cat /home/jsosug/hidden
This is hidden file.
test@localhost:~$

 試しに、「/tmp」ディレクトリに「/bin/touch」コマンドで「hogehoge」というファイルを作成すると、下記のようにrootアカウントで作成できていることが分かります。

test@localhost:~$ sudo -u#-1 /bin/touch /tmp/hogehoge
test@localhost:~$ ls -l /tmp
合計 28
-rw-r--r-- 1 root test 	0 10月 31 20:21 hogehoge
drwx------ 3 root root   4096 10月 31 15:40 systemd-private-35f05b06f7dfcada1f10b15c20ac7-systemd-timesyncd.service-SDjQ

2.ここで、sudoersにALLが設定されていない場合にはどうなるでしょうか? ALLが設定されていないため、【Case1】の動作で#-1というユーザーで動作させたことになります。そのため、【Case1】の2.の箇所の処理を通り、/etc/sudoersに#-1という文字列が設定されていないため、最初まで/etc/sudoersを確認した後にDENY(0)が返されます。

 結果として下記のようになり、rootアカウントを取得することはできません。

test@localhost:~$ sudo -u jsosug /bin/cat /home/jsosug/hidden
残念ですが、ユーザー test は'/bin/cat /home/jsosug/hidden' を #-1 として localhost.localdomain 上で実行することは許可されていません。
test@localhost:~$

 以上のことから、今回の脆弱性は下記の状態でのみ、発生することが分かります。

  • UID="#-1"(または4294967295)でアクセスして
  • /etc/sudoersにALLが設定されている

脆弱性の修正

 今回の脆弱性の修正版では、UIDに#-1(または4294967295)を与えないようにするため、-1(または4294967295)を「EINVAL」とし、値で与えられた場合には「Error」として処理することにしてあります。これにより、setresuid()に-1を与えないようになっています。

今回の脆弱性の教訓

 sudoersの設定には、大まかに下記の2通りがあります。当然、2.の方がセキュリティは高くなります。

  1. ALLから権限が不要なユーザーを!を使って削除する
  2. 一つ一つ権限が必要なユーザーを追加する

 今回の脆弱性では、/etc/sudoersにALLを設定した場合が対象になっています。そのため、2.を選択していた場合には影響を受けませんでした。そういう意味では、もともとセキュリティを高く設定していたユーザーは賢い選択をしていたといえるでしょう。

 しかしながら、実環境下でsudoersを一つ一つ設定していくのは運用上かなりの負担となります(筆者もそういう環境下で運用を行った経験がありますが、ユーザーだけではなく新しいアプリを追加するなどの場合にも一苦労でした)。そういう意味では、バランスを取って運用しやすいsudoersの設定(つまり1.を選択)も相応のメリットがあると思います。

 いずれにせよ、今回の場合は1.と2.で結果が違ったのは「たまたま」であるため、運用では「小まめにパッケージの脆弱性が出たら更新を繰り返す」という基本的なことが大事になると思います。

筆者紹介

面和毅

略歴:OSSのセキュリティ専門家として20年近くの経験があり、主にOS系のセキュリティに関しての執筆や講演を行う。大手ベンダーや外資系、ユーザー企業などでさまざまな立場を経験。2015年からサイオステクノロジーのOSS/セキュリティエバンジェリストとして活躍し、同社でSIOSセキュリティブログを連載中。

CISSP:#366942

近著:『Linuxセキュリティ標準教科書』(LPI-Japan)」


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

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

メールマガジン登録

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