aws_recon 0.4.1 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 212cb7795c7ff6e28ef56336bdd26de0e4d174e71b85f841fb71d60584e6967f
4
- data.tar.gz: 2c25dacdbf4124361ae3a76726d72557ba5cb6ac16fbdffd0ae636f8d8ef5f86
3
+ metadata.gz: f57ce63e04f7bad6fdbecd4e412ed5bee5e20a4a174e13bf84e2ad421a462179
4
+ data.tar.gz: a40190f6985c6eaa4445e24eb7d7e9161c88423a4a846663be2160b4e2c9a2da
5
5
  SHA512:
6
- metadata.gz: '08a247b20671f56f119101e26e257489ae71c81461e5cf59d0ccf9538c1f0a81d72bedae93eed1a5f3e9e18de846f4a9000e781b0a69c355355f8fd4195ba129'
7
- data.tar.gz: e479cb51db2afc92493b06f17928a9ae6549b8799e345484835219e177c191d29360d3309eec32ba1ea9b5ae3a5e84cfa9c31c61c480c422f0022497d6e46a9b
6
+ metadata.gz: 7b51e177c7fc4dee6373d35d528db677561895dff0f7d65ce73776672bbef40f3fd951337eb2df160edb5b328bfb762467e13aa8682b991abe062635958bb73d
7
+ data.tar.gz: 6c08343cc189bcb4366ac29fc7a685726f3fd9bd6789ca5145bddc6d7c42f5effbbbfd867f1353b02780671e2a368599cfc4098b48e10b7efcfac60b66266cab
@@ -65,6 +65,17 @@ module AwsRecon
65
65
  @resources.concat(collection) if @options.output_file
66
66
  end
67
67
 
68
+ #
69
+ # Format @resources as either
70
+ #
71
+ def formatted_json
72
+ if @options.jsonl
73
+ @resources.map { |r| JSON.generate(r) }.join("\n")
74
+ else
75
+ @resources.to_json
76
+ end
77
+ end
78
+
68
79
  #
69
80
  # main wrapper
70
81
  #
@@ -112,7 +123,7 @@ module AwsRecon
112
123
  if @options.output_file && !@options.s3
113
124
  puts "Saving resources to #{@options.output_file}.\n\n"
114
125
 
115
- File.write(@options.output_file, @resources.to_json)
126
+ File.write(@options.output_file, formatted_json)
116
127
  end
117
128
 
118
129
  # write output file to S3 bucket
@@ -128,7 +139,7 @@ module AwsRecon
128
139
  # build IO object and gzip it
129
140
  io = StringIO.new
130
141
  gzip_data = Zlib::GzipWriter.new(io)
131
- gzip_data.write(@resources.to_json)
142
+ gzip_data.write(formatted_json)
132
143
  gzip_data.close
133
144
 
134
145
  # send it to S3
@@ -19,7 +19,7 @@ class Route53 < Mapper
19
19
  response.hosted_zones.each do |zone|
20
20
  struct = OpenStruct.new(zone.to_h)
21
21
  struct.type = 'zone'
22
- struct.arn = "aws:route53:#{@region}:#{@account}:zone/#{zone.name}"
22
+ struct.arn = "arn:aws:route53:#{@region}:#{@account}:zone/#{zone.name}"
23
23
  struct.logging_config = @client
24
24
  .list_query_logging_configs({ hosted_zone_id: zone.id })
25
25
  .query_logging_configs.first.to_h
@@ -73,6 +73,9 @@ class S3 < Mapper
73
73
  end
74
74
 
75
75
  resources.push(struct.to_h)
76
+
77
+ rescue Aws::S3::Errors::NoSuchBucket
78
+ # skip missing bucket
76
79
  end
77
80
  end
78
81
 
@@ -20,6 +20,7 @@ class Parser
20
20
  :output_file,
21
21
  :output_format,
22
22
  :threads,
23
+ :jsonl,
23
24
  :collect_user_data,
24
25
  :skip_slow,
25
26
  :skip_credential_report,
@@ -55,6 +56,7 @@ class Parser
55
56
  false,
56
57
  false,
57
58
  false,
59
+ false,
58
60
  false
59
61
  )
60
62
 
@@ -116,6 +118,11 @@ class Parser
116
118
  args.threads = threads.to_i if (0..Parser::MAX_THREADS).include?(threads.to_i)
117
119
  end
118
120
 
121
+ # output NDJSON/JSONL format
122
+ opts.on('-l', '--json-lines', 'Output NDJSON/JSONL format (default: false)') do
123
+ args.jsonl = true
124
+ end
125
+
119
126
  # collect EC2 instance user data
120
127
  opts.on('-u', '--user-data', 'Collect EC2 instance user data (default: false)') do
121
128
  args.collect_user_data = true
@@ -1,3 +1,3 @@
1
1
  module AwsRecon
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.6"
3
3
  end
data/readme.md CHANGED
@@ -54,13 +54,13 @@ To run locally, first install the gem:
54
54
 
55
55
  ```
56
56
  $ gem install aws_recon
57
- Fetching aws_recon-0.4.0.gem
57
+ Fetching aws_recon-0.4.5.gem
58
58
  Fetching aws-sdk-3.0.1.gem
59
59
  Fetching parallel-1.20.1.gem
60
60
  ...
61
61
  Successfully installed aws-sdk-3.0.1
62
62
  Successfully installed parallel-1.20.1
63
- Successfully installed aws_recon-0.4.0
63
+ Successfully installed aws_recon-0.4.5
64
64
  ```
65
65
 
66
66
  Or add it to your Gemfile using `bundle`:
@@ -72,7 +72,7 @@ Resolving dependencies...
72
72
  ...
73
73
  Using aws-sdk 3.0.1
74
74
  Using parallel-1.20.1
75
- Using aws_recon 0.4.0
75
+ Using aws_recon 0.4.5
76
76
  ```
77
77
 
78
78
  ## Usage
@@ -249,7 +249,7 @@ Most users will want to limit collection to relevant services and regions. Runni
249
249
  ```
250
250
  $ aws_recon -h
251
251
 
252
- AWS Recon - AWS Inventory Collector (0.4.0)
252
+ AWS Recon - AWS Inventory Collector (0.4.5)
253
253
 
254
254
  Usage: aws_recon [options]
255
255
  -r, --regions [REGIONS] Regions to scan, separated by comma (default: all)
@@ -261,6 +261,7 @@ Usage: aws_recon [options]
261
261
  -o, --output [OUTPUT] Specify output file (default: output.json)
262
262
  -f, --format [FORMAT] Specify output format (default: aws)
263
263
  -t, --threads [THREADS] Specify max threads (default: 8, max: 128)
264
+ -l, --json-lines Output NDJSON/JSONL format (default: false)
264
265
  -u, --user-data Collect EC2 instance user data (default: false)
265
266
  -z, --skip-slow Skip slow operations (default: false)
266
267
  -g, --skip-credential-report Skip generating IAM credential report (default: false)
@@ -0,0 +1,151 @@
1
+ AWSTemplateFormatVersion: '2010-09-09'
2
+ Description: 'Deploys AWS Recon inventory collection resources, scheduled ECS task and corresponding IAM roles and policies.'
3
+ Resources:
4
+ AWSReconVPC:
5
+ Type: AWS::EC2::VPC
6
+ Properties:
7
+ CidrBlock: '10.75.0.0/27'
8
+ Tags:
9
+ - Key: Name
10
+ Value: aws-recon-CFN
11
+ AWSReconSubnet:
12
+ Type: AWS::EC2::Subnet
13
+ Properties:
14
+ CidrBlock: '10.75.0.0/28'
15
+ VpcId: !Ref AWSReconVPC
16
+ Tags:
17
+ - Key: Name
18
+ Value: aws-recon-CFN
19
+ DependsOn: AWSReconVPC
20
+ AWSReconSecurityGroup:
21
+ Type: AWS::EC2::SecurityGroup
22
+ Properties:
23
+ GroupDescription: AWS Recon collection egress
24
+ VpcId: !Ref AWSReconVPC
25
+ SecurityGroupEgress:
26
+ - IpProtocol: -1
27
+ FromPort: 0
28
+ ToPort: 0
29
+ CidrIp: 0.0.0.0/0
30
+ Tags:
31
+ - Key: Name
32
+ Value: aws-recon-CFN
33
+ AWSReconInternetGateway:
34
+ Type: AWS::EC2::InternetGateway
35
+ Properties:
36
+ Tags:
37
+ - Key: Name
38
+ Value: aws-recon-CFN
39
+ AWSReconInternetGatewayAttachment:
40
+ Type: AWS::EC2::VPCGatewayAttachment
41
+ Properties:
42
+ InternetGatewayId: !Ref AWSReconInternetGateway
43
+ VpcId: !Ref AWSReconVPC
44
+ AWSReconEgressRouteTable:
45
+ Type: AWS::EC2::RouteTable
46
+ Properties:
47
+ VpcId: !Ref AWSReconVPC
48
+ Tags:
49
+ - Key: Name
50
+ Value: aws-recon-CFN
51
+ AWSReconSubnetRouteTableAssociation:
52
+ Type: AWS::EC2::SubnetRouteTableAssociation
53
+ Properties:
54
+ SubnetId: !Ref AWSReconSubnet
55
+ RouteTableId: !Ref AWSReconEgressRouteTable
56
+ AWSReconEgressRoute:
57
+ Type: AWS::EC2::Route
58
+ Properties:
59
+ DestinationCidrBlock: '0.0.0.0/0'
60
+ GatewayId: !Ref AWSReconInternetGateway
61
+ RouteTableId: !Ref AWSReconEgressRouteTable
62
+ AWSReconECSCluster:
63
+ Type: AWS::ECS::Cluster
64
+ Properties:
65
+ ClusterName: aws-recon-CFN
66
+ CapacityProviders:
67
+ - FARGATE
68
+ Tags:
69
+ - Key: Name
70
+ Value: aws-recon-CFN
71
+ DependsOn: AWSReconSubnet
72
+ AWSReconECSTask:
73
+ Type: AWS::ECS::TaskDefinition
74
+ Properties:
75
+ Family: aws-recon-CFN
76
+ RequiresCompatibilities:
77
+ - FARGATE
78
+ NetworkMode: awsvpc
79
+ Cpu: 1024
80
+ Memory: 2048
81
+ TaskRoleArn: !Ref AWSReconECSTaskRole
82
+ ExecutionRoleArn: !Ref AWSReconECSExecutionRole
83
+ ContainerDefinitions:
84
+ - Name: aws-recon-CFN
85
+ Image: 'darkbitio/aws_recon:latest'
86
+ EntryPoint:
87
+ - 'aws_recon'
88
+ - '--verbose'
89
+ - '--format'
90
+ - 'custom'
91
+ AWSReconECSTaskRole:
92
+ Type: AWS::IAM::Role
93
+ Properties:
94
+ RoleName: aws-recon-ecs-task-role
95
+ ManagedPolicyArns:
96
+ - 'arn:aws:iam::aws:policy/ReadOnlyAccess'
97
+ Policies:
98
+ - PolicyName: AWSReconECSTaskRole
99
+ PolicyDocument:
100
+ Version: '2012-10-17'
101
+ Statement:
102
+ - Effect: Allow
103
+ Action: 's3:PutObject'
104
+ Resource: 'arn:aws:s3:::CHANGEME/*'
105
+ AssumeRolePolicyDocument:
106
+ Version: '2012-10-17'
107
+ Statement:
108
+ - Effect: Allow
109
+ Principal:
110
+ Service:
111
+ - ecs.amazonaws.com
112
+ - ecs-tasks.amazonaws.com
113
+ Action: 'sts:AssumeRole'
114
+ AWSReconECSExecutionRole:
115
+ Type: AWS::IAM::Role
116
+ Properties:
117
+ RoleName: aws-recon-ecs-execution-role
118
+ Policies:
119
+ - PolicyName: AWSReconECSTaskExecutionPolicy
120
+ PolicyDocument:
121
+ Version: '2012-10-17'
122
+ Statement:
123
+ - Effect: Allow
124
+ Action:
125
+ - 'ecr:GetAuthorizationToken'
126
+ - 'ecr:BatchCheckLayerAvailability'
127
+ - 'ecr:GetDownloadUrlForLayer'
128
+ - 'ecr:BatchGetImage'
129
+ - 'logs:CreateLogStream'
130
+ - 'logs:PutLogEvents'
131
+ Resource: '*'
132
+ AssumeRolePolicyDocument:
133
+ Version: '2012-10-17'
134
+ Statement:
135
+ - Effect: Allow
136
+ Principal:
137
+ Service:
138
+ - ecs-tasks.amazonaws.com
139
+ Action: 'sts:AssumeRole'
140
+ AWSReconCloudWatchEventsRole:
141
+ Type: AWS::IAM::Role
142
+ Properties:
143
+ RoleName: aws-recon-events-role
144
+ AssumeRolePolicyDocument:
145
+ Version: '2012-10-17'
146
+ Statement:
147
+ - Effect: Allow
148
+ Principal:
149
+ Service:
150
+ - events.amazonaws.com
151
+ Action: 'sts:AssumeRole'
@@ -1,6 +1,6 @@
1
1
  # https://www.terraform.io/docs/providers/aws/r/cloudwatch_event_rule.html
2
2
  resource "aws_cloudwatch_event_rule" "default" {
3
- name = "${var.aws_recon_base_name}-${random_id.rule.hex}"
3
+ name = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}"
4
4
  description = "AWS Recon scheduled task"
5
5
  schedule_expression = var.schedule_expression
6
6
  }
@@ -24,7 +24,3 @@ resource "aws_cloudwatch_event_target" "default" {
24
24
  }
25
25
  }
26
26
  }
27
-
28
- resource "random_id" "rule" {
29
- byte_length = 4
30
- }
@@ -1,14 +1,10 @@
1
1
  resource "aws_ecs_cluster" "aws_recon" {
2
- name = "${var.aws_recon_base_name}-${random_id.cluster.hex}"
2
+ name = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}"
3
3
  capacity_providers = [local.ecs_task_provider]
4
4
  }
5
5
 
6
- resource "random_id" "cluster" {
7
- byte_length = 4
8
- }
9
-
10
6
  resource "aws_ecs_task_definition" "aws_recon_task" {
11
- family = "${var.aws_recon_base_name}-${random_id.cluster.hex}"
7
+ family = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}"
12
8
  task_role_arn = aws_iam_role.aws_recon_role.arn
13
9
  execution_role_arn = aws_iam_role.ecs_task_execution.arn
14
10
  requires_compatibilities = [local.ecs_task_provider]
@@ -18,12 +14,14 @@ resource "aws_ecs_task_definition" "aws_recon_task" {
18
14
 
19
15
  container_definitions = jsonencode([
20
16
  {
21
- name = "${var.aws_recon_base_name}-${random_id.cluster.hex}"
17
+ name = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}"
22
18
  image = "${var.aws_recon_container_name}:${var.aws_recon_container_version}"
23
19
  assign_public_ip = true
24
20
  entryPoint = [
25
21
  "aws_recon",
26
22
  "--verbose",
23
+ "--format",
24
+ "custom",
27
25
  "--s3-bucket",
28
26
  "${aws_s3_bucket.aws_recon.bucket}:${data.aws_region.current.name}",
29
27
  "--regions",
@@ -42,7 +40,7 @@ resource "aws_ecs_task_definition" "aws_recon_task" {
42
40
  }
43
41
 
44
42
  resource "aws_cloudwatch_log_group" "aws_recon" {
45
- name = "/ecs/${var.aws_recon_base_name}-${random_id.cluster.hex}"
43
+ name = "/ecs/${var.aws_recon_base_name}-${random_id.aws_recon.hex}"
46
44
  retention_in_days = var.retention_period
47
45
  }
48
46
 
File without changes
File without changes
@@ -0,0 +1,15 @@
1
+ output "aws_recon_ecs_cluster" {
2
+ value = aws_ecs_cluster.aws_recon.name
3
+ }
4
+
5
+ output "aws_recon_ecs_scheduled_task" {
6
+ value = aws_cloudwatch_event_rule.default.name
7
+ }
8
+
9
+ output "aws_recon_s3_bucket" {
10
+ value = aws_s3_bucket.aws_recon.bucket
11
+ }
12
+
13
+ output "aws_recon_task_manual_run_command" {
14
+ value = "\nOne-off task run command:\n\naws ecs run-task --task-definition ${aws_ecs_task_definition.aws_recon_task.family} --cluster ${aws_ecs_cluster.aws_recon.name} --launch-type FARGATE --network-configuration \"awsvpcConfiguration={subnets=[${aws_subnet.subnet.id}],securityGroups=[${aws_security_group.sg.id}],assignPublicIp=ENABLED}\"\n"
15
+ }
File without changes
@@ -1,6 +1,7 @@
1
1
  resource "aws_s3_bucket" "aws_recon" {
2
- bucket = "${var.aws_recon_base_name}-${random_id.bucket.hex}-${data.aws_iam_account_alias.current.id}"
3
- acl = "private"
2
+ bucket = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}-${data.aws_iam_account_alias.current.id}"
3
+ acl = "private"
4
+ force_destroy = true
4
5
 
5
6
  lifecycle_rule {
6
7
  id = "expire-after-${var.retention_period}-days"
@@ -12,8 +13,8 @@ resource "aws_s3_bucket" "aws_recon" {
12
13
  }
13
14
  }
14
15
 
15
- resource "random_id" "bucket" {
16
- byte_length = 4
16
+ resource "random_id" "aws_recon" {
17
+ byte_length = 6
17
18
  }
18
19
 
19
20
  data "aws_iam_account_alias" "current" {}
@@ -41,6 +41,7 @@ variable "aws_regions" {
41
41
  ]
42
42
  }
43
43
 
44
+ # must be one of: 0, 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365
44
45
  variable "retention_period" {
45
46
  type = number
46
47
  default = 30
@@ -3,24 +3,23 @@
3
3
  resource "aws_vpc" "vpc" {
4
4
  cidr_block = local.cidr_block
5
5
  tags = {
6
- Name = "${var.aws_recon_base_name}-${random_id.vpc.hex}"
6
+ Name = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}"
7
7
  }
8
8
  }
9
9
 
10
10
  # Create subnet
11
11
  resource "aws_subnet" "subnet" {
12
- vpc_id = aws_vpc.vpc.id
13
- cidr_block = local.subnet_cidr_block
14
- availability_zone = data.aws_availability_zones.available.names[0]
15
- map_public_ip_on_launch = true
12
+ vpc_id = aws_vpc.vpc.id
13
+ cidr_block = local.subnet_cidr_block
14
+ availability_zone = data.aws_availability_zones.available.names[0]
16
15
 
17
16
  tags = {
18
- Name = "${var.aws_recon_base_name}-${random_id.vpc.hex}-public"
17
+ Name = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}-public"
19
18
  }
20
19
  }
21
20
 
22
21
  resource "aws_security_group" "sg" {
23
- name = "${var.aws_recon_base_name}-${random_id.vpc.hex}"
22
+ name = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}"
24
23
  description = "Allow AWS Recon collection egress"
25
24
  vpc_id = aws_vpc.vpc.id
26
25
 
@@ -32,7 +31,7 @@ resource "aws_security_group" "sg" {
32
31
  }
33
32
 
34
33
  tags = {
35
- Name = "${var.aws_recon_base_name}-${random_id.vpc.hex}"
34
+ Name = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}"
36
35
  }
37
36
  }
38
37
 
@@ -40,7 +39,7 @@ resource "aws_internet_gateway" "igw" {
40
39
  vpc_id = aws_vpc.vpc.id
41
40
 
42
41
  tags = {
43
- Name = "${var.aws_recon_base_name}-${random_id.vpc.hex}"
42
+ Name = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}"
44
43
  }
45
44
  }
46
45
 
@@ -53,7 +52,7 @@ resource "aws_route_table" "rt" {
53
52
  }
54
53
 
55
54
  tags = {
56
- Name = "${var.aws_recon_base_name}-${random_id.vpc.hex}"
55
+ Name = "${var.aws_recon_base_name}-${random_id.aws_recon.hex}"
57
56
  }
58
57
  }
59
58
 
@@ -67,10 +66,6 @@ locals {
67
66
  subnet_cidr_block = cidrsubnet(local.cidr_block, 8, 0)
68
67
  }
69
68
 
70
- resource "random_id" "vpc" {
71
- byte_length = 4
72
- }
73
-
74
69
  data "aws_region" "current" {}
75
70
 
76
71
  data "aws_availability_zones" "available" {
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.4.1
4
+ version: 0.4.6
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: 2021-04-01 00:00:00.000000000 Z
12
+ date: 2021-04-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk
@@ -244,15 +244,16 @@ files:
244
244
  - lib/aws_recon/services.yaml
245
245
  - lib/aws_recon/version.rb
246
246
  - readme.md
247
- - terraform/cloudwatch.tf
248
- - terraform/ecs.tf
249
- - terraform/iam.tf
250
- - terraform/main.tf
251
- - terraform/output.tf
252
- - terraform/readme.md
253
- - terraform/s3.tf
254
- - terraform/vars.tf
255
- - terraform/vpc.tf
247
+ - utils/cloudformation/aws-recon-cfn-template.yml
248
+ - utils/terraform/cloudwatch.tf
249
+ - utils/terraform/ecs.tf
250
+ - utils/terraform/iam.tf
251
+ - utils/terraform/main.tf
252
+ - utils/terraform/output.tf
253
+ - utils/terraform/readme.md
254
+ - utils/terraform/s3.tf
255
+ - utils/terraform/vars.tf
256
+ - utils/terraform/vpc.tf
256
257
  homepage: https://github.com/darkbitio/aws-recon
257
258
  licenses:
258
259
  - MIT
data/terraform/output.tf DELETED
@@ -1,13 +0,0 @@
1
- output "aws_recon_s3_bucket" {
2
- value = aws_s3_bucket.aws_recon.bucket
3
- }
4
-
5
- output "aws_recon_ecs_cluster" {
6
- value = aws_ecs_cluster.aws_recon.name
7
- }
8
-
9
- output "aws_recon_ecs_scheduled_task" {
10
- value = aws_cloudwatch_event_rule.default.name
11
- }
12
-
13
-