aws_recon 0.4.1 → 0.4.6

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: 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
-