Slide 1

Slide 1 text

AWS × 形式手法で 人知を超えたセキュリティを 手に入れろ JAWS DAYS 2018 (2018/03/10) [Security Slot] C トラック チェシャ猫 (@y_taka_23)

Slide 2

Slide 2 text

#jd2018_c Tweet Me!

Slide 3

Slide 3 text

目次 ★ IAM 設定の理想と現実 ★ モデル検査器 Alloy 入門 ★ Alloy による IAM 検証 #jd2018_c

Slide 4

Slide 4 text

IAM Identity and Access Management #jd2018_c

Slide 5

Slide 5 text

IAM 設定の難しさ ★ 機能そのものの複雑性 ○ そもそも設定できる項目が多い ○ 多数の AWS リソースの連携が必要 ○ 最小権限の原則から細分化されがち ★ 運用の中でより複雑化 ○ 設定ミスすると被害が大きい ○ 既存の Policy に手を出せなくなる #jd2018_c

Slide 6

Slide 6 text

IAM 設定を補助するツール ★ Policy Validator ○ 構文的なチェックのみ ★ Visual Editor ★ IAM Policy Simulator ○ 操作主体となる Group や User を選ぶ ○ 操作対象となる Resource や Action を選ぶ ○ Allow または Deny を判定してくれる #jd2018_c

Slide 7

Slide 7 text

#jd2018_c

Slide 8

Slide 8 text

IAM Policy Simulator の限界 ★ 論理的な不整合が検出できない ○ 重複や互いに矛盾する Policy の存在 ★ 具体的な設定は教えてくれない ○ 結局は経験とカンによる設計に ★ IAM 以外の要素を考慮できない ○ 例えばセキュリティグループや VPC 設計と合わせて考えたいとき困る #jd2018_c

Slide 9

Slide 9 text

“ 人間の直感だけでは まともに戦えない世界

Slide 10

Slide 10 text

形式手法 Formal Methods #jd2018_c

Slide 11

Slide 11 text

形式手法とは ★ システムを数学的対象として記述 ○ その対象に関する理論を用いて検証 ○ 選んだ対象によって特性が変わる ★ いわゆるテストと比較すると ○ テストケースの漏れが生じない ○ 実装以前の設計レベルで検査できる ○ さほど普及しておらず習熟者が少ない #jd2018_c

Slide 12

Slide 12 text

モデル検査器 Alloy Alloy Model Checker #jd2018_c

Slide 13

Slide 13 text

Alloy の特徴 ★ 関係論理でシステムを定義 ○ データモデル的な表現に向く ★ SAT ソルバにより具体例を発見 ○ 条件を満たす例を自動で全列挙 ○ コーナーケースも含め機械的に網羅 ★ 発見した具体例を可視化 ○ 直感的で導入のハードルが下がる #jd2018_c

Slide 14

Slide 14 text

sig User { policy : Policy } sig Policy {} run {} #jd2018_c

Slide 15

Slide 15 text

#jd2018_c

Slide 16

Slide 16 text

#jd2018_c

Slide 17

Slide 17 text

#jd2018_c

Slide 18

Slide 18 text

システムを関係論理で記述 ★ シグニチャ ○ 有限集合を表す ○ さっきの例では User や Policy ★ フィールド ○ シグニチャ上の関係を表す ○ さっきの例では policy ○ 実体は部分集合 policy ⊆ User × Policy #jd2018_c

Slide 19

Slide 19 text

(u0, p0) (u0, p1) (u0, p2) (u1, p0) (u1, p1) (u1, p2) (u2, p0) (u2, p1) (u2, p2) User0 User1 User2 Policy0 Policy1 Policy2 #jd2018_c

Slide 20

Slide 20 text

(u0, p2) (u1, p1) (u2, p0) User0 User1 User2 Policy0 Policy1 Policy2 #jd2018_c

Slide 21

Slide 21 text

(u0, p2) (u1, p2) (u2, p1) User0 User1 User2 Policy0 Policy1 Policy2 #jd2018_c

Slide 22

Slide 22 text

(u0, p2) (u1, p2) (u2, p2) User0 User1 User2 Policy0 Policy1 Policy2 #jd2018_c

Slide 23

Slide 23 text

関係の多重度 ★ 対応する要素の個数を指定 ○ one : ちょうど 1 個(デフォルト) ○ lone : 0 個または 1 個 ○ set : 0 個以上 ○ some : 1 個以上 ○ no : 0 個 ★ ER 図における 1..* などに相当 #jd2018_c

Slide 24

Slide 24 text

二種類の検査モード ★ assert + check ○ 必ず満たされてほしい条件を与える ○ 全探索して違反が存在すれば表示 ★ pred + run ○ 満たされるかどうか不明な条件を与える ○ 全探索して条件を満たす例を発見 #jd2018_c

Slide 25

Slide 25 text

“ 先入観も疲労もない 信頼できるナビゲータ

Slide 26

Slide 26 text

Alloy による IAM の検証 Beating the IAM Policy Simulator #jd2018_c

Slide 27

Slide 27 text

Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ○ ★ 具体的な設定は教えてくれない ○ ★ IAM 以外の要素を考慮できない ○ #jd2018_c

Slide 28

Slide 28 text

Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ○ assert + check で違反を検出 ★ 具体的な設定は教えてくれない ○ ★ IAM 以外の要素を考慮できない ○ #jd2018_c

Slide 29

Slide 29 text

{ “Version”: “2012-10-17” “Statement”: [ { “Effect”: “Allow”, “Action”: [“ec2:*”], “Resource”: [“*”] }, ] } { “Version”: “2012-10-17” “Statement”: [ { “Effect”: “Deny”, “Action”: [“ec2:*”], “Resource”: [“*”] } ] } #jd2018_c

Slide 30

Slide 30 text

{ “Version”: “2012-10-17” “Statement”: [ { “Effect”: “Allow”, “Action”: [“ec2:*”], “Resource”: [“*”] }, ] } { “Version”: “2012-10-17” “Statement”: [ { “Effect”: “Deny”, “Action”: [“ec2:*”], “Resource”: [“*”] } ] } 同時に設定されると無意味 #jd2018_c

Slide 31

Slide 31 text

assert noConflictWithAllowAndDeny { no u : User { some p1, p2 : u.policy, s1 : p1.statement, s2 : p2.statement { s1.effect = Allow s2.effect = Deny some (s1.resource & s2.resource) some (s1.action & s2.action) } } } fact singleStatement { all p : Policy | lone p.statement } check noConfictWithAllowAndDeny #jd2018_c

Slide 32

Slide 32 text

assert noConflictWithAllowAndDeny { no u : User { some p1, p2 : u.policy, s1 : p1.statement, s2 : p2.statement { s1.effect = Allow s2.effect = Deny some (s1.resource & s2.resource) some (s1.action & s2.action) } } } fact singleStatement { all p : Policy | lone p.statement } check noConfictWithAllowAndDeny s1 と s2 がバッティング #jd2018_c

Slide 33

Slide 33 text

assert noConflictWithAllowAndDeny { no u : User { some p1, p2 : u.policy, s1 : p1.statement, s2 : p2.statement { s1.effect = Allow s2.effect = Deny some (s1.resource & s2.resource) some (s1.action & s2.action) } } } fact singleStatement { all p : Policy | lone p.statement } check noConfictWithAllowAndDeny Policy ごとに Statement が高々1 つなら大丈夫 (?) #jd2018_c

Slide 34

Slide 34 text

#jd2018_c Alloy が発見した Inter-Policy Conflict の例

Slide 35

Slide 35 text

Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ○ assert + check で違反を検出 ★ 具体的な設定は教えてくれない ○ ★ IAM 以外の要素を考慮できない ○ #jd2018_c

Slide 36

Slide 36 text

Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ○ assert + check で違反を検出 ★ 具体的な設定は教えてくれない ○ pred + run で仕様から実装を発見 ★ IAM 以外の要素を考慮できない ○ #jd2018_c

Slide 37

Slide 37 text

sig Statement { effect : one Effect, resource : set Resource, action : set Action, notAction : set Action } fact exclusiveAction { all s : Statement { some s.action => no s.notAction some s.notAction => no s.action } } pred deniedByStatement(s : Statement, r : Resource, a : Action) { s.effect = Deny r in s.resource a in s.action or (some s.notAction and a not in s.notAction) } #jd2018_c

Slide 38

Slide 38 text

sig Statement { effect : one Effect, resource : set Resource, action : set Action, notAction : set Action } fact exclusiveAction { all s : Statement { some s.action => no s.notAction some s.notAction => no s.action } } pred deniedByStatement(s : Statement, r : Resource, a : Action) { s.effect = Deny r in s.resource a in s.action or (some s.notAction and a not in s.notAction) } 除外アクション #jd2018_c

Slide 39

Slide 39 text

sig Statement { effect : one Effect, resource : set Resource, action : set Action, notAction : set Action } fact exclusiveAction { all s : Statement { some s.action => no s.notAction some s.notAction => no s.action } } pred deniedByStatement(s : Statement, r : Resource, a : Action) { s.effect = Deny r in s.resource a in s.action or (some s.notAction and a not in s.notAction) } 除外アクションが指定されているが a は該当せず #jd2018_c

Slide 40

Slide 40 text

pred allowedByStatement(s : Statement, ...) {...} pred deniedByPolicy(p : Policy, ...) {...} pred allowedByPolicy(p : Policy, ...) {...} pred allowed(u : User, r : Resource, a : Action) { no p : u.policy | deniedByPolicy[p, r, a] some p : u.policy | allowedByPolicy[p, r, a] } pred requirement { some u : User, r : Resource, a : Action { allowed[u, r, a] } } run requirement #jd2018_c

Slide 41

Slide 41 text

pred allowedByStatement(s : Statement, ...) {...} pred deniedByPolicy(p : Policy, ...) {...} pred allowedByPolicy(p : Policy, ...) {...} pred allowed(u : User, r : Resource, a : Action) { no p : u.policy | deniedByPolicy[p, r, a] some p : u.policy | allowedByPolicy[p, r, a] } pred requirement { some u : User, r : Resource, a : Action { allowed[u, r, a] } } run requirement 禁止する Policy がなく、かつ許可する Policy が存在 #jd2018_c

Slide 42

Slide 42 text

pred allowedByStatement(s : Statement, ...) {...} pred deniedByPolicy(p : Policy, ...) {...} pred allowedByPolicy(p : Policy, ...) {...} pred allowed(u : User, r : Resource, a : Action) { no p : u.policy | deniedByPolicy[p, r, a] some p : u.policy | allowedByPolicy[p, r, a] } pred requirement { some u : User, r : Resource, a : Action { allowed[u, r, a] } } run requirement アクセスが許可される具体例は? #jd2018_c

Slide 43

Slide 43 text

Alloy が自動で発見した Action 指定を用いるパターン #jd2018_c

Slide 44

Slide 44 text

Alloy が自動で発見した NotAction 指定を用いるパターン #jd2018_c

Slide 45

Slide 45 text

Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ○ assert + check で違反を検出 ★ 具体的な設定は教えてくれない ○ pred + run で仕様から実装を発見 ★ IAM 以外の要素を考慮できない ○ #jd2018_c

Slide 46

Slide 46 text

Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ○ assert + check で違反を検出 ★ 具体的な設定は教えてくれない ○ pred + run で仕様から実装を発見 ★ IAM 以外の要素を考慮できない ○ サービス単位でモジュール分割 #jd2018_c

Slide 47

Slide 47 text

module s3 enum Resource { Bucket, Object, ...} enum Action { ListBucket, PutObject, GetObject, ...} module ec2 open s3 enum Resource { Instance, SecurityGroup, ...} enum Action { StartInstances, StopInstances, ...} pred accessibleViaEndpoint(i : Instance, b : s3/Bucket) { ... } #jd2018_c

Slide 48

Slide 48 text

module s3 enum Resource { Bucket, Object, ...} enum Action { ListBucket, PutObject, GetObject, ...} module ec2 open s3 enum Resource { Instance, SecurityGroup, ...} enum Action { StartInstances, StopInstances, ...} pred accessibleViaEndpoint(i : Instance, b : s3/Bucket) { ... } S3 用モジュール EC2 用モジュール #jd2018_c

Slide 49

Slide 49 text

module s3 enum Resource { Bucket, Object, ...} enum Action { ListBucket, PutObject, GetObject, ...} module ec2 open s3 enum Resource { Instance, SecurityGroup, ...} enum Action { StartInstances, StopInstances, ...} pred accessibleViaEndpoint(i : Instance, b : s3/Bucket) { ... } モジュールの読み込み #jd2018_c

Slide 50

Slide 50 text

module s3 enum Resource { Bucket, Object, ...} enum Action { ListBucket, PutObject, GetObject, ...} module ec2 open s3 enum Resource { Instance, SecurityGroup, ...} enum Action { StartInstances, StopInstances, ...} pred accessibleViaEndpoint(i : Instance, b : s3/Bucket) { ... } IAM 外、EC2 特有の条件 #jd2018_c

Slide 51

Slide 51 text

module main open s3 open ec2 open iam one sig Binder { res : iam/Resource one -> one (s3/Resource + ec2/Resource) act : iam/Action one -> one (s3/Action + ec2/Action) } pred requirement { some u : iam/User, b : s3/Bucket, i : ec2/Instance { iam/allowed[u, Binder.res.b, Binder.act.s3/GetObject] ec2/accessibleViaEndpoint[i, b] } } #jd2018_c

Slide 52

Slide 52 text

module main open s3 open ec2 open iam one sig Binder { res : iam/Resource one -> one (s3/Resource + ec2/Resource) act : iam/Action one -> one (s3/Action + ec2/Action) } pred requirement { some u : iam/User, b : s3/Bucket, i : ec2/Instance { iam/allowed[u, Binder.res.b, Binder.act.s3/GetObject] ec2/accessibleViaEndpoint[i, b] } } 個別サービス + IAM を読み込み #jd2018_c

Slide 53

Slide 53 text

module main open s3 open ec2 open iam one sig Binder { res : iam/Resource one -> one (s3/Resource + ec2/Resource) act : iam/Action one -> one (s3/Action + ec2/Action) } pred requirement { some u : iam/User, b : s3/Bucket, i : ec2/Instance { iam/allowed[u, Binder.res.b, Binder.act.s3/GetObject] ec2/accessibleViaEndpoint[i, b] } } S3 系リソースと EC2 系リソースの和集合 #jd2018_c

Slide 54

Slide 54 text

module main open s3 open ec2 open iam one sig Binder { res : iam/Resource one -> one (s3/Resource + ec2/Resource) act : iam/Action one -> one (s3/Action + ec2/Action) } pred requirement { some u : iam/User, b : s3/Bucket, i : ec2/Instance { iam/allowed[u, Binder.res.b, Binder.act.s3/GetObject] ec2/accessibleViaEndpoint[i, b] } } IAM 側の (抽象的な) リソースと 1 : 1 対応 #jd2018_c

Slide 55

Slide 55 text

module main open s3 open ec2 open iam one sig Binder { res : iam/Resource one -> one (s3/Resource + ec2/Resource) act : iam/Action one -> one (s3/Action + ec2/Action) } pred requirement { some u : iam/User, b : s3/Bucket, i : ec2/Instance { iam/allowed[u, Binder.res.b, Binder.act.s3/GetObject] ec2/accessibleViaEndpoint[i, b] } } IAM 以外の条件も混ぜて扱える #jd2018_c

Slide 56

Slide 56 text

Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ○ assert + check で違反を検出 ★ 具体的な設定は教えてくれない ○ pred + run で仕様から実装を発見 ★ IAM 以外の要素を考慮できない ○ サービス単位でモジュール分割 #jd2018_c

Slide 57

Slide 57 text

まとめ Recapture #jd2018_c

Slide 58

Slide 58 text

まとめ ★ 形式手法とは何か ○ システムを数学的に記述し検査 ○ Alloy の場合は関係論理ベース ★ Alloy のアドバンテージ ○ 意図しない設定の不整合を例とともに検出 ○ 仕様から考えられる実装を発見・列挙 ○ モジュール化・拡張可能なモデル #jd2018_c

Slide 59

Slide 59 text

Have a Nice Security! Presented by チェシャ猫 (@y_taka_23) #jd2018_c

Slide 60

Slide 60 text

Credits Special thanks to all the people who made and released these awesome resources for free: ▷ Presentation template by SlidesCarnival ▷ Photographs by Unsplash 60 #jd2018_c