あるプログラムには機密ファイルを読み取る権限があり、別の利用者にはそのプログラムの設定ファイルを書き換える権限だけがあるとする。設定ファイルには読み取り対象と送信先を指定できる。プログラムが設定内容をそのまま処理に反映する設計なら、利用者は機密ファイルを直接開けなくても、その内容を外部へ送信させられる。OS のアクセス制御は、利用者による機密ファイルへの直接アクセスを拒否し、プログラムによる読み取りを許可しているため、設定された規則どおりに機能している。それでも、機密ファイルの内容が、本来その情報を取得できない主体の指定した宛先へ送信される可能性がある。
この現象を理解するには、権限を保有する主体、操作内容を指定する主体、実際に処理を実行する主体の役割を区別する必要がある。機密ファイルの読み取り権限を持つのはプログラムであり、読み取り対象と送信先を決めるのは設定ファイルを変更できる利用者である。実際のファイル操作もプログラムが実行する。権限を保有する主体と実行する主体が一致していても、操作内容を指定する主体は別に存在し得る。プログラムが設定内容を解釈してファイル操作へ変換することで、利用者の設定変更が、プログラムの権限を用いた処理につながる。
ただし、設定ファイルを変更できることが、常に機密情報の取得を可能にするわけではない。プログラムが読み取り可能なファイルを業務上許可された範囲に限定し、送信先についても独立した許可条件を適用していれば、利用者が任意のパスや宛先を指定しても、そのまま実行されるとは限らない。反対に、設定値を検証せず、プログラム自身の権限で処理する場合には、設定ファイルの変更権限が、機密ファイルの読み取りや外部送信を間接的に実行させる能力へつながる。両者の違いは、利用者やプログラムに直接付与された権限よりも、設定を解釈する処理と、実行前に適用される制約によって生じる。
さらに、この関係には時間的な側面がある。ある時点では設定ファイルに正当な読み取り対象と送信先が記録され、プログラムが正常に動作しているとする。その後、設定を書き換えられる主体が内容を変更すれば、プログラムの実行ファイルや OS の権限設定が変わらなくても、実際に実行される操作は変化し得る。設定ファイルの変更が直ちに反映されるのか、再読み込みや再起動によって反映されるのかによって、操作が実行可能になる時点も異なる。ある時点の権限一覧だけでは、外部入力の変更後に成立する操作経路まで確定できない。
権限境界の安全性を評価するには、各主体へ直接与えられた権限に加えて、外部入力から実行可能になる操作経路、その経路の成立条件、実行結果を観測できる範囲を調べる必要がある。ある操作を実行できること、実際に実行したこと、その操作が記録に残ることは、それぞれ異なる。実行経路が成立した時点と異常が検出された時点に差があれば、その間に操作が繰り返される可能性もある。さらに、外部の設定やコードを修復しても、既に読み込まれた内容や端末上に保存された状態が残る場合には、修復前の影響が継続し得る。
このようなシステムでは、権限境界を静的な設定値として確認する方法と、入力、状態、観測、介入によって実行可能な操作が変化する構造として評価する方法を区別できる。後者では、どの操作経路が成立しているかだけでなく、どの条件によって成立し、どの操作によって遮断されるかが評価対象になる。この見方は、構造をグラフと時間発展によって記述する構造振動モデルにも接続する。ただし、構造自体が変化した量と、同じ構造の下で外部入力に応じて変化した操作到達可能性は、異なる量として扱う必要がある。権限設定が不変であっても実行可能な操作が変化するという事実は、その区別を必要とする具体的な理由である。
1. 権限を持つ主体と操作を引き起こす主体
利用者 A には設定ファイルの変更だけを許し、機密ファイルの読み取りを拒否する。プログラム P は業務上の必要から機密ファイルを読み取れ、同時にネットワーク通信もできる。例えば、P が定期的に文書を外部の保管先へ送信する業務を担っているとする。設定ファイルには、送信する文書のパスと送信先のアドレスが記録されている。A はこの設定を管理できるが、機密ファイルを直接読み取る権限を持たない。ここで P が設定ファイルに記録されたパスを読み取り、対象ファイルを開いて、指定されたアドレスへ内容を送信する処理を実装している場合、A は設定値を変更することで送信対象と送信先を決定できる。
A が機密ファイルを直接開こうとすれば、OS のアクセス制御によって拒否される。一方、P が同じファイルを開く場合には、P の実行権限によって読み取りが許可される。A が設定ファイルへ機密ファイルのパスを書き込み、その設定を P が読み込んでファイルを開くと、OS から見たファイルアクセスの主体は P となる。さらに、P が読み取った内容を設定された送信先へ転送すれば、A は機密ファイルを直接読むことなく、その情報を取得できる可能性がある。A に新しいファイルアクセス権限を付与する操作は必要ない。既に存在する P の権限と、A が変更できる設定値が組み合わされることで、この経路が成立する。
この構成では、ファイルの読み取り、送信先の指定、通信という処理を、それぞれ別の条件で評価する必要がある。P に機密ファイルの読み取りを許可する理由は、P が担当する業務にある。しかし、P が機密ファイルを読み取れることから、設定ファイルに記載されたすべての読み取り対象と送信先が正当であるとは導けない。設定内容を指定した A に、対象文書を選択する権限や、指定した宛先へ情報を送信させる権限があるかを確認する必要がある。P が設定値を無条件に受け入れる場合、プログラムに対する操作の要求が、要求元の権限を評価されないまま実行へ進むことになる。
| 対象 | 直接与えられた権限・役割 | 間接的な操作との関係 | 確認すべき条件 |
|---|---|---|---|
| 利用者 A | 設定ファイルを変更できる。機密ファイルの直接読み取りは許可されていない。 | 読み取り対象と送信先を設定することで、P に実行させる処理の内容を指定できる。 | A がどの対象と送信先を指定することまで許可されているかを確認する。 |
| プログラム P | 業務上必要な機密ファイルの読み取りとネットワーク通信が許可されている。 | A が指定した設定内容を解釈し、自身の権限を用いてファイル操作と通信を実行する。 | 設定値から実行する操作を決める際、要求元と操作対象の許可条件を検証するかを確認する。 |
| 設定ファイル | A が変更でき、P が読み込む情報である。 | 読み取り対象と送信先を指定する入力として、P の実行内容に影響する。 | 指定できる項目、値の制約、読み込み時点、変更内容の反映条件を確認する。 |
| 機密ファイルの外部送信 | 読み取りと通信の両方が成立した場合に実行される操作である。 | P の権限を利用して、A に直接許可されていない情報取得が成立する可能性がある。 | 送信対象、送信先、操作要求元の組み合わせが許可範囲に含まれるかを確認する。 |
表の各項目では、直接の権限設定が成立していることを前提としている。A は設定ファイルを変更でき、P は機密ファイルを読み取れる。この二つの条件だけでは、機密ファイルの外部送信が A に許可された操作かどうかは決まらない。さらに、P が設定内容をファイル操作へ変換することと、送信先が A の指定に従って決定されることが組み合わさって、情報の取得経路が成立する。この経路を制約するには、設定ファイルへの書き込み権限だけでなく、P が実行する個々の操作について、対象と宛先の妥当性を判断する仕組みが必要になる。
OS のアクセス制御と監査の役割も、この構成では区別される。ファイルアクセスの監査記録には、対象ファイルを開いたプロセスや、その実行に使用された利用者の権限が記録される場合がある。しかし、設定ファイルを書き換えた主体や、設定変更が処理へ反映された時点まで記録されているとは限らない。P が機密ファイルを読み取ったという記録だけでは、その読み取りが業務上の正当な要求によるものか、A が変更した設定によって引き起こされたものかを判別する材料が不足する。操作の経緯を追跡するには、設定の変更者、変更前後の値、P による読み込み、実際のファイルアクセスと通信を、対応付けられる形で記録する必要がある。
既稿「認可の安全性は権限の成立時点まで定義する」は、操作によって新しく成立する権限を操作前の認可判断へ持ち込むことで、許可判定に循環が生じる条件を分析した[1]。その場合、認可規則が正しくても、判定に使用する権限状態の時点によって結果が変わる。一方、利用者 A とプログラム P の例では、権限状態を同じ時点で評価しても、操作を指定する主体と実行する主体の違いから問題が成立する。A に機密ファイルの読み取り権限がないという事実と、P にその権限があるという事実は、どちらも正しい。両者の間に、A の指定を P の操作へ変換する処理が存在することが、直接の権限設定からは読み取れない実行能力を生んでいる。
Saltzer と Schroeder が整理した最小権限の原則は、プログラム P に与える権限を、担当する処理に必要な範囲へ限定するための基礎になる[2]。P にネットワーク通信が不要であれば、その権限を取り除くことで外部送信の経路を制約できる。しかし、業務上、機密ファイルの読み取りと外部送信の両方が必要な場合には、P の権限を削減するだけでは業務要件を満たせない。P が読み取ってよいファイルの範囲、送信してよい宛先、設定内容を変更した主体に許可される操作を、それぞれ定義する必要がある。プログラムが持つ権限の上限を制限することと、その権限をどの要求に対して行使するかを判定することは、異なる制御である。
この例から、権限境界を評価する対象は、利用者とファイルの直接的なアクセス関係から、利用者、設定情報、プログラム、保護対象、送信先をつなぐ操作経路へ広がる。外部の主体が変更できる情報が、どの処理で解釈され、どの権限を用いた操作へ変換されるかによって、間接的に実行させられる操作の範囲が決まる。設定ファイルの変更者が同じでも、P の解釈処理や検証条件が異なれば到達可能な操作は変わる。反対に、P の実行機構と権限設定を固定しても、設定内容の変更によって実行される操作が変化し得る。権限の成立条件を正確に捉えるには、直接の権限関係と、その権限を利用する実行経路を分けて記述する必要がある。
2. 外部情報が命令として扱われる条件
外部から変更できる情報が、プログラムの実行能力へ結び付くかどうかは、その情報を受け取った処理によって決まる。例えば、利用者が画面の見出しを変更できる場合、入力された文字列が画面へ表示されるだけなら、変更者が制御できるのは表示内容である。一方、同じ文字列をファイルパスとして解釈し、指定されたファイルを開く処理へ渡せば、変更者は読み取り対象を選択できる。さらに、その文字列を OS のコマンドとして実行する処理へ渡せば、プログラムが持つ実行権限の範囲で、より多くの操作へ到達する可能性が生じる。入力を変更できるという条件が同じでも、入力を利用する処理が異なれば、変更者が引き起こせる操作も異なる。
この違いは、入力された文字列が処理に渡されるまでの経路を調べると明確になる。画面表示のために受け取った文字列が表示機能にだけ渡される構成では、文字列の内容は表示結果を決める。ファイルの読み取り対象として利用される構成では、文字列の内容がファイルを選ぶ条件となり、プログラムがそのファイルへアクセスする。外部入力の内容が、プログラムの権限を用いた操作の引数として利用されることで、情報の変更が操作対象の変更へつながる。外部から受け取った情報が直接実行される場合に加え、情報が既存の機能の引数や実行条件を変更する場合にも、間接的な実行能力が成立する。
外部情報の形式だけでは、この関係を判断できない。文字列、JSON、JavaScript は情報の表現方法として異なるが、実際にどの操作が成立するかは、受け取る側の解釈と実行機構に依存する。JSON 形式の設定値であっても、プログラムが任意の送信先を受け入れ、読み取った情報をその宛先へ転送するなら、設定を変更できる主体は情報の送信先を制御できる。反対に、JavaScript を実行する構成であっても、実行環境が隔離され、利用できる関数や資源へのアクセスが制限されていれば、コードが実行できる操作はその制約を受ける。実行コードであることと、OS 上の任意の操作を実行できることは、別々の条件である。
入力の変更がどこまでの操作へつながるかを判断するには、少なくとも入力を変更できる主体、入力として許される値、入力を解釈する機能、その機能が利用できる権限を対応付ける必要がある。例えば、ログファイルの保存先を指定できる設定で、保存先があらかじめ決められたディレクトリ内に制限されている場合、変更者が選択できる出力先はその範囲内に収まる。一方、任意のファイルパスを指定でき、プログラムが自身の権限でその場所へ書き込む場合には、変更者が直接書き込めないファイルを上書きできる可能性がある。設定値の検証条件と、実際のファイル操作に使用される権限の組合せが、両者の結果を分ける。
| 外部情報の用途 | プログラム側の解釈 | 変更者が制御できる操作 | 操作範囲を決める条件 |
|---|---|---|---|
| 画面の見出し | 文字列を表示内容として使用する。 | 表示される文字列を変更できる。 | 入力された文字列が表示以外の機能へ渡されるかどうかで決まる。 |
| ログの出力先 | 設定値をファイルパスとして解釈し、書き込み処理へ渡す。 | ログを書き込むファイルやディレクトリを選択できる。 | 許可された保存先の範囲、パスの検証、プログラムの書き込み権限によって決まる。 |
| ネットワークの送信先 | 設定値を通信先として解釈し、送信処理へ渡す。 | プログラムが送信する情報の宛先を指定できる。 | 送信対象の情報、許可された宛先、通信を実行する権限によって決まる。 |
| 外部スクリプト | 取得したコードを実行環境で解釈し、利用可能な関数を呼び出す。 | コード内の処理と、実行環境を通じて呼び出せる操作を指定できる。 | コードの完全性確認、実行環境の隔離、公開された関数、資源へのアクセス制限によって決まる。 |
表に示した四つの例では、入力の変更者に与えられた直接の権限と、入力の変更によって実行させられる操作の範囲が異なる。特に、ファイルパスと送信先の指定は、入力そのものをプログラムとして実行する処理を必要としない。プログラムにあらかじめ実装されたファイル操作や通信機能が、外部から指定された値を使って実行されるためである。変更者が制御できる入力の範囲が広く、その値に対する検証が不足しているほど、プログラムの持つ権限を利用して操作させられる対象も広がり得る。ただし、入力値の自由度だけで操作範囲が決まるわけではなく、実行時の権限と処理上の制約を合わせて確認する必要がある。
MITRE の CWE-829 は、信頼境界の外側から実行機能を取り込み、適切な制御を行わないことで生じる弱点を分類している[3]。外部から取得したスクリプトを実行する構成では、取得先の資源を変更できる主体が、プログラムの処理内容に影響する可能性がある。例えば、正規の配信元から取得するスクリプトであっても、その配信元に置かれたファイルが第三者によって改ざんされれば、受け取るプログラムが解釈するコードは変化する。取得先が正規であることと、取得した内容が期待したコードと一致することは、異なる検証条件である。さらに、期待したコードと一致していても、そのコードが利用できる内部機能と実行権限については別の制約が必要になる。
ここでは、外部情報を制御できる主体と、その情報を実行する主体の間にある信頼境界が関係する。外部情報を受け取るプログラムが、自身に許可された操作をすべて外部コードから呼び出せるようにしていれば、外部コードの変更者が利用できる操作範囲も広がる。一方、外部コードから呼び出せる関数を限定し、個々の要求について操作対象と実行権限を確認すれば、コードが変更されても実行可能な操作を制約できる。外部資源の完全性を確認する仕組みと、実行時に許可する操作を限定する仕組みは、異なる段階で作用する。前者は想定外のコードを取り込むことを防ぎ、後者は取り込まれたコードが利用できる権限の範囲を決める。
入力内容を変更できることが実行能力へつながる条件は、情報の形式、解釈処理、呼び出し可能な機能、実行時の権限という関係から説明できる。表示専用の文字列を変更する場合には、表示機能が操作範囲を限定する。ファイルパスや送信先を指定する場合には、既存の機能が外部入力を操作対象へ変換する。外部スクリプトを実行する場合には、実行環境から利用できる関数が操作範囲を決める。いずれも、外部情報の変更者が直接持つ権限だけでは、実行可能な操作の全体を把握できないという点で共通する。権限を持つプログラムが外部入力をどの操作へ変換し、その操作を誰の要求として認可するかが、間接的な権限行使の成立条件となる。
3. 正規プログラムを介した権限の行使
権限を持つプログラムが別の主体の要求を代理で処理する場合、プログラム自身に与えられた権限と、要求元に認められた操作範囲を区別する必要がある。例えば、あるサービスに機密ファイルの読み取り権限が与えられていても、そのサービスを利用するすべての利用者が機密ファイルの内容を取得してよいとは限らない。サービスが要求元の権限を確認せず、受け取った要求を自身の権限で実行する設計なら、本来は利用者に許可されていない操作が成立する可能性がある。ここでは、権限を持つプログラム自体が正規のものであり、OS のアクセス制御も設定どおりに機能している。それでも、プログラムが誰の要求に基づいて権限を行使するかを判断する処理に不足があれば、権限の利用目的が変わってしまう。
Norm Hardy が示した Confused Deputy の問題は、権限を持つ仲介者が、ほかの主体から受け取った要求を処理する際に、どの権限を使用すべきかを適切に区別できず、本来の目的とは異なる操作を実行してしまう構造を説明する[4]。仲介者自身には、その操作を実行する正当な権限がある。しかし、要求元がその権限を利用してよいかという判断は、仲介者の権限が存在することだけでは確定しない。MITRE の CWE-441 も、意図しない代理処理や仲介処理を通じて権限が悪用される弱点を分類している[5]。この分類で焦点となるのは、権限を持つ仲介者が要求を受け取り、その要求を実行する際に、要求元の権限と仲介者自身の権限をどのように扱うかという関係である。
具体例として、バックアップサービス P が、複数の利用者の文書を保管するために機密ファイルの読み取り権限を持っているとする。一般利用者 A は、自分に許可された文書のバックアップを P に要求できる。P には、指定されたファイルを読み取り、指定された保管先へ転送する機能が実装されている。通常の処理では、A が自分の文書を指定し、P がその文書を読み取って保管先へ送信する。この処理は、A に認められた操作を P が代理で実行するものであり、業務上の必要性がある。
ところが、P が要求されたファイルのパスと送信先だけを受け取り、その組合せが A に許可されているかを確認しない場合、A は自分には読み取れない機密ファイルを指定できる。P は自身に与えられた権限でそのファイルを開き、要求された送信先へ内容を転送する。A が機密ファイルへ直接アクセスすれば OS に拒否されるが、P による読み取りは許可される。ここでは、P が持つ正当な読み取り権限と、A が指定した操作対象が結び付けられることで、A の直接権限を超える結果が生じる。P の権限が新たに拡大されたのではなく、既に存在する権限を利用する要求の範囲が適切に制約されていないのである。
この例で必要なのは、バックアップサービス P が機密ファイルを読めるかという確認に加え、利用者 A がそのファイルのバックアップを要求できるかという確認である。さらに、送信先を自由に指定できる機能があるなら、A がその送信先へ文書を転送させてよいかも判断しなければならない。ファイルの読み取りとネットワーク通信がそれぞれ許可されていても、特定の文書を特定の宛先へ送信するという組合せが正当であるとは限らない。操作の正当性は、実行するプログラム、要求元、操作対象、送信先、処理目的の関係によって決まる。
| 確認対象 | バックアップサービスでの具体例 | 確認が不足した場合の結果 |
|---|---|---|
| 要求元の識別 | バックアップを要求した利用者が A であることを確認する。 | どの利用者の権限に基づいて要求を判断するかが不明確になる。 |
| 読み取り対象の認可 | A が指定した文書をバックアップする権限を持つか確認する。 | A に直接許可されていない機密ファイルを P に読み取らせる経路が成立する。 |
| 送信先の認可 | 指定された保管先が、その文書について許可された宛先か確認する。 | 読み取りが許可された文書であっても、許可されていない宛先へ送信される可能性がある。 |
| 実行に使用する権限 | P が業務上必要な読み取りと通信の権限だけを使用する。 | P が利用できる余分な機能や資源まで、要求処理を通じて利用される可能性が生じる。 |
| 処理の記録 | 要求元、操作対象、送信先、認可結果、実行結果を対応付けて記録する。 | P がファイルを読み取った事実は確認できても、誰の要求によって実行されたかを追跡しにくくなる。 |
表の各条件は、互いに代替できるものではない。要求元を正しく識別しても、その利用者に指定ファイルの読み取りを要求する権限があるとは限らない。また、読み取り対象が許可されていても、送信先の制約がなければ、情報が本来想定していない場所へ移動する可能性がある。P に与える権限を最小限に抑えることは、代理処理を通じて利用され得る操作の上限を制約する。一方、要求ごとの認可は、P が実行できる操作のうち、どの操作を特定の利用者のために実行してよいかを決定する。両者を組み合わせることで、サービスの業務上必要な機能を維持しながら、要求元による権限の利用範囲を限定できる。
この構造を OS の特権昇格と区別することも必要である。特権昇格では、一般に攻撃者の処理が、それまで許されていなかった権限を取得することが問題になる。一方、バックアップサービス P の例では、A 自身の権限設定は変更されず、P の実行権限も変化していない。変わるのは、A の要求によって P が実行する操作である。A は直接利用できない資源に対して、P を経由した操作を成立させている。この関係は、直接のアクセス権限と間接的に行使させられる操作を区別することで説明できる。
外部スクリプトから正規プログラムの内部 API を呼び出せる構成にも、権限を持つ実行主体を別の主体が利用するという共通点がある。例えば、外部から取得したスクリプトが、ランチャー内部のファイル操作機能を呼び出せる場合、そのスクリプトの内容を変更できる主体は、ランチャー自身の権限を用いた処理に影響を与えられる。ただし、この構成が Confused Deputy に該当するかは、要求元の権限をどのように識別し、どの権限を選択して実行する設計なのかによって決まる。外部コードが実行されること自体は、信頼境界の外側から実行機能を取り込む問題としても評価できる。どの分類に該当するかより先に、外部の主体が制御できる処理と、正規プログラムが持つ権限との接続を明らかにする必要がある。
権限を持つ仲介者が一つの場合には、要求元、実行主体、操作対象の関係を直接追跡できる。仲介者が複数ある場合には、要求の処理過程で、要求元の識別情報や認可条件がどのように引き継がれるかが問題になる。例えば、利用者 A の要求をサービス P が受け取り、P が内部サービス Q にファイルの読み取りを依頼する構成を考える。Q が P からの要求であるという理由だけで処理を許可すれば、A に許可された操作範囲が Q の認可判断に反映されない可能性がある。P と Q の間で通信が正規に認証されていることは、A が要求した操作の正当性を保証するものではない。
複数の仲介者を経由する構成では、各サービスが持つ権限に加え、要求がどの主体に由来し、途中でどの操作へ変換され、最終的にどの資源へ到達するかを調べる必要がある。要求元の権限が途中で失われる場合や、上流サービスに与えられた信頼が下流サービスで無条件に適用される場合には、個々のサービスの権限設定が正しくても、結合された経路を通じて許可範囲外の操作が成立し得る。権限境界は、各プログラムの内部に設定された規則だけでなく、プログラム間で要求と権限がどのように結び付けられるかによって決まる。
4. 複数の機能を経由した操作の到達可能性
外部から変更できる情報をプログラム P が受け取り、P が内部機構 Q を呼び出し、Q が OS のファイル操作 F を実行する構成を考える。利用者 A には F を直接呼び出す権限がない。一方、P は外部から与えられた設定を読み取り、Q は必要な権限を用いてファイルを操作できる。A が設定を書き換えることで P の処理内容を変更し、その結果として P が Q にファイルの読み取りを依頼するなら、A は自身に許可されていない操作を間接的に実行させられる可能性がある。この関係では、A が制御できる入力から、P の処理、Q の機能、F の実行までが一つの経路として結び付いている。
例えば、P が設定ファイルから読み取り対象のパスを取得し、その値を Q に渡すとする。Q は指定されたファイルを開き、内容を P に返す。P は受け取った内容を、設定ファイルに記載された送信先へ転送する。この構成で A が読み取り対象と送信先の両方を指定できれば、A は P と Q が持つ機能を組み合わせて、機密情報を外部へ移動させられる場合がある。A が実行している操作は設定ファイルの変更であり、実際のファイル読み取りは Q、通信は P が担当する。個々の処理は、それぞれのプログラムに与えられた権限で実行される。しかし、読み取り対象と送信先を決める入力の制御者が A であるため、処理全体の結果は A の指定に依存する。
ただし、A から P、P から Q、Q から F という呼び出し関係を図に描くだけでは、この経路が実行可能であることの証明にはならない。P が受け付ける入力の形式、Q が要求する引数、F を実行する際の権限、処理を開始するための状態が、それぞれ満たされる必要がある。例えば、P が Q を呼び出す機能を持っていても、A が変更できる設定値によってその呼び出しを選択できなければ、A から Q への操作経路は成立しない。また、Q が任意のファイルを読み取る機能を持っていても、P が Q に渡せる引数を固定していれば、A が読み取り対象を自由に選ぶことはできない。呼び出し可能な機能の存在と、外部主体がその機能を指定した引数で実行させられることは、異なる条件である。
経路を評価する際には、各処理で受け取った値が、次の処理へどのように渡されるかも確認する必要がある。例えば、A が入力したファイルパスを P が検証し、その後に Q へ渡す構成では、P の検証によって読み取り対象が制約される。しかし、P が許可済みディレクトリ内のファイルだけを受け付ける設計であっても、Q が別の基準でパスを解釈する場合には、P が確認した対象と Q が実際に開く対象が一致するとは限らない。シンボリックリンクをたどる処理や、相対パスを絶対パスへ解決する処理によって、最終的な参照先が変わる場合もある。入力値の検証が存在するという事実に加えて、検証した対象と実際に操作される対象が一致することが、経路の制約条件となる。
さらに、各機能の呼び出し条件が個別には満たされていても、それらが同じ実行過程で同時に成立するとは限らない。Q が機密ファイルを読み取れる状態と、P が外部へ通信できる状態が異なる場合、読み取りと送信を連結できないことがある。P が取得したファイル内容を通信処理へ渡さず、固定された集計結果だけを送信する実装であれば、読み取り機能と通信機能が存在しても、機密ファイルの内容を外部へ送る経路にはならない。実行可能性を判断するには、個別機能の権限に加えて、処理順序、引数の受け渡し、実行時の状態、取得結果の利用方法まで確認する必要がある。
操作経路を成立させる条件と制約する条件を、次のように整理できる。
| 確認対象 | 経路が成立する条件 | 成立を制約する条件 |
|---|---|---|
| 入力の制御 | A が P の動作を決める値を変更でき、その値が実行時に読み込まれる。 | 入力できる値、変更できる項目、指定可能な処理対象が制限されている。 |
| 内部機能の呼び出し | P が外部入力に従って Q の操作を選択し、必要な引数を渡せる。 | 要求元の権限に基づく認可と引数検証が行われ、許可された操作だけが Q に渡される。 |
| 資源へのアクセス | Q が実行時に必要な権限を持ち、指定された資源に対して F を実行できる。 | Q の権限、アクセス可能な資源、パスの解決結果、実行時の状態が制限されている。 |
| 外部への伝達 | 取得結果が通信処理へ渡され、指定された外部の宛先へ送信できる。 | 送信できる情報、送信先、通信の実行条件が制限されている。 |
表の四つの条件は、機密ファイルの外部送信という一つの結果に対して、異なる段階で作用する。A が設定ファイルを書き換えられても、P がその設定を処理に反映しなければ、操作対象は変わらない。P が Q を呼び出せても、Q が指定されたファイルへアクセスできなければ、読み取りは成立しない。Q がファイルを読み取れても、その内容を P が外部へ送信する経路がなければ、情報は指定された宛先へ到達しない。最終的な操作を実行可能にするには、各段階の条件が一つの実行過程で結び付く必要がある。
反対に、これらの条件のうち一つでも確実に制約できれば、対象とする操作経路を遮断できる場合がある。例えば、P が要求元 A に許可されたファイルだけを Q に指定できる設計なら、A は Q の読み取り権限を利用しても、許可範囲外のファイルを指定できない。また、P が送信先を業務上認められた保管先に固定していれば、A は設定値を変更しても任意の宛先へ情報を送信させられない。ただし、一つの経路を遮断したことから、同じ資源へ到達するすべての経路が遮断されたとは導けない。別の内部機能や通信機構を介して同じ操作が成立する可能性があるため、評価対象となる操作へ到達する経路全体を確認する必要がある。
この違いは、プログラムの呼び出し関係と、外部主体からの操作到達可能性を区別すると明確になる。呼び出し関係は、P が Q を利用でき、Q が F を実行できるという構造を示す。一方、A の操作到達可能性は、その構造の中で A が制御できる入力を起点とし、必要な条件を満たして F まで実行させられるかを示す。例えば、Q が複数のファイル操作を実装していても、P がそのうち読み取り専用の機能しか呼び出さなければ、A が実行させられる操作には書き込みが含まれない。さらに、P が読み取り対象を固定していれば、A が制御できるのは処理を開始するタイミングだけになる場合もある。同じ呼び出し構造でも、外部主体が制御できる入力の範囲によって、実行させられる操作が変わる。
実行時の条件を考えると、操作到達可能性には時間的な側面もある。P が設定ファイルを起動時に一度だけ読み込む設計なら、A が設定を書き換えても、起動中の P が直ちに新しい内容へ従うとは限らない。定期的に設定を再読み込みする場合には、その処理が実行された時点で操作対象が変わる可能性がある。また、Q が利用する認証情報の期限切れや、対象ファイルのアクセス権限の変更によって、以前は実行可能だった経路が成立しなくなる場合もある。プログラム間の呼び出し関係が維持されていても、入力内容と実行時の状態によって、外部主体が到達できる操作の範囲は変化し得る。
操作経路の存在を確認することと、その経路が実際に使用されたことも区別する必要がある。A が P に指定できる入力を持ち、P と Q を経由して F を実行できる構成であっても、A がその入力を与えたとは限らない。反対に、実行記録に F の呼び出しが残っていても、その記録だけでは A が操作を引き起こしたことまでは確定しない。操作を指定した入力、その入力が P に読み込まれた時点、Q に渡された引数、F の実行結果を対応付けることで、到達可能性の分析と実際の操作の確認を区別できる。
複数の機能を経由する権限の評価では、プログラムごとに与えられた権限の一覧に加えて、外部主体が制御できる入力から最終的な操作へ至る経路を調べる必要がある。その経路は、呼び出し関係が存在するだけで成立するのではなく、入力の制御範囲、引数の検証、実行時の権限、処理順序、状態の条件によって成立する。これらの条件を満たす経路を特定すれば、外部主体に直接許可されている操作と、ほかのプログラムを介して実行させられる操作との差を評価できる。また、構造が同じでも入力や状態が変わることで操作到達可能性が変化するため、権限境界を時間の中で評価するための基礎にもなる。
5. 操作経路の成立条件と制約
外部の主体が、ほかのプログラムを介して何を実行させられるかを評価するには、操作を比較可能な単位で定義する必要がある。例えば、「ファイルを読む」という表現だけでは、機密ファイルを読み取る操作と、公開ファイルを読み取る操作を区別できない。また、同じファイルを読み取る場合でも、結果をプログラム内部で集計する処理と、外部の送信先へ転送する処理では、情報の利用範囲が異なる。権限境界からの逸脱を判断するには、どの主体が、どの対象について、どの操作を、どの実行権限で行い、結果をどこへ渡すかまで具体化する必要がある。
利用者 A がプログラム P に文書の送信を要求できる構成を考える。A には自分が管理する文書を指定された保管先へ送信することが許されている。一方、P には複数の利用者の文書を読み取る権限があり、業務上必要なネットワーク通信も許可されている。P が要求元の権限を確認せず、指定された文書と送信先をそのまま処理するなら、A は自分の文書だけでなく、ほかの利用者の文書も送信対象として指定できる可能性がある。さらに、送信先を自由に変更できれば、A に読み取りが認められた文書であっても、業務上許可されていない宛先へ転送させられる場合がある。どちらも P が持つ正当な機能を利用しているが、A に許可された操作の範囲を超えている。
ここで、プログラム P が実行できる操作と、利用者 A が P に実行させられる操作を区別する。P に機密ファイルの読み取り権限が存在しても、A がその読み取りを要求できるとは限らない。また、A が P にファイルの読み取りを要求できても、その内容を任意の送信先へ転送させられるとは限らない。操作の到達可能性は、P が利用できる機能の範囲に加え、A が変更できる入力、P が受け付ける要求、要求時の認可、実行時の状態によって決まる。P の権限一覧から A の実行可能な操作集合をそのまま導くことはできない。
この関係を集合として表す。主体 a が、特定のシステム構成と実行条件の下で、ほかのプログラムを介して実行させられる操作の集合を \(R(a)\) とする。一方、その主体に要求仕様上認められる操作の集合を \(L(a)\) とする。ここでは評価時点の入力と実行状態を固定し、それらを変更した場合の到達可能性は別の条件として比較する。両者の比較では、操作対象、実行内容、結果の送信先などを同じ粒度で定義する。例えば、「文書を送信する」という操作を一つの要素にするのではなく、「文書 X を保管先 Y へ送信する」という具体的な操作を一つの要素として扱う。これにより、同じ送信機能を使用していても、許可された処理と許可されていない処理を区別できる。
許可されていない到達可能な操作の集合を、次のように定義する。
\[B(a)=R(a)\setminus L(a)\]
この式の右辺にある \(R(a)\) は、主体 a が間接的に実行させられる操作の集合である。\(L(a)\) は、その主体に認められた操作の集合である。集合の差を表す記号 \(\setminus\) は、前者に含まれるが後者には含まれない要素を取り出す。したがって、\(B(a)\) には、主体 a がプログラムを介して実行させられるにもかかわらず、その主体には許可されていない具体的な操作が含まれる。これは権限の大きさを一つの数値へ置き換える式ではなく、許可範囲から外れた操作を特定するための定義である。
例えば、A に許可されている操作が「自分の文書 X を指定された保管先 Y へ送信すること」である場合を考える。P がこの要求を受け付け、正しく実行するなら、その操作は \(R(a)\) と \(L(a)\) の両方に含まれる。一方、A がほかの利用者の機密ファイル Z を同じ保管先 Y へ送信させられる場合、その操作は \(R(a)\) に含まれるが、\(L(a)\) には含まれない。また、自分の文書 X を許可されていない外部の宛先 W へ送信させられる場合も、操作対象と送信先の組合せが許可範囲から外れる。この二つの操作が \(B(a)\) に含まれる。
| 操作 | プログラムを介して実行可能か | 利用者 A に許可されるか | 集合上の評価 |
|---|---|---|---|
| 自分の文書 X を保管先 Y へ送信する | P が要求を受け付け、読み取りと送信を実行できる。 | A に許可された業務上の操作である。 | \(R(a)\) と \(L(a)\) の両方に含まれ、\(B(a)\) には含まれない。 |
| ほかの利用者の機密ファイル Z を保管先 Y へ送信する | P が要求元の権限を検証しなければ、実行可能になる場合がある。 | A には機密ファイル Z の送信が許可されていない。 | 実行可能な場合は \(R(a)\) に含まれ、\(L(a)\) から外れるため、\(B(a)\) に含まれる。 |
| 自分の文書 X を外部の宛先 W へ送信する | P が任意の送信先を受け付ければ、実行可能になる場合がある。 | A に許可される送信先は保管先 Y に限られる。 | 実行可能な場合は、送信対象が正当でも宛先が許可範囲外であるため、\(B(a)\) に含まれる。 |
| 機密ファイル Z を外部の宛先 W へ送信する | P が読み取り対象と送信先の両方を制限しなければ、実行可能になる場合がある。 | 読み取り対象と送信先の両方が A の許可範囲から外れる。 | 実行可能な場合は \(B(a)\) に含まれ、複数の制約を同時に逸脱する操作となる。 |
表では、文書の読み取りと送信という同じ機能を使用していても、対象ファイルと送信先の組合せによって評価が変わることを示している。P がファイルを読み取れるかという条件だけでは、A に許される操作を判定できない。A が文書 X を読み取ることを許可されていても、任意の送信先へ転送することまで許可されているとは限らない。また、送信先 Y が正当な保管先であっても、そこへ任意の機密ファイルを送信してよいとは限らない。許可される操作は、個別の権限を独立に確認するだけでなく、対象と処理内容の組合せを含めて定義する必要がある。
\(B(a)\) が空集合である場合、定義したシステム構成と操作の範囲では、主体 a が間接的に実行させられる操作が、すべて許可範囲内に収まっていることを意味する。例えば、P が A の要求を受け付ける際に、対象文書が A に許可されているか、送信先がその文書について許可された場所かを確認し、条件を満たす要求だけを実行すれば、表に示した許可範囲外の操作は実行できなくなる。ただし、\(B(a)=\varnothing\) という結果は、評価対象に含めた主体、操作、実行条件について成立する。評価から漏れた機能や別の操作経路が存在する場合、それらについても同じ条件が成立するとは限らない。
実際のシステムでは、\(R(a)\) を直接列挙することが難しい場合がある。例えば、P が複数の内部 API を呼び出せるなら、A の入力から到達できる操作は、API の組合せ、呼び出し順序、実行状態によって変わる。入力値の制限を通過した後に、別の機能が引数を変更する場合もある。さらに、ファイルのアクセス権限や認証情報が実行途中で変化すれば、同じ要求が異なる結果になる可能性がある。操作到達可能性を調べるには、プログラムが持つ機能の一覧だけでなく、外部主体から制御可能な入力を起点として、条件を満たす実行経路を追跡する必要がある。
このような経路を制約する方法には、異なる作用点がある。MITRE の CWE-250 は、処理に必要以上の権限でプログラムを実行することによって、意図しない操作の影響範囲が広がる問題を説明している[6]。P に不要な読み取り権限や通信権限があれば、それを削減することで、P を介して実行可能な操作の上限を制限できる。一方、P に機密ファイルの読み取りと外部送信の両方が業務上必要な場合には、P の権限を維持しながら、A の要求について対象と送信先を認可する方法が必要になる。実行主体の権限を制限することと、要求元に許された操作を判定することは、\(R(a)\) を異なる位置から制約する。
NIST SP 800-207 のゼロトラストアーキテクチャは、ネットワーク内に存在するという理由だけで資源へのアクセスを暗黙に許可せず、アクセスを認証と認可の対象として扱う考え方を整理している[7]。この考え方を P の代理処理に対応させると、P が正規のプログラムであることや、A と P の通信が認証されていることに加え、A が要求した操作そのものについて許可条件を確認する必要がある。要求元を識別する処理が存在していても、その主体に操作対象や送信先を指定する権限があるかを判定しなければ、代理実行による権限の利用範囲を制約できない。
最小権限と要求ごとの認可は、操作集合に対して異なる形で作用する。前者は P が利用できる資源や機能の範囲を限定するため、P を介して実行させられる操作全体の上限を制約する。後者は、P が技術的に実行できる操作のうち、A の要求として認めるものを選別する。例えば、P が機密ファイルを読み取れる必要があっても、A の要求からそのファイルを指定できない設計なら、A が P に実行させられる操作集合には、その読み取りを含めずに済む。さらに、送信先について独立した制約を設ければ、読み取りが許可された文書についても、不適切な宛先への転送を防げる。
ただし、これらの制約が実装されていることと、許可範囲外の操作が実際に到達不能であることは、検証上区別する必要がある。例えば、P の通常の要求処理では認可を行っていても、別の内部 API が同じファイル操作を認可なしで実行する場合、A がその API を呼び出せるなら、許可範囲外の操作経路が残る。ある処理経路で \(B(a)\) に該当する操作が防止されたとしても、別の経路から同じ操作へ到達できれば、システム全体の \(R(a)\) にはその操作が残る。権限境界の評価では、個々の制約の存在と、制約を含む実行経路全体の到達可能性を対応付ける必要がある。
さらに、\(R(a)\) は評価時点の構成と実行条件に依存する。例えば、P が起動時に外部スクリプトを読み込み、その内容に応じて内部 API を呼び出す構成では、読み込まれたコードが変わることで、A が実行させられる操作が変化する可能性がある。プログラム本体と OS の権限設定が変わらなくても、外部コードの変更によって、それまで使用されていなかった内部機能が呼び出される場合がある。また、P が保持する認証情報や対象資源のアクセス制御が変化すれば、同じコードから到達できる操作も変わり得る。\(R(a)\) を評価するには、実行機構、読み込まれたコード、入力値、認可規則、実行時の状態を特定する必要がある。
同様に、\(L(a)\) も要求仕様や運用上の権限変更によって変わる場合がある。例えば、A が機密文書の管理担当者へ正式に変更されたなら、以前は許可されていなかった操作が許可範囲に加わる可能性がある。反対に、A の担当業務が終了すれば、以前は許可されていた操作を取り消す必要がある。この場合、\(R(a)\) が変わらなくても、\(L(a)\) の変更によって \(B(a)\) が変化する。許可範囲から外れた操作が存在するかという評価は、プログラムの実装だけでなく、その時点で適用される権限規則にも依存する。
操作集合の差を用いる方法は、権限の評価を、主体が直接持つ権限の一覧から、具体的な操作が許可範囲内に収まるかという判断へ進める。例えば、設定ファイルの変更者がプログラムを介して機密ファイルを外部送信できる場合、その送信操作を \(R(a)\) に含め、要求仕様上認められていなければ \(B(a)\) に含める。この評価では、OS の権限昇格が発生したかどうかとは独立に、実効的な権限境界からの逸脱を特定できる。さらに、構造や入力条件が変化するたびに到達可能な操作を再評価することで、権限設定が同じでも実行能力が変わる現象を記述できる。
この性質は、外部コードを取得して実行するソフトウェアで具体的に現れる。正規プログラムに与えられた権限が変わらなくても、取得したコードの内容によって内部機能の呼び出し方が変われば、外部主体が実行させられる操作集合も変化する。外部から変更可能な情報と、プログラムが持つ実行権限がどのように結び付いているかを確認することが、実際の侵害経路を評価する条件となる。
6. 正規ランチャーが攻撃経路となった事案
2026 年に公表された NIKKE PC ランチャー侵害の技術解析では、Level Infinite の公式 CDN 上にある JavaScript ファイル 4 件に、第三者によるコードの挿入が確認された。対象となったのは、ランチャーが読み込む aegis-fix.min.js、vue-bucket.min.js、images.7fec4c32.js、FeedList.feb647c9.js である。解析によれば、これらのファイルには 2026 年 9 月 27 日付の改ざん内容が存在し、挿入されたコードは攻撃者が管理する外部のスクリプトを読み込むようになっていた[8]。利用者が非公式の配布サイトから別の実行ファイルを入手することは、攻撃経路の成立条件ではなかった。正規ランチャーが通常の処理として取得する外部資源に、攻撃者のコードが含まれていたのである。
この事案では、ソフトウェアの配布経路と、その経路を通じて取得される内容を区別する必要がある。公式 CDN は、ランチャーが必要な資源を取得するための正規の配布基盤である。しかし、正規の配布基盤から応答が返されることと、応答に含まれるコードが開発元の意図した内容と一致することは、異なる条件である。改ざんが確認されたのは、利用者の端末にインストールされたランチャーの実行ファイルではなく、ランチャーが外部から読み込む JavaScript ファイルだった。攻撃者が CDN 上のファイルを書き換えられた具体的な経緯は、技術解析では解明されていない[8]。取得したコードを実行する仕組みがランチャー側に存在したため、配信内容の変更が端末上の処理内容の変更へつながった。
解析された改ざんコードは、攻撃者側のアドレスを整数配列として埋め込み、実行時に文字列へ復元する処理を持っていた。復元されたアドレスを使って外部スクリプトを読み込み、その処理をランチャーの実行環境へ取り込む構成だった。これにより、公式 CDN に置かれたファイルの改ざんが、攻撃者の管理する別の配信先からコードを取得する経路へ接続された。公式 CDN 上の改ざんファイルがランチャーに読み込まれ、攻撃者側で配信する追加コードが取得されることで、ランチャーが実行する処理を段階的に制御する仕組みが成立していた[8]。
さらに、外部スクリプトはランチャー内部のファイル取得機能を利用して、Lua による処理を含む追加のプログラムを取得する構造になっていた。技術解析では、ランチャー側の JavaScript と内部機能を結ぶ仕組みを通じて、Srv_DownloadFile が呼び出され、悪性エージェントを含むファイルが取得される経路が確認されている。ここでは、外部から読み込まれた JavaScript が、単に画面上の要素を変更するだけでなく、ランチャー内部に用意されたファイル取得機能を利用している。ランチャーの内部機能が外部コードから呼び出せるため、外部コードの制御者は、ランチャーが本来備えている処理を追加のプログラムの取得に利用できた。
取得された Lua エージェントについては、ランチャー内部の通信機構に接続し、外部から与えられる指示に応答する構成が解析されている。具体的には、comm_center と呼ばれるランチャー内部の通信機構へ k2f_chan という通信経路を登録し、外部のサーバーから伝えられる指示に応じて処理を実行する仕組みだった[8]。この段階では、改ざんされた JavaScript を最初に読み込んだことが、追加コードの取得、内部通信機構への接続、遠隔からの操作要求の受け付けへとつながっている。攻撃者が最初に制御した配信内容と、最終的に端末上で操作を実行する機能との間には、複数の処理が存在していた。
解析されたエージェントには、LuaJIT の FFI を利用して Windows の機能を呼び出す処理も含まれていた。LuaJIT の公式資料によれば、FFI は Lua のコードから外部の C 関数を呼び出し、C のデータ構造を利用するための機構である[9]。例えば、Lua の処理から利用可能な C 関数を呼び出せれば、実行環境に許された範囲でファイル操作などの処理へ接続できる。FFI はそれ自体が OS の管理者権限を与える仕組みではない。実際に実行できる操作は、呼び出す関数、実行中のプロセスが持つ権限、対象資源へのアクセス制約によって決まる。この事案では、外部コードから取り込まれた Lua の処理が、ランチャーの実行環境を利用して端末上の機能へ到達していたことが焦点となる。
この攻撃経路を、外部から変更された内容と、実際に処理を実行する機構に分けると、権限の利用関係を整理できる。
| 段階 | 入力・変更された内容 | 処理を実行する機構 | 操作範囲への影響 |
|---|---|---|---|
| 公式 CDN 上の資源 | ランチャーが取得する JavaScript ファイル 4 件に、第三者のコードが挿入された。 | 正規ランチャーが外部資源を取得し、読み込む。 | 配信内容の変更が、ランチャー内部で実行されるコードの変更につながる。 |
| 外部スクリプトの読み込み | 改ざんコードから、攻撃者が管理する外部スクリプトの取得先が指定された。 | ランチャー内の JavaScript 実行環境が追加コードを読み込む。 | 公式 CDN 上の改ざんコードから、攻撃者側で配信する追加コードへ実行経路が広がる。 |
| 追加プログラムの取得 | 外部スクリプトが、悪性エージェントを含むファイルの取得を指示した。 | ランチャー内部のファイル取得機能が呼び出される。 | 外部コードがランチャーの既存機能を利用して追加の処理を端末へ取り込む。 |
| 内部通信機構への接続 | 取得された Lua エージェントが、外部からの指示を受け付ける通信経路を登録した。 | ランチャー内部の通信機構と Lua の実行環境が利用される。 | 遠隔から与えられた操作要求が端末上の処理へ渡される経路が成立する。 |
| OS 機能の利用 | 悪性エージェントに実装された操作や外部からの指示に応じて、処理対象が選択される。 | LuaJIT FFI などを通じて、実行環境で利用可能な関数が呼び出される。 | ランチャーの実行権限の範囲で、ファイルや端末上の情報へアクセスする操作が可能になる。 |
表の各段階では、改ざんが確認された配布資源と、端末上で処理を実行する主体が異なる。最初の段階で改ざんが確認されたのは CDN に置かれた JavaScript ファイルである。そこから追加のスクリプトが読み込まれ、ランチャー内部の機能によって別のプログラムが取得され、最終的に端末上の機能が利用される。各段階が次の段階に必要な処理を提供することで、配布資源の改ざんという限定された入口から、端末上のファイル操作や通信へ至る経路が成立していた。ただし、各処理が実行されるには、対象のコードが実際に読み込まれ、追加ファイルの取得が成功し、実行環境で必要な機能が利用可能であることが必要になる。
この経路が成立したことと、すべてのランチャー起動時に悪性エージェントが動作したことも区別する必要がある。技術解析では、公式 CDN 上の改ざんコードが存在した期間と、実際に悪性エージェントが起動したと報告された時点を分けている。報告された最も早いエージェントの起動は 2026 年 10 月 23 日であり、改ざんファイルの存在が確認された 9 月 27 日とは異なる。さらに、追加コードの取得や実行が毎回同じ結果になったわけではない。ランチャーが改ざんされたファイルを読み込んだこと、悪性エージェントを取得したこと、取得したエージェントが起動したことは、異なる成立条件を持つ段階として評価する必要がある[8]。
悪性エージェントには、任意のプログラムを起動する機能、ファイルを閲覧する機能、画面を撮影する機能、ブラウザに保存された認証情報へアクセスする機能などが含まれていた。これらの機能は、ゲームの画面表示や更新処理のために読み込まれた外部コードから、端末上の情報やプログラム実行へ操作経路が延びていたことを示す。一方、各機能が実装されているという事実と、攻撃者が実際にそれらを使用したという事実は区別される。解析されたプログラムの内容から確認できるのは、特定の条件の下で実行可能な処理である。どの端末で、いつ、どの指示が実行されたかを確定するには、その端末に残る実行記録や通信記録などの証拠が必要になる。
技術解析の根拠にも範囲がある。MotherSphere の報告は、感染が確認された端末の記録、取得されたファイル、逆解析した悪性コード、外部サーバーの応答などを組み合わせている。追加の端末から寄せられた報告も参照しているが、独立に確認できた内容と、報告者から得られた情報を区別している[8]。したがって、解析された悪性コードに実装された機能を、そのまま全利用者の被害状況へ一般化することはできない。攻撃経路が技術的に成立すること、特定端末でエージェントの起動が確認されたこと、具体的な情報の取得や送信が確認されたことは、それぞれ異なる証拠によって支えられる。
さらに、外部資源が改ざんされていた期間と、実際に改ざんされた内容が端末へ配信された期間も一致するとは限らない。技術解析では、一部のファイルが配布元で正常な内容へ戻された後も、CDN の一部のサーバーから改ざんされた内容が返されていたことが確認されている。ランチャー側のキャッシュにも改ざんされたファイルが残存する場合があった[8]。この構成では、配布元の修正、CDN 上の内容の更新、端末側で読み込まれる内容の更新が、異なる時点で成立し得る。実行ファイルや権限設定が変更されていなくても、どの資源が実際に読み込まれるかによって、端末上で実行される処理が変わる。
この時間的な違いは、実行経路を単一の構成図として確認するだけでは捉えきれない性質を示している。ある時点では正常なコードが配信され、別の時点では改ざんされたコードが配信される。また、同じ時点でも、接続した CDN サーバーや端末内のキャッシュによって、読み込まれる内容が異なる場合がある。ランチャーが持つ内部機能と OS の権限設定が同じであっても、取得するコードの内容と実行時の状態によって、外部主体が実行させられる操作が変化する。実行経路を評価するには、プログラムの構造に加えて、どの入力が、どの時点で、どの実行環境へ取り込まれたかを確認する必要がある。
NIKKE PC ランチャー侵害の構造的な特徴は、攻撃者が端末上の正規プログラムを直接置き換えることなく、そのプログラムが外部から取り込むコードを通じて内部機能へ到達したことにある。外部コードの取得、追加プログラムの実行、内部通信機構の利用、OS 機能の呼び出しが連結されることで、配布資源の改ざんが、端末上の操作を間接的に実行させる経路につながった。権限を持つ実行主体が正規のプログラムであっても、その主体が誰の制御する情報に従って動作するかによって、実際に行われる処理は変わる。正規の配布経路と正規の実行主体が維持されたまま、外部条件の変更によって操作到達可能性が変化するという点に、この事案を権限構造の分析へ接続する根拠がある。
7. 実行可能性と実際の侵害の証拠
マルウェアのプログラムを解析すると、実装されている命令の種類、読み取る可能性があるファイル、通信に使用する機能、外部から受け付ける要求などを確認できる。例えば、任意のファイルを開く関数が存在し、その関数を遠隔操作の命令から呼び出せるなら、攻撃者がファイルを読み取るための処理経路を持っていたことが分かる。しかし、その関数が存在することと、実際に機密ファイルが読み取られたことは異なる。さらに、ファイルの読み取りが実行されたとしても、その内容が攻撃者の管理するサーバーへ送信されたかどうかは、別の操作として確認する必要がある。プログラムの解析から得られる実行能力と、個々の端末で発生した操作の履歴は、異なる証拠によって評価される。
NIKKE PC ランチャー侵害事案で解析された悪性エージェントには、ファイルの閲覧や取得、画面撮影、保存された認証情報へのアクセス、任意のプログラム起動などの機能が含まれていた。これらの機能は、ランチャーの実行環境を通じて、ゲームの表示や更新とは異なる端末操作へ到達できる可能性を示している。ただし、ある端末でエージェントが動作したことから、その端末で実装済みのすべての機能が使用されたとは導けない。遠隔から与えられる指示、対象ファイルの存在、実行時のアクセス権限、通信状態などによって、実際に行われる操作は変わる。悪性エージェントが持つ機能の一覧は、攻撃者が利用し得た操作の範囲を調べるための資料であり、個々の利用者について確認された被害の一覧ではない。
この違いを具体的に考える。悪性エージェントが、ブラウザに保存された認証情報を収集する処理を実装していたとする。コードの解析によって、その処理が対象とする保存場所やファイル形式を特定できる場合がある。しかし、対象となるブラウザが端末に存在するか、認証情報が保存されているか、その情報にエージェントがアクセスできるかによって、収集処理の結果は異なる。さらに、収集されたデータを外部へ送信するには、送信処理が実行され、通信が成立する必要がある。情報を収集する機能の存在から、特定の端末で認証情報が取得され、攻撃者へ渡ったという結論まで進むには、複数の成立条件と観測証拠を確認しなければならない。
MotherSphere が公開した NIKKE Launcher Check は、改ざんされたスクリプトの読み込み、遠隔操作エージェントの実行、追加されたファイルやレジストリの変更などについて、端末に残された痕跡を調べる検査ツールである[10]。このツールは既存の情報を読み取って検査するもので、検査対象のファイルやレジストリを変更する処理を行わず、外部へのネットワーク通信も行わない。検査結果によって、改ざんされたコードに接触した痕跡と、悪性エージェントが実際に動作した痕跡を区別するための情報が得られる。ただし、検査結果の意味は、どの痕跡が確認されたかによって異なる。改ざんされたスクリプトの存在を示す記録と、エージェントの起動を示す記録は、攻撃経路の異なる段階に対応している。
例えば、ランチャーのキャッシュに改ざんされた JavaScript が残っていた場合、その端末に改ざんされた内容が保存されていたことを確認できる。しかし、保存された内容が実際に実行されたか、その後に追加のプログラムが取得されたかは、キャッシュの存在だけでは確定しない。一方、悪性エージェントの起動を示すログや、エージェントが作成するファイルが確認された場合には、改ざんされたスクリプトへの接触よりも先の処理が行われた可能性を、具体的な痕跡に基づいて評価できる。さらに、認証情報の取得や外部送信まで確認するには、それぞれの操作に対応する記録や保存物が必要になる。攻撃経路のどの段階を証拠が支えているかによって、導ける結論の範囲が決まる。
証拠と結論の対応を整理すると、次のようになる。
| 確認対象 | 得られる証拠 | 証拠から判断できること | 追加の確認が必要なこと |
|---|---|---|---|
| 悪性コードの解析 | 実装された命令、対象ファイル、関数呼び出し、通信処理が確認される。 | 必要な実行条件を満たした場合に、どの操作が可能かを分析できる。 | 個々の端末で、そのコードが読み込まれ、実際に使用されたかを確認する必要がある。 |
| 改ざんされた資源の保存 | ランチャーのキャッシュなどに、改ざんされたスクリプトが残っている。 | 改ざんされた内容が端末へ取得されたことを確認できる。 | スクリプトが実行され、追加の処理が開始されたかを確認する必要がある。 |
| 悪性エージェントの起動 | 起動を示すログ、関連ファイル、実行状態などの痕跡が確認される。 | 悪性エージェントが端末上で動作したことを裏付ける材料になる。 | どの命令を受け取り、どの資源へアクセスしたかを確認する必要がある。 |
| ファイルや認証情報へのアクセス | 対象ファイルへのアクセス記録や、収集処理によって生成された保存物が確認される。 | 特定の情報に対する操作が行われた可能性を具体的に評価できる。 | 取得した情報の内容、操作を行った主体、外部送信の有無を確認する必要がある。 |
| 外部サーバーとの通信 | 通信先、通信時刻、接続状態、通信量などが記録される。 | 端末と外部サーバーの間で通信が発生したことを確認できる。 | 通信内容が確認できない場合、どの情報が送信されたかを確定するには別の証拠が必要になる。 |
表で示した証拠は、攻撃経路の異なる段階を観測したものである。悪性コードの解析によってファイル読み取り機能が確認されても、それは実行可能性を支える証拠である。ファイルへのアクセス記録が確認されれば、特定の操作が実行されたという判断へ進める。さらに、外部通信の記録が存在すれば、通信の発生を確認できる。しかし、通信の存在だけでは、読み取られたファイルの内容が送信されたとまでは確定しない。実行可能性、操作の発生、情報の流出という結論には、それぞれ対応する証拠が必要になる。
複数の記録を組み合わせる場合には、記録間の対応関係も確認する必要がある。例えば、ある時刻に機密ファイルが読み取られ、その直後に外部サーバーへの通信が記録されていたとする。この二つの事実から、ファイルの読み取りと通信が時間的に近接していたことは分かる。しかし、通信に含まれていた情報がそのファイルの内容だったかどうかは、通信データ、アプリケーションの処理記録、送信前に生成されたファイルなど、追加の証拠によって判断する必要がある。端末上で複数の処理が同時に動作していれば、時間的に近いという理由だけで、あるファイルアクセスと特定の通信を因果的に結び付けることはできない。
NIST SP 800-86 は、ファイル、OS、ネットワーク、アプリケーションなど、複数の情報源からデジタル証拠を収集し、解析する手法を整理している[11]。ファイルシステムに残る記録は、ファイルの存在や変更状態を示す場合がある。プロセスの実行記録は、特定のプログラムが起動したことを示す場合がある。ネットワークの記録は、通信先や通信時刻を示す場合がある。これらの情報を対応付けることで、単一の記録からは分からない処理の経緯を再構成できる。ただし、証拠の収集範囲、記録の完全性、時刻情報の精度、記録の保存期間によって、再構成できる内容には制約がある。
記録が存在しない場合にも、その意味を慎重に評価する必要がある。例えば、悪性エージェントが実行後に一時ファイルを削除する場合、そのファイルが現在の端末上で見つからなくても、過去に作成されなかったとは限らない。また、ログに実行した命令の内容が記録されない設計なら、ログの解析から命令の履歴を完全に復元することはできない。記録の保存期間が終了している場合や、調査対象外の保存場所に痕跡が存在する場合もある。検査で痕跡が見つからなかったという結果は、指定された検査対象と検出条件に該当する記録が確認されなかったことを意味する。過去のすべての操作が存在しなかったことを証明するには、観測範囲がその操作を確実に捕捉できるという条件が必要になる。
この制約は、調査の対象を区別することでより明確になる。マルウェアのプログラムを解析する作業では、実行可能な命令や操作対象を調べる。一方、個々の端末を調査する作業では、その端末で実際にどの処理が発生したかを確認する。さらに、組織全体の被害を評価する場合には、対象となる端末の数、調査できた端末の範囲、各端末の検査条件を区別する必要がある。ある端末で悪性エージェントの起動が確認されたとしても、同じランチャーを利用していたすべての端末で起動したとは限らない。また、調査対象となった端末の検出数を、そのまま利用者全体の感染率として扱うには、調査対象の選び方について別の根拠が必要になる。
既稿「サイバー攻撃の被害はシステムの管理境界を越えて広がる」では、侵害された場所に集まる情報や、そこから到達できるほかの資源が、潜在的な被害範囲を決めることを論じた[12]。例えば、侵害された端末に複数のサービスの認証情報が保存されていれば、それらの情報を利用した別の資源へのアクセスが可能になる場合がある。しかし、到達可能な資源の存在と、実際にそれらが利用されたことは異なる。今回の権限分析では、外部主体から操作を到達させられる範囲と、その範囲内で実際に生じた操作を別々に定義することで、潜在的な侵害範囲と確認された被害の差を明確にできる。
この違いを集合で表す。主体 a が、固定されたシステム構成と実行条件の下で間接的に実行させられる操作の集合を、既に定義した \(R(a)\) とする。また、同じ条件と評価期間において、主体 a の制御する入力や命令によって実際に実行された操作の集合を \(X(a)\) とする。\(R(a)\) は実行可能性を表し、\(X(a)\) は実際の操作履歴に含まれる操作の種類を表す。実行条件が固定され、評価対象となる操作の粒度が一致していれば、次の関係が成立する。
\[X(a)\subseteq R(a)\]
この式は、実際に実行された操作が、その時点で実行可能だった操作の範囲に含まれることを表している。例えば、悪性エージェントがファイル読み取り、画面撮影、外部通信の三つを実行できる状態にあっても、攻撃者がファイル読み取りだけを指示したなら、実際の操作集合にはその読み取りが含まれる一方、画面撮影が含まれるとは限らない。実行可能な操作の種類が多いことから、そのすべてが実行されたと判断することはできない。また、実際の操作履歴を集合として扱う場合、同じ操作が何回実行されたかという回数や、実行順序は集合だけでは表現されない。それらを評価するには、時刻や操作結果を含む履歴が必要になる。
さらに、実際の操作集合 \(X(a)\) と、調査によって確認された操作の集合も区別する必要がある。例えば、悪性エージェントがファイルを読み取ったとしても、その操作がログに記録されなければ、後から収集した記録だけでは読み取りを確認できない場合がある。逆に、不審な通信記録が存在しても、それが悪性エージェントによる情報送信であると確定するには、通信を実行したプロセスや内容との対応付けが必要になる。観測結果は、実際の操作の一部を示す場合があり、また、操作そのものではなく、操作に伴って生じた状態変化を示す場合もある。このため、観測された記録の集合を、そのまま \(X(a)\) と同一視することは適切ではない。
ここには、実行可能性、実行履歴、観測という三つの異なる対象がある。実行可能性は、操作を引き起こすための経路が存在し、その経路の実行条件が満たされるかという問題である。実行履歴は、その経路を通じて、どの操作が実際に行われたかという問題である。観測は、実行された操作や、その結果として生じた状態変化のうち、どの情報を取得できたかという問題である。例えば、ある操作が実行可能であっても、攻撃者が利用しなければ実行履歴には現れない。また、操作が実行されても、対応する記録が保存されなければ観測結果からは確認できない。三つを分離することで、実装された機能から実際の被害を過大に推測することと、記録が見つからないことから安全性を過大に評価することの両方を避けられる。
時間の経過によって実行条件が変わる場合には、\(R(a)\) と \(X(a)\) の関係にも評価時点を指定する必要がある。例えば、ある時点ではランチャーが正常なスクリプトを読み込んでおり、別の時点では改ざんされたスクリプトを読み込んでいたとする。プログラム本体の権限が変化していなくても、取得されたコードによって呼び出せる内部機能が変われば、その時点で実行可能な操作の範囲も変わる。さらに、配布内容が修正された後も、既に起動したエージェントが端末上に残っていれば、配布経路を修復した時点と、端末上で実行可能な操作が制約される時点は一致しない場合がある。操作到達可能性を評価する際には、どのコードが読み込まれ、どの処理が起動し、どの権限が利用できた時点なのかを特定する必要がある。
侵害の調査結果が示すのは、取得できた証拠に基づいて再構成された操作と状態である。一方、セキュリティ設計で確認する必要があるのは、攻撃者が操作を実行したかどうかにかかわらず、外部から制御可能な入力を通じて許可範囲外の操作へ到達できるかという条件である。前者は過去に発生した事実の確認に関係し、後者は同じ構成で将来も成立し得る操作経路の評価に関係する。外部入力、実行機構、端末の状態が時間とともに変化する以上、実行可能性と観測結果を別々に記述することが、権限境界を動的な構造として評価するための基礎になる。
8. 権限構造は時間とともに変化する
ある時点のプログラム P が、外部から取得したコードを読み込み、内部 API を呼び出す機構を持っているとする。平常時には画面表示に必要な処理だけを記述したコードを受け取っている。しかし、外部の配信内容が変更され、ファイルの読み取りやネットワーク通信を呼び出すコードが配信されるようになれば、P が実行する処理は変化する。P の実行ファイル、内部 API、OS から与えられた権限が同じでも、外部コードによって呼び出される機能が変わるためである。この場合、プログラムが持つ権限の範囲は変わっていないが、外部コードを制御する主体が実行させられる操作の範囲は変化し得る。
この変化が成立するには、外部の配信内容が変更されるだけでなく、P が変更後の内容を取得し、そのコードを実行する必要がある。例えば、P が起動時に一度だけ JavaScript を読み込む構成なら、配信元のファイルが書き換えられても、すでに起動している P が直ちに新しいコードへ切り替わるとは限らない。次回の起動時に取得し直す場合もあれば、保存済みのキャッシュを使用して以前の内容を実行する場合もある。配信元で改ざんが成立した時刻と、端末上で改ざんコードが実行可能になった時刻は、取得処理とキャッシュの状態によって異なる。
例えば、時刻 t0 に正常なコードが配信され、P がそのコードを読み込んでいたとする。時刻 t1 に攻撃者が配信元のコードを改ざんしても、P が再取得しなければ、端末上の処理内容は以前の状態にとどまる。時刻 t2 に P が改ざんされたコードを取得して実行すると、外部コードから呼び出される内部 API の種類が変わり、それまで外部主体が実行させられなかった操作が可能になる場合がある。さらに、時刻 t3 に配信元を修正しても、端末上で改ざんコードが実行中であったり、追加のプログラムがすでに起動していたりすれば、実行可能な操作が直ちに修復前の状態へ戻るとは限らない。各時点の違いを決めるのは、配信元の内容だけでなく、その内容がどこへ保存され、どの処理へ反映されたかという関係である。
この過程では、外部の配信内容と、端末が実際に使用している内容を区別する必要がある。配信元のファイルを変更する操作は、そのファイルを次に取得する処理へ影響する。一方、端末のキャッシュに保存されたコードを変更するには、キャッシュの更新や無効化など、別の処理が必要になる場合がある。また、コードを取得し直しても、すでに起動した処理が終了するとは限らない。外部コードが追加のプログラムを起動したり、永続的な設定を変更したりしていれば、それらは元の配信内容とは異なる状態として端末上に存在する。配布元の修復と端末上の実行状態の修復は、作用する対象が異なるのである。
NIKKE PC ランチャーの侵害事案でも、配布された JavaScript の内容、CDN に保持された内容、端末側のキャッシュ、悪性エージェントの動作状態を区別する必要があった。配布元の改ざんを修正しても、キャッシュに残されたコードや、すでに実行された処理によって作られた状態が自動的に消えるとは限らない。ある端末で改ざんコードが実行されたとしても、その後にどの追加処理が成立したかによって、修復すべき対象は異なる。外部資源の内容が正常に戻ったことと、その端末で攻撃者が実行させられる操作がなくなったことは、別々に確認する必要がある。
各構成要素の更新条件を整理すると、次のようになる。
| 対象 | 状態が変化する契機 | 操作到達可能性への影響 | 修復時に確認すること |
|---|---|---|---|
| 配布元のコード | 公開されたファイルが改ざん、更新、修正される。 | 次に取得されるコードの内容が変わり、呼び出される内部機能が変化する可能性がある。 | 配布元で期待したコードが提供されていることを確認する。 |
| CDN のキャッシュ | キャッシュの有効期限、更新、無効化などによって配信内容が切り替わる。 | 配布元の修正後も、改ざんされたコードが一部の取得処理へ返される可能性がある。 | 実際に配信される内容が期待したコードへ更新されていることを確認する。 |
| 端末側のキャッシュ | 再取得、キャッシュの無効化、保存内容の更新などが行われる。 | 配布元が修正されても、端末が保存済みの改ざんコードを利用する場合がある。 | ランチャーが実際に読み込む内容を確認する。 |
| 稼働中のプログラム | コードの読み込み、再実行、停止、再起動などが行われる。 | 以前に読み込んだコードや、起動済みの追加処理が継続する場合がある。 | 修復前のコードに由来する処理が動作しているかを確認する。 |
| 端末に保存された状態 | 追加ファイルの作成、設定変更、認証情報の保存や更新などが行われる。 | 元のコードが実行されなくなっても、追加された機能や変更済みの状態が残る場合がある。 | 追加ファイル、設定変更、認証情報などについて、発生した操作に応じた確認を行う。 |
この表では、状態の変化が異なる場所で、異なる条件によって生じることを示している。配布元のコードを修正する操作は、端末側のキャッシュに保存された内容を必ずしも変更しない。また、端末側のキャッシュを更新しても、稼働中のプログラムが以前に読み込んだコードを使用し続ける場合がある。さらに、悪性コードがすでに追加ファイルや設定変更を残していた場合、それらはキャッシュとは別に確認しなければならない。修復の対象が配布元、取得内容、実行中の処理、保存された状態のどれであるかによって、修復後に実行可能な操作が制約されたかを判断する条件も異なる。
この関係は、セキュリティ上の権限を時間的に評価する必要性を示している。静的なアクセス制御の一覧では、P にどの権限が与えられているかを確認できる。しかし、同じ権限設定の下でも、読み込むコードが変われば、P が実際に呼び出す機能が変わる。さらに、読み込んだコードが端末内に状態を残せば、後の処理は現在の配信内容だけからは決まらなくなる。外部入力の変化が実行内容を変え、その実行結果が端末の状態を変え、変更された状態がさらに後の実行条件へ影響する。このように、入力の変更と状態の更新が連続することで、実効的な操作到達可能性は時間の中で変化する。
既稿「構造振動モデルとは何か」は、構造を固定されたものとして捉えるだけでなく、環境条件や観測に応じて再編される過程として扱う考え方を示している[13]。また、「構造振動モデルを社会に適用する」では、観測が得られる時点と、判断や更新が実施される時点の違いが、構造の状態に影響することを論じている[14]。ソフトウェアの権限構造でも、外部コードが変更された時点、端末が変更後の内容を取得した時点、実際の操作が行われた時点、異常が観測された時点、修復が反映された時点を区別できる。各時点を一つにまとめると、どの状態に対する観測や介入なのかが不明確になる。
例えば、改ざんコードが時刻 t1 に配信され、端末で時刻 t2 に実行され、時刻 t3 に異常が検出されたとする。t1 から t2 までの間には、配信元の状態が変化していても、端末がまだ改ざんコードを実行していない場合がある。t2 から t3 までの間には、端末上で実行可能な操作が変化していても、その変化が運用者に観測されていない場合がある。さらに、t3 の検出結果を受けて配布元を修正しても、端末側への反映には別の時間が必要になる場合がある。配信、実行、観測、介入の各時点を分離することで、どの期間にどの操作経路が成立し得たのかを具体的に評価できる。
ただし、こうした時間的変化を構造振動モデルで記述するには、何を構造に含め、何を環境条件として扱うかを定義する必要がある。例えば、分析対象をランチャー内部の実行機構に限定するなら、ランチャーが利用できる内部 API、呼び出し関係、実行権限などを構造として扱い、外部から取得するコードの内容を環境条件として扱える。この定義では、ランチャーの構造が同じでも、外部コードの変更によって実行される操作が変化する。一方、CDN とランチャーを一体の配布システムとして分析するなら、CDN に保持されたファイルや配布経路も構造状態に含めることができる。その場合、配布資源の改ざんは、分析対象としたシステム内部の状態変化として表現される。
構造と環境条件の区別は、分析対象の境界によって決まる。ランチャー内部だけを対象とするモデルと、配布基盤から端末までを含むモデルでは、同じ改ざん事象を異なる位置に表現することになる。しかし、これは都合に応じて変化の意味を変更してよいということではない。比較する期間を通じて分析対象の境界を固定し、構造に含める要素と環境条件に含める要素を一貫して定義する必要がある。さらに、構造そのものと、その構造が保持する実行中の状態を区別しなければ、コードの変更と、すでに起動した処理が残存することを同じ種類の変化として扱ってしまう。
例えば、ランチャーの実行機構と内部 API を構造として固定した場合、正常なスクリプトを読み込む条件と改ざんされたスクリプトを読み込む条件では、構造の変更がなくても操作到達可能性が異なる場合がある。一方、悪性エージェントが端末上へ新しい実行機能を追加し、その機能が既存の構造へ接続された場合には、モデルの定義によっては構造自体の更新として表現する必要がある。さらに、エージェントを停止しても追加されたファイルが残る場合には、実行中の機能と保存済みの状態を別に評価する必要がある。構造、外部条件、実行状態のいずれが変化したかを区別することで、操作到達可能性が変わった原因を特定できる。
この区別は、修復の効果を判断する際にも必要になる。配信元の改ざんコードを取り除くことは、外部から新たに悪性コードが供給される経路を制約する。一方、すでに端末上へ取得されたコードや追加された実行機能を停止することは、端末側で成立している操作経路を制約する。さらに、攻撃者が認証情報を取得していた場合には、その認証情報を利用して別のサービスへアクセスする経路が残る可能性がある。配布元の修復と、端末上の実行経路の修復と、認証情報の無効化は、それぞれ異なる状態へ作用する。修復が実施されたという事実から安全性の回復を判断するには、対象となる操作経路が実際に遮断されたことを確認する必要がある。
権限構造を時間の中で評価すると、ある時点での安全性は、その時点の構造だけでなく、外部から与えられる入力と、過去の実行によって残された状態にも依存することが分かる。正常な配信内容へ戻った時点でも、端末が改ざんコードを保持していれば、以前の実行経路が残る場合がある。また、端末上の処理を停止しても、すでに取得された認証情報を外部の主体が利用できる状態なら、影響は別の場所へ残り得る。システムの安全性を評価するには、構造がどう変化したか、環境条件がどう変わったか、どの状態が残っているかを、それぞれの時点で確認する必要がある。
このような時間的な関係を記述するためには、権限を持つ主体、機能、資源、操作経路を構造として定義し、その構造が環境条件に応じてどの操作を実行可能にするかを評価する必要がある。同時に、観測された情報と実際の状態を区別し、介入によってどの要素が更新されたかを追跡する必要がある。プログラムの権限設定が変わらないまま操作到達可能性が変化する場合と、内部機能や実行経路そのものが更新される場合を分離することで、静的な権限一覧だけでは把握できない時間的な変化を説明できる。構造振動モデルを適用する際の基礎となるのは、構造の変化と、同じ構造に対する入力や状態の変化を区別することである。
9. 権限関係を構造振動モデルへ写像する
権限システムの時間的な変化を分析するには、プログラムに与えられた権限の一覧を、そのままシステム全体の構造とみなす方法では十分ではない。例えば、利用者 A が外部スクリプトを変更でき、ランチャー P がそのスクリプトを読み込み、内部実行機構 Q が OS のファイル操作 F を呼び出せるとする。A に F の直接実行権限がなくても、A が変更したコードを P が実行し、そのコードから Q を呼び出せるなら、A から F へ至る操作経路が成立する可能性がある。この経路を分析するには、各主体が保有する権限だけでなく、外部情報の変更、コードの取得、内部機能の呼び出し、資源へのアクセスという関係を同じ構造の中に記述する必要がある。
既稿「構造振動モデルを数理モデルとして定義する」は、構造を有向重み付きグラフとして表現し、その状態、環境条件、観測、介入、更新を離散時間のモデルにまとめている[15]。有向グラフとは、要素同士の関係に方向を持たせた表現である。例えば、P が Q を呼び出せることから、Q が P を呼び出せるとは限らないため、両者の関係には方向が必要になる。また、同じ呼び出し関係でも、利用可能な権限や実行条件が異なれば操作の到達範囲も変わる。この違いを表現するため、関係そのものに加えて、その関係に付随する属性を持たせる。
時刻 \(t\) の構造を、既稿の定義に従って次のように表す。
\[S_t=(V_t,E_t,W_t)\]
\(S_t\) は時刻 \(t\) における分析対象の構造である。\(V_t\) は構造を構成するノードの集合、\(E_t\) はノード間に存在する有向の関係、\(W_t\) は、関係の強度、頻度、コスト、依存度などを表す重みである。この定義を権限システムへ適用する場合、ノードには利用者、外部ファイル、ランチャー、内部実行機構、OS の操作、機密資源などを対応させる。エッジには、外部ファイルを変更できる関係、プログラムが外部コードを取得する関係、内部機能を呼び出す関係、ファイルへアクセスする関係などを対応させる。関係の種類は \(E_t\) で区別する。呼び出し引数、認可、実行時の状態といった経路の成立条件は、構造の重みとは分けて判定する。
例えば、外部主体 A、スクリプト D、ランチャー P、内部実行機構 Q、ファイル操作 F、機密ファイル X を考える。A から D への関係は、A が D を変更できることを表す。D から P への関係は、P が D を取得して処理することを表す。P から Q への関係は、P の処理から Q を呼び出せることを表す。Q から F への関係は、Q がファイル操作を実行できることを表し、F から X への関係は、その操作の対象として X を指定できることを表す。これらを結ぶことで、外部の変更者から機密ファイルへの操作経路をグラフ上に記述できる。
ただし、グラフに関係を記録するときには、その関係が何を意味するかを区別する必要がある。「変更できる」「取得できる」「呼び出せる」「許可される」は、互いに異なる条件を表している。例えば、P が Q を呼び出せるという関係は、P の内部処理から Q へ要求を渡す仕組みが存在することを示す。一方、その要求が正当に許可されるかどうかは、要求元の権限、操作対象、引数の検証などによって決まる。呼び出し機構が存在することと、あらゆる引数について呼び出しが許可されることを同一の関係として扱うと、実行可能な操作の範囲を過大に評価することになる。
さらに、「実行できる」と「実行した」も分ける必要がある。Q が F を呼び出せるという関係は、特定の条件の下で F が実行可能であることを示す。一方、実際に F が呼び出されたことは、ある時点で発生した出来事である。例えば、ランチャーが内部のファイル取得機能を備えていても、外部スクリプトからその機能が呼び出されたとは限らない。実行可能性を表す関係と、実行記録から確認された出来事を区別すれば、グラフ上の経路が存在することを、実際に攻撃が行われた証拠として誤って解釈することを防げる。構造に含める実行可能な関係と、観測によって得られる実行記録は、役割の異なる情報である。
権限分析に必要な要素と関係を整理すると、次のようになる。
| 構造上の要素 | 権限システムでの具体例 | 分析上の意味 | 確認する条件 |
|---|---|---|---|
| 主体のノード | 利用者 A、外部コードの変更者、正規プログラムを実行する主体などを表す。 | 操作を指定する主体と、権限を用いて処理する主体を区別する。 | 誰が入力を変更でき、誰の権限で操作が実行されるかを確認する。 |
| プログラムのノード | ランチャー P、内部実行機構 Q、ファイル操作機能 F などを表す。 | 入力がどの機能を経由して最終的な操作へ変換されるかを記述する。 | 各機能が呼び出せる操作と、その実行条件を確認する。 |
| 資源のノード | 外部スクリプト D、機密ファイル X、送信先のサーバーなどを表す。 | 変更される情報、操作対象、結果の到達先を区別する。 | 資源ごとのアクセス権限と、操作対象を指定できる範囲を確認する。 |
| 変更・取得のエッジ | A が D を変更でき、P が D を取得できる関係を表す。 | 外部主体が制御する内容が、正規プログラムへ取り込まれる経路を示す。 | 変更可能な範囲、取得条件、内容の検証、キャッシュの利用条件を確認する。 |
| 呼び出し・操作のエッジ | P から Q、Q から F、F から X への関係を表す。 | 外部入力から資源操作までの到達経路を示す。 | 呼び出し条件、引数の制約、実行権限、操作対象の認可を確認する。 |
| 重み | 関係の強度、頻度、コスト、依存度などを表す。 | 定義した数値尺度に基づいて、関係の違いを比較する。 | 権限の種類や実行条件と混同せず、重みの意味と算出方法を定める。 |
| 観測情報 | コードの取得記録、関数呼び出しの記録、ファイルアクセス、通信記録などを表す。 | 構造上の操作経路が実際に利用されたかを検証する材料になる。 | 記録された出来事と、構造上の実行可能性を区別する。 |
表では、主体、プログラム、資源をノードとして表し、それらを結ぶ変更、取得、呼び出し、操作の関係をエッジとして整理している。ただし、同じノードやエッジであっても、分析に必要な意味が異なる場合には区別が必要になる。例えば、外部スクリプト D を「読み込める」という関係と、D の内容を「実行できる」という関係は同じではない。P が D を取得しても、取得内容をデータとして表示するだけなら、D の変更者が内部機能を自由に呼び出せるとは限らない。取得した内容を実行コードとして解釈し、内部 API へ接続する処理が存在する場合に、D の変更から P の操作へ至る経路が成立する可能性が生じる。
同じ理由から、エッジが連続して存在することだけで、最後の資源操作が成立すると判断することもできない。例えば、P が Q を呼び出せても、Q が受け付ける引数を P が自由に指定できるとは限らない。また、Q がファイル操作 F を利用できても、F の対象として機密ファイル X を指定できるかどうかは別の条件である。さらに、各関係が異なる実行状態でのみ成立する場合には、個々の関係が存在していても、一つの実行過程として連結できないことがある。実行可能な経路を判定するには、各関係が要求する条件を、入力値と実行状態に対して整合的に満たせるかを確認する必要がある。
例えば、P が Q に渡せるファイルパスを、許可済みディレクトリ内へ限定している場合を考える。Q が OS の機能を利用して任意のファイルを読み取れるとしても、P を経由する外部主体 A の操作範囲は、P が許可するパスに制約される。反対に、P が外部スクリプトから任意のパスを受け取り、そのまま Q に渡すなら、A が指定できる操作対象は広がる可能性がある。P と Q の呼び出し関係が同じでも、P が許容する引数の範囲によって、A から機密ファイル X への到達可能性が異なる。この差を記述するには、呼び出し関係の存在だけでなく、その関係に付随する入力制約や認可条件を保持しなければならない。
重み \(W_t\) を用いる場合にも、何を数値で表すかを明確にする必要がある。例えば、関係の強度、呼び出し頻度、処理コスト、依存度などは、それぞれ異なる意味を持つ。呼び出し頻度が高いことと、より広い権限を持つことは同じではない。また、ファイルを読み取る権限とネットワークへ送信する権限を、一つの数値の大小だけで比較することも適切ではない。権限の種類や対象資源の違いはエッジの意味として区別し、引数検証や認可などの実行条件は別に判定する。関係の意味を失ったまま重みだけを比較すると、グラフ上の差を計算できても、どの操作が新たに実行可能になったかを説明できなくなる。
NIKKE PC ランチャーの侵害事案へこの表現を適用すると、改ざんされた JavaScript、ランチャーの取得処理、内部のファイル取得機能、Lua の実行機構、OS の資源操作などを、それぞれ異なる要素として記述できる。例えば、公式 CDN 上の JavaScript に第三者のコードが挿入されていたという事実と、ランチャーがその JavaScript を取得する関係を結び付けると、外部から変更されたコードがランチャーへ取り込まれる経路を表現できる。さらに、そのコードから内部機能を呼び出す関係を加えれば、外部のコード変更が端末上の処理へ影響する条件を表せる。ここで確認するのは、攻撃者がランチャーの OS 権限を直接取得したかどうかではなく、攻撃者が制御するコードを起点として、ランチャーの権限で実行される操作へ到達できるかという関係である。
ただし、NIKKE の事案で確認された各機能をグラフへ記録するときにも、技術解析から確認できる関係と、個々の端末で観測された実行を分ける必要がある。例えば、悪性エージェントがファイル読み取り機能を実装していたなら、その機能への呼び出し経路を構造として記述できる。一方、特定の端末で機密ファイルが読み取られたという事実を記述するには、対応する実行記録や保存された痕跡が必要になる。構造上の経路を分析することと、観測結果から実際の操作を再構成することは、異なる判断である。この区別を維持すれば、攻撃コードの機能を確認したことから、すべての端末で同じ操作が実行されたと推測する誤りを避けられる。
構造振動モデルでは、グラフとして表した構造を数値的に比較するため、構造からベクトル空間への写像を用いる。既稿の計算表現に従い、写像を \(\phi\) とすると、次のように表される。
\[x_t=\phi(S_t)\]
\(x_t\) は、時刻 \(t\) の構造 \(S_t\) を数値的に扱うための表現である。例えば、構造に含まれるノードや関係の変化を、同じ計算方法で比較できる形へ変換することが、この写像の役割となる。異なる時点の構造を同じ基準で表現すれば、構成要素や関係がどの程度変化したかを調べるための材料になる。ただし、どの情報を写像に含め、どの差を保存するかは、採用する \(\phi\) の定義に依存する。権限分析では、操作到達可能性を左右する関係や条件が失われないように、比較対象と写像の性質を確認する必要がある。
例えば、ある時点のグラフでは P から Q への呼び出しが許可されており、別の時点ではその呼び出しが制限されたとする。この変更は、外部主体 A が Q を介して実行させられる操作の範囲に影響する可能性がある。一方、グラフをベクトルへ変換した結果だけを比較しても、特定の操作経路が成立するかどうかを直接判断できるとは限らない。構造の数値表現が近い二つのグラフでも、一方には機密ファイルへの到達経路があり、他方にはその経路が存在しない場合がある。構造の近さと、特定の操作への到達可能性は、異なる評価対象である。
このため、構造振動モデルを権限システムへ適用する際には、構造の数値的な比較と、操作経路の成立判定を役割の異なる計算として扱う。構造の比較では、ノード、関係、重みが時間とともにどう変化したかを調べる。一方、操作経路の判定では、外部主体が制御できる入力を起点として、必要な引数、認可条件、実行権限、状態の制約を満たしながら、目的の操作まで到達できるかを調べる。例えば、外部スクリプトからファイル操作機能へ到達できる経路が新たに成立した場合、構造の変化量が小さくても、権限境界の評価にとっては重要な差となる。数値的な構造差だけでは、その経路がどの資源へ到達するかまで表現できるとは限らない。
さらに、構造を時刻ごとに比較する場合には、分析対象の境界を固定する必要がある。例えば、ランチャー内部の機能と呼び出し関係だけを構造に含め、外部から取得するコードの内容を環境条件として扱うなら、コードが変更されてもグラフ構造は変化しない場合がある。一方、CDN に置かれたファイルの内容や、端末に保存された追加の実行機能まで構造に含めるなら、同じ事象が構造の変化として表現される可能性がある。どちらの表現でも、対象とするシステムの境界を明確に定義すれば、変化の原因を分析できる。しかし、比較する時点ごとに境界を変更すると、構造の変化量が、実際のシステムの変化なのか、モデルの対象範囲の違いなのかを判別できなくなる。
また、構造上の関係と、実行時に変化する値を分離することも必要になる。例えば、P が Q を呼び出せるという関係が維持されていても、P が読み込んだ外部コードの内容によって、実際に Q を呼び出すかどうかが変わる場合がある。このとき、呼び出し機構の存在を表す構造は同じでも、外部主体が実行させられる操作は変化し得る。反対に、外部コードの内容が同じでも、Q からファイル操作を呼び出す機能が削除されれば、操作経路そのものが失われる可能性がある。前者は固定された構造に対する入力条件の違いとして表現でき、後者は構造の変更として表現できる。両者を分けることで、同じ操作到達可能性の変化についても、原因となった条件を区別できる。
権限システムの構造を \(S_t=(V_t,E_t,W_t)\) として表す意義は、個々のプログラムが持つ権限を一覧化することよりも、外部の主体から最終的な資源操作へ至る関係を明示できる点にある。さらに、\(x_t=\phi(S_t)\) によって構造を計算可能な表現へ変換すれば、時点間の構造差を比較するための基礎が得られる。ただし、操作経路の成立は、元のグラフに与えられた関係の意味と、実行時の条件に基づいて判定する必要がある。構造の比較と権限経路の検証を分離することで、構造そのものが変化した場合と、同じ構造の下で外部入力によって実行可能な操作が変化した場合を、異なる現象として記述できる。
10. 外部条件が変わると操作の到達範囲も変わる
同じランチャーが、時刻によって異なる外部コードを読み込む場合を考える。ランチャー内部のコード取得機構、Lua 実行環境、内部 API、OS から与えられた権限が変化していなくても、取得したコードがどの内部機能を呼び出すかによって、実行される処理は異なる。例えば、正常なコードが画面表示に必要な関数だけを呼び出している一方、改ざんされたコードがファイル操作のための関数を呼び出すなら、外部コードの変更者が実行させられる操作の範囲は変わり得る。ランチャーに新しい権限を付与する操作は必要ない。既に存在する内部機能のうち、外部入力から利用される機能が変化するためである。
この現象を分析するには、プログラムが備える実行機構と、その実行機構へ与えられる外部条件を分離する必要がある。ランチャーがファイルを読み取れることは、ランチャー自身の実行権限に関する性質である。一方、外部から取得したコードがファイル読み取り機能を呼び出すかどうかは、取得内容と実行時の条件に依存する。外部コードからファイル読み取り機能へ到達する経路が存在していても、正常なコードがその経路を利用しなければ、通常の実行ではファイル読み取りが発生しない場合がある。しかし、外部コードの変更者がその呼び出しを追加できるなら、変更後のコードを実行する条件の下では、同じ内部機能を利用できる可能性がある。構造上の機能の存在と、特定の入力によってその機能が利用されることは、異なる評価対象となる。
構造振動モデルでは、時刻 \(t\) の構造 \(S_t\) と環境条件 \(C_t\) を分けて扱う。第 9 章で定義した構造には、主体、プログラム、内部機能、資源、およびそれらの間の関係が含まれる。一方、環境条件には、分析対象の外側から与えられる入力や、その構造が動作する際に参照する条件を含めることができる。ランチャー内部の実行機構を分析対象とする場合、外部から取得するスクリプトの内容を環境条件へ含めれば、実行機構を固定したまま、異なるコードを与えた場合の操作到達可能性を比較できる。
この違いを数理的に記述するため、外部主体 \(a\) が、時刻 \(t\) に実際に読み込まれたコードと実行時の状態を含む環境条件を固定したとき、その条件の下で実行させられる操作の集合を、次のように定義する。
\[R_t(a)=R(a;S_t,C_t)\]
\(R_t(a)\) は、外部主体 \(a\) が、指定された時点の入力と実行状態の下で、ほかのプログラムを介して実行させられる操作の集合である。将来、外部主体が入力を変更した場合まで一括した潜在的な操作集合とは区別する。右辺の \(S_t\) は、その時点で対象とするプログラムや機能の構造を表し、\(C_t\) は外部から取得するコードや実行時に参照する条件を表す。関数 \(R\) は、これらの条件の下で、外部主体から最終的な操作まで到達できるかを評価するものとして定義する。例えば、外部主体が変更できるスクリプトから、ランチャーの内部機能を呼び出し、機密ファイルの読み取りへ至る経路が実行可能なら、その読み取り操作は \(R_t(a)\) に含まれる。
ただし、ここでいう実行可能性は、グラフに呼び出し関係が存在するという意味だけではない。外部コードが内部 API を呼び出すには、その API が実行環境へ公開されている必要がある。また、呼び出しに必要な引数を与えられること、実行時の認可条件を満たすこと、対象資源へアクセスする権限があることなども必要になる。例えば、ランチャーがファイル読み取り機能を備えていても、外部コードからその機能を呼び出せなければ、外部コードの変更者はその経路を利用できない。呼び出せる場合でも、読み取り対象が特定のディレクトリに制限されていれば、任意の機密ファイルへ到達できるとは限らない。
この条件を明示するため、外部主体 \(a\) から操作へ至るグラフ上の経路を \(\pi\) とする。経路 \(\pi\) に沿って処理を実行する際、必要な入力値、関数の呼び出し条件、認可、実行状態などが整合的に満たされることを、次のように表す。
\[\Gamma_t(\pi,C_t)=1\]
\(\Gamma_t\) は、時刻 \(t\) の環境条件の下で、経路 \(\pi\) を実行できるかを判定する条件である。値が 1 なら経路の実行条件が満たされ、0 なら少なくとも一つの条件が満たされていないものとする。例えば、P が Q を呼び出せても、Q に渡せるファイルパスが許可済みディレクトリ内に制限されている場合、機密ファイルがその範囲外にあれば、そのファイルへの読み取り経路は成立しない。この場合、呼び出し関係を表すエッジが存在していても、対象とする操作について \(\Gamma_t(\pi,C_t)=0\) となる。
この判定では、経路を構成する各処理の条件が、一つの実行過程として両立することが必要になる。例えば、ある認証情報を利用できる状態と、対象ファイルへアクセスできる状態が異なる時点でしか成立しない場合、個々の条件が過去に成立したという理由だけで、経路全体が実行可能とは判断できない。また、途中の処理が引数を変更したり、実行状態を更新したりする場合には、その変更後の値を用いて後続処理の成立条件を評価する必要がある。経路上のすべての関数が存在することと、実際に一連の呼び出しを最後まで実行できることを区別するために、この条件を導入する。
正常なスクリプトと改ざんされたスクリプトの比較へ戻る。ランチャー P が同じ内部 API と OS 権限を維持しているとする。正常なスクリプトでは画面表示の関数だけが呼び出され、改ざんされたスクリプトではファイル読み取り機能が呼び出される。外部主体がスクリプトの内容を制御でき、そのコードがランチャーに取得され、内部 API の呼び出し条件を満たすなら、改ざんされたスクリプトによって新しい操作経路が利用可能になる。ここで変化したのは、ランチャーの内部機能そのものではなく、その機能を利用するための入力条件である。
構造を固定した比較では、次の条件を考えられる。
\[S_{t+1}=S_t,\qquad C_{t+1}\ne C_t\]
左側の等式は、比較する二つの時点で構造が同じであることを示す。右側の不等式は、環境条件が変化したことを示す。例えば、ランチャーの内部 API、呼び出し関係、OS の権限設定を維持したまま、取得するスクリプトを変更した場合が該当する。ただし、外部条件が変化しても、必ず操作到達可能性が変わるわけではない。変更後のコードが以前と同じ操作しか呼び出さない場合や、追加された呼び出しが実行環境によって拒否される場合には、到達可能な操作集合は変化しないことがある。
一方、外部条件の変更によって、以前は利用できなかった操作経路が成立すれば、次の関係が生じる。
\[R_{t+1}(a)\ne R_t(a)\]
例えば、正常なスクリプトの条件では外部主体が画面表示に関する操作だけを実行させられ、改ざんされたスクリプトの条件では機密ファイルの読み取りまで実行させられる場合、二つの操作集合は異なる。実行機構の構造と権限設定が同じでも、外部条件の変化が内部機能の呼び出し方を変え、外部主体が利用できる操作の範囲を変化させる。これは、構造の変更と、固定された構造に対する入力の変更を区別する具体的な例である。
この比較では、どの外部条件を変更するかによって結果が異なる。例えば、配信元のファイルが改ざんされても、ランチャーが以前の正常なコードをキャッシュから読み込んでいる場合、端末で実行されるコードは変わらない。一方、配信元が修正された後でも、端末が改ざんされたコードをキャッシュから読み込めば、以前の操作経路が引き続き利用可能になる場合がある。配信元の状態と、端末が実際に読み込む内容は区別する必要がある。操作到達可能性を評価する場合、環境条件 \(C_t\) にどのコードが実際に読み込まれるかを含めることで、配信元の変更と端末上の実行可能性の変化を対応付けられる。
同じ構造に対して異なる環境条件を与えた場合を、次のように整理できる。
| 比較する条件 | 構造と環境の状態 | 操作経路の成立条件 | 操作到達可能性への影響 |
|---|---|---|---|
| 正常なスクリプトを実行する場合 | ランチャーの内部機能を固定し、画面表示だけを呼び出すコードを与える。 | 表示処理の呼び出し条件が満たされ、ファイル操作を指定する入力は与えられていない。 | 外部コードの変更者が実行させられる操作は、与えられた入力と呼び出し条件の範囲に収まる。 |
| 改ざんされたスクリプトを実行する場合 | ランチャーの内部機能を固定し、ファイル操作の呼び出しを含むコードを与える。 | 内部 API が外部コードから利用でき、引数と実行権限の条件が満たされる。 | 以前は外部入力から利用されなかったファイル操作が、実行可能な操作集合に加わる場合がある。 |
| 改ざんコードの呼び出しが制約される場合 | 外部コードにファイル操作の呼び出しが含まれていても、内部 API の認可や引数制限が適用される。 | 対象資源について実行条件が満たされず、該当経路の判定が 0 になる。 | 外部コードが変更されても、その操作は実行可能な操作集合に加わらない。 |
| 配信元の修正後もキャッシュが残る場合 | 配信元のコードは正常に戻っているが、端末が改ざんされた内容を保持している。 | 端末がキャッシュ内のコードを読み込み、内部機能への呼び出し条件を満たす。 | 配信元の修正後も、端末上では以前の操作経路が成立する場合がある。 |
| 実行時の権限が制約される場合 | 同じ外部コードが読み込まれていても、対象資源へのアクセス権限が変更されている。 | 内部関数を呼び出せても、OS が対象資源へのアクセスを拒否する。 | 外部コードの内容が同じでも、資源操作への到達可能性が制約される。 |
表の比較では、正常なスクリプトと改ざんされたスクリプトの違いだけでなく、実行環境による制約と、端末が保持する内容の違いも扱っている。外部コードにファイル操作の呼び出しが含まれている場合でも、その呼び出しが利用できるかどうかは、内部 API の公開範囲や OS のアクセス制御によって決まる。また、配信元で正常なコードが提供されていても、端末が以前の改ざんコードを使用していれば、実行可能な操作は修復前の条件に従う可能性がある。このように、操作到達可能性を変化させる要因は、配信内容だけでなく、実際に読み込まれた内容と実行時の制約に分かれる。
ただし、環境条件へ含める情報は、分析対象の構造をどこまでとするかによって変わる。ランチャー内部の実行機構だけを構造として定義する場合、CDN から取得するコードの内容や、外部から与えられる操作要求を環境条件へ分類できる。一方、CDN とランチャーを一体の配布システムとして構造に含めるなら、CDN に保存されたコードの改ざんは、構造に含まれる資源の状態変更となる。また、端末に保存された追加の実行機能を構造に含める場合には、悪性エージェントの導入によって新しい関係が追加されたものとして記述できる。構造と環境条件の分類は、モデルが対象とするシステム境界に依存する。
この分類は、同じ分析の途中で変更すると、比較の意味が変わってしまう。例えば、時刻 \(t\) では外部スクリプトを環境条件として扱い、時刻 \(t+1\) ではスクリプトを構造の一部として扱った場合、二つの時点の構造差には、システムの実際の変化と、モデルの分類方法の違いが混在する。構造が変化したかを判断するには、分析対象の境界、ノードとエッジの定義、重みの意味を比較期間を通じて統一する必要がある。さらに、環境条件についても、配信元の状態を評価するのか、端末が実際に読み込む内容を評価するのかを区別しなければならない。
操作到達可能性の変化を調べる場合には、構造と環境条件を固定した比較も有効である。例えば、同じランチャーの実行機構に対して、正常なコードと改ざんされたコードをそれぞれ与え、ほかの実行条件をそろえる。正常なコードでは成立しなかったファイル操作の経路が、改ざんされたコードでは成立するなら、その比較条件の下では、外部コードの違いが操作到達可能性の差を生んでいると評価できる。一方、同時に OS の権限や内部 API の公開範囲まで変化していれば、操作到達可能性の変化を外部コードの変更だけに帰属させることはできない。構造と環境条件を分けることには、実行可能性の変化を引き起こした要因を区別する意味がある。
NIKKE PC ランチャーの侵害事案では、公式 CDN 上の JavaScript が改ざんされ、その内容を読み込んだランチャーが追加の処理を実行する経路が解析された。ランチャーの内部機能と OS の実行権限が維持されたまま、外部から取得するコードの内容によって実行される操作が変わり得るという構造が、技術解析によって具体的に示されている[8]。ただし、個々の端末で実際にどのコードが読み込まれたか、追加のプログラムが起動したか、どの操作が実行されたかは、それぞれの端末の状態と観測記録によって評価する必要がある。実行可能性を表す \(R_t(a)\) は、攻撃者が実際にすべての操作を行ったことを意味するものではない。
また、外部条件の変更によって操作到達可能性が変わる場合でも、構造そのものが変化しているとは限らない。ランチャー内部の機能と呼び出し関係を固定したモデルでは、正常なコードと改ざんされたコードの違いを環境条件の差として表せる。この条件で新しい操作経路が成立するなら、構造が不変でも実行可能な操作集合が変化したことになる。反対に、内部 API の削除やアクセス制御の変更によって経路が遮断された場合には、モデルの定義に応じて構造や権限属性の更新として表現できる。同じ操作到達可能性の変化でも、原因が入力の変更である場合と、構造の変更である場合とでは、必要な修復や制御が異なる。
ここから、権限境界の評価には、構造の状態と、構造が外部条件に対してどのように応答するかという二つの観点が必要になる。プログラムの権限設定が不変であっても、外部コードの変更によって内部機能の利用経路が変われば、外部主体が実行させられる操作は変化し得る。一方、内部機能への呼び出し条件を制約すれば、外部コードが変更されても、許可範囲外の操作へ到達する経路を制限できる。操作到達可能性を構造と環境条件の関数として定義することで、どの変化が実行機構に由来し、どの変化が外部入力に由来するかを分けて評価できる。
11. 構造の変化量と危険性は一致しない
構造振動モデルでは、隣接する二つの時点の構造差を振幅として表す。第 9 章で定義した構造 \(S_t\) は、主体、プログラム、内部機能、資源、およびそれらの関係からなるグラフである。構造が時間とともに変化した場合、その変化を一定の基準で比較するために、グラフを数値表現へ写像し、二つの時点の距離を計算する。例えば、ランチャーの内部機能が追加された場合や、外部コードから呼び出せる API が変更された場合、構造に含めたノード、エッジ、属性に差が生じる。この差を測定することと、変更後にどの操作が実行可能になったかを評価することは、異なる計算である。
既稿の定義に従い、時刻 \(t\) の構造振幅 \(A_t\) を次のように表す。
\[A_t=d(S_t,S_{t-1})=\|\phi(S_t)-\phi(S_{t-1})\|_2\]
\(S_t\) は現在の構造、\(S_{t-1}\) は一つ前の時点の構造である。\(\phi\) はグラフ構造を数値ベクトルへ変換する写像であり、\(d\) はその数値表現に基づく距離を表す。右辺の \(\|\cdot\|_2\) はユークリッドノルムであり、二つのベクトルの対応する成分の差を二乗して合計し、その平方根を求める。例えば、二つの構造がそれぞれ \((1,2)\) と \((4,6)\) というベクトルに変換されたなら、その距離は \(\sqrt{(4-1)^2+(6-2)^2}=5\) となる。この値は、採用した数値表現における構造差の大きさを示す。
構造振幅の意味は、写像 \(\phi\) の定義に依存する。例えば、内部 API の追加や削除を数値表現へ反映する場合、その変更によって振幅が生じる。一方、実行可能な操作の種類を区別しない数値表現では、ファイル読み取り機能が追加されたことと、表示機能が追加されたことを適切に区別できない可能性がある。さらに、異なるグラフが同じベクトルへ写像される場合には、構造に差があっても計算上の振幅が 0 になる。このため、\(A_t=0\) という結果から、元のグラフが必ず同一であると結論できるのは、写像がその違いを保存する条件を満たす場合である。一方、元の構造が完全に同一なら、同じ写像を用いる限り、振幅は 0 になる。
権限境界の安全性を評価する際には、構造振幅とは別に、外部主体が実行させられる操作を調べる必要がある。第 10 章では、外部主体 \(a\) が時刻 \(t\) の構造 \(S_t\) と環境条件 \(C_t\) の下で実行させられる操作の集合を \(R_t(a)\) と定義した。ここでいう操作は、ファイルの読み取り、外部への送信、プログラムの起動などを、対象資源や実行条件とともに具体化したものである。また、その主体に要求仕様上許可される操作の集合を、時刻ごとに \(L_t(a)\) とする。この二つを比較すれば、外部主体が実行させられるにもかかわらず、その主体には認められていない操作を特定できる。
権限境界から逸脱する操作の集合を、次のように定義する。
\[B_t(a)=R_t(a)\setminus L_t(a)\]
\(B_t(a)\) は、時刻 \(t\) において外部主体 \(a\) が間接的に実行させられる操作のうち、その主体に許可されていない操作の集合である。集合の差を表す \(\setminus\) は、左側の集合に含まれ、右側の集合に含まれない要素を取り出す。例えば、利用者 A が自分の文書を指定された保管先へ送信することは許可されていても、ほかの利用者の機密ファイルを任意の外部宛先へ送信することは許可されていない場合、その送信操作が実行可能なら \(B_t(a)\) に含まれる。\(B_t(a)=\varnothing\) なら、評価対象とした主体、操作、実行条件の範囲において、到達可能な操作はすべて許可範囲内に収まっている。
ここで、\(A_t\) と \(B_t(a)\) は、表している対象が異なる。\(A_t\) は構造の数値表現における変化量であり、0 以上の数値として計算される。一方、\(B_t(a)\) は許可範囲から外れた具体的な操作の集合である。ファイルの読み取りと外部送信という二つの操作が含まれていても、それだけで危険性を一つの数値へ換算したことにはならない。操作対象となる情報、実行に必要な権限、結果の影響範囲などが異なるためである。振幅の大小と、許可外の操作が成立するかどうかは、それぞれ独立した基準で評価する必要がある。
この違いが明確になるのは、ランチャー内部の構造を固定したまま、外部コードだけが変更される場合である。例えば、時刻 \(t-1\) にランチャー P が正常な JavaScript を読み込み、画面表示に必要な処理だけを実行していたとする。次の時刻 \(t\) に、同じ取得機構と内部 API を備えた P が、改ざんされた JavaScript を読み込む。改ざんコードには、以前から存在していたファイル読み取り機能とネットワーク通信機能を呼び出す処理が含まれている。ここでは、ランチャー内部の構造、API の公開範囲、OS の実行権限は変化していない。外部から与えられるコードの内容が変わったことで、呼び出される機能が変化する。
ランチャー内部だけを構造として定義し、外部から取得するコードを環境条件へ含めるなら、この二つの時点では \(S_t=S_{t-1}\) となる。したがって、同じ写像を用いて計算した構造振幅は \(A_t=0\) である。しかし、正常なコードでは利用されていなかったファイル読み取りや外部送信の経路が、改ざんコードによって実行可能になれば、操作到達可能性は変化する。その操作が外部主体に許可されていなければ、変更後の \(B_t(a)\) には、変更前の \(B_{t-1}(a)\) に含まれていなかった操作が加わる。構造振幅が 0 でも、許可範囲外の操作が新たに実行可能になるという関係が成立する。
ただし、この比較では、\(R_t(a)\) が何を対象としているかを明確にする必要がある。ここで比較しているのは、各時点で実際に読み込まれているコードと実行条件を固定した場合の操作到達可能性である。正常なコードを読み込んだ状態と、改ざんされたコードを読み込んだ状態では、利用可能な操作が異なり得る。一方、攻撃者が将来任意のコードへ書き換えられることまで含めて潜在的な操作能力を評価する場合には、変更可能なコード全体を対象に経路を調べる必要がある。その定義では、正常なコードが現在読み込まれていても、攻撃者が任意の改ざんコードを供給できる時点で、将来成立させられる操作を評価対象へ含めることになる。現在の実行条件の下で成立する操作と、入力を変更することで将来成立させられる操作は、評価範囲が異なる。
NIKKE PC ランチャー侵害の構造を、この比較へ対応させることもできる。ランチャーが公式 CDN 上の JavaScript を取得し、内部機能を呼び出す構成を固定する。正常な配信内容では表示や更新に必要な処理が実行される一方、改ざんされた配信内容では追加のコード取得や内部実行機構の利用が指示される。ランチャーの内部機能が変更されていなくても、外部から与えられるコードの違いによって、実行可能になる処理が変化する。さらに、改ざんコードが起動した悪性エージェントが端末上に新しい実行経路を作った場合には、その追加機能を構造へ含めるかどうかによって、構造の更新として表現する範囲が変わる。配信内容の変更による影響と、実行結果として端末上に生じた構造変更を区別する必要がある。
反対に、構造振幅が大きくても、権限境界の逸脱が縮小する場合がある。例えば、ランチャーが外部コードを実行する際、内部 API を直接呼び出せる構成から、許可された操作だけを提供する隔離環境へ変更したとする。この修正では、外部コードから利用できる関数の範囲、内部機能との接続方法、要求に対する認可処理などが変更される。構造に含めた複数の関係が変化するため、採用した構造表現に応じて振幅が生じる。一方、外部コードから機密ファイルの読み取りや任意の送信先への通信を実行させられなくなれば、\(B_t(a)\) に含まれる操作は減少する。構造の変化が大きいことは、安全性の悪化を意味するわけではない。
例えば、修正前に外部コードからファイル読み取り機能 F と通信機能 N を直接呼び出せたとする。修正後には、外部コードから呼び出せる機能を表示処理と限定された情報取得機能だけに変更し、F と N は認可済みの内部処理からのみ利用できるようにする。この変更によって、外部コードから F や N へ直接到達するエッジが削除されたり、呼び出し条件が厳しくなったりする。変更後もランチャー自身は業務上必要なファイル操作や通信を実行できるが、外部コードの変更者がそれらを自由に指定できる経路は制約される。内部機能を保持しながら、要求元に対して許可する操作を限定することで、構造変更が許可外の操作集合を縮小する方向に働く。
逆に、構造変更によって新しい内部 API が追加された場合でも、その機能が外部コードから利用できるかどうかで、権限境界への影響は異なる。例えば、ログの表示形式を変更するための内部関数が追加されても、外部主体が機密ファイルへ到達する経路が新たに成立するとは限らない。一方、同程度の構造変更であっても、ファイル読み取り機能が外部コードから呼び出せるようになれば、許可範囲外の操作が増える可能性がある。構造変更の量が同程度であっても、変更された関係の意味と、その関係が接続する操作対象によって、権限境界への影響は変わる。
構造振幅と操作到達可能性の違いを、比較条件ごとに整理すると次のようになる。
| 比較条件 | 構造振幅の意味 | 権限境界の評価 |
|---|---|---|
| 構造固定・入力変更 | 同じ構造を比較する限り、振幅は 0 になる。 | 外部入力によって実行される内部機能が変化すれば、許可外の操作が増減する場合がある。 |
| 構造変更・入力固定 | 採用した数値表現に反映される構造差に応じて振幅が生じる。 | 新しい操作経路が追加される場合も、認可や隔離によって既存の経路が遮断される場合もある。 |
| 構造変更・入力変更 | 構造差を測定できるが、入力の変更による影響は振幅だけでは表せない。 | 構造と入力の両方が操作到達可能性に影響するため、それぞれを固定した比較によって原因を分離する必要がある。 |
表の三つの条件は、操作到達可能性が変化したとき、その原因がどこにあるかを区別するためのものである。構造を固定した比較では、入力条件の変更による影響を調べられる。入力を固定した比較では、内部機能や呼び出し制約の変更による影響を調べられる。両方が同時に変化した場合には、観測された操作集合の差を、どちらか一方の変更だけに帰属させることはできない。例えば、外部コードが改ざんされた時期に、ランチャーの内部 API も更新されていたなら、改ざんコードが新しい操作へ到達できた原因には、入力と構造の両方が関係している可能性がある。
この場合、同じ構造に異なる入力を与えた比較と、同じ入力を異なる構造へ与えた比較を組み合わせることで、要因ごとの影響を調べられる。例えば、修正前のランチャーへ正常なコードと改ざんコードをそれぞれ与え、次に修正後のランチャーへ同じ二種類のコードを与える。修正前には改ざんコードから機密ファイルへ到達でき、修正後にはその経路が遮断されるなら、修正後の構造がその操作経路を制約していることを確認できる。一方、正常なコードではどちらの構造でも同じ表示処理が実行されるなら、業務上必要な機能を維持しながら、外部コードが利用できる権限の範囲を限定したと評価できる。ただし、比較には認可規則、実行権限、対象ファイル、キャッシュなどの実行条件をそろえる必要がある。
既稿「安全判定の揺らぎを入力・構造・評価方法に分けて測る」は、同じ判断対象に対する評価が変化したとき、入力条件、判断に用いる構造、評価方法の影響を分離する考え方を示している[16]。今回の権限分析にも、変化の原因を分けて調べるという考え方が対応する。ただし、評価対象は異なる。既稿が扱ったのは判定器の出力に生じる変動であり、ここで扱っているのは、外部主体から具体的な資源操作へ到達できるかという実行可能性である。入力が同じでも判定結果が変わるという現象と、入力の変更によって新しい操作経路が成立するという現象は、同じ量で測定されるわけではない。
この違いは、評価方法の選択にも影響する。構造振幅 \(A_t\) を測定する場合には、グラフをどのように数値化し、どの距離を用いるかが結果を決める。一方、許可外の操作集合 \(B_t(a)\) を求める場合には、外部主体が制御できる入力の範囲、各機能の呼び出し条件、認可規則、実行時の権限を確認する必要がある。例えば、グラフの数値表現に大きな差が生じても、機密ファイルへの操作経路が維持されていれば、その経路に関する権限境界の評価は改善しない。反対に、構造上の一つの呼び出し関係を削除するだけで、許可範囲外の操作へ至る唯一の経路が遮断される場合には、小さな構造変更が安全性の評価を大きく変えることもある。
さらに、\(B_t(a)\) が縮小したという判断には、許可された操作が維持されているかという確認も必要になる。例えば、ランチャーのネットワーク通信を全面的に禁止すれば、外部コードによる不正な送信は制約される可能性がある。しかし、正規の更新処理まで停止する場合には、業務上必要な機能も失われる。許可外の操作を減らすことと、許可された操作を維持することは、別々に確認すべき条件である。隔離や認可の導入によって \(B_t(a)\) を縮小しながら、\(L_t(a)\) に含まれる必要な操作を実行可能な状態に保てるかが、権限構造を修正する際の判断基準となる。
また、\(B_t(a)\) の変化を安全性の改善や悪化として解釈するには、比較する二つの時点で許可集合 \(L_t(a)\) が変化しているかも確認する必要がある。例えば、プログラムの実行機構と外部入力が同じでも、利用者の業務上の権限が取り消されれば、それまで許可されていた操作が許可範囲外へ移る。この場合、到達可能な操作集合 \(R_t(a)\) が変化しなくても、\(B_t(a)\) は増加する可能性がある。逆に、正式な権限付与によって許可範囲が広がれば、同じ操作が \(B_t(a)\) から外れる場合もある。操作到達可能性の変化と、許可規則の変化を分けることで、技術的な実行経路が変化したのか、認可上の基準が変化したのかを区別できる。
構造振幅だけを監視しても、入力変更によって成立した権限逸脱は捕捉できない場合がある。ランチャー内部の構造を固定したまま改ざんされたコードを読み込む場合には \(A_t=0\) でも許可外の操作が増え得るため、構造差と操作到達可能性を独立に評価する必要がある。
12. 観測の遅れが侵害の継続条件を変える
攻撃者が操作を実行できる経路が成立した時刻と、運用者がその異常を把握した時刻は、通常、一致するとは限らない。例えば、ランチャーが取得する JavaScript が改ざんされても、端末がそのコードを取得するまでは、端末上の処理内容は変化しない場合がある。改ざんコードを取得した後も、追加のプログラムが起動するには、必要な処理が実行されることが条件となる。さらに、悪性エージェントが起動しても、監視対象となる操作が発生するか、対応する記録が保存されなければ、運用者が異常を検出するための情報が得られない場合がある。配信内容の変更、端末上での実行、証拠の記録、異常の検出は、それぞれ異なる条件で成立する。
NIKKE PC ランチャーの侵害事案で考えると、改ざんされた JavaScript が公式 CDN に置かれたことと、ある端末で悪性エージェントが動作したことは区別される。ランチャーが改ざんされたコードを取得したか、追加ファイルの取得が成功したか、エージェントが起動したかによって、端末ごとの状態は異なる。例えば、端末 A が改ざん前のコードをキャッシュから読み込んでいる一方、端末 B が改ざん後のコードを取得した場合、同じランチャーを利用していても実行される処理が異なる可能性がある。さらに、端末 B で悪性エージェントが起動しても、その起動を記録する仕組みが存在するかどうかによって、調査時に確認できる情報は変わる。攻撃経路の成立と、成立した経路を観測できることは、異なる問題である。
構造振動モデルでは、分析対象の構造と環境条件から得られる観測結果を、観測写像によって表現する。第 9 章で定義した構造 \(S_t\) と、第 10 章で扱った環境条件 \(C_t\) を用いると、観測結果は次のように表される。
\[O_t=G(S_t,C_t)\]
\(O_t\) は、時刻 \(t\) において取得できる観測情報を表す。\(S_t\) は主体、プログラム、内部機能、資源、およびそれらの関係からなる構造であり、\(C_t\) は外部コードや実行時の条件を表す。\(G\) は、その構造と環境条件の下で、監視や調査によってどの情報が得られるかを表す写像である。権限システムでは、通信ログ、プロセスの起動記録、ファイルアクセスの記録、キャッシュ、保存ファイル、レジストリの状態などが、観測結果の具体例になる。これらの情報は、実行された操作そのものに加えて、操作が残した状態変化を示す場合もある。
例えば、ランチャーが外部スクリプトを取得したとき、取得先の URL と通信時刻を記録する仕組みがあれば、外部資源へのアクセスが発生したことを確認できる。しかし、その記録だけでは、取得したコードが実際に実行されたかどうかは確定しない。さらに、コードが実行された場合でも、内部 API の呼び出しを記録していなければ、どの機能が利用されたかを復元する材料が不足する。悪性エージェントが追加のファイルを作成した場合には、そのファイルが実行の痕跡となることがあるが、ファイルの存在だけでは、その後にどの遠隔操作命令が実行されたかを特定できない。観測情報が支える結論は、記録された操作と状態の範囲によって決まる。
構造が同じでも、監視の設定や記録の保存条件が異なれば、得られる観測結果は変化する。例えば、プロセスの起動だけを記録する環境では、悪性エージェントが起動したことを確認できても、エージェントによる個々のファイルアクセスは確認できない場合がある。一方、ファイル操作の記録を取得する環境では、対象ファイルへのアクセス時刻を調べられる可能性がある。ただし、どの利用者の要求に基づいて操作が実行されたかを記録していなければ、ファイルアクセスと外部からの命令を対応付けることは難しい。観測範囲を広げることは、実行された操作の再構成に利用できる情報を増やすが、個々の記録が持つ意味や証拠としての限界まで解消するわけではない。
観測情報と、そこから導ける結論の関係を整理すると、次のようになる。
| 観測対象 | 確認できる情報 | 確認に必要な追加条件 | 監視が不足した場合の影響 |
|---|---|---|---|
| 外部コードの取得 | ランチャーが特定の時刻に外部資源を取得したことを確認できる。 | 取得した内容が改ざんコードだったかを判断するには、保存内容や完全性を確認する情報が必要になる。 | 改ざんされた資源が端末へ到達したかを特定しにくくなる。 |
| 追加プログラムの起動 | 悪性エージェントに対応するプロセスや実行処理が起動した痕跡を確認できる。 | 起動元や実行内容を特定するには、関連するログや保存ファイルとの対応付けが必要になる。 | コードが取得された段階と、端末上で実際に動作した段階を区別しにくくなる。 |
| ファイルへのアクセス | 特定のプロセスが対象ファイルを開いた時刻や操作の種類を確認できる場合がある。 | 外部からの命令による操作かを判断するには、要求元や実行経路との対応付けが必要になる。 | どの資源が実際に操作されたかを復元する材料が不足する。 |
| 外部への通信 | 通信先、通信時刻、接続状態、通信量などを確認できる場合がある。 | 送信された情報を確定するには、通信内容や送信元の処理に関する証拠が必要になる。 | 通信の発生や継続を検出しにくくなり、情報流出の範囲も特定しにくくなる。 |
| 保存ファイル・レジストリ | 追加されたファイルや設定変更など、端末に残る状態を確認できる。 | 作成時刻、変更主体、関連する実行処理を特定するには、ほかの記録が必要になる場合がある。 | 配布元の修復後に残る実行機能や状態を見落とす可能性がある。 |
| 監視システムの検出結果 | どの条件に該当する異常が、いつ検出されたかを確認できる。 | 異常が実際に発生した時刻と、検出結果が運用者へ通知された時刻を区別する必要がある。 | 対応を開始する時点が遅れ、成立している操作経路が継続する可能性がある。 |
表に示した観測対象は、攻撃経路の異なる段階に対応している。外部コードの取得記録は、改ざんされた資源がランチャーへ取り込まれた可能性を調べる材料になる。追加プログラムの起動記録は、取得されたコードから実行処理が開始されたかを調べる材料になる。ファイルアクセスや通信の記録は、実行された操作の対象と結果を調べるために利用できる。しかし、取得、起動、資源操作、通信という各段階は、必ずしも同じ記録に含まれない。どの段階まで確認できたかを区別しなければ、改ざんコードの取得だけを根拠に情報流出が発生したと判断したり、通信記録が存在しないことを根拠に悪性コードの実行そのものを否定したりすることになる。
観測の不完全性は、記録の取得対象だけでなく、保存期間や記録の完全性からも生じる。例えば、プロセスの起動記録が一定期間で削除される場合、調査を開始した時点では、悪性エージェントの起動を示す情報が残っていない可能性がある。また、端末の時刻が正しく同期されていなければ、異なる情報源に記録された操作の順序を判断する際に誤差が生じる。さらに、悪性コードが自身の作成した一時ファイルを削除する場合には、調査時点のファイルシステムから、その作成や利用の履歴を完全に復元できるとは限らない。記録が見つからなかったという結果は、指定した監視条件と調査範囲において該当する証拠が確認されなかったことを意味する。
構造振動モデルの観測写像 \(G\) を権限分析へ適用する場合、観測結果が過去の操作によって作られた記録を含むことにも注意が必要である。例えば、時刻 \(t\) に保存されているログには、それ以前に実行された操作が記録されている場合がある。その場合、\(O_t\) は時刻 \(t\) に発生した操作だけを表すものではなく、時刻 \(t\) に利用できる観測情報を表す。過去の実行によって蓄積された記録は、分析対象の保存状態として扱うか、環境条件として明示する必要がある。観測時刻と操作の発生時刻を区別することで、後から発見された痕跡を、その発見時刻に実行された操作として誤って扱うことを避けられる。
この違いは、攻撃経路が成立してから異常が検出されるまでの遅延を評価する際に重要になる。外部主体が許可範囲外の操作へ到達できる状態になった時刻を \(t_e\)、その状態に関する異常が検出された時刻を \(t_d\) とする。両方の時刻が特定でき、\(t_d\) が \(t_e\) 以降であれば、検出遅延を次のように定義できる。
\[\tau_d=t_d-t_e\]
\(\tau_d\) は、許可範囲外の操作経路が成立してから、対応する異常が検出されるまでの経過時間である。例えば、端末で改ざんコードが実行可能になった時刻が 10 時であり、監視システムが異常を検出した時刻が 14 時であれば、検出遅延は 4 時間となる。ただし、これは説明用の例であり、NIKKE PC ランチャー侵害事案における実測値を表すものではない。また、検出時刻が分かっていても、操作経路が成立した時刻を特定できない場合には、検出遅延を一つの確定値として計算することはできない。その場合には、取得記録や起動記録から成立時刻の範囲を推定し、遅延の評価に不確実性があることを明示する必要がある。
検出遅延が長い場合、攻撃者が成立した操作経路を利用できる時間が長くなる可能性がある。例えば、改ざんコードの実行後も端末上の悪性エージェントが動作し続け、遠隔から命令を受け付けていたなら、検出までの間に複数の操作が実行される余地がある。一方、悪性コードが一度だけ起動して終了した場合や、外部通信が途中で遮断された場合には、検出遅延が長くても、その期間を通じて同じ操作経路が利用可能だったとは限らない。実際の被害は、攻撃者が与えた命令、実行回数、対象資源、通信の成立条件などによって変わる。経過時間は操作が継続し得た期間を評価するための指標であり、実際の操作回数や取得された情報量を直接表すものではない。
さらに、検出と介入の間にも時間差がある。監視システムが異常を検出しても、その結果が運用者へ通知され、対象が調査され、必要な修復操作が実施されるまでには別の処理が必要になる。例えば、CDN 上の改ざんコードを検出した後、配布元の修正が実施されても、端末が保持しているコードや起動済みの悪性エージェントまで自動的に停止するとは限らない。検出が早く行われても、介入対象が配布元だけに限定されていれば、端末側に残った操作経路が継続する可能性がある。検出までの遅延と、検出後に操作経路が遮断されるまでの遅延を区別する必要がある。
NIST SP 800-137 は、情報システムのセキュリティ状態を継続的に把握し、脅威、脆弱性、セキュリティ対策の有効性などに関する情報を、リスク管理上の判断へ反映するための継続的監視を整理している[17]。権限構造の分析に対応させると、監視の役割は、外部入力の変更、想定外の内部機能の呼び出し、許可範囲外の資源操作などについて、判断に必要な情報を適切な時点で取得できるようにすることにある。例えば、外部コードの取得時に内容の完全性を確認できれば、改ざんされた資源の取り込みを早い段階で検出できる可能性がある。また、内部機能の呼び出しやファイルアクセスを監視すれば、取得したコードが実際にどの操作を行ったかを調べる材料が増える。ただし、監視対象を増やすことと、すべての実行結果を完全に記録できることは同義ではない。
監視で得られた情報を修復へ結び付けるには、観測結果がどの操作経路に対応しているかを確認する必要がある。例えば、外部スクリプトの改ざんを検出した場合、配信資源の修正は、新たな改ざんコードの供給経路を制約する。一方、端末上で悪性エージェントの起動が確認された場合には、端末に残る実行機能や設定変更についても調査する必要がある。さらに、認証情報へのアクセスが確認された場合には、コードやプログラムの修復とは別に、その認証情報を利用した操作経路が残っているかを評価する必要がある。観測された異常が攻撃経路のどの段階に対応するかによって、必要な介入対象が変わる。
観測結果が不完全な場合には、修復後に残る不確実性も明示する必要がある。例えば、改ざんされた JavaScript の配信を停止できたとしても、どの端末で悪性エージェントが起動したかを確認できなければ、配布元の修復だけを根拠に端末側の安全性が回復したと判断することは難しい。反対に、端末上の検査で悪性エージェントの痕跡が見つからなくても、検査対象や保存期間の制約によって、過去の実行を確認できない場合がある。観測から得られた情報と、修復によって実際に変更された状態を対応付けることで、確認できた範囲と、追加の検証が必要な範囲を区別できる。
権限構造の時間的な評価では、許可範囲外の操作経路が成立した時点、実際の操作が行われた時点、その痕跡が記録された時点、異常が検出された時点、修復が反映された時点を分けて扱う必要がある。構造と環境条件によって操作到達可能性が決まり、実際の操作によって端末の状態が変化し、その一部が観測情報として得られる。運用者は観測された情報に基づいて介入するため、観測の範囲と遅延が、その後の構造更新へ影響する。観測できた操作の範囲を実行可能な操作全体と同一視せず、どの経路が成立し、どの経路が実際に利用され、どの経路が修復によって遮断されたかを区別することが、動的な権限境界の評価に必要となる。
13. 修復によってどの構造が更新されるか
侵害されたシステムを修復するとき、最初に異常が見つかった場所を修正することと、攻撃者が利用できる操作経路を遮断することは、異なる作業である。例えば、ランチャーが読み込む JavaScript ファイルが改ざんされていた場合、配布元のファイルを正常な内容へ戻すことで、新たに配信されるコードを修正できる。しかし、すでに改ざんされたコードを取得した端末では、その内容がキャッシュに残っている可能性がある。さらに、改ざんコードが追加のプログラムを起動し、端末上にファイルや設定を作成していた場合、それらは配布元とは別の場所に保存されている。配布元の修復によって変更される状態と、端末上で引き続き利用可能な操作経路を区別する必要がある。
NIKKE PC ランチャーの侵害事案では、この違いが具体的に報告されている。MotherSphere の技術解析によれば、改ざんされた JavaScript ファイル 4 件は異なる時点で正常な内容へ戻され、一部の CDN サーバーでは配布元が修正された後も古い改ざん内容が返されていた。特に FeedList.feb647c9.js は、2026 年 10 月 28 日に配布元で正常な内容へ戻されたものの、一部の CDN サーバーでは 11 月 4 日まで改ざんされた内容が残っていたと報告されている。また、ランチャーが利用する端末側のキャッシュにも改ざんコードが残存し、再び読み込まれる可能性が指摘された[8]。同じファイルについて、配布元での修正時刻、CDN で正常な内容が返されるようになった時刻、端末側の保存内容が更新された時刻は、それぞれ異なり得る。
ここで、配布元のファイルを正常な内容へ戻したという事実だけを修復完了の根拠にすると、実際にランチャーが取得する内容を見落とす可能性がある。例えば、配布元には正常な JavaScript が存在していても、CDN が改ざんされた応答を保持していれば、ランチャーは以前のコードを取得する場合がある。また、CDN が正常な応答を返す状態になっていても、ランチャーが端末側のキャッシュを優先する構成なら、保存済みの改ざんコードが読み込まれる可能性が残る。配布元から端末上の実行環境までの各段階では、同じ資源の異なる複製が利用されるため、修正された複製がどれなのかを確認する必要がある。
HTTP キャッシュの一般的な仕組みは、RFC 9111 に規定されている[18]。HTTP のキャッシュでは、保存された応答を再利用する条件や、有効期限、再検証、無効化などが定義されている。例えば、配布元の資源が更新されても、キャッシュされた応答が利用可能な条件を満たしていれば、取得側へ保存済みの内容が返される場合がある。この仕組みによって、配布元の内容と取得側で実際に利用される内容の更新時刻に差が生じ得る。ただし、ランチャーが独自に保存するファイルや、アプリケーション内部のキャッシュは、HTTP のキャッシュ規則だけで動作を確定できるものではない。各保存領域がどの処理で更新され、どの条件で再利用されるかを、実装に即して確認する必要がある。
さらに、端末が改ざんコードを取得した後には、取得内容とは独立した状態が作られる場合がある。例えば、改ざんされた JavaScript が内部のファイル取得機能を利用して追加のプログラムを保存し、そのプログラムが起動されたとする。この場合、JavaScript の取得経路を遮断しても、保存済みの追加プログラムが自動的に削除されるとは限らない。また、追加プログラムが自動起動の設定を作成していた場合には、ランチャーを終了した後も、別の時点でプログラムが再び実行される可能性がある。外部コードの供給を止める操作と、端末上に残った実行機能を停止する操作は、異なる対象へ作用する。
認証情報への影響が発生していた場合には、さらに別の修復対象が生じる。例えば、悪性エージェントが端末上の認証情報を取得し、その情報が攻撃者へ渡っていたとする。この場合、端末から悪性エージェントを除去しても、攻撃者が取得済みの認証情報を利用できる可能性がある。認証情報を利用した操作は、元のランチャーや悪性エージェントが動作していなくても、別の端末やサービスを経由して成立し得る。端末上の不正な処理を停止することと、取得された可能性がある認証情報の利用を制約することは、異なる介入となる。ただし、認証情報へアクセスする機能が実装されていたという事実から、特定の利用者の認証情報が実際に取得されたと確定することはできない。必要な対処は、確認された証拠と、残存する不確実性の範囲に応じて判断する必要がある。
修復によって更新する対象は、配布される内容、端末に保存された内容、稼働中の処理、追加された実行機能、認証情報などに分かれる。これらの対象は、互いに異なる更新条件を持つ。例えば、キャッシュを削除すれば、次回の取得時に新しい内容が利用される可能性があるが、すでにメモリ上へ読み込まれたコードが停止するとは限らない。また、悪性エージェントのプロセスを停止しても、再起動のための設定が残っていれば、後の時点で実行経路が再び成立する可能性がある。修復作業を評価するには、どの対象を変更したかに加え、その変更によってどの操作経路が制約されたかを確認する必要がある。
構造振動モデルでは、時刻 \(t\) の構造が、環境条件、観測、介入に応じて更新される関係を、次のように表す。
\[S_{t+1}=M(S_t,C_t,O_t,U_t)\]
\(S_t\) は時刻 \(t\) の構造、\(C_t\) は環境条件、\(O_t\) は観測結果、\(U_t\) は運用者などによる介入を表す。\(M\) は、これらの条件を受けて構造がどのように更新されるかを表す写像である。右辺で与えられた状態と条件によって、次の時刻の構造 \(S_{t+1}\) が決まる。例えば、外部コードから呼び出せる内部 API を制限する介入を行い、その変更が実際に適用されれば、外部コードと内部機能の間に存在する呼び出し関係や、その関係に付随する認可条件が更新される。この場合、構造を構成する関係そのものに変更が生じる。
ただし、介入が実施されたという事実だけでは、構造が必ず変更されたとは限らない。例えば、外部コードを取得する先のファイルを正常な内容へ差し替える介入を行っても、ランチャー内部の実行機構を構造として定義している場合には、その構造自体は変わらないことがある。この場合、変更されたのは外部から与えられる内容であり、環境条件 \(C_t\) に対応する。一方、ランチャー内部の API を削除したり、外部コードから利用できる関数を制限したりする介入は、構造に含めた関係や属性の変更として表現できる。介入の対象が構造の内側にあるか、外側にあるかによって、更新される量は異なる。
例えば、分析対象をランチャー内部の実行機構に限定し、CDN に保存されたコードを環境条件へ分類した場合、配布元の修正によって環境条件が変化しても、構造には変更が生じないことがある。この条件では、\(S_{t+1}=S_t\) が成立していても、正常なコードが読み込まれるようになれば、操作到達可能性 \(R_{t+1}(a)\) が変わる可能性がある。一方、悪性エージェントを構造に含めており、その実行機能が削除された場合には、構造に含まれるノードや呼び出し関係が変化する。構造を更新したのか、環境条件を更新したのかを区別することで、修復によって操作到達可能性が変化した原因を特定できる。
配布元の修復と端末の修復を混同しないため、介入対象、期待する効果、残存し得る経路、修復後の確認事項を整理する。
| 介入対象 | 介入の内容 | 制約される操作経路 | 残存し得る状態・経路 | 修復後の確認 |
|---|---|---|---|---|
| 配布元のファイル | 改ざんされた JavaScript を、期待した正常な内容へ差し替える。 | 配布元から新たに改ざんコードを供給する経路を制約する。 | CDN や端末のキャッシュに、以前の改ざんコードが残る場合がある。 | 配布元で提供される内容の完全性を確認する。 |
| CDN のキャッシュ | 改ざんされた応答の無効化や更新を行う。 | CDN に残る古い改ざんコードを端末へ配信する経路を制約する。 | 未更新の配信経路や端末側のキャッシュに、改ざん内容が残る場合がある。 | 対象となる配信経路から、期待した内容が返されることを確認する。 |
| 端末側のキャッシュ | 保存された改ざんコードを除去し、正常な内容を再取得できる状態へ変更する。 | 端末が保存済みの改ざんコードを再び読み込む経路を制約する。 | すでに起動している処理や追加されたプログラムが残る場合がある。 | ランチャーが実際に読み込む内容を確認する。 |
| 稼働中の処理 | 改ざんコードに由来する実行処理や悪性エージェントを停止する。 | 現在動作している処理から、端末上の機能を呼び出す経路を制約する。 | 追加ファイルや自動起動設定が残れば、後の時点で再実行される可能性がある。 | 対象となる処理が停止し、再び起動する条件が残っていないことを確認する。 |
| 追加ファイル・永続化設定 | 悪性コードが追加した実行ファイルや、再起動のための設定を除去する。 | ランチャーの再起動とは独立して悪性処理が起動する経路を制約する。 | 別の保存場所に追加された機能や、取得済みの認証情報を利用する経路が残る場合がある。 | 関連する保存場所と起動条件を調べ、対応する実行経路が遮断されたことを確認する。 |
| 認証情報・認証状態 | 影響が疑われる認証情報の変更や無効化、必要に応じた認証済み状態の失効を行う。 | 取得された可能性がある認証情報を利用して、別のサービスへアクセスする経路を制約する。 | 認証情報とは別に保存されたデータや、ほかの有効な認証手段が残る場合がある。 | 対象の認証情報と認証状態が無効化され、意図しないアクセス経路が残っていないか確認する。 |
| 内部実行機構 | 外部コードから呼び出せる内部 API を制限し、必要な認可処理を追加する。 | 外部入力から許可範囲外の操作へ至る呼び出し経路を制約する。 | 別の内部機能や、すでに端末上に作られた実行機能から同じ操作へ到達する場合がある。 | 外部コードが変更されても、許可外の操作へ到達できないことを確認する。 |
この表では、各介入が異なる対象へ作用することを示している。配布元のファイルを修復することは、攻撃者が制御するコードの供給経路を制約する。一方、端末側のキャッシュを修復することは、保存済みの改ざんコードが再び利用される経路を制約する。また、稼働中の処理を停止することは、その時点で動作している悪性エージェントからの操作を制約する。これらは互いに代替できる操作ではなく、すでに攻撃経路がどの段階まで進んでいたかによって、必要な介入の組合せが変わる。
特に、端末上に追加された実行機能と、攻撃者が取得した可能性のある認証情報は、配布元とは異なる管理境界に属する。例えば、悪性エージェントが新しいプログラムを保存した場合、そのプログラムの削除は端末上のファイルと実行状態を変更する。一方、認証情報の無効化は、その情報を受け付けるサービス側の認証状態を変更する。両者は作用するシステムが異なるため、端末の修復によってサービス側の認証状態まで更新されたとは限らない。攻撃によって操作経路が別の管理境界へ延びていた場合には、それぞれの境界で必要な変更を確認する必要がある。
修復による影響を構造振動モデルで評価する場合、介入の前後で操作到達可能性を比較できる。例えば、外部主体 \(a\) が改ざんコードを通じて機密ファイルの読み取りと外部送信を実行させられる状態から、内部 API の制限によってその経路を利用できなくなった状態へ変化したとする。この場合、介入前の操作集合 \(R_t(a)\) と、介入後の操作集合 \(R_{t+1}(a)\) を比較すれば、どの操作が到達不能になったかを確認できる。さらに、許可集合 \(L_t(a)\) と比較して、許可範囲外の操作集合 \(B_t(a)\) がどのように変化したかを調べれば、修復が権限境界の逸脱を減らしたかを評価できる。
ただし、修復前後で操作集合が異なることだけでは、どの介入がその変化を引き起こしたかを確定できない場合がある。例えば、同じ期間に CDN の修正、端末側のキャッシュ削除、ランチャーの更新が行われたなら、実行可能な操作の減少には複数の変更が関係している可能性がある。原因を特定するには、各介入がどの状態へ作用するかを明らかにし、その状態の変更によって対象の操作経路が遮断されることを検証する必要がある。内部 API の変更を評価する場合には、外部コードの内容とほかの実行条件を固定した比較が有効である。一方、キャッシュの削除を評価する場合には、削除前後で実際に読み込まれるコードを確認する必要がある。比較対象をそろえることで、介入と結果の対応関係を調べられる。
さらに、修復によって操作経路が遮断されたという判断には、介入後の状態が継続することも関係する。例えば、キャッシュを削除した直後には正常なコードが読み込まれていても、配信元の改ざんが残っていれば、次回の取得によって改ざんコードが再び保存される可能性がある。また、悪性エージェントのプロセスを停止しても、自動起動設定が残っていれば、端末の再起動後に同じ機能が動作する場合がある。介入直後の一時的な状態と、次の取得や再起動を経た後の状態を区別する必要がある。修復の効果は、一度の操作結果だけでなく、想定される再実行条件の下で操作経路が再成立するかどうかによって評価される。
修復時には、観測可能な証拠が介入によって変化することにも注意が必要である。NIKKE PC ランチャー侵害の技術解析では、2026 年 11 月 5 日以降の更新された公式 PC クライアントが、利用者の同意に基づいて関連するログ、DLL ファイル、レジストリ項目を削除する機能を備えたことが報告されている。また、一部のログが同意確認なしに削除されたという報告もある[8]。不正なファイルや設定を除去する操作は修復に必要となる場合があるが、同じ保存領域に攻撃の実行を確認するための証拠が含まれていると、削除後に過去の操作を復元することが難しくなる可能性がある。修復によって実行経路を遮断することと、調査に必要な証拠を保持することは、それぞれの目的を考慮して順序を決める必要がある。
例えば、端末に残されたログから悪性エージェントの起動時刻を確認できる場合、そのログを保存してから修復することで、後から実行履歴を調べるための情報を保持できる。一方、ログやキャッシュを削除した後では、攻撃経路の成立を示す痕跡が失われる場合がある。ただし、証拠を保持するために悪性処理を無制限に動作させ続ければ、その間に許可範囲外の操作が実行される可能性もある。継続する侵害を制約するための措置と、証拠を保全するための措置は、対象の状態と緊急性に応じて組み合わせる必要がある。どの介入がどの記録を変更するかを把握することが、修復後の証拠評価にも関係する。
NIST SP 800-61 Rev. 3 は、インシデント対応を組織のサイバーセキュリティリスク管理の活動へ組み込み、事前の準備、検出、対応、復旧の有効性を改善するための推奨事項を整理している[19]。権限構造の分析に対応させると、インシデント対応で実施した操作の一覧だけでなく、それらの操作がどの実行経路を制約し、どの状態を変更したかを確認する必要がある。例えば、改ざんファイルを差し替えたという作業記録は、配布元に対する介入が行われたことを示す。一方、その介入後に端末が正常なコードを読み込んだか、悪性エージェントが停止したか、追加された実行機能が残っていないかは、それぞれ別の確認事項となる。実施した作業の完了と、目的とした操作経路の遮断を分けて評価する必要がある。
修復の成否を評価する際には、正常な操作が維持されているかという条件も必要になる。例えば、ランチャーのファイル取得機能を全面的に停止すれば、外部コードから不正なファイルを取得する経路は制約される可能性がある。しかし、同じ機能が正規のゲーム更新にも利用されていれば、更新処理まで停止することになる。また、ネットワーク通信を全面的に禁止する方法は、外部への情報送信を制約できる一方、サービスの利用に必要な通信も遮断する。操作経路を削除することだけを修復の目的にすると、本来維持すべき機能も失われる可能性がある。
このため、修復後の構造には、許可範囲外の操作を遮断することと、許可された操作を実行可能に保つことの両方が求められる。例えば、外部コードから任意のファイルを読み取る機能を呼び出せる構成を、業務上必要な資源だけにアクセスできる構成へ変更する場合を考える。この変更によって、外部主体が機密ファイルへ到達する経路を遮断しながら、ランチャーが正常な更新ファイルを取得する機能を維持できる可能性がある。修復の評価では、単に構造が変更されたかどうかではなく、どの操作が実行不能になり、どの操作が引き続き実行可能であるかを具体的に確認する必要がある。
さらに、修復の対象となる操作経路が複数存在する場合には、一つの経路を遮断しても、別の経路から同じ操作へ到達する可能性がある。例えば、外部 JavaScript からファイル操作機能を呼び出す経路を制限しても、すでに端末上へ保存された悪性エージェントが別の方法でファイルへアクセスできる場合には、同じ資源操作が引き続き実行可能である。配布元の修復によって新たな感染経路を制約し、端末側の修復によって既存の実行経路を制約し、必要に応じて認証情報を無効化することで、異なる経路をそれぞれ遮断する必要がある。最終的な操作へ到達する複数の経路を区別することが、修復対象の漏れを防ぐ条件となる。
構造振動モデルにおける更新写像 \(M\) は、介入がどの状態へ作用し、次の時点の構造をどう変えるかを記述するためのものである。しかし、更新によって構造が変化したという事実だけでは、安全性の改善を判定できない。例えば、外部コードの呼び出し経路が一つ削除されても、別の経路が残っていれば、許可外の操作集合 \(B_t(a)\) は変化しない場合がある。反対に、構造の変更がわずかであっても、許可外の操作へ至る唯一の経路が遮断されれば、\(B_t(a)\) からその操作が除かれる可能性がある。修復の効果を評価する量は、構造の更新そのものではなく、その更新後に成立する操作到達可能性と許可範囲の関係である。
したがって、修復によって何が更新されたかを判断するには、介入対象、更新された状態、実際に読み込まれる内容、残存する実行経路を対応付ける必要がある。配布元のコードを正常化しても、端末のキャッシュや稼働中の処理に改ざんコードが残る場合がある。端末上の悪性エージェントを除去しても、取得済みの認証情報を利用する経路が残る可能性がある。内部 API を制限しても、別の機能を介して同じ操作へ到達できる場合がある。各介入の前後で操作到達可能性を確認し、許可範囲外の操作が実際に遮断されたことを検証することが、権限構造の修復を評価する条件となる。
14. 構造の安定性をどのように評価するか
構造振動モデルで構造の変化量を測定すると、システムが時間とともにどの程度変化しているかを調べられる。しかし、構造の変化が小さいことと、権限境界が安全に保たれていることは異なる。例えば、ランチャー内部の実行機構と OS の権限設定が長期間変化していなくても、外部から取得したコードが内部 API を通じて機密ファイルへアクセスできる構成なら、許可範囲外の操作経路は残り続ける。反対に、外部コードを隔離するために実行機構を大幅に変更した場合、構造の変化量は大きくなるが、外部主体が実行させられる操作を制約できる可能性がある。構造の安定性と権限境界の安全性は、それぞれの評価条件を明示したうえで比較する必要がある。
既稿の構造振動モデルでは、構造がある基準構造 \(S^*\) の近傍に留まることを、運用上の安定性を評価する一つの条件として扱う。例えば、ランチャーの内部機能や呼び出し関係が、想定した構成から大きく変化していなければ、構造の数値表現に基づく距離は小さくなる場合がある。この評価は、構成要素や関係がどの程度維持されているかを調べるために利用できる。一方、基準構造そのものに許可範囲外の操作経路が存在していれば、その構造へ近い状態が続いていても、安全性が確保されているとは限らない。安定した構造を維持することと、安全な構造を維持することを区別する必要がある。
例えば、ランチャー P が外部スクリプト D を読み込み、D から内部のファイル読み取り機能 F を呼び出せる構成を考える。P の実行ファイル、内部 API、アクセス制御が長期間変化していなければ、構造振幅 \(A_t\) は小さい値を取り続ける可能性がある。しかし、D の内容を外部主体 A が変更でき、F に任意のファイルパスを渡せるなら、A は機密ファイルを P の権限で読み取らせられる場合がある。正常なスクリプトが F を呼び出していなかったとしても、その事実だけでは、改ざんされたスクリプトから F を利用する経路が制約されているとは判断できない。構造が変化していないという観測は、外部主体による入力変更に対して、どの操作が実行可能になるかまで示すものではない。
反対に、外部スクリプトの実行環境を変更し、内部 API へ直接アクセスできる構成から、限定された機能だけを呼び出せる構成へ改修したとする。この場合、プログラム間の呼び出し関係や認可条件が変更されるため、構造に差が生じる。改修後に、外部コードから機密ファイルの読み取りや任意の宛先への通信が実行できなくなれば、外部主体が利用できる許可外の操作経路は縮小する。一方、正常な更新処理や画面表示が引き続き実行できれば、業務上必要な機能も維持される。構造の変化量が大きいという事実だけから、その改修を不安定化や危険性の増大として評価することはできない。変更された関係がどの操作を新たに許可し、どの操作を制約したかを確認する必要がある。
この違いを数理的に評価するため、第 11 章で定義した許可外の操作集合 \(B_t(a)\) を用いる。\(B_t(a)\) は、時刻 \(t\) に外部主体 \(a\) が間接的に実行させられる操作集合 \(R_t(a)\) から、その主体に許可された操作集合 \(L_t(a)\) を除いたものである。この集合が空であれば、評価対象とした条件の下では、外部主体が実行させられる操作は許可範囲内に収まっている。ただし、ある一つの入力について集合が空であることから、外部主体が変更できるすべての入力について同じ結果になるとは限らない。権限境界の安全性を評価するには、外部主体が実際に制御できる入力の範囲を含めて、成立条件を指定する必要がある。
そこで、評価対象とする外部主体の集合を \(\mathcal{A}_{\mathrm{scope}}\)、想定する環境条件の集合を \(\mathcal{C}_{\mathrm{scope}}\) とする。例えば、前者には外部スクリプトの内容を変更できる主体や、ランチャーへ操作要求を送信できる主体を含める。後者には、正常なスクリプト、改ざんされたスクリプト、異なるキャッシュ状態、実行時の認証情報やアクセス制約など、評価に含める条件を定める。これらの範囲に対して、許可外の操作が実行可能にならないことを要求する。
\[\forall a\in\mathcal{A}_{\mathrm{scope}},\ \forall C\in\mathcal{C}_{\mathrm{scope}}:\quad R(a;S_t,C)\setminus L_t(a)=\varnothing\]
この式は、評価対象に含まれる各外部主体について、想定した環境条件の下で許可外の操作が到達可能にならないことを求める条件である。\(\varnothing\) は空集合を表す。例えば、外部コードを変更できる主体 A に対し、正常なコードだけでなく、内部 API の不適切な呼び出しを含むコードを与えた場合にも、許可範囲外のファイル操作が実行できないことを確認する。外部入力の内容が変化しても、実行環境や認可機構によって許可外の操作経路が遮断されるなら、対象とする条件の下で \(B_t(a)=\varnothing\) を満たすことになる。
この評価で重要なのは、対象範囲を固定することである。例えば、外部スクリプトから直接呼び出せる API だけを評価しても、スクリプトが別の内部機能を介して同じファイル操作へ到達できるなら、評価対象から経路が漏れている。また、端末のキャッシュに改ざんコードが残る条件を除外していれば、配布元が正常な状態に戻った後の再実行可能性を十分に評価できない。主体、操作、環境条件を明確に定義することによって、どの範囲について許可外の操作が存在しないと判断したのかを説明できる。対象外の主体や条件については、同じ安全性が成立するかを別に確認する必要がある。
さらに、操作集合の粒度をそろえることも必要になる。例えば、外部コードが「ファイルを読み取れる」という分類だけで評価すると、ゲームの更新に必要な公開ファイルの読み取りと、利用者の機密ファイルの読み取りが同じ操作として扱われてしまう。また、「外部通信を実行できる」という分類だけでは、正規の更新サーバーへの接続と、攻撃者が指定した宛先への情報送信を区別できない。操作対象、実行内容、送信先、要求元などを同じ粒度で定義して初めて、\(R_t(a)\) と \(L_t(a)\) を適切に比較できる。許可外の操作集合を求める際には、どの情報がどの宛先へ移動することまで許されるかを含める必要がある。
ただし、許可外の操作が存在しないという条件だけでは、ソフトウェアとして必要な機能が維持されているかを評価できない。例えば、ランチャーが外部コードを一切実行せず、ネットワーク通信もすべて停止する構成に変更されたとする。この場合、外部主体が不適切な操作を実行させられなくなる可能性があるが、ゲームの更新や起動に必要な処理まで失われることがある。許可外の操作を減らすという目的だけを考えれば有効に見える制約でも、ソフトウェアの要求仕様を満たすとは限らない。安全性の評価には、禁止すべき操作の遮断と、必要な操作の維持という二つの条件がある。
このため、正当に必要な操作については、許可集合 \(L_t(a)\) の中から、実際に実行可能であることを要求する操作を明確に定める必要がある。例えば、正規ランチャーには、許可された更新サーバーから必要なファイルを取得し、その内容を所定の保存先へ配置する機能が求められる。一方、外部スクリプトの変更者には、任意の機密ファイルを読み取ったり、任意の送信先へ転送したりする能力を認める必要はない。実行主体と要求元を区別したうえで、正規の更新処理が成立し、外部主体による許可外の操作が成立しないことを同時に確認する。対象とする要求仕様に応じて必要な操作を選別することが、機能を維持したまま権限境界を制約する条件となる。
この二つの条件を評価するには、正常な入力と、権限境界を越える操作を指定する入力を比較する方法が有効である。例えば、正常な更新コードを読み込ませた場合には、更新ファイルの取得と配置が成功することを確認する。一方、同じ実行環境へ機密ファイルの読み取りを要求するコードを与えた場合には、その要求が拒否されることを確認する。さらに、内部 API の呼び出し方法を変えたり、異なるパス表記を使用したりしても、同じ制約が適用されるかを調べる必要がある。単一の入力で拒否が確認されたことは、その入力に対応する経路が制約されていることを示す。対象となる操作経路全体の安全性を判断するには、入力条件と呼び出し経路の網羅範囲を明示する必要がある。
構造上の制約を設計する際には、外部から取り込む内容を検証する方法と、取り込まれた内容が利用できる権限を制限する方法を区別できる。例えば、外部スクリプトを取得する前に、その内容が期待したものと一致するかを検証する仕組みがあれば、改ざんされたコードを実行環境へ取り込む経路を制約できる。一方、内容の検証を通過したコードであっても、そのコードが内部のファイル操作や通信機能を自由に呼び出せる設計なら、実行時の権限境界は別に評価する必要がある。取得内容の完全性と、取得後の実行権限は、攻撃経路の異なる段階に作用する制約である。
W3C の Subresource Integrity は、ウェブページが外部資源を取得する際に、あらかじめ指定したハッシュ値と取得内容を照合する仕組みを規定している[20]。例えば、ウェブページが読み込む JavaScript について期待するハッシュ値を指定し、取得した内容の計算結果が一致しなければ、その資源の利用を拒否する。この仕組みは、配布元から返された内容が期待した内容と一致するかを検証するために利用できる。ただし、検証に用いるハッシュ値自体が攻撃者によって変更されれば、改ざんされたコードに対応する値へ置き換えられる可能性がある。そのため、取得するコードの完全性を検証する仕組みと、期待値を信頼できる形で管理する仕組みの両方が必要になる。
また、Subresource Integrity はウェブ資源の取得に関する仕様であり、任意のネイティブアプリケーションの内部ファイル取得機構に、そのまま適用できることを意味するものではない。ランチャーが独自の通信機構でスクリプトや追加ファイルを取得する場合には、その取得処理がどのように内容を検証できるかを、実装に即して検討する必要がある。重要なのは、どの仕組みを採用するかという名称よりも、実際に実行されるコードが、改ざんを検出できる条件の下で取り込まれているかという点である。配信元が正規であることだけを確認する場合と、取得内容の完全性まで確認する場合とでは、外部コードの変更が実行環境へ到達する条件が異なる。
一方、コードを実行する環境では、外部から取り込まれた内容が利用できる内部機能を限定することが重要になる。例えば、ランチャー内部のファイル取得機能、OS のコマンド実行機能、認証情報へアクセスする機能が、外部スクリプトから直接呼び出せる構成では、外部コードの変更者がそれらの機能を利用できる可能性がある。これに対し、外部コードから利用できる関数を表示処理や限定されたデータ取得だけに制約し、ファイル操作や通信については内部の認可処理を通す構成なら、外部入力の変更が許可外の操作へつながる経路を減らせる。実行環境の隔離は、外部コードを取得すること自体とは別に、そのコードが利用できる権限の範囲へ作用する。
Electron のセキュリティ指針は、信頼できないコンテンツに強い実行権限を与える場合の危険性や、外部コンテンツと内部機能の境界を制約するための設計上の注意点を整理している[21]。例えば、外部コンテンツから強力な内部 API へ直接アクセスできる構成では、コンテンツの制御者が利用できる操作も広がる可能性がある。反対に、内部機能を隔離し、外部側へ公開する機能を必要な範囲に限定すれば、外部コードが変更された場合にも、操作の到達範囲を制約できる。ただし、この指針は Electron を利用するアプリケーションに関するものであり、NIKKE PC ランチャーが Electron で実装されていたことや、特定の Electron の設定が利用されていたことを示す根拠ではない。ここでは、外部コンテンツと権限を持つ内部機能の接続を制限する設計上の比較対象となる。
さらに、実装された機能の安全性を維持するには、ソフトウェアの開発と供給の過程で、想定外の変更を検出し、検証できる仕組みが必要になる。NIST SP 800-218 は、Secure Software Development Framework として、ソフトウェアの開発、構築、供給などの活動に組み込むセキュリティ上の実践を整理している[22]。外部コードを取得して実行するソフトウェアへ対応させると、配布資源がどの工程で作成され、誰が変更でき、どのように検証され、利用者へ届けられるかという管理上の条件が関係する。例えば、配信内容の変更を承認された成果物へ限定し、配布前後で内容の整合性を確認する仕組みがあれば、想定外のコードが実行環境へ供給される経路を制約するための材料になる。
ただし、開発工程や配布経路の管理が適切であっても、実行環境の内部 API が外部コードへ広く公開されている場合には、取得内容が変更された際の操作到達可能性を別に評価する必要がある。また、実行環境を隔離していても、配布資源が改ざんされたまま運用されれば、表示内容の改変や、隔離範囲内での不正な処理が発生する可能性がある。取得内容の検証、実行できる機能の限定、要求ごとの認可、配布工程の管理は、同じ経路上の異なる条件を制約する。各段階が実際にどの操作を防止するのかを確認することで、対策の効果を具体的に評価できる。
操作経路のどの段階へ制約を適用するかを、次のように整理できる。
| 制御対象 | 制約の方法 | 評価すべき結果 |
|---|---|---|
| 配布される内容 | 取得した資源が期待した内容と一致するかを検証し、検証に用いる期待値の管理も保護する。 | 改ざんされた内容が実行環境へ取り込まれる経路を拒否できるか確認する。 |
| 外部コードの実行環境 | 外部コードから呼び出せる内部機能と利用可能な資源を限定し、必要な機能だけを公開する。 | 外部コードの内容が変更されても、許可外の資源操作へ到達できないか確認する。 |
| 権限を持つ仲介者 | 要求元の識別、操作対象の検証、要求ごとの認可を行い、必要な権限だけで処理する。 | 正規プログラムの権限が、許可されていない要求へ利用される経路を遮断できるか確認する。 |
| 修復と再検証 | 配布元、キャッシュ、稼働中の処理、保存された状態をそれぞれ更新し、必要な機能を含めて再評価する。 | 介入後に許可外の操作経路が残っていないことと、業務上必要な操作が維持されていることを確認する。 |
表の各制約は、攻撃経路の異なる段階へ作用する。配布される内容の検証は、想定外のコードを取り込む入口へ作用する。実行環境の制約は、取り込まれたコードが利用できる内部機能へ作用する。仲介者による認可は、要求元が正規プログラムの権限を利用してよいかという判断へ作用する。修復と再検証は、すでに改ざんされた内容が端末へ取り込まれたり、追加の実行機能が作られたりした後の状態へ作用する。いずれか一つの制約が有効でも、ほかの経路から同じ操作へ到達できる場合があるため、最終的な資源操作までの経路全体を確認する必要がある。
これらの制約を適用した後には、構造の変化量と操作到達可能性を別々に測定する。例えば、内部 API の公開範囲を縮小する改修によって構造振幅 \(A_t\) が大きくなった場合でも、外部コードから機密ファイルの読み取りへ到達できなくなれば、許可外の操作集合 \(B_t(a)\) は縮小する可能性がある。一方、配布資源の完全性確認を追加しても、実際に実行されるコードの検証が行われない経路が残っていれば、その経路を介した操作到達可能性は維持される場合がある。どの制約を実装したかという作業結果と、その制約によってどの操作が到達不能になったかという検証結果を対応付ける必要がある。
さらに、改修直後だけでなく、環境条件が変わった場合の応答も確認する必要がある。例えば、正常なコードを読み込んだ状態では問題がなくても、改ざんされたコードを読み込ませると内部 API を通じて機密ファイルへ到達できるなら、外部入力の変更に対する権限境界は維持されていない。また、配布元のコードを修正した直後には正常な動作へ戻っていても、端末のキャッシュに改ざんコードが残っていれば、再起動後に以前の経路が成立する可能性がある。介入後の一時点で \(B_t(a)=\varnothing\) が確認された場合でも、想定した環境条件の範囲で同じ結果が維持されるかを調べる必要がある。
この評価は、実際に観測された操作だけを調べる方法とも異なる。例えば、改修後の監視期間に機密ファイルへの不正なアクセスが記録されなかったとしても、それだけでは、外部コードからその操作を実行させる経路が存在しないとは確定できない。攻撃者が当該機能を利用しなかった場合や、監視対象から操作が漏れた場合にも、同じ観測結果が得られる可能性がある。操作到達可能性の評価では、実行機構、入力制約、認可規則、資源への権限を確認し、どの経路が実行可能かを調べる必要がある。観測結果は、その判定を検証する材料として利用できるが、観測されなかったことと到達不能であることを同一視することはできない。
また、評価対象となる環境条件を広げると、確認すべき操作経路も増える。例えば、正常なコードだけを対象にすれば、正規の更新処理が動作することを確認できる。しかし、改ざんコード、古いキャッシュ、異なるアクセス権限、追加プログラムの残存などを含めると、同じランチャーについて複数の実行状態を評価する必要が生じる。すべての可能な入力と状態を網羅的に列挙することが困難な場合には、外部主体が制御できる入力の範囲、許可外の操作へ至る主要な経路、介入後に残存し得る状態を明示し、その範囲について実行可能性を検証する。確認した範囲を限定することは、評価結果の意味を明確にするための条件である。
このように、構造の安定性と権限境界の安全性を同時に評価するには、構造の数値的な距離、外部条件に対する操作到達可能性、許可された機能の維持、介入後の状態を分けて調べる必要がある。構造が長期間変わっていないことは、既存の実行機構が維持されていることを示す場合がある。しかし、その構造を通じて外部主体がどの操作を実行させられるかは、入力と実行条件によって決まる。外部コードが変更されても許可外の操作へ到達できず、修復によって失われるべき経路が実際に遮断され、必要な操作が維持されることを確認して初めて、権限境界の安全性を具体的に評価できる。
15. 権限境界を更新される構造として捉える
利用者 A が機密ファイルを直接読み取る権限を持たなくても、そのファイルを読み取れるプログラム P に対して、読み取り対象と送信先を指定できる場合には、A の要求によって機密情報が外部へ送信される可能性がある。OS のアクセス制御は、A による直接の読み取りを拒否し、P による読み取りを許可しているため、設定された規則どおりに動作している。それでも、P が A の指定した対象と送信先を十分に検証しなければ、A に許可されていない情報の取得が成立する。ここで生じているのは、A の直接権限の変更ではなく、P が保有する権限を A の要求によって行使させる経路の成立である。
NIKKE PC ランチャーの侵害事案は、この関係が正規のソフトウェアを通じて成立し得ることを示している。第三者による改ざんが確認されたのは、ランチャーが公式 CDN から取得する JavaScript だった。改ざんされたコードは、追加の処理を取得し、ランチャー内部の機能を経由して端末上の操作へ到達する経路を形成していた。利用者が非公式の実行ファイルを導入することや、攻撃者が OS の管理者権限を直接取得することは、この経路の成立条件ではなかった。正規ランチャーに備わっていた機能と実行権限が、外部から変更されたコードの指示によって利用されたのである。
この事案には、操作経路の成立を時間の中で評価する必要性も現れている。配布元の JavaScript が改ざんされた時刻と、端末がその内容を取得した時刻は一致するとは限らない。改ざんコードを取得しても、追加のプログラムが実際に起動したかどうかは別の条件に依存する。さらに、配布元の内容が正常に戻されても、CDN や端末側のキャッシュに以前のコードが残っていたり、悪性エージェントがすでに起動していたりすれば、操作経路が継続する可能性がある。配信内容の修正と端末上の実行可能性の回復は、異なる状態の更新として確認する必要がある。
この時間的な関係を記述するため、構造振動モデルでは、時刻 \(t\) の構造 \(S_t\)、環境条件 \(C_t\)、観測結果 \(O_t\)、介入 \(U_t\) を区別する。権限システムでは、利用者、ランチャー、内部機能、資源、それらを結ぶ呼び出し関係やアクセス関係を構造として表せる。外部から取得するコードの内容は、分析対象をランチャー内部に限定する場合、環境条件として扱える。また、通信ログやプロセスの起動記録などは観測情報となり、内部 API の制限や悪性エージェントの除去などは介入に対応する。分析対象の境界を固定すれば、構造自体の変更と、構造が受け取る入力の変更を分けて比較できる。
外部主体 \(a\) が時刻 \(t\) の条件で実行させられる操作の集合を \(R_t(a)\)、その主体に許可される操作の集合を \(L_t(a)\) とすると、許可範囲から外れた操作は次のように表せる。
\[B_t(a)=R_t(a)\setminus L_t(a)\]
\(B_t(a)\) は、外部主体が間接的に実行させられる具体的な操作のうち、要求仕様上認められていないものの集合である。例えば、ランチャーを介した機密ファイルの読み取りと外部送信が技術的に可能であり、その操作が外部主体に許可されていなければ、該当する操作がこの集合に含まれる。\(B_t(a)=\varnothing\) は、評価対象とした主体、操作、環境条件の範囲で、到達可能な操作が許可範囲内に収まっていることを意味する。ただし、評価対象から漏れた内部機能や実行経路について、同じ結果まで保証するものではない。操作の粒度と評価範囲を明示することが、この条件を安全性の判断に利用する前提となる。
一方、構造振動モデルの構造振幅 \(A_t\) は、隣接する時点の構造を数値表現へ写像し、その距離を計算する量である。ランチャー内部の実行機構を構造として固定した場合、正常なコードから改ざんコードへ入力が変わっても、構造振幅は 0 となり得る。しかし、改ざんコードによって内部のファイル操作や通信機能が新たに利用可能になれば、\(B_t(a)\) は変化する。反対に、外部コードの実行環境を隔離し、内部 API の公開範囲を制約する改修では、構造振幅が大きくても、許可外の操作を減らせる場合がある。構造がどの程度変化したかと、許可外の操作へ到達できるかは、異なる評価軸である。
この枠組みから、特定の侵害事案に周期的な構造振動が発生したことや、構造振幅から被害規模を予測できることが直ちに導かれるわけではない。構造振動モデルを権限分析へ適用する意義は、構造、環境条件、観測、介入を明示し、それぞれの変化が操作到達可能性にどのように関係するかを比較可能にする点にある。例えば、構造が不変であるにもかかわらず操作到達可能性が変化した場合には、外部入力や実行状態の変更を調べられる。一方、構造を更新した後にも許可外の操作が残っている場合には、残存する呼び出し経路や資源へのアクセス条件を確認できる。構造振幅と許可外の操作集合を別々に評価することで、変更量の大きさと安全性の改善を混同せずに済む。
権限境界は、主体へ直接与えられた権限だけで決まるものではなく、その権限を持つプログラムへ外部から何を実行させられるかによっても決まる。さらに、その到達可能性は、外部コードの変更、キャッシュの状態、内部機能の更新、認可規則の変更によって時間とともに変化する。正規ランチャーを通じた侵害事案が示したのは、外部の配布資源が改ざんされると、端末上の正規プログラムの権限を利用した操作へつながり得るという構造である。その経路を評価するには、誰が入力を制御し、どの機能がその入力を解釈し、どの権限で最終的な操作が実行されるかを確認する必要がある。そして修復後には、配布元が正常になったことに加え、端末上に残る状態を含めて許可外の操作経路が遮断されたかを検証する。権限境界の安全性は、この操作到達可能性を、入力、状態、観測、介入の変化に応じて継続的に評価することで確かめられる。
参考文献
- id774, 認可の安全性は権限の成立時点まで定義する(2026-11-03). https://blog.id774.net/entry/2026/11/03/5824/
- Jerome H. Saltzer and Michael D. Schroeder, The Protection of Information in Computer Systems(1975-09). Proceedings of the IEEE. https://doi.org/10.1109/PROC.1975.9939
- MITRE, CWE-829: Inclusion of Functionality from Untrusted Control Sphere. https://cwe.mitre.org/data/definitions/829.html
- Norm Hardy, The Confused Deputy: (or why capabilities might have been invented)(1988-10-01). ACM SIGOPS Operating Systems Review. https://doi.org/10.1145/54289.871709
- MITRE, CWE-441: Unintended Proxy or Intermediary. https://cwe.mitre.org/data/definitions/441.html
- MITRE, CWE-250: Execution with Unnecessary Privileges. https://cwe.mitre.org/data/definitions/250.html
- Scott Rose, Oliver Borchert, Stu Mitchell and Sean Connelly, Zero Trust Architecture(2020-08). NIST SP 800-207. https://csrc.nist.gov/pubs/sp/800/207/final
- MotherSphere, NIKKE PC launcher compromise (November 2026). https://gist.github.com/MotherSphere/d6c049a09ba8ac3085c51ee9df24a4e5
- LuaJIT, FFI Library. https://luajit.org/ext_ffi.html
- MotherSphere, NIKKE Launcher Check. https://github.com/MotherSphere/NIKKE-Launcher-Check
- Karen Kent, Suzanne Chevalier, Tim Grance and Hung Dang, Guide to Integrating Forensic Techniques into Incident Response(2006-08). NIST SP 800-86. https://csrc.nist.gov/pubs/sp/800/86/final
- id774, サイバー攻撃の被害はシステムの管理境界を越えて広がる(2026-10-13). https://blog.id774.net/entry/2026/10/13/5778/
- id774, 構造振動モデルとは何か(2026-02-17). https://blog.id774.net/entry/2026/02/17/3666/
- id774, 構造振動モデルを社会に適用する(2026-02-25). https://blog.id774.net/entry/2026/02/25/3807/
- id774, 構造振動モデルを数理モデルとして定義する(2026-04-05). https://blog.id774.net/entry/2026/04/05/4318/
- id774, 安全判定の揺らぎを入力・構造・評価方法に分けて測る(2026-10-21). https://blog.id774.net/entry/2026/10/21/5796/
- Kelley Dempsey et al., Information Security Continuous Monitoring (ISCM) for Federal Information Systems and Organizations(2011-09). NIST SP 800-137. https://csrc.nist.gov/pubs/sp/800/137/final
- Roy T. Fielding, Mark Nottingham and Julian Reschke, HTTP Caching(2022-06). RFC 9111. https://www.rfc-editor.org/rfc/rfc9111.html
- Alexander Nelson, Sanjay Rekhi, Murugiah Souppaya and Karen Scarfone, Incident Response Recommendations and Considerations for Cybersecurity Risk Management: A CSF 2.0 Community Profile(2025-04). NIST SP 800-61 Rev. 3. https://csrc.nist.gov/pubs/sp/800/61/r3/final
- W3C, Subresource Integrity(2016-06-23). https://www.w3.org/TR/2016/REC-SRI-20160623/
- Electron, Security. https://www.electronjs.org/docs/latest/tutorial/security
- Murugiah Souppaya, Karen Scarfone and Donna Dodson, Secure Software Development Framework (SSDF) Version 1.1: Recommendations for Mitigating the Risk of Software Vulnerabilities(2022-02). NIST SP 800-218. https://csrc.nist.gov/pubs/sp/800/218/final