cartography 0.116.1__py3-none-any.whl → 0.118.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cartography might be problematic. Click here for more details.
- cartography/_version.py +2 -2
- cartography/cli.py +11 -0
- cartography/client/core/tx.py +23 -2
- cartography/config.py +5 -0
- cartography/graph/job.py +6 -2
- cartography/graph/statement.py +4 -0
- cartography/intel/aws/__init__.py +1 -0
- cartography/intel/aws/apigateway.py +18 -5
- cartography/intel/aws/ec2/elastic_ip_addresses.py +3 -1
- cartography/intel/aws/ec2/internet_gateways.py +4 -2
- cartography/intel/aws/ec2/load_balancer_v2s.py +11 -5
- cartography/intel/aws/ec2/network_interfaces.py +4 -0
- cartography/intel/aws/ec2/reserved_instances.py +3 -1
- cartography/intel/aws/ec2/tgw.py +11 -5
- cartography/intel/aws/ec2/volumes.py +1 -1
- cartography/intel/aws/ecr.py +202 -26
- cartography/intel/aws/ecr_image_layers.py +174 -21
- cartography/intel/aws/elasticsearch.py +13 -4
- cartography/intel/aws/identitycenter.py +93 -54
- cartography/intel/aws/inspector.py +26 -14
- cartography/intel/aws/permission_relationships.py +3 -3
- cartography/intel/aws/s3.py +26 -13
- cartography/intel/aws/ssm.py +3 -5
- cartography/intel/azure/__init__.py +16 -0
- cartography/intel/azure/compute.py +9 -4
- cartography/intel/azure/container_instances.py +95 -0
- cartography/intel/azure/cosmosdb.py +31 -15
- cartography/intel/azure/data_lake.py +124 -0
- cartography/intel/azure/sql.py +25 -12
- cartography/intel/azure/storage.py +19 -9
- cartography/intel/azure/subscription.py +3 -1
- cartography/intel/crowdstrike/spotlight.py +5 -2
- cartography/intel/entra/app_role_assignments.py +9 -2
- cartography/intel/gcp/__init__.py +26 -9
- cartography/intel/gcp/clients.py +8 -4
- cartography/intel/gcp/compute.py +39 -18
- cartography/intel/gcp/crm/folders.py +9 -3
- cartography/intel/gcp/crm/orgs.py +8 -3
- cartography/intel/gcp/crm/projects.py +14 -3
- cartography/intel/github/teams.py +3 -3
- cartography/intel/jamf/computers.py +7 -1
- cartography/intel/oci/iam.py +23 -9
- cartography/intel/oci/organizations.py +3 -1
- cartography/intel/oci/utils.py +28 -5
- cartography/intel/okta/awssaml.py +8 -7
- cartography/intel/pagerduty/escalation_policies.py +13 -6
- cartography/intel/pagerduty/schedules.py +9 -4
- cartography/intel/pagerduty/services.py +7 -3
- cartography/intel/pagerduty/teams.py +5 -2
- cartography/intel/pagerduty/users.py +3 -1
- cartography/intel/pagerduty/vendors.py +3 -1
- cartography/intel/trivy/__init__.py +109 -58
- cartography/models/aws/ec2/networkinterfaces.py +2 -0
- cartography/models/aws/ecr/image.py +38 -1
- cartography/models/aws/ecr/repository_image.py +1 -1
- cartography/models/azure/container_instance.py +55 -0
- cartography/models/azure/data_lake_filesystem.py +51 -0
- cartography/rules/cli.py +8 -6
- cartography/rules/data/frameworks/mitre_attack/__init__.py +7 -1
- cartography/rules/data/frameworks/mitre_attack/requirements/t1098_account_manipulation/__init__.py +317 -0
- cartography/rules/data/frameworks/mitre_attack/requirements/t1190_exploit_public_facing_application/__init__.py +1 -0
- cartography/rules/spec/model.py +13 -0
- cartography/sync.py +1 -1
- cartography/util.py +5 -1
- {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/METADATA +5 -4
- {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/RECORD +70 -65
- {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/WHEEL +0 -0
- {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/entry_points.txt +0 -0
- {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.116.1.dist-info → cartography-0.118.0.dist-info}/top_level.txt +0 -0
cartography/rules/data/frameworks/mitre_attack/requirements/t1098_account_manipulation/__init__.py
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
from cartography.rules.spec.model import Fact
|
|
2
|
+
from cartography.rules.spec.model import Module
|
|
3
|
+
from cartography.rules.spec.model import Requirement
|
|
4
|
+
|
|
5
|
+
# AWS
|
|
6
|
+
_aws_account_manipulation_permissions = Fact(
|
|
7
|
+
id="aws_account_manipulation_permissions",
|
|
8
|
+
name="IAM Principals with Account Creation and Modification Permissions",
|
|
9
|
+
description=(
|
|
10
|
+
"AWS IAM users and roles with permissions to create, modify, or delete IAM "
|
|
11
|
+
"accounts and their associated policies."
|
|
12
|
+
),
|
|
13
|
+
cypher_query="""
|
|
14
|
+
MATCH (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
|
|
15
|
+
MATCH (principal)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
16
|
+
WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
|
|
17
|
+
AND NOT principal.name CONTAINS 'QuickSetup'
|
|
18
|
+
AND principal.name <> 'OrganizationAccountAccessRole'
|
|
19
|
+
AND stmt.effect = 'Allow'
|
|
20
|
+
WITH a, principal, stmt,
|
|
21
|
+
// Return labels that are not the general "AWSPrincipal" label
|
|
22
|
+
[label IN labels(principal) WHERE label <> 'AWSPrincipal'][0] AS principal_type,
|
|
23
|
+
// Define the list of IAM actions to match on
|
|
24
|
+
[p IN ['iam:Create','iam:Attach','iam:Put','iam:Update','iam:Add'] |
|
|
25
|
+
p] AS patterns
|
|
26
|
+
WITH a, principal, principal_type, stmt,
|
|
27
|
+
// Filter on the desired IAM actions
|
|
28
|
+
[action IN stmt.action
|
|
29
|
+
WHERE ANY(prefix IN patterns WHERE action STARTS WITH prefix)
|
|
30
|
+
OR action = 'iam:*'
|
|
31
|
+
OR action = '*'
|
|
32
|
+
] AS matched_actions
|
|
33
|
+
// Return only statement actions that we matched on
|
|
34
|
+
WHERE size(matched_actions) > 0
|
|
35
|
+
UNWIND matched_actions AS action
|
|
36
|
+
RETURN DISTINCT a.name AS account,
|
|
37
|
+
principal.name AS principal_name,
|
|
38
|
+
principal.arn AS principal_arn,
|
|
39
|
+
principal_type,
|
|
40
|
+
collect(action) as action,
|
|
41
|
+
stmt.resource AS resource
|
|
42
|
+
ORDER BY account, principal_name
|
|
43
|
+
""",
|
|
44
|
+
cypher_visual_query="""
|
|
45
|
+
MATCH p = (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
|
|
46
|
+
MATCH p1 = (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
47
|
+
WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
|
|
48
|
+
AND NOT principal.name CONTAINS 'QuickSetup'
|
|
49
|
+
AND NOT principal.name = 'OrganizationAccountAccessRole'
|
|
50
|
+
AND stmt.effect = 'Allow'
|
|
51
|
+
AND ANY(action IN stmt.action WHERE
|
|
52
|
+
action STARTS WITH 'iam:Create'
|
|
53
|
+
OR action STARTS WITH 'iam:Attach'
|
|
54
|
+
OR action STARTS WITH 'iam:Put'
|
|
55
|
+
OR action STARTS WITH 'iam:Update'
|
|
56
|
+
OR action STARTS WITH 'iam:Add'
|
|
57
|
+
OR action = 'iam:*'
|
|
58
|
+
OR action = '*'
|
|
59
|
+
)
|
|
60
|
+
RETURN *
|
|
61
|
+
""",
|
|
62
|
+
module=Module.AWS,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
_aws_trust_relationship_manipulation = Fact(
|
|
66
|
+
id="aws_trust_relationship_manipulation",
|
|
67
|
+
name="Roles with Cross-Account Trust Relationship Modification Capabilities",
|
|
68
|
+
description=(
|
|
69
|
+
"AWS IAM principals with permissions to modify role trust policies "
|
|
70
|
+
"(specifically AssumeRolePolicyDocuments)."
|
|
71
|
+
),
|
|
72
|
+
cypher_query="""
|
|
73
|
+
MATCH (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
|
|
74
|
+
MATCH (principal)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
75
|
+
OPTIONAL MATCH (groupmember:AWSUser)
|
|
76
|
+
WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
|
|
77
|
+
AND NOT principal.name CONTAINS 'QuickSetup'
|
|
78
|
+
AND principal.name <> 'OrganizationAccountAccessRole'
|
|
79
|
+
AND stmt.effect = 'Allow'
|
|
80
|
+
WITH a, principal, stmt,
|
|
81
|
+
[label IN labels(principal) WHERE label <> 'AWSPrincipal'][0] AS principal_type,
|
|
82
|
+
['iam:UpdateAssumeRolePolicy','iam:CreateRole'] AS patterns
|
|
83
|
+
WITH a, principal, principal_type, stmt,
|
|
84
|
+
[action IN stmt.action
|
|
85
|
+
WHERE ANY(p IN patterns WHERE action = p)
|
|
86
|
+
OR action = 'iam:*' OR action = '*'
|
|
87
|
+
] AS matched_actions
|
|
88
|
+
WHERE size(matched_actions) > 0
|
|
89
|
+
UNWIND matched_actions AS action
|
|
90
|
+
RETURN DISTINCT a.name AS account,
|
|
91
|
+
principal.name AS principal_name,
|
|
92
|
+
principal.arn AS principal_arn,
|
|
93
|
+
principal_type,
|
|
94
|
+
collect(distinct action) as action,
|
|
95
|
+
stmt.resource AS resource
|
|
96
|
+
ORDER BY account, principal_name
|
|
97
|
+
""",
|
|
98
|
+
cypher_visual_query="""
|
|
99
|
+
MATCH p = (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
|
|
100
|
+
MATCH p1 = (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
101
|
+
MATCH (principal)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
102
|
+
WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
|
|
103
|
+
AND principal.name <> 'OrganizationAccountAccessRole'
|
|
104
|
+
AND stmt.effect = 'Allow'
|
|
105
|
+
RETURN *
|
|
106
|
+
""",
|
|
107
|
+
module=Module.AWS,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
_aws_service_account_manipulation_via_ec2 = Fact(
|
|
111
|
+
id="aws_service_account_manipulation_via_ec2",
|
|
112
|
+
name="Service Resources with Account Manipulation Through Instance Profiles",
|
|
113
|
+
description=(
|
|
114
|
+
"AWS EC2 instances with attached IAM roles that can manipulate other AWS accounts. "
|
|
115
|
+
"Also indicates whether the instance is internet-exposed."
|
|
116
|
+
),
|
|
117
|
+
cypher_query="""
|
|
118
|
+
MATCH (a:AWSAccount)-[:RESOURCE]->(ec2:EC2Instance)
|
|
119
|
+
MATCH (ec2)-[:INSTANCE_PROFILE]->(profile:AWSInstanceProfile)
|
|
120
|
+
MATCH (profile)-[:ASSOCIATED_WITH]->(role:AWSRole)
|
|
121
|
+
MATCH (role)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
122
|
+
WHERE stmt.effect = 'Allow'
|
|
123
|
+
WITH a, ec2, role,
|
|
124
|
+
// Define the list of IAM actions to match on
|
|
125
|
+
['iam:Create', 'iam:Attach', 'iam:Put', 'iam:Update'] AS patterns,
|
|
126
|
+
// Filter on the desired IAM actions
|
|
127
|
+
[action IN stmt.action
|
|
128
|
+
WHERE ANY(p IN ['iam:Create','iam:Attach','iam:Put','iam:Update', 'iam:Add'] WHERE action STARTS WITH p)
|
|
129
|
+
OR action = 'iam:*'
|
|
130
|
+
OR action = '*'
|
|
131
|
+
] AS actions
|
|
132
|
+
// For the instances that are internet open, include the SG and rules
|
|
133
|
+
OPTIONAL MATCH (ec2{exposed_internet:True})-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)<-[:MEMBER_OF_EC2_SECURITY_GROUP]-(ip:IpPermissionInbound)
|
|
134
|
+
// Return only statement actions that we matched on
|
|
135
|
+
WHERE size(actions) > 0
|
|
136
|
+
UNWIND actions AS flat_action
|
|
137
|
+
WITH a, ec2, role, sg, ip,
|
|
138
|
+
collect(DISTINCT flat_action) AS actions
|
|
139
|
+
RETURN DISTINCT a.name AS account,
|
|
140
|
+
a.id as account_id,
|
|
141
|
+
ec2.instanceid AS instance_id,
|
|
142
|
+
ec2.exposed_internet AS internet_accessible,
|
|
143
|
+
ec2.publicipaddress as public_ip_address,
|
|
144
|
+
role.name AS role_name,
|
|
145
|
+
collect(actions) as action,
|
|
146
|
+
ip.fromport as from_port,
|
|
147
|
+
ip.toport as to_port
|
|
148
|
+
ORDER BY account, instance_id, internet_accessible, from_port
|
|
149
|
+
""",
|
|
150
|
+
cypher_visual_query="""
|
|
151
|
+
MATCH p = (a:AWSAccount)-[:RESOURCE]->(ec2:EC2Instance)
|
|
152
|
+
MATCH p1 = (ec2)-[:INSTANCE_PROFILE]->(profile:AWSInstanceProfile)
|
|
153
|
+
MATCH p2 = (profile)-[:ASSOCIATED_WITH]->(role:AWSRole)
|
|
154
|
+
MATCH p3 = (role)-[:POLICY]->(:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
155
|
+
WHERE stmt.effect = 'Allow'
|
|
156
|
+
AND ANY(action IN stmt.action WHERE
|
|
157
|
+
action STARTS WITH 'iam:Create'
|
|
158
|
+
OR action STARTS WITH 'iam:Attach'
|
|
159
|
+
OR action STARTS WITH 'iam:Put'
|
|
160
|
+
OR action STARTS WITH 'iam:Update'
|
|
161
|
+
OR action STARTS WITH 'iam:Add'
|
|
162
|
+
OR action = 'iam:*'
|
|
163
|
+
OR action = '*'
|
|
164
|
+
)
|
|
165
|
+
WITH p, p1, p2, p3, ec2
|
|
166
|
+
// Include the SG and rules for the instances that are internet open
|
|
167
|
+
MATCH p4=(ec2{exposed_internet: true})-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)<-[:MEMBER_OF_EC2_SECURITY_GROUP]-(ip:IpPermissionInbound)
|
|
168
|
+
RETURN *
|
|
169
|
+
""",
|
|
170
|
+
module=Module.AWS,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
_aws_service_account_manipulation_via_lambda = Fact(
|
|
174
|
+
id="aws_service_account_manipulation",
|
|
175
|
+
name="Service Resources with Account Manipulation Through Lambda Roles",
|
|
176
|
+
description=(
|
|
177
|
+
"AWS Lambda functions with IAM roles that can manipulate other AWS accounts."
|
|
178
|
+
),
|
|
179
|
+
cypher_query="""
|
|
180
|
+
// Find Lambda functions with account manipulation capabilities
|
|
181
|
+
MATCH (a:AWSAccount)-[:RESOURCE]->(lambda:AWSLambda)
|
|
182
|
+
MATCH (lambda)-[:STS_ASSUMEROLE_ALLOW]->(role:AWSRole)
|
|
183
|
+
MATCH (role)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
184
|
+
WHERE stmt.effect = 'Allow'
|
|
185
|
+
WITH a, lambda, role, stmt,
|
|
186
|
+
// Define the list of IAM actions to match on
|
|
187
|
+
['iam:Create', 'iam:Attach', 'iam:Put', 'iam:Update'] AS patterns,
|
|
188
|
+
// Filter on the desired IAM actions
|
|
189
|
+
[action IN stmt.action
|
|
190
|
+
WHERE ANY(p IN ['iam:Create', 'iam:Attach', 'iam:Put', 'iam:Update', 'iam:Add'] WHERE action STARTS WITH p)
|
|
191
|
+
OR action = 'iam:*'
|
|
192
|
+
OR action = '*'
|
|
193
|
+
] AS actions
|
|
194
|
+
// Return only statement actions that we matched on
|
|
195
|
+
WHERE size(actions) > 0
|
|
196
|
+
UNWIND actions AS flat_action
|
|
197
|
+
WITH a, lambda, role, stmt,
|
|
198
|
+
collect(DISTINCT flat_action) AS actions
|
|
199
|
+
RETURN DISTINCT a.name AS account,
|
|
200
|
+
a.id as account_id,
|
|
201
|
+
lambda.arn AS arn,
|
|
202
|
+
lambda.description AS description,
|
|
203
|
+
lambda.anonymous_access AS internet_accessible,
|
|
204
|
+
role.name AS role_name,
|
|
205
|
+
actions
|
|
206
|
+
ORDER BY account, arn, internet_accessible
|
|
207
|
+
""",
|
|
208
|
+
cypher_visual_query="""
|
|
209
|
+
MATCH p = (a:AWSAccount)-[:RESOURCE]->(lambda:AWSLambda)
|
|
210
|
+
MATCH p1 = (lambda)-[:STS_ASSUMEROLE_ALLOW]->(role:AWSRole)
|
|
211
|
+
MATCH p2 = (role)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
212
|
+
WHERE stmt.effect = 'Allow'
|
|
213
|
+
AND ANY(action IN stmt.action WHERE
|
|
214
|
+
action STARTS WITH 'iam:Create'
|
|
215
|
+
OR action STARTS WITH 'iam:Attach'
|
|
216
|
+
OR action STARTS WITH 'iam:Put'
|
|
217
|
+
OR action STARTS WITH 'iam:Update'
|
|
218
|
+
OR action STARTS WITH 'iam:Add'
|
|
219
|
+
OR action = 'iam:*'
|
|
220
|
+
OR action = '*'
|
|
221
|
+
)
|
|
222
|
+
RETURN *
|
|
223
|
+
""",
|
|
224
|
+
module=Module.AWS,
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
_aws_policy_manipulation_capabilities = Fact(
|
|
228
|
+
id="aws_policy_manipulation_capabilities",
|
|
229
|
+
name="Principals with IAM Policy Creation and Modification Capabilities",
|
|
230
|
+
description=(
|
|
231
|
+
"AWS IAM principals that can create, modify, or attach IAM policies to other principals. "
|
|
232
|
+
),
|
|
233
|
+
cypher_query="""
|
|
234
|
+
MATCH (a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
|
|
235
|
+
MATCH (principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
236
|
+
WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
|
|
237
|
+
AND NOT principal.name CONTAINS 'QuickSetup'
|
|
238
|
+
AND principal.name <> 'OrganizationAccountAccessRole'
|
|
239
|
+
AND stmt.effect = 'Allow'
|
|
240
|
+
|
|
241
|
+
WITH a, principal, stmt,
|
|
242
|
+
// Return labels that are not the general "AWSPrincipal" label
|
|
243
|
+
[label IN labels(principal) WHERE label <> 'AWSPrincipal'][0] AS principal_type,
|
|
244
|
+
// Define the list of IAM actions to match on
|
|
245
|
+
[p IN
|
|
246
|
+
['iam:CreatePolicy', 'iam:CreatePolicyVersion', 'iam:AttachUserPolicy', 'iam:AttachRolePolicy', 'iam:AttachGroupPolicy',
|
|
247
|
+
'iam:AttachRolePolicy', 'iam:AttachGroupPolicy', 'iam:DetachUserPolicy', 'iam:DetachRolePolicy', 'iam:DetachGroupPolicy',
|
|
248
|
+
'iam:PutUserPolicy', 'iam:PutRolePolicy', 'iam:PutGroupPolicy'] |
|
|
249
|
+
p] AS patterns
|
|
250
|
+
|
|
251
|
+
// Return only statement actions that we matched on
|
|
252
|
+
WITH a, principal, principal_type, stmt,
|
|
253
|
+
[action IN stmt.action
|
|
254
|
+
WHERE ANY(p IN patterns WHERE action = p)
|
|
255
|
+
OR action = 'iam:*' OR action = '*'
|
|
256
|
+
] AS matched_actions
|
|
257
|
+
WHERE size(matched_actions) > 0
|
|
258
|
+
UNWIND matched_actions AS action
|
|
259
|
+
RETURN DISTINCT a.name AS account,
|
|
260
|
+
principal.name AS principal_name,
|
|
261
|
+
principal.arn AS principal_arn,
|
|
262
|
+
principal_type,
|
|
263
|
+
collect(action) as action,
|
|
264
|
+
stmt.resource AS resource
|
|
265
|
+
ORDER BY account, principal_name
|
|
266
|
+
""",
|
|
267
|
+
cypher_visual_query="""
|
|
268
|
+
MATCH p1=(a:AWSAccount)-[:RESOURCE]->(principal:AWSPrincipal)
|
|
269
|
+
MATCH p2=(principal)-[:POLICY]->(policy:AWSPolicy)-[:STATEMENT]->(stmt:AWSPolicyStatement)
|
|
270
|
+
WHERE NOT principal.name STARTS WITH 'AWSServiceRole'
|
|
271
|
+
AND NOT principal.name CONTAINS 'QuickSetup'
|
|
272
|
+
AND principal.name <> 'OrganizationAccountAccessRole'
|
|
273
|
+
AND stmt.effect = 'Allow'
|
|
274
|
+
AND ANY(action IN stmt.action WHERE
|
|
275
|
+
action CONTAINS 'iam:CreatePolicy' OR action CONTAINS 'iam:CreatePolicyVersion'
|
|
276
|
+
OR action CONTAINS 'iam:AttachUserPolicy' OR action CONTAINS 'iam:AttachRolePolicy'
|
|
277
|
+
OR action CONTAINS 'iam:AttachGroupPolicy' OR action CONTAINS 'iam:DetachUserPolicy'
|
|
278
|
+
OR action CONTAINS 'iam:DetachRolePolicy' OR action CONTAINS 'iam:DetachGroupPolicy'
|
|
279
|
+
OR action CONTAINS 'iam:PutUserPolicy' OR action CONTAINS 'iam:PutRolePolicy'
|
|
280
|
+
OR action CONTAINS 'iam:PutGroupPolicy' OR action = 'iam:*' OR action = '*'
|
|
281
|
+
)
|
|
282
|
+
RETURN *
|
|
283
|
+
""",
|
|
284
|
+
module=Module.AWS,
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
t1098 = Requirement(
|
|
289
|
+
id="t1098",
|
|
290
|
+
name="Account Manipulation",
|
|
291
|
+
description=(
|
|
292
|
+
"Adversaries may manipulate accounts to maintain or elevate access to victim systems. "
|
|
293
|
+
"Activity that subverts security policies. For example in cloud this is "
|
|
294
|
+
"updating IAM policies or adding new global admins."
|
|
295
|
+
),
|
|
296
|
+
target_assets="Identities that can manipulate other identities",
|
|
297
|
+
facts=(
|
|
298
|
+
# AWS
|
|
299
|
+
_aws_account_manipulation_permissions,
|
|
300
|
+
_aws_trust_relationship_manipulation,
|
|
301
|
+
_aws_service_account_manipulation_via_ec2,
|
|
302
|
+
_aws_service_account_manipulation_via_lambda,
|
|
303
|
+
_aws_policy_manipulation_capabilities,
|
|
304
|
+
),
|
|
305
|
+
requirement_url="https://attack.mitre.org/techniques/T1098/",
|
|
306
|
+
attributes={
|
|
307
|
+
"tactic": "persistence,privilege_escalation",
|
|
308
|
+
"technique_id": "T1098",
|
|
309
|
+
"services": [
|
|
310
|
+
"iam",
|
|
311
|
+
"sts",
|
|
312
|
+
"ec2",
|
|
313
|
+
"lambda",
|
|
314
|
+
],
|
|
315
|
+
"providers": ["AWS"],
|
|
316
|
+
},
|
|
317
|
+
)
|
|
@@ -116,6 +116,7 @@ t1190 = Requirement(
|
|
|
116
116
|
id="t1190",
|
|
117
117
|
name="Exploit Public-Facing Application",
|
|
118
118
|
description="Adversaries may attempt to take advantage of a weakness in an Internet-facing computer or program using software, data, or commands in order to cause unintended or unanticipated behavior.",
|
|
119
|
+
target_assets="Compute and storage resources that are accessible from the public internet",
|
|
119
120
|
facts=(
|
|
120
121
|
# AWS
|
|
121
122
|
_aws_ec2_instance_internet_exposed,
|
cartography/rules/spec/model.py
CHANGED
|
@@ -58,9 +58,21 @@ class Requirement:
|
|
|
58
58
|
"""
|
|
59
59
|
|
|
60
60
|
id: str
|
|
61
|
+
"""A unique identifier for the requirement, e.g. T1098 in MITRE ATT&CK."""
|
|
61
62
|
name: str
|
|
63
|
+
"""A brief name for the requirement, e.g. "Account Manipulation"."""
|
|
62
64
|
description: str
|
|
65
|
+
"""A brief description of the requirement."""
|
|
66
|
+
target_assets: str
|
|
67
|
+
"""
|
|
68
|
+
A short description of the assets that this requirement is related to. E.g. "Cloud
|
|
69
|
+
identities that can manipulate other identities". This field is used as
|
|
70
|
+
documentation: `description` tells us information about the requirement;
|
|
71
|
+
`target_assets` tells us what specific objects in cartography we will search for to
|
|
72
|
+
find Facts related to the requirement.
|
|
73
|
+
"""
|
|
63
74
|
facts: tuple[Fact, ...]
|
|
75
|
+
"""The facts that are related to this requirement."""
|
|
64
76
|
attributes: dict[str, Any] | None = None
|
|
65
77
|
"""
|
|
66
78
|
Metadata attributes for the requirement. Example:
|
|
@@ -74,6 +86,7 @@ class Requirement:
|
|
|
74
86
|
```
|
|
75
87
|
"""
|
|
76
88
|
requirement_url: str | None = None
|
|
89
|
+
"""A URL reference to the requirement in the framework, e.g. https://attack.mitre.org/techniques/T1098/"""
|
|
77
90
|
|
|
78
91
|
|
|
79
92
|
@dataclass(frozen=True)
|
cartography/sync.py
CHANGED
|
@@ -52,7 +52,7 @@ from cartography.util import STATUS_SUCCESS
|
|
|
52
52
|
logger = logging.getLogger(__name__)
|
|
53
53
|
|
|
54
54
|
|
|
55
|
-
TOP_LEVEL_MODULES = OrderedDict(
|
|
55
|
+
TOP_LEVEL_MODULES: OrderedDict[str, Callable[..., None]] = OrderedDict(
|
|
56
56
|
{ # preserve order so that the default sync always runs `analysis` at the very end
|
|
57
57
|
"create-indexes": cartography.intel.create_indexes.run,
|
|
58
58
|
"airbyte": cartography.intel.airbyte.start_airbyte_ingestion,
|
cartography/util.py
CHANGED
|
@@ -153,6 +153,9 @@ def merge_module_sync_metadata(
|
|
|
153
153
|
:param synced_type: The sub-module's type
|
|
154
154
|
:param update_tag: Timestamp used to determine data freshness
|
|
155
155
|
"""
|
|
156
|
+
# Import here to avoid circular import with cartography.client.core.tx
|
|
157
|
+
from cartography.client.core.tx import run_write_query
|
|
158
|
+
|
|
156
159
|
template = Template(
|
|
157
160
|
"""
|
|
158
161
|
MERGE (n:ModuleSyncMetadata{id:'${group_type}_${group_id}_${synced_type}'})
|
|
@@ -164,7 +167,8 @@ def merge_module_sync_metadata(
|
|
|
164
167
|
n.lastupdated=$UPDATE_TAG
|
|
165
168
|
""",
|
|
166
169
|
)
|
|
167
|
-
|
|
170
|
+
run_write_query(
|
|
171
|
+
neo4j_session,
|
|
168
172
|
template.safe_substitute(
|
|
169
173
|
group_type=group_type,
|
|
170
174
|
group_id=group_id,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cartography
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.118.0
|
|
4
4
|
Summary: Explore assets and their relationships across your technical infrastructure.
|
|
5
5
|
Maintainer: Cartography Contributors
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -42,6 +42,7 @@ Requires-Dist: python-digitalocean>=1.16.0
|
|
|
42
42
|
Requires-Dist: adal>=1.2.4
|
|
43
43
|
Requires-Dist: azure-cli-core>=2.26.0
|
|
44
44
|
Requires-Dist: azure-mgmt-compute>=5.0.0
|
|
45
|
+
Requires-Dist: azure-mgmt-containerinstance>=10.0.0
|
|
45
46
|
Requires-Dist: azure-mgmt-resource>=10.2.0
|
|
46
47
|
Requires-Dist: azure-mgmt-cosmosdb>=6.0.0
|
|
47
48
|
Requires-Dist: azure-mgmt-web>=7.0.0
|
|
@@ -58,7 +59,7 @@ Requires-Dist: python-dateutil
|
|
|
58
59
|
Requires-Dist: xmltodict
|
|
59
60
|
Requires-Dist: duo-client
|
|
60
61
|
Requires-Dist: cloudflare<5.0.0,>=4.1.0
|
|
61
|
-
Requires-Dist: scaleway>=2.
|
|
62
|
+
Requires-Dist: scaleway>=2.10.0
|
|
62
63
|
Requires-Dist: google-cloud-resource-manager>=1.14.2
|
|
63
64
|
Requires-Dist: types-aiobotocore-ecr
|
|
64
65
|
Requires-Dist: typer>=0.9.0
|
|
@@ -88,7 +89,7 @@ You can learn more about the story behind Cartography in our [presentation at BS
|
|
|
88
89
|
|
|
89
90
|
## Supported platforms
|
|
90
91
|
- [Airbyte](https://cartography-cncf.github.io/cartography/modules/airbyte/index.html) - Organization, Workspace, User, Source, Destination, Connection, Tag, Stream
|
|
91
|
-
- [Amazon Web Services](https://cartography-cncf.github.io/cartography/modules/aws/index.html) - ACM, API Gateway, CloudWatch, CodeBuild, Config, Cognito, EC2, ECS, ECR (including image layers), EFS, Elasticsearch, Elastic Kubernetes Service (EKS), DynamoDB, Glue, GuardDuty, IAM, Inspector, KMS, Lambda, RDS, Redshift, Route53, S3, Secrets Manager(Secret Versions), Security Hub, SNS, SQS, SSM, STS, Tags
|
|
92
|
+
- [Amazon Web Services](https://cartography-cncf.github.io/cartography/modules/aws/index.html) - ACM, API Gateway, CloudWatch, CodeBuild, Config, Cognito, EC2, ECS, ECR (including multi-arch images, image layers, and attestations), EFS, Elasticsearch, Elastic Kubernetes Service (EKS), DynamoDB, Glue, GuardDuty, IAM, Inspector, KMS, Lambda, RDS, Redshift, Route53, S3, Secrets Manager(Secret Versions), Security Hub, SNS, SQS, SSM, STS, Tags
|
|
92
93
|
- [Anthropic](https://cartography-cncf.github.io/cartography/modules/anthropic/index.html) - Organization, ApiKey, User, Workspace
|
|
93
94
|
- [BigFix](https://cartography-cncf.github.io/cartography/modules/bigfix/index.html) - Computers
|
|
94
95
|
- [Cloudflare](https://cartography-cncf.github.io/cartography/modules/cloudflare/index.html) - Account, Role, Member, Zone, DNSRecord
|
|
@@ -102,7 +103,7 @@ You can learn more about the story behind Cartography in our [presentation at BS
|
|
|
102
103
|
- [Keycloak](https://cartography-cncf.github.io/cartography/modules/keycloak/index.html) - Realms, Users, Groups, Roles, Scopes, Clients, IdentityProviders, Authentication Flows, Authentication Executions, Organizations, Organization Domains
|
|
103
104
|
- [Kubernetes](https://cartography-cncf.github.io/cartography/modules/kubernetes/index.html) - Cluster, Namespace, Service, Pod, Container, ServiceAccount, Role, RoleBinding, ClusterRole, ClusterRoleBinding, OIDCProvider
|
|
104
105
|
- [Lastpass](https://cartography-cncf.github.io/cartography/modules/lastpass/index.html) - users
|
|
105
|
-
- [Microsoft Azure](https://cartography-cncf.github.io/cartography/modules/azure/index.html) - App Service, CosmosDB, Functions, Logic Apps, Resource Group, SQL, Storage, Virtual Machine
|
|
106
|
+
- [Microsoft Azure](https://cartography-cncf.github.io/cartography/modules/azure/index.html) - App Service, Container Instance, CosmosDB, Functions, Logic Apps, Resource Group, SQL, Storage, Virtual Machine
|
|
106
107
|
- [Microsoft Entra ID](https://cartography-cncf.github.io/cartography/modules/entra/index.html) - Users, Groups, Applications, OUs, App Roles, federation to AWS Identity Center
|
|
107
108
|
- [NIST CVE](https://cartography-cncf.github.io/cartography/modules/cve/index.html) - Common Vulnerabilities and Exposures (CVE) data from NIST database
|
|
108
109
|
- [Okta](https://cartography-cncf.github.io/cartography/modules/okta/index.html) - users, groups, organizations, roles, applications, factors, trusted origins, reply URIs, federation to AWS roles, federation to AWS Identity Center
|