誰も使っていないアカウントが最も強い権限を持っていた
目標
アカウント・ロール・権限のデータから有効権限を展開し、使われていない権限・休眠アカウント・職務分離違反・権限昇格経路を見つけて縮小案を作ったあと、適用した状態で再判定して、違反が減ったことを数字で示します。
なぜ重要なのか
権限一覧は、時間が経つと、誰も説明できない状態になります。エアギャップ環境では、データを外に移せる唯一の通路が、そうする権限を持ったアカウントなので、この一覧がそのまま持ち出し経路の一覧です。そのため、監査は「誰が何をできるか」を尋ね、その答えは、記憶ではなく、データから計算して出さなければなりません。このラボで難しい部分は、ルールではなく構造です。ロールの継承が循環すると、素朴な再帰が止まらず、権限を付与できるアカウントは、1段階だけたどると、実際の到達範囲を見逃します。
ステップ
python3で/root/least/dataに6つのデータファイルを作ります。生成スクリプトをそのまま使ってください。- 継承を展開したアカウント別の有効権限を
/root/least/effective.jsonに、互いを継承するロール2つを/root/least/cycle.txtに書きます。 - 持っている権限のうち、観測期間に使われなかったものを、
/root/least/unused.csvにaccount_id,permで書きます。 - 基準日時点で未ログインが90日以上か、退職の表示があるアカウントを、
/root/least/dormant.csvにaccount_id,days_idle,reasonで書きます。 - 有効権限から職務分離ルールに違反したペアを、
/root/least/sod.csvにaccount_id,rule_id,perm_a,perm_bで書きます。 - 自分でロールを足して到達できる追加の権限を、
/root/least/escalation.jsonにアカウント別に書きます。 - 割り当てごとに取り消し/維持と理由を決めて、
/root/least/plan.csvにaccount_id,role,action,reasonで書きます。 - 縮小案を適用した割り当てを
/root/least/after/assignments.csvに、前後の数を比べた報告を/root/least/after/report.jsonに残します。
参考
- 基準日は
/root/least/data/asof.txtにあります。dateで今日を使うと、同じデータから日ごとに違う答えが出ます。 - 職務分離ルールと休眠の基準日数は、
/root/least/data/policy.jsonに入っています。数字をコードに埋め込まず、そのファイルから読んでください。 - 継承を展開するときは、すでに訪問したロールを記憶しながら下ります。そうしないと、
RecursionErrorが出ます。 - ステップ7の「その割り当てだけが与える権限」は、その割り当てを外したときに消える権限です。他のロールが同じ権限をすでに与えていれば、その割り当てが与えるものはありません。
- よくある間違い1: ステップ6で1段階だけたどってしまうことです。付与されたロールが、また別のロールを付与できます。
- よくある間違い2: ステップ8で、元の割り当てファイルを上書きしてしまうことです。適用前のデータが残っていてはじめて、前後を比べられます。
- 標準文書: NIST SP 800-53 Rev 5、NIST SP 800-171 Rev 3。このラボのルール番号(SOD-01など)は、標準の統制番号ではなく、データの中でだけ使う合成番号です。
判定の土台になるデータを作る
python3で/root/least/dataにaccounts.csv・roles.json・assignments.csv・usage.csv・policy.json・asof.txtの6つを作ります。乱数を使わない生成スクリプトをそのまま使ってください。
エアギャップ環境にはダウンロードできるサンプルがないので、まずデータを自分で作ります。乱数を使わないからこそ、誰が何回回しても同じデータが出て、互いの判定を突き合わせられます。採点ツールは、ファイルの内容を標準形に変えてフィンガープリントを突き合わせるので、データを手で直すと、後のステップがすべて止まります。
継承を展開して、アカウントが実際に持っているものを見る
/root/least/effective.jsonにアカウント別の有効権限の一覧を、/root/least/cycle.txtに互いを継承するロールの名前を、1行に1つずつ書いてください。
ロールは他のロールを継承し、継承は複数の段階です。すでに訪問したロールを記憶しないと、再帰が終わりません。そして、その事実自体が、このデータで見つけるべきものの1つです。2つのロールが互いを継承すれば、2つの有効権限は同じになります。
持っているのに一度も使っていない権限を数える
/root/least/unused.csvに先頭行account_id,permを置き、有効権限のうちusage.csvにないものを、1行に1つずつ書いてください。
使用記録は、アカウントと権限のペアです。有効権限の集合から、使った権限の集合を引くと、残るものが答えです。この一覧が判定ではなく質問票だという点を忘れないでください。四半期に1回使う権限は、観測期間には見えません。
基準日で休眠アカウントを分ける
/root/least/dormant.csvに先頭行account_id,days_idle,reasonを置き、基準日から数えた未ログインの日数がpolicy.jsonの基準以上か、状態がterminatedのアカウントを書いてください。理由は미접속・퇴직・미접속+퇴직のいずれかです(韓国語で順に「未ログイン」「退職」「未ログインと退職の両方」を意味する語です)。
基準日はasof.txtにあります。今日の日付を使うと、同じデータから昨日と今日で答えが変わり、監査資料に使えません。日数は、基準日から最終ログイン日を引いた日数で、2つの理由が重なれば、両方を書きます。
一緒に持ってはいけない権限のペアを探す
/root/least/sod.csvに先頭行account_id,rule_id,perm_a,perm_bを置き、policy.jsonのルールごとに、2つの権限を一緒に持つアカウントを書いてください。
ルールは、権限1つではなく、ペアにかかります。有効権限の集合にaとbが両方あれば、違反です。ルール番号をコードに埋め込まず、policy.jsonを回しながら判定してください。ルールが増えても、コードはそのままでなければなりません。
自分で増やせる権限までたどる
/root/least/escalation.jsonにアカウント別に、今はないが、自分でロールを足して到達できる権限の一覧を書いてください。追加で得るものがないアカウントは入れません。
権限を付与できる権限を持つアカウントは、自分にロールを付けられます。そうして付けたロールが、また別のロールを付与できるなら、もう一歩進みます。付けられるロールがなくなるまで繰り返したあと、到達した権限から、もともと持っていた権限を引いてください。
割り当てごとに取り消すか残すかを決める
/root/least/plan.csvに先頭行account_id,role,action,reasonを置き、割り当て1つにつき1行ずつ書いてください。actionはrevokeまたはkeepで、reasonは휴면・중복・미사용・사용のいずれかです(韓国語で順に「休眠」「重複」「未使用」「使用」を意味する語です)。
判定の順序が結果を変えます。休眠アカウントなら、理由を問わずすべて取り消します。そのあと、その割り当てだけが与える権限が1つもなければ重複で、あるのに1つも使われていなければ未使用です。残りが維持です。
適用したあとで再判定して減ったかを見る
縮小案を適用した割り当てを/root/least/after/assignments.csvに残し、/root/least/after/report.jsonにassignments_before・assignments_after・sod_before・sod_after・unused_before・unused_after・escalation_before・escalation_after・dormantの9つの数を書いてください。
元のデータはそのままにして、適用結果を新しいファイルに書きます。そうすれば、前後を比べられ、もう一度採点しても同じ結果が出ます。報告の数は、手で数えず、前のステップと同じ関数で、適用後の割り当てから計算し直してください。採点ツールも、同じ計算を行います。