aws_recon 0.2.16 → 0.2.21

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af7cd78c7eed6c8f3c0679561e0c8831f5839545daa75b3579c670ad5ed342b5
4
- data.tar.gz: 8eae0b3544a30f71e8fea38a00326bb4b40cd44bdfc38bf6e4f330fe2c96b7e0
3
+ metadata.gz: f284896f9397e44d7662775c85b1f4363bcbc284420a248bc936b80ddef6d5e8
4
+ data.tar.gz: 572b909d6d5bce44d908f70204e3d511cbfae1d5ed8574a99ffe0d7559f836b3
5
5
  SHA512:
6
- metadata.gz: 746f85c95fa41ed06b63a95f16196d8fb04be14627d6121813f5ba0eefd4c5920f6ad3dc664ffb59e0d06fe6ce09232789aea81cf6dad73a96ea32272e66724e
7
- data.tar.gz: 22a3823f86304c6dd28ec9ff02c78f1142571b53263ea055543fe353d95226856fef00e64975a5fd856b0f462bc60bf8206bd6f09ae034c32fa71608396a59e4
6
+ metadata.gz: dc68e292ca1d346e8313117d6f93ebe0587fdf61b735b445ec6b90bd6d4c5c4d2a0165f2a47d6bcf57cb046b7a8e1dee769120f0ff569fe613f3930afdad9dac
7
+ data.tar.gz: 3f67fa10f1286a1eb9f5d5a1d56bc2ccb6dc5b6a9e7a9324b991e1f468f2fd41000081d1aa9f20a723ae17471b3e3a41463bc870e8e94dcd6e21bfb02fdcb0e6
@@ -3,6 +3,9 @@
3
3
  module AwsRecon
4
4
  end
5
5
 
6
+ require 'aws_recon/lib/patch.rb'
7
+ String.include PolicyStringParser
8
+
6
9
  require 'parallel'
7
10
  require 'ostruct'
8
11
  require 'optparse'
@@ -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
@@ -0,0 +1,25 @@
1
+ class Backup < Mapper
2
+ #
3
+ # Returns an array of resources.
4
+ #
5
+ def collect
6
+ resources = []
7
+
8
+ #
9
+ # list_backup_plans
10
+ #
11
+ @client.list_protected_resources.each_with_index do |response, page|
12
+ log(response.context.operation_name, page)
13
+
14
+ response.results.each do |resource|
15
+ struct = OpenStruct.new(resource.to_h)
16
+ struct.type = 'protected_resource'
17
+ struct.arn = resource.resource_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
@@ -16,7 +16,7 @@ class ECR < Mapper
16
16
  struct.type = 'repository'
17
17
  struct.arn = repo.repository_arn
18
18
  struct.policy = @client
19
- .get_repository_policy({ repository_name: repo.repository_name }).to_h
19
+ .get_repository_policy({ repository_name: repo.repository_name }).policy_text.parse_policy
20
20
 
21
21
  rescue Aws::ECR::Errors::ServiceError => e
22
22
  raise e unless suppressed_errors.include?(e.code)
@@ -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: JSON.parse(CGI.unescape(p.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: JSON.parse(CGI.unescape(p.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 = JSON.parse(CGI.unescape(role.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: JSON.parse(CGI.unescape(p.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: JSON.parse(CGI.unescape(p.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 = JSON.parse(CGI.unescape(@client.describe_policy({ policy_id: policy.id }).policy.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.Policy = JSON.parse(CGI.unescape(struct.Policy))
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/#{parameter.name}"
33
+ struct.arn = "arn:aws:#{@service}:#{@region}::parameter:#{parameter.name}"
34
34
 
35
35
  resources.push(struct.to_h)
36
36
  end
@@ -0,0 +1,10 @@
1
+ #
2
+ # Parse and unescape AWS policy document string
3
+ #
4
+ module PolicyStringParser
5
+ def parse_policy
6
+ JSON.parse(CGI.unescape(self))
7
+ rescue StandardError
8
+ nil
9
+ end
10
+ end
@@ -4,6 +4,10 @@
4
4
  alias: organizations
5
5
  - name: AccessAnalyzer
6
6
  alias: aa
7
+ - name: ApplicationAutoScaling
8
+ alias: aas
9
+ - name: Backup
10
+ alias: backup
7
11
  - name: ConfigService
8
12
  alias: config
9
13
  - name: CodeBuild
@@ -89,6 +93,10 @@
89
93
  alias: cloudwatchlogs
90
94
  - name: Kafka
91
95
  alias: kafka
96
+ - name: SecretsManager
97
+ alias: sm
98
+ - name: SecurityHub
99
+ alias: sh
92
100
  - name: Support
93
101
  global: true
94
102
  alias: support
@@ -1,3 +1,3 @@
1
1
  module AwsRecon
2
- VERSION = "0.2.16"
2
+ VERSION = "0.2.21"
3
3
  end
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://badge.fury.io/rb/aws_recon)
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,7 +224,9 @@ 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
229
+ - [x] Backup
228
230
  - [x] GuardDuty
229
231
  - [ ] Macie
230
232
  - [x] Systems Manager
@@ -269,6 +271,8 @@ AWS Recon aims to collect all resources and metadata that are relevant in determ
269
271
  - [x] S3
270
272
  - [x] SageMaker
271
273
  - [x] SES
274
+ - [x] SecretsManager
275
+ - [x] SecurityHub
272
276
  - [x] ServiceQuotas
273
277
  - [x] Shield
274
278
  - [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.16
4
+ version: 0.2.21
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-18 00:00:00.000000000 Z
12
+ date: 2020-11-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk
@@ -184,8 +184,10 @@ 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
190
+ - lib/aws_recon/collectors/backup.rb
189
191
  - lib/aws_recon/collectors/cloudformation.rb
190
192
  - lib/aws_recon/collectors/cloudfront.rb
191
193
  - lib/aws_recon/collectors/cloudtrail.rb
@@ -222,6 +224,8 @@ files:
222
224
  - lib/aws_recon/collectors/route53domains.rb
223
225
  - lib/aws_recon/collectors/s3.rb
224
226
  - lib/aws_recon/collectors/sagemaker.rb
227
+ - lib/aws_recon/collectors/secretsmanager.rb
228
+ - lib/aws_recon/collectors/securityhub.rb
225
229
  - lib/aws_recon/collectors/servicequotas.rb
226
230
  - lib/aws_recon/collectors/ses.rb
227
231
  - lib/aws_recon/collectors/shield.rb
@@ -235,6 +239,7 @@ files:
235
239
  - lib/aws_recon/collectors/xray.rb
236
240
  - lib/aws_recon/lib/formatter.rb
237
241
  - lib/aws_recon/lib/mapper.rb
242
+ - lib/aws_recon/lib/patch.rb
238
243
  - lib/aws_recon/options.rb
239
244
  - lib/aws_recon/services.yaml
240
245
  - lib/aws_recon/version.rb