aws_recon 0.2.15 → 0.2.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/aws_recon.rb +3 -0
- data/lib/aws_recon/collectors/applicationautoscaling.rb +25 -0
- data/lib/aws_recon/collectors/dynamodb.rb +13 -0
- data/lib/aws_recon/collectors/ec2.rb +34 -0
- data/lib/aws_recon/collectors/guardduty.rb +14 -1
- data/lib/aws_recon/collectors/iam.rb +5 -5
- data/lib/aws_recon/collectors/lambda.rb +4 -0
- data/lib/aws_recon/collectors/organizations.rb +1 -1
- data/lib/aws_recon/collectors/s3.rb +7 -1
- data/lib/aws_recon/collectors/secretsmanager.rb +26 -0
- data/lib/aws_recon/collectors/securityhub.rb +23 -0
- data/lib/aws_recon/collectors/sns.rb +2 -0
- data/lib/aws_recon/collectors/sqs.rb +1 -1
- data/lib/aws_recon/collectors/ssm.rb +1 -1
- data/lib/aws_recon/lib/patch.rb +10 -0
- data/lib/aws_recon/services.yaml +6 -0
- data/lib/aws_recon/version.rb +1 -1
- data/readme.md +5 -2
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b945e5c44370658e13ee470fee26d7e0b46fb6102a661485be9513af305f45d
|
4
|
+
data.tar.gz: 969330b10b9a8264bdb5759b1c910b74ccf05e855f8f380cdebdac8b3694fb11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7d26039b60a21370bd7000d7ccaca93cfc5efc7c0dba88ae5d7ea12d63d3a7b8f973b06d3a1a2633fb82804a716f163ffda23f96a00ee73251eb85956f14dfd
|
7
|
+
data.tar.gz: 61b1aa696e9ec44fd6b93d4ced975be8a2bb514537ed232db8a11cb840045bc52132a215a21a99e573f4df0b557b1612eb4dda458c249c0e5f86939b83049680
|
data/lib/aws_recon.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
class ApplicationAutoScaling < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# DynamoDB auto-scaling policies
|
10
|
+
#
|
11
|
+
@client.describe_scaling_policies({ service_namespace: 'dynamodb' }).each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.scaling_policies.each do |policy|
|
15
|
+
struct = OpenStruct.new(policy.to_h)
|
16
|
+
struct.type = 'auto_scaling_policy'
|
17
|
+
struct.arn = policy.policy_arn
|
18
|
+
|
19
|
+
resources.push(struct.to_h)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
resources
|
24
|
+
end
|
25
|
+
end
|
@@ -5,6 +5,19 @@ class DynamoDB < Mapper
|
|
5
5
|
def collect
|
6
6
|
resources = []
|
7
7
|
|
8
|
+
#
|
9
|
+
# describe_limits
|
10
|
+
#
|
11
|
+
@client.describe_limits.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
struct = OpenStruct.new(response)
|
15
|
+
struct.type = 'limits'
|
16
|
+
struct.arn = "arn:aws:dynamodb:#{@region}:#{@account}:limits"
|
17
|
+
|
18
|
+
resources.push(struct.to_h)
|
19
|
+
end
|
20
|
+
|
8
21
|
#
|
9
22
|
# list_tables
|
10
23
|
#
|
@@ -130,6 +130,21 @@ class EC2 < Mapper
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
+
#
|
134
|
+
# describe_network_acls
|
135
|
+
#
|
136
|
+
@client.describe_network_acls.each_with_index do |response, page|
|
137
|
+
log(response.context.operation_name, page)
|
138
|
+
|
139
|
+
response.network_acls.each do |network_acl|
|
140
|
+
struct = OpenStruct.new(network_acl.to_h)
|
141
|
+
struct.type = 'network_acl'
|
142
|
+
struct.arn = network_acl.network_acl_id # no true ARN
|
143
|
+
|
144
|
+
resources.push(struct.to_h)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
133
148
|
#
|
134
149
|
# describe_subnets
|
135
150
|
#
|
@@ -175,6 +190,21 @@ class EC2 < Mapper
|
|
175
190
|
end
|
176
191
|
end
|
177
192
|
|
193
|
+
#
|
194
|
+
# describe_internet_gateways
|
195
|
+
#
|
196
|
+
@client.describe_internet_gateways.each_with_index do |response, page|
|
197
|
+
log(response.context.operation_name, page)
|
198
|
+
|
199
|
+
response.internet_gateways.each do |gateway|
|
200
|
+
struct = OpenStruct.new(gateway.to_h)
|
201
|
+
struct.type = 'internet_gateway'
|
202
|
+
struct.arn = gateway.internet_gateway_id # no true ARN
|
203
|
+
|
204
|
+
resources.push(struct.to_h)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
178
208
|
#
|
179
209
|
# describe_route_tables
|
180
210
|
#
|
@@ -215,6 +245,10 @@ class EC2 < Mapper
|
|
215
245
|
struct = OpenStruct.new(snapshot.to_h)
|
216
246
|
struct.type = 'snapshot'
|
217
247
|
struct.arn = snapshot.snapshot_id # no true ARN
|
248
|
+
struct.create_volume_permissions = @client.describe_snapshot_attribute({
|
249
|
+
attribute: 'createVolumePermission',
|
250
|
+
snapshot_id: snapshot.snapshot_id
|
251
|
+
}).create_volume_permissions.map(&:to_h)
|
218
252
|
|
219
253
|
resources.push(struct.to_h)
|
220
254
|
end
|
@@ -21,8 +21,21 @@ class GuardDuty < Mapper
|
|
21
21
|
struct.type = 'detector'
|
22
22
|
struct.arn = "arn:aws:guardduty:#{@region}:detector/#{detector}"
|
23
23
|
|
24
|
+
# get_findings_statistics (only active findings)
|
25
|
+
struct.findings_statistics = @client.get_findings_statistics({
|
26
|
+
detector_id: detector,
|
27
|
+
finding_statistic_types: ['COUNT_BY_SEVERITY'],
|
28
|
+
finding_criteria: {
|
29
|
+
criterion: {
|
30
|
+
'service.archived': {
|
31
|
+
eq: ['false']
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}).finding_statistics.to_h
|
36
|
+
|
24
37
|
# get_master_account
|
25
|
-
struct.master_account = @client.get_master_account({ detector_id: detector }).to_h
|
38
|
+
struct.master_account = @client.get_master_account({ detector_id: detector }).master.to_h
|
26
39
|
|
27
40
|
resources.push(struct.to_h)
|
28
41
|
end
|
@@ -26,7 +26,7 @@ class IAM < Mapper
|
|
26
26
|
user.user_policy_list.map do |p|
|
27
27
|
{
|
28
28
|
policy_name: p.policy_name,
|
29
|
-
policy_document:
|
29
|
+
policy_document: p.policy_document.parse_policy
|
30
30
|
}
|
31
31
|
end
|
32
32
|
end
|
@@ -42,7 +42,7 @@ class IAM < Mapper
|
|
42
42
|
group.group_policy_list.map do |p|
|
43
43
|
{
|
44
44
|
policy_name: p.policy_name,
|
45
|
-
policy_document:
|
45
|
+
policy_document: p.policy_document.parse_policy
|
46
46
|
}
|
47
47
|
end
|
48
48
|
end
|
@@ -54,12 +54,12 @@ class IAM < Mapper
|
|
54
54
|
response.role_detail_list.each do |role|
|
55
55
|
struct = OpenStruct.new(role.to_h)
|
56
56
|
struct.type = 'role'
|
57
|
-
struct.assume_role_policy_document =
|
57
|
+
struct.assume_role_policy_document = role.assume_role_policy_document.parse_policy
|
58
58
|
struct.role_policy_list = if role.role_policy_list
|
59
59
|
role.role_policy_list.map do |p|
|
60
60
|
{
|
61
61
|
policy_name: p.policy_name,
|
62
|
-
policy_document:
|
62
|
+
policy_document: p.policy_document.parse_policy
|
63
63
|
}
|
64
64
|
end
|
65
65
|
end
|
@@ -75,7 +75,7 @@ class IAM < Mapper
|
|
75
75
|
policy.policy_version_list.map do |p|
|
76
76
|
{
|
77
77
|
version_id: p.version_id,
|
78
|
-
document:
|
78
|
+
document: p.document.parse_policy,
|
79
79
|
is_default_version: p.is_default_version,
|
80
80
|
create_date: p.create_date
|
81
81
|
}
|
@@ -12,7 +12,11 @@ class Lambda < Mapper
|
|
12
12
|
struct = OpenStruct.new(function)
|
13
13
|
struct.type = 'function'
|
14
14
|
struct.arn = function.function_arn
|
15
|
+
struct.policy = @client.get_policy({ function_name: function.function_name }).policy.parse_policy
|
15
16
|
|
17
|
+
rescue Aws::Lambda::Errors::ResourceNotFoundException => e
|
18
|
+
log_error(e.code)
|
19
|
+
ensure
|
16
20
|
resources.push(struct.to_h)
|
17
21
|
end
|
18
22
|
end
|
@@ -40,7 +40,7 @@ class Organizations < Mapper
|
|
40
40
|
response.policies.each do |policy|
|
41
41
|
struct = OpenStruct.new(policy.to_h)
|
42
42
|
struct.type = 'service_control_policy'
|
43
|
-
struct.content =
|
43
|
+
struct.content = @client.describe_policy({ policy_id: policy.id }).policy.content.parse_policy
|
44
44
|
|
45
45
|
resources.push(struct.to_h)
|
46
46
|
end
|
@@ -29,16 +29,20 @@ class S3 < Mapper
|
|
29
29
|
# to create a bucket, you must set the location_constraint
|
30
30
|
# bucket parameter to the same region. (https://docs.aws.amazon.com/general/latest/gr/s3.html)
|
31
31
|
client = if location.empty?
|
32
|
+
struct.location = 'us-east-1'
|
32
33
|
@client
|
33
34
|
else
|
35
|
+
struct.location = location
|
34
36
|
Aws::S3::Client.new({ region: location })
|
35
37
|
end
|
36
38
|
|
37
39
|
operations = [
|
38
40
|
{ func: 'get_bucket_acl', key: 'acl', field: nil },
|
39
41
|
{ func: 'get_bucket_encryption', key: 'encryption', field: 'server_side_encryption_configuration' },
|
42
|
+
{ func: 'get_bucket_replication', key: 'replication', field: 'replication_configuration' },
|
40
43
|
{ func: 'get_bucket_policy', key: 'policy', field: 'policy' },
|
41
44
|
{ func: 'get_bucket_policy_status', key: 'public', field: 'policy_status' },
|
45
|
+
{ func: 'get_public_access_block', key: 'public_access_block', field: 'public_access_block_configuration' },
|
42
46
|
{ func: 'get_bucket_tagging', key: 'tagging', field: nil },
|
43
47
|
{ func: 'get_bucket_logging', key: 'logging', field: 'logging_enabled' },
|
44
48
|
{ func: 'get_bucket_versioning', key: 'versioning', field: nil },
|
@@ -51,7 +55,7 @@ class S3 < Mapper
|
|
51
55
|
resp = client.send(op.func, { bucket: bucket.name })
|
52
56
|
|
53
57
|
struct[op.key] = if op.key == 'policy'
|
54
|
-
resp.policy.string
|
58
|
+
resp.policy.string.parse_policy
|
55
59
|
else
|
56
60
|
op.field ? resp.send(op.field).to_h : resp.to_h
|
57
61
|
end
|
@@ -77,6 +81,8 @@ class S3 < Mapper
|
|
77
81
|
NoSuchBucketPolicy
|
78
82
|
NoSuchTagSet
|
79
83
|
NoSuchWebsiteConfiguration
|
84
|
+
ReplicationConfigurationNotFoundError
|
85
|
+
NoSuchPublicAccessBlockConfiguration
|
80
86
|
]
|
81
87
|
end
|
82
88
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class SecretsManager < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_auto_scaling_groups
|
10
|
+
#
|
11
|
+
@client.list_secrets.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.secret_list.each_with_index do |secret, i|
|
15
|
+
log(response.context.operation_name, i)
|
16
|
+
|
17
|
+
struct = OpenStruct.new(secret.to_h)
|
18
|
+
struct.type = 'secret'
|
19
|
+
|
20
|
+
resources.push(struct.to_h)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
resources
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class SecurityHub < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_hub
|
10
|
+
#
|
11
|
+
@client.describe_hub.each do |response|
|
12
|
+
log(response.context.operation_name)
|
13
|
+
|
14
|
+
struct = OpenStruct.new(response.to_h)
|
15
|
+
struct.type = 'hub'
|
16
|
+
struct.arn = response.hub_arn
|
17
|
+
|
18
|
+
resources.push(struct.to_h)
|
19
|
+
end
|
20
|
+
|
21
|
+
resources
|
22
|
+
end
|
23
|
+
end
|
@@ -18,6 +18,8 @@ class SNS < Mapper
|
|
18
18
|
struct = OpenStruct.new(@client.get_topic_attributes({ topic_arn: topic.topic_arn }).attributes.to_h)
|
19
19
|
struct.type = 'topic'
|
20
20
|
struct.arn = topic.topic_arn
|
21
|
+
struct.policy = struct.delete_field('Policy').parse_policy
|
22
|
+
struct.effective_delivery_policy = struct.delete_field('EffectiveDeliveryPolicy').parse_policy
|
21
23
|
struct.subscriptions = []
|
22
24
|
|
23
25
|
# list_subscriptions_by_topic
|
@@ -18,7 +18,7 @@ class SQS < Mapper
|
|
18
18
|
struct = OpenStruct.new(@client.get_queue_attributes({ queue_url: queue, attribute_names: ['All'] }).attributes.to_h)
|
19
19
|
struct.type = 'queue'
|
20
20
|
struct.arn = struct.QueueArn
|
21
|
-
struct.
|
21
|
+
struct.policy = struct.delete_field('Policy').parse_policy
|
22
22
|
|
23
23
|
resources.push(struct.to_h)
|
24
24
|
end
|
@@ -30,7 +30,7 @@ class SSM < Mapper
|
|
30
30
|
struct = OpenStruct.new(parameter.to_h)
|
31
31
|
struct.string_type = parameter.type
|
32
32
|
struct.type = 'parameter'
|
33
|
-
struct.arn = "arn:aws:#{@service}:#{@region}::parameter
|
33
|
+
struct.arn = "arn:aws:#{@service}:#{@region}::parameter:#{parameter.name}"
|
34
34
|
|
35
35
|
resources.push(struct.to_h)
|
36
36
|
end
|
data/lib/aws_recon/services.yaml
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
alias: organizations
|
5
5
|
- name: AccessAnalyzer
|
6
6
|
alias: aa
|
7
|
+
- name: ApplicationAutoScaling
|
8
|
+
alias: aas
|
7
9
|
- name: ConfigService
|
8
10
|
alias: config
|
9
11
|
- name: CodeBuild
|
@@ -89,6 +91,10 @@
|
|
89
91
|
alias: cloudwatchlogs
|
90
92
|
- name: Kafka
|
91
93
|
alias: kafka
|
94
|
+
- name: SecretsManager
|
95
|
+
alias: sm
|
96
|
+
- name: SecurityHub
|
97
|
+
alias: sh
|
92
98
|
- name: Support
|
93
99
|
global: true
|
94
100
|
alias: support
|
data/lib/aws_recon/version.rb
CHANGED
data/readme.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/darkbitio/aws-recon/smoke-test/main)
|
2
|
-
[![Gem Version](https://badge.fury.io/rb/aws_recon.svg)](https://
|
1
|
+
[![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/darkbitio/aws-recon/smoke-test/main)](https://github.com/darkbitio/aws-recon/actions?query=branch%3Amain)
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/aws_recon.svg)](https://rubygems.org/gems/aws_recon)
|
3
3
|
|
4
4
|
# AWS Recon
|
5
5
|
|
@@ -224,6 +224,7 @@ AWS Recon aims to collect all resources and metadata that are relevant in determ
|
|
224
224
|
|
225
225
|
- [x] AccessAnalyzer
|
226
226
|
- [x] AdvancedShield
|
227
|
+
- [x] ApplicationAutoScaling
|
227
228
|
- [x] Athena
|
228
229
|
- [x] GuardDuty
|
229
230
|
- [ ] Macie
|
@@ -269,6 +270,8 @@ AWS Recon aims to collect all resources and metadata that are relevant in determ
|
|
269
270
|
- [x] S3
|
270
271
|
- [x] SageMaker
|
271
272
|
- [x] SES
|
273
|
+
- [x] SecretsManager
|
274
|
+
- [x] SecurityHub
|
272
275
|
- [x] ServiceQuotas
|
273
276
|
- [x] Shield
|
274
277
|
- [x] SNS
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws_recon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Larsen
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-11-
|
12
|
+
date: 2020-11-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- lib/aws_recon/collectors/acm.rb
|
185
185
|
- lib/aws_recon/collectors/apigateway.rb
|
186
186
|
- lib/aws_recon/collectors/apigatewayv2.rb
|
187
|
+
- lib/aws_recon/collectors/applicationautoscaling.rb
|
187
188
|
- lib/aws_recon/collectors/athena.rb
|
188
189
|
- lib/aws_recon/collectors/autoscaling.rb
|
189
190
|
- lib/aws_recon/collectors/cloudformation.rb
|
@@ -222,6 +223,8 @@ files:
|
|
222
223
|
- lib/aws_recon/collectors/route53domains.rb
|
223
224
|
- lib/aws_recon/collectors/s3.rb
|
224
225
|
- lib/aws_recon/collectors/sagemaker.rb
|
226
|
+
- lib/aws_recon/collectors/secretsmanager.rb
|
227
|
+
- lib/aws_recon/collectors/securityhub.rb
|
225
228
|
- lib/aws_recon/collectors/servicequotas.rb
|
226
229
|
- lib/aws_recon/collectors/ses.rb
|
227
230
|
- lib/aws_recon/collectors/shield.rb
|
@@ -235,6 +238,7 @@ files:
|
|
235
238
|
- lib/aws_recon/collectors/xray.rb
|
236
239
|
- lib/aws_recon/lib/formatter.rb
|
237
240
|
- lib/aws_recon/lib/mapper.rb
|
241
|
+
- lib/aws_recon/lib/patch.rb
|
238
242
|
- lib/aws_recon/options.rb
|
239
243
|
- lib/aws_recon/services.yaml
|
240
244
|
- lib/aws_recon/version.rb
|