aws_recon 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +12 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +1000 -0
- data/LICENSE.txt +21 -0
- data/Rakefile +10 -0
- data/aws_recon.gemspec +36 -0
- data/bin/aws_recon +5 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/aws_recon.rb +19 -0
- data/lib/aws_recon/aws_recon.rb +115 -0
- data/lib/aws_recon/collectors/acm.rb +32 -0
- data/lib/aws_recon/collectors/apigateway.rb +50 -0
- data/lib/aws_recon/collectors/apigatewayv2.rb +37 -0
- data/lib/aws_recon/collectors/athena.rb +28 -0
- data/lib/aws_recon/collectors/autoscaling.rb +35 -0
- data/lib/aws_recon/collectors/cloudformation.rb +29 -0
- data/lib/aws_recon/collectors/cloudfront.rb +28 -0
- data/lib/aws_recon/collectors/cloudtrail.rb +33 -0
- data/lib/aws_recon/collectors/cloudwatch.rb +33 -0
- data/lib/aws_recon/collectors/cloudwatchlogs.rb +36 -0
- data/lib/aws_recon/collectors/codebuild.rb +29 -0
- data/lib/aws_recon/collectors/codepipeline.rb +27 -0
- data/lib/aws_recon/collectors/collectors.rb +2 -0
- data/lib/aws_recon/collectors/configservice.rb +80 -0
- data/lib/aws_recon/collectors/directconnect.rb +25 -0
- data/lib/aws_recon/collectors/directyservice.rb +27 -0
- data/lib/aws_recon/collectors/dms.rb +25 -0
- data/lib/aws_recon/collectors/dynamodb.rb +26 -0
- data/lib/aws_recon/collectors/ec2.rb +257 -0
- data/lib/aws_recon/collectors/ecr.rb +39 -0
- data/lib/aws_recon/collectors/ecs.rb +40 -0
- data/lib/aws_recon/collectors/efs.rb +25 -0
- data/lib/aws_recon/collectors/eks.rb +36 -0
- data/lib/aws_recon/collectors/elasticloadbalancing.rb +41 -0
- data/lib/aws_recon/collectors/elasticloadbalancingv2.rb +63 -0
- data/lib/aws_recon/collectors/elasticsearch.rb +27 -0
- data/lib/aws_recon/collectors/firehose.rb +29 -0
- data/lib/aws_recon/collectors/guardduty.rb +33 -0
- data/lib/aws_recon/collectors/iam.rb +136 -0
- data/lib/aws_recon/collectors/kafka.rb +27 -0
- data/lib/aws_recon/collectors/kinesis.rb +26 -0
- data/lib/aws_recon/collectors/kms.rb +71 -0
- data/lib/aws_recon/collectors/lambda.rb +42 -0
- data/lib/aws_recon/collectors/lightsail.rb +38 -0
- data/lib/aws_recon/collectors/organizations.rb +36 -0
- data/lib/aws_recon/collectors/rds.rb +81 -0
- data/lib/aws_recon/collectors/redshift.rb +40 -0
- data/lib/aws_recon/collectors/route53.rb +28 -0
- data/lib/aws_recon/collectors/route53domains.rb +25 -0
- data/lib/aws_recon/collectors/s3.rb +80 -0
- data/lib/aws_recon/collectors/sagemaker.rb +25 -0
- data/lib/aws_recon/collectors/servicequotas.rb +44 -0
- data/lib/aws_recon/collectors/ses.rb +28 -0
- data/lib/aws_recon/collectors/shield.rb +67 -0
- data/lib/aws_recon/collectors/sns.rb +38 -0
- data/lib/aws_recon/collectors/sqs.rb +28 -0
- data/lib/aws_recon/collectors/ssm.rb +41 -0
- data/lib/aws_recon/collectors/support.rb +43 -0
- data/lib/aws_recon/collectors/transfer.rb +24 -0
- data/lib/aws_recon/collectors/wafv2.rb +49 -0
- data/lib/aws_recon/collectors/workspaces.rb +24 -0
- data/lib/aws_recon/collectors/xray.rb +19 -0
- data/lib/aws_recon/lib/formatter.rb +32 -0
- data/lib/aws_recon/lib/mapper.rb +69 -0
- data/lib/aws_recon/options.rb +141 -0
- data/lib/aws_recon/services.yaml +134 -0
- data/lib/aws_recon/version.rb +3 -0
- data/readme.md +226 -0
- data/readme_gem.md +39 -0
- metadata +245 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
class ECR < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_repositories
|
10
|
+
#
|
11
|
+
@client.describe_repositories.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.repositories.each do |repo|
|
15
|
+
struct = OpenStruct.new(repo.to_h)
|
16
|
+
struct.type = 'repository'
|
17
|
+
struct.arn = repo.repository_arn
|
18
|
+
struct.policy = @client
|
19
|
+
.get_repository_policy({ repository_name: repo.repository_name }).to_h
|
20
|
+
|
21
|
+
rescue Aws::ECR::Errors::ServiceError => e
|
22
|
+
raise e unless suppressed_errors.include?(e.code)
|
23
|
+
ensure
|
24
|
+
resources.push(struct.to_h)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
resources
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# not an error
|
34
|
+
def suppressed_errors
|
35
|
+
%w[
|
36
|
+
RepositoryPolicyNotFoundException
|
37
|
+
]
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class ECS < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
# TODO: test live
|
6
|
+
#
|
7
|
+
def collect
|
8
|
+
resources = []
|
9
|
+
|
10
|
+
#
|
11
|
+
# describe_clusters
|
12
|
+
#
|
13
|
+
@client.describe_clusters.each_with_index do |response, page|
|
14
|
+
log(response.context.operation_name, page)
|
15
|
+
|
16
|
+
response.clusters.each do |cluster|
|
17
|
+
struct = OpenStruct.new(cluster.to_h)
|
18
|
+
struct.type = 'cluster'
|
19
|
+
struct.arn = cluster.cluster_arn
|
20
|
+
struct.tasks = []
|
21
|
+
|
22
|
+
# list_tasks
|
23
|
+
@client.list_tasks({ cluster: cluster.cluster_arn }).each_with_index do |response, page|
|
24
|
+
log(response.context.operation_name, 'list_tasks', page)
|
25
|
+
|
26
|
+
# describe_tasks
|
27
|
+
response.task_arns.each do |task_arn|
|
28
|
+
@client.describe_tasks({ cluster: cluster.cluster_arn, tasks: [task_arn] }).tasks.each do |task|
|
29
|
+
struct.tasks.push(task)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
resources.push(struct.to_h)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
resources
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class EFS < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_file_systems
|
10
|
+
#
|
11
|
+
@client.describe_file_systems.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.file_systems.each do |filesystem|
|
15
|
+
struct = OpenStruct.new(filesystem.to_h)
|
16
|
+
struct.type = 'filesystem'
|
17
|
+
struct.arn = filesystem.file_system_arn
|
18
|
+
|
19
|
+
resources.push(struct.to_h)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
resources
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class EKS < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_clusters
|
10
|
+
#
|
11
|
+
@client.list_clusters.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
# describe_cluster
|
15
|
+
response.clusters.each do |cluster|
|
16
|
+
struct = OpenStruct.new(@client.describe_cluster({ name: cluster }).cluster.to_h)
|
17
|
+
struct.type = 'cluster'
|
18
|
+
struct.nodegroups = []
|
19
|
+
|
20
|
+
# list_nodegroups
|
21
|
+
@client.list_nodegroups({ cluster_name: cluster }).each_with_index do |response, page|
|
22
|
+
log(response.context.operation_name, 'list_nodegroups', page)
|
23
|
+
|
24
|
+
# describe_nodegroup
|
25
|
+
response.nodegroups.each do |nodegroup|
|
26
|
+
struct.nodegroups.push(@client.describe_nodegroup({ cluster_name: cluster, nodegroup_name: nodegroup }).nodegroup.to_h)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
resources.push(struct.to_h)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
resources
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class ElasticLoadBalancing < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_load_balancers
|
10
|
+
#
|
11
|
+
@client.describe_load_balancers.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.load_balancer_descriptions.each do |elb|
|
15
|
+
struct = OpenStruct.new(elb.to_h)
|
16
|
+
struct.type = 'load_balancer'
|
17
|
+
struct.arn = elb.dns_name
|
18
|
+
|
19
|
+
# describe_load_balancer_policies
|
20
|
+
struct.policies = @client
|
21
|
+
.describe_load_balancer_policies({ load_balancer_name: elb.load_balancer_name })
|
22
|
+
.policy_descriptions.map(&:to_h)
|
23
|
+
|
24
|
+
# describe_load_balancer_attributes
|
25
|
+
struct.attributes = @client
|
26
|
+
.describe_load_balancer_attributes({ load_balancer_name: elb.load_balancer_name })
|
27
|
+
.load_balancer_attributes.to_h
|
28
|
+
|
29
|
+
# describe_tags
|
30
|
+
struct.tags = @client
|
31
|
+
.describe_tags({ load_balancer_names: [elb.load_balancer_name] })
|
32
|
+
.tag_descriptions.map(&:tags)
|
33
|
+
.flatten.map(&:to_h)
|
34
|
+
|
35
|
+
resources.push(struct.to_h)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
resources
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class ElasticLoadBalancingV2 < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# describe_load_balancers
|
10
|
+
#
|
11
|
+
@client.describe_load_balancers.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.load_balancers.each do |elb|
|
15
|
+
struct = OpenStruct.new(elb.to_h)
|
16
|
+
struct.type = 'load_balancer'
|
17
|
+
struct.arn = elb.load_balancer_arn
|
18
|
+
struct.listeners = []
|
19
|
+
struct.target_groups = []
|
20
|
+
|
21
|
+
# describe_load_balancer_attributes
|
22
|
+
struct.attributes = @client
|
23
|
+
.describe_load_balancer_attributes({ load_balancer_arn: elb.load_balancer_arn })
|
24
|
+
.attributes.map(&:to_h)
|
25
|
+
|
26
|
+
# describe_tags
|
27
|
+
struct.tags = @client
|
28
|
+
.describe_tags({ resource_arns: [elb.load_balancer_arn] })
|
29
|
+
.tag_descriptions.map(&:tags)
|
30
|
+
.flatten.map(&:to_h)
|
31
|
+
|
32
|
+
# describe_listeners
|
33
|
+
@client.describe_listeners({ load_balancer_arn: elb.load_balancer_arn }).each_with_index do |response, _page|
|
34
|
+
log(response.context.operation_name, page)
|
35
|
+
|
36
|
+
response.listeners.each do |listener|
|
37
|
+
struct.listeners.push(listener.to_h)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# describe_target_groups
|
42
|
+
@client.describe_target_groups({ load_balancer_arn: elb.load_balancer_arn }).each_with_index do |response, page|
|
43
|
+
log(response.context.operation_name, page)
|
44
|
+
|
45
|
+
response.target_groups.each do |target_group|
|
46
|
+
tg = OpenStruct.new(target_group.to_h)
|
47
|
+
|
48
|
+
# describe_target_health
|
49
|
+
tg.health_descriptions = @client
|
50
|
+
.describe_target_health({ target_group_arn: target_group.target_group_arn })
|
51
|
+
.target_health_descriptions.map(&:to_h)
|
52
|
+
|
53
|
+
struct.target_groups.push(tg.to_h)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
resources.push(struct.to_h)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
resources
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class ElasticsearchService < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_domain_names
|
10
|
+
#
|
11
|
+
@client.list_domain_names.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
response.domain_names.each do |domain|
|
15
|
+
log(response.context.operation_name, 'describe_elasticsearch_domain', page)
|
16
|
+
|
17
|
+
# describe_elasticsearch_domains
|
18
|
+
struct = OpenStruct.new(@client.describe_elasticsearch_domain({ domain_name: domain.domain_name }).domain_status.to_h)
|
19
|
+
struct.type = 'domain'
|
20
|
+
|
21
|
+
resources.push(struct.to_h)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
resources
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Firehose < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
# TODO: test live
|
6
|
+
# TODO: confirm paging behavior
|
7
|
+
#
|
8
|
+
def collect
|
9
|
+
resources = []
|
10
|
+
|
11
|
+
#
|
12
|
+
# list_delivery_streams
|
13
|
+
#
|
14
|
+
@client.list_delivery_streams.each_with_index do |response, page|
|
15
|
+
log(response.context.operation_name, page)
|
16
|
+
|
17
|
+
# describe_delivery_stream
|
18
|
+
response.delivery_stream_names.each do |stream|
|
19
|
+
struct = OpenStruct.new(@client.describe_delivery_stream({ delivery_stream_name: stream }).delivery_stream_description.to_h)
|
20
|
+
struct.type = 'stream'
|
21
|
+
struct.arn = struct.delivery_stream_arn
|
22
|
+
|
23
|
+
resources.push(struct.to_h)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
resources
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class GuardDuty < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
# TODO: test live
|
6
|
+
#
|
7
|
+
def collect
|
8
|
+
resources = []
|
9
|
+
|
10
|
+
#
|
11
|
+
# list_detectors
|
12
|
+
#
|
13
|
+
@client.list_detectors.each_with_index do |response, page|
|
14
|
+
log(response.context.operation_name, page)
|
15
|
+
|
16
|
+
response.detector_ids.each do |detector|
|
17
|
+
log(response.context.operation_name, 'get_detector', detector)
|
18
|
+
|
19
|
+
# get_detector
|
20
|
+
struct = OpenStruct.new(@client.get_detector({ detector_id: detector }).to_h)
|
21
|
+
struct.type = 'detector'
|
22
|
+
struct.arn = "arn:aws:guardduty:#{@region}:detector/#{detector}"
|
23
|
+
|
24
|
+
# get_master_account
|
25
|
+
struct.master_account = @client.get_master_account({ detector_id: detector }).to_h
|
26
|
+
|
27
|
+
resources.push(struct.to_h)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
resources
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
class IAM < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# get_account_authorization_details
|
10
|
+
# list_mfa_devices
|
11
|
+
# list_ssh_public_keys
|
12
|
+
#
|
13
|
+
@client.get_account_authorization_details.each_with_index do |response, page|
|
14
|
+
log(response.context.operation_name, page)
|
15
|
+
|
16
|
+
# users
|
17
|
+
response.user_detail_list.each do |user|
|
18
|
+
struct = OpenStruct.new(user.to_h)
|
19
|
+
struct.type = 'user'
|
20
|
+
struct.mfa_devices = @client.list_mfa_devices({ user_name: user.user_name }).mfa_devices.map(&:to_h)
|
21
|
+
struct.ssh_keys = @client.list_ssh_public_keys({ user_name: user.user_name }).ssh_public_keys.map(&:to_h)
|
22
|
+
|
23
|
+
resources.push(struct.to_h)
|
24
|
+
end
|
25
|
+
|
26
|
+
# groups
|
27
|
+
response.group_detail_list.each do |group|
|
28
|
+
struct = OpenStruct.new(group.to_h)
|
29
|
+
struct.type = 'group'
|
30
|
+
|
31
|
+
resources.push(struct.to_h)
|
32
|
+
end
|
33
|
+
|
34
|
+
# roles
|
35
|
+
response.role_detail_list.each do |role|
|
36
|
+
struct = OpenStruct.new(role.to_h)
|
37
|
+
struct.type = 'role'
|
38
|
+
|
39
|
+
resources.push(struct.to_h)
|
40
|
+
end
|
41
|
+
|
42
|
+
# polices
|
43
|
+
response.policies.each do |policy|
|
44
|
+
struct = OpenStruct.new(policy.to_h)
|
45
|
+
struct.type = 'policy'
|
46
|
+
|
47
|
+
resources.push(struct.to_h)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# get_account_password_policy
|
53
|
+
#
|
54
|
+
@client.get_account_password_policy.each do |response|
|
55
|
+
log(response.context.operation_name)
|
56
|
+
|
57
|
+
struct = OpenStruct.new(response.password_policy.to_h)
|
58
|
+
struct.type = 'password_policy'
|
59
|
+
|
60
|
+
resources.push(struct.to_h)
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# get_account_summary
|
65
|
+
#
|
66
|
+
@client.get_account_summary.each do |response|
|
67
|
+
log(response.context.operation_name)
|
68
|
+
|
69
|
+
struct = OpenStruct.new(response.summary_map)
|
70
|
+
struct.type = 'account_summary'
|
71
|
+
|
72
|
+
resources.push(struct.to_h)
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# list_server_certificates
|
77
|
+
#
|
78
|
+
@client.list_server_certificates.each_with_index do |response, page|
|
79
|
+
log(response.context.operation_name, page)
|
80
|
+
|
81
|
+
response.server_certificate_metadata_list.each do |cert|
|
82
|
+
struct = OpenStruct.new(cert)
|
83
|
+
struct.type = 'server_certificate'
|
84
|
+
struct.arn = cert.arn
|
85
|
+
|
86
|
+
resources.push(struct.to_h)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# list_virtual_mfa_devices
|
92
|
+
#
|
93
|
+
@client.list_virtual_mfa_devices.each_with_index do |response, page|
|
94
|
+
log(response.context.operation_name, page)
|
95
|
+
|
96
|
+
response.virtual_mfa_devices.each do |mfa_device|
|
97
|
+
struct = OpenStruct.new(mfa_device.to_h)
|
98
|
+
struct.type = 'virtual_mfa_device'
|
99
|
+
struct.arn = mfa_device.serial_number
|
100
|
+
|
101
|
+
resources.push(struct.to_h)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# get_credential_report
|
107
|
+
#
|
108
|
+
begin
|
109
|
+
@client.get_credential_report.each do |response|
|
110
|
+
log(response.context.operation_name)
|
111
|
+
|
112
|
+
struct = OpenStruct.new
|
113
|
+
struct.type = 'credential_report'
|
114
|
+
struct.content = CSV.parse(response.content, headers: :first_row).map(&:to_h)
|
115
|
+
struct.report_format = response.report_format
|
116
|
+
struct.generated_time = response.generated_time
|
117
|
+
|
118
|
+
resources.push(struct.to_h)
|
119
|
+
end
|
120
|
+
rescue Aws::IAM::Errors::ServiceError => e
|
121
|
+
log_error(e.code)
|
122
|
+
raise e unless suppressed_errors.include?(e.code)
|
123
|
+
end
|
124
|
+
|
125
|
+
resources
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
# not an error
|
131
|
+
def suppressed_errors
|
132
|
+
%w[
|
133
|
+
ReportNotPresent
|
134
|
+
]
|
135
|
+
end
|
136
|
+
end
|