SV.USAGERULES.PERMISSIONS
特権昇格への露呈
一部の関数では、正しく実行するための特殊な権限が必要とされるか、特定のユーザーまたは特定グループのメンバーだけ (ローカル管理者など) が実行することができます。その他の関数では、ユーザーのアカウントで特定の権限 (システムリソースへのアクセスを取得する権限など) が有効にされることが必要とされます。たとえば、ネットワークサービスでは、権限 TCP または UDP ポートを割り当てるには、スーパーユーザー権限が必要とされることがよくあります。この作業は、普通のユーザーは行えません。
昇格された権限が必要となるのは一時的に過ぎない場合でも、多くのプログラムではそれらの昇格された権限が削除されずに残るので、不必要なルート権限で実行され続けます。
権限を削除するには、プロセスで有効なユーザー ID とグループ ID を権限度の低いユーザーまたはグループの ID に設定する必要があります。このとき、一時的に削除するにはシステム呼び出し seteuid() とsetegid()、恒久的に削除するには setuid() とsetgid() を使用します。
低権限プログラムが、高権限操作 (権限ファイルを開くなど) を実行する必要があるときは、setuid を使用して権限を昇格する必要があります。setuid 機能では、ルート権限で実行するユーザーとして実行可能ファイルを起動することができます。ここでも、プログラムが高権限操作の実行終了後すぐに低権限に戻らないことは珍しくありません。
SV.USAGERULES.PERMISSIONS チェッカーは、setegid()、seteuid()、setuid()、setregid()、setreuid() および AddAccessAllowedAce() または AddAccessAllowedAceEx() への権限昇格の呼び出しインスタンスを探し、レビューできるようにフラグを立てます。
脆弱性とリスク
無許可のコードが制御を取得できる可能性をできるだけ抑えるため、システムを必要最小限の権限で実行することをお勧めします。特殊な権限を必要とする関数を呼び出す必要があるアプリケーションは、システムをハッカーによる攻撃にさらしたままにする可能性があります。余計な権限で実行すると、オペレーティングシステムまたは環境での通常のセキュリティチェックが無効になる可能性があります。さらに、昇格された権限での操作中に、あらかじめ存在する弱点がセキュリティ脆弱性に変わります。アプリケーションを昇格された権限で実行するのは、短時間に制限し、関係するセキュリティへの影響をユーザーに通知する必要があります。
軽減と防止
アプリケーションを実行する必要があるのはどのタイプのアカウントなのかを確立するための最初の手順は、アプリケーションが使用するリソースおよびアプリケーションが呼び出す権限 API を調べることです。アプリケーションまたはその大部分で、管理者権限が必要ないことに気付くことがあります。Writing Secure Code (Michael Howard、David LeBlanc 共著) では、この評価を実行するための優れた説明が行われており、読むことを強くお勧めします。
悪意のある攻撃にできるだけさらさないようにするため、次の手法を採用してください。
- できるだけ権限度の低いアカウントで実行し、権限の昇格はできるだけ遅らせ、しかも必要最小限の昇格にとどめます。これを行う 1 つの方法は、トークンで有効にする権限を PrivilegeCheck で指定することです。使用できる権限が、現在の操作にふさわしくない場合、そのコードを無効にし、ユーザーに管理者権限のあるアカウントにログインするよう促すことができます。
- ユーザーがユーザー名とパスワードで適切に認証されていることを確認します。CredUIPromptForCredentials (GUI) または CredUICmdLinePromptForCredentials (コマンドライン) を呼び出してユーザー名とパスワードを取得して、ユーザーを認証します。
- ユーザーに成り済まします。システムなど、高権限アカウントで開始されるプロセスは、権限レベルを下げるために、ImpersonateLoggedOnUser や類似の成り済まし関数を呼び出すことで、ユーザーアカウントに成り済ますことができます。RevertToSelf の呼び出しをスレッドに挿入して、プロセスを元のシステム権限に戻します。
- 権限コードを分離します。管理者パーミッションを必要とする関数を複数の別々のアプリケーションに分散させます。
- 正しい廃止順序で権限を削除していきます。setuid プログラムと setguid プログラムの場合、グループレベルの権限を削除してからユーザーレベルの権限を削除することが重要です。
-
昇格された権限が正常に削除されたことを確認します。次の呼び出しからの戻り値をチェックすることが重要です。
- setuid
- setguid
- RpcImpersonateClient
- ImpersonateNamedPipeClient
- ImpersonateSelf
- SetThreatToken
- ImpersonateLoggedOnUser
- CoImpersonateClient
- ImpersonateAnonymousToken
- ImpersonateDdeClientWindow
- ImpersonateSecurityContext
プログラムが権限を操作しているときに、これらの関数のいずれかの呼び出しに失敗すると、権限が降格させられないことがあります。戻り値がチェックされず、適切なアクションが取られない場合、プログラムは権限アカウントで引き続き操作を続行することがあります。
外部参考資料
- CERT POS02-C: 最小権限の原則に従う
- CERT POS36-C: 権限放棄時に正しい廃止順序を守る
- CERT POS37-C: 権限が正常に放棄されたことの確認
- CWE-250: 不必要な権限での実行
- CWE-269: 不適切な権限管理
- CWE-273: 削除された権限の不適切なチェック
- CWE-732: 重要なリソースへの不正確なパーミッション割り当て
- OWASP A1:2021 アクセス制御の不備
- OWASP A4:2021 安全でないデザイン
- STIG-ID: APP3450.1 アクセス制御
- STIG-ID: APP3480.1 役割ベースのアクセス
- STIG-ID: APP3480.2 役割ベースのアクセス
- STIG-ID: APP3500 過剰な権限
- STIG-ID: APP3590.2 バッファオーバーフローに脆弱なアプリケーション
セキュリティトレーニング
Secure Code Warrior が提供しているアプリケーションセキュリティトレーニング教材。