aws_recon 0.2.7 → 0.2.12
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 +4 -4
- data/.github/workflows/docker-build.yml +38 -0
- data/.github/workflows/smoke-test.yml +23 -0
- data/Dockerfile +35 -0
- data/LICENSE.txt +1 -1
- data/aws_recon.gemspec +1 -0
- data/binstub/aws_recon +10 -0
- data/lib/aws_recon/aws_recon.rb +1 -1
- data/lib/aws_recon/collectors/accessanalyzer.rb +24 -0
- data/lib/aws_recon/collectors/ec2.rb +12 -0
- data/lib/aws_recon/collectors/iam.rb +60 -1
- data/lib/aws_recon/collectors/organizations.rb +15 -0
- data/lib/aws_recon/collectors/shield.rb +2 -2
- data/lib/aws_recon/collectors/sqs.rb +1 -0
- data/lib/aws_recon/lib/formatter.rb +1 -1
- data/lib/aws_recon/lib/mapper.rb +2 -1
- data/lib/aws_recon/options.rb +7 -0
- data/lib/aws_recon/services.yaml +2 -0
- data/lib/aws_recon/version.rb +1 -1
- data/readme.md +61 -5
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91c04c23df1fe4fb4ca28ae164c15bc2994a63b8acf0b33b07aedeeb7a11f021
|
4
|
+
data.tar.gz: 148087c3e082a71c78efccdf6628a9d70115a4f409ac9c7dfdb503218e11d168
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53d87f172f074567da9b2d31ff9fad2e3507bef9e95da5a419ff30e3fbb70c00c46bc70b8b9b1af57da400aceb8a524b79c042dda648cd6098a9792b5eb628ea
|
7
|
+
data.tar.gz: 90396f3003e5d34b8dd21a582fc2bab93f11b28744cac6c207658e16c4f43376fa42932d03e3e8438b73fd80400036af172b7573da82fa38043e9ba78e29137c
|
@@ -0,0 +1,38 @@
|
|
1
|
+
name: docker-build
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: build
|
6
|
+
paths:
|
7
|
+
- 'lib/aws_recon/version.rb '
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
docker-build:
|
11
|
+
runs-on: ubuntu-20.04
|
12
|
+
steps:
|
13
|
+
- name: Checkout
|
14
|
+
uses: actions/checkout@v2
|
15
|
+
with:
|
16
|
+
fetch-depth: 1
|
17
|
+
- name: Set up QEMU
|
18
|
+
uses: docker/setup-qemu-action@v1
|
19
|
+
- name: Set up Docker Buildx
|
20
|
+
uses: docker/setup-buildx-action@v1
|
21
|
+
- name: Login to DockerHub
|
22
|
+
uses: docker/login-action@v1
|
23
|
+
with:
|
24
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
25
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
26
|
+
- name: Set version tag
|
27
|
+
run: |
|
28
|
+
echo "VERSION_TAG=$(grep VERSION lib/aws_recon/version.rb | awk -F\" '{print $2}')" >> $GITHUB_ENV
|
29
|
+
- name: Build and push
|
30
|
+
id: docker_build
|
31
|
+
uses: docker/build-push-action@v2
|
32
|
+
with:
|
33
|
+
push: true
|
34
|
+
build-args: |
|
35
|
+
VERSION=${{ env.VERSION_TAG }}
|
36
|
+
tags: |
|
37
|
+
darkbitio/aws_recon:${{ env.VERSION_TAG }}
|
38
|
+
darkbitio/aws_recon:latest
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: smoke-test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: main
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
smoke-test:
|
9
|
+
runs-on: ubuntu-20.04
|
10
|
+
steps:
|
11
|
+
- name: Checkout
|
12
|
+
uses: actions/checkout@v2
|
13
|
+
with:
|
14
|
+
fetch-depth: 1
|
15
|
+
- name: Set version tag
|
16
|
+
run: |
|
17
|
+
echo "VERSION_TAG=$(grep VERSION lib/aws_recon/version.rb | awk -F\" '{print $2}')" >> $GITHUB_ENV
|
18
|
+
- name: Smoke Test :${{ env.VERSION_TAG }}
|
19
|
+
run: |
|
20
|
+
docker run -t --rm darkbitio/aws_recon:${{ env.VERSION_TAG }} aws_recon
|
21
|
+
- name: Smoke Test :latest
|
22
|
+
run: |
|
23
|
+
docker run -t --rm darkbitio/aws_recon:latest aws_recon
|
data/Dockerfile
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
ARG RUBY_VERSION=2.6.6
|
2
|
+
FROM ruby:${RUBY_VERSION}-alpine
|
3
|
+
|
4
|
+
LABEL maintainer="Darkbit <info@darkbit.io>"
|
5
|
+
|
6
|
+
# Supply AWS Recon version at build time
|
7
|
+
ARG VERSION
|
8
|
+
ARG USER=recon
|
9
|
+
ARG GEM=aws_recon
|
10
|
+
ARG BUNDLER_VERSION=2.1.4
|
11
|
+
|
12
|
+
# Install new Bundler version
|
13
|
+
RUN rm /usr/local/lib/ruby/gems/*/specifications/default/bundler-*.gemspec && \
|
14
|
+
gem uninstall bundler && \
|
15
|
+
gem install bundler -v ${BUNDLER_VERSION}
|
16
|
+
|
17
|
+
# Install gem
|
18
|
+
RUN gem install ${GEM} -v ${VERSION}
|
19
|
+
|
20
|
+
# Create non-root user
|
21
|
+
RUN addgroup -S ${USER} && \
|
22
|
+
adduser -S ${USER} \
|
23
|
+
-G ${USER} \
|
24
|
+
-s /bin/ash \
|
25
|
+
-h /${USER}
|
26
|
+
|
27
|
+
# Copy binstub
|
28
|
+
COPY binstub/${GEM} /usr/local/bundle/bin/
|
29
|
+
RUN chmod +x /usr/local/bundle/bin/${GEM}
|
30
|
+
|
31
|
+
# Switch user
|
32
|
+
USER ${USER}
|
33
|
+
WORKDIR /${USER}
|
34
|
+
|
35
|
+
CMD ["ash"]
|
data/LICENSE.txt
CHANGED
data/aws_recon.gemspec
CHANGED
@@ -33,4 +33,5 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_development_dependency 'solargraph', '~> 0.39.11'
|
34
34
|
spec.add_development_dependency 'rubocop', '~> 0.87.1'
|
35
35
|
spec.add_development_dependency 'pry', '~> 0.13.1'
|
36
|
+
spec.add_development_dependency 'byebug', '~> 11.1'
|
36
37
|
end
|
data/binstub/aws_recon
ADDED
data/lib/aws_recon/aws_recon.rb
CHANGED
@@ -44,7 +44,7 @@ module AwsRecon
|
|
44
44
|
#
|
45
45
|
def collect(service, region)
|
46
46
|
mapper = Object.const_get(service.name)
|
47
|
-
resources = mapper.new(service.name, region, @options)
|
47
|
+
resources = mapper.new(@account_id, service.name, region, @options)
|
48
48
|
|
49
49
|
collection = resources.collect.map do |resource|
|
50
50
|
if @options.output_format == 'custom'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class AccessAnalyzer < Mapper
|
2
|
+
#
|
3
|
+
# Returns an array of resources.
|
4
|
+
#
|
5
|
+
def collect
|
6
|
+
resources = []
|
7
|
+
|
8
|
+
#
|
9
|
+
# list_analyzers
|
10
|
+
#
|
11
|
+
@client.list_analyzers.each_with_index do |response, page|
|
12
|
+
log(response.context.operation_name, page)
|
13
|
+
|
14
|
+
# analyzers
|
15
|
+
response.analyzers.each do |analyzer|
|
16
|
+
struct = OpenStruct.new(analyzer.to_h)
|
17
|
+
struct.type = 'analyzer'
|
18
|
+
resources.push(struct.to_h)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
resources
|
23
|
+
end
|
24
|
+
end
|
@@ -31,6 +31,18 @@ class EC2 < Mapper
|
|
31
31
|
|
32
32
|
# regional calls
|
33
33
|
if @region != 'global'
|
34
|
+
#
|
35
|
+
# get_ebs_encryption_by_default
|
36
|
+
#
|
37
|
+
@client.get_ebs_encryption_by_default.each do |response|
|
38
|
+
log(response.context.operation_name)
|
39
|
+
|
40
|
+
struct = OpenStruct.new(response.to_h)
|
41
|
+
struct.type = 'ebs_encryption_settings'
|
42
|
+
|
43
|
+
resources.push(struct.to_h)
|
44
|
+
end
|
45
|
+
|
34
46
|
#
|
35
47
|
# describe_instances
|
36
48
|
#
|
@@ -10,7 +10,10 @@ class IAM < Mapper
|
|
10
10
|
# list_mfa_devices
|
11
11
|
# list_ssh_public_keys
|
12
12
|
#
|
13
|
-
|
13
|
+
opts = {
|
14
|
+
filter: %w[User Role Group LocalManagedPolicy AWSManagedPolicy]
|
15
|
+
}
|
16
|
+
@client.get_account_authorization_details(opts).each_with_index do |response, page|
|
14
17
|
log(response.context.operation_name, page)
|
15
18
|
|
16
19
|
# users
|
@@ -19,6 +22,14 @@ class IAM < Mapper
|
|
19
22
|
struct.type = 'user'
|
20
23
|
struct.mfa_devices = @client.list_mfa_devices({ user_name: user.user_name }).mfa_devices.map(&:to_h)
|
21
24
|
struct.ssh_keys = @client.list_ssh_public_keys({ user_name: user.user_name }).ssh_public_keys.map(&:to_h)
|
25
|
+
struct.user_policy_list = if user.user_policy_list
|
26
|
+
user.user_policy_list.map do |p|
|
27
|
+
{
|
28
|
+
policy_name: p.policy_name,
|
29
|
+
policy_document: JSON.parse(CGI.unescape(p.policy_document))
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
22
33
|
|
23
34
|
resources.push(struct.to_h)
|
24
35
|
end
|
@@ -27,6 +38,14 @@ class IAM < Mapper
|
|
27
38
|
response.group_detail_list.each do |group|
|
28
39
|
struct = OpenStruct.new(group.to_h)
|
29
40
|
struct.type = 'group'
|
41
|
+
struct.group_policy_list = if group.group_policy_list
|
42
|
+
group.group_policy_list.map do |p|
|
43
|
+
{
|
44
|
+
policy_name: p.policy_name,
|
45
|
+
policy_document: JSON.parse(CGI.unescape(p.policy_document))
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
30
49
|
|
31
50
|
resources.push(struct.to_h)
|
32
51
|
end
|
@@ -35,6 +54,15 @@ class IAM < Mapper
|
|
35
54
|
response.role_detail_list.each do |role|
|
36
55
|
struct = OpenStruct.new(role.to_h)
|
37
56
|
struct.type = 'role'
|
57
|
+
struct.assume_role_policy_document = JSON.parse(CGI.unescape(role.assume_role_policy_document))
|
58
|
+
struct.role_policy_list = if role.role_policy_list
|
59
|
+
role.role_policy_list.map do |p|
|
60
|
+
{
|
61
|
+
policy_name: p.policy_name,
|
62
|
+
policy_document: JSON.parse(CGI.unescape(p.policy_document))
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
38
66
|
|
39
67
|
resources.push(struct.to_h)
|
40
68
|
end
|
@@ -43,6 +71,16 @@ class IAM < Mapper
|
|
43
71
|
response.policies.each do |policy|
|
44
72
|
struct = OpenStruct.new(policy.to_h)
|
45
73
|
struct.type = 'policy'
|
74
|
+
struct.policy_version_list = if policy.policy_version_list
|
75
|
+
policy.policy_version_list.map do |p|
|
76
|
+
{
|
77
|
+
version_id: p.version_id,
|
78
|
+
document: JSON.parse(CGI.unescape(p.document)),
|
79
|
+
is_default_version: p.is_default_version,
|
80
|
+
create_date: p.create_date
|
81
|
+
}
|
82
|
+
end
|
83
|
+
end
|
46
84
|
|
47
85
|
resources.push(struct.to_h)
|
48
86
|
end
|
@@ -56,6 +94,7 @@ class IAM < Mapper
|
|
56
94
|
|
57
95
|
struct = OpenStruct.new(response.password_policy.to_h)
|
58
96
|
struct.type = 'password_policy'
|
97
|
+
struct.arn = "arn:aws:iam::#{@account}:account_password_policy/global"
|
59
98
|
|
60
99
|
resources.push(struct.to_h)
|
61
100
|
end
|
@@ -68,6 +107,7 @@ class IAM < Mapper
|
|
68
107
|
|
69
108
|
struct = OpenStruct.new(response.summary_map)
|
70
109
|
struct.type = 'account_summary'
|
110
|
+
struct.arn = "arn:aws:iam::#{@account}:account_summary/global"
|
71
111
|
|
72
112
|
resources.push(struct.to_h)
|
73
113
|
end
|
@@ -102,6 +142,24 @@ class IAM < Mapper
|
|
102
142
|
end
|
103
143
|
end
|
104
144
|
|
145
|
+
#
|
146
|
+
# generate_credential_report
|
147
|
+
#
|
148
|
+
unless @options.skip_credential_report
|
149
|
+
status = 'STARTED'
|
150
|
+
interval = 5
|
151
|
+
|
152
|
+
# wait for report to generate
|
153
|
+
while status != 'COMPLETE'
|
154
|
+
@client.generate_credential_report.each do |response|
|
155
|
+
log(response.context.operation_name)
|
156
|
+
status = response.state
|
157
|
+
end
|
158
|
+
|
159
|
+
sleep interval unless status == 'COMPLETE'
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
105
163
|
#
|
106
164
|
# get_credential_report
|
107
165
|
#
|
@@ -111,6 +169,7 @@ class IAM < Mapper
|
|
111
169
|
|
112
170
|
struct = OpenStruct.new
|
113
171
|
struct.type = 'credential_report'
|
172
|
+
struct.arn = "arn:aws:iam::#{@account}:credential_report/global"
|
114
173
|
struct.content = CSV.parse(response.content, headers: :first_row).map(&:to_h)
|
115
174
|
struct.report_format = response.report_format
|
116
175
|
struct.generated_time = response.generated_time
|
@@ -31,6 +31,21 @@ class Organizations < Mapper
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
#
|
35
|
+
# list_policies
|
36
|
+
#
|
37
|
+
@client.list_policies({ filter: 'SERVICE_CONTROL_POLICY' }).each_with_index do |response, page|
|
38
|
+
log(response.context.operation_name, page)
|
39
|
+
|
40
|
+
response.policies.each do |policy|
|
41
|
+
struct = OpenStruct.new(policy.to_h)
|
42
|
+
struct.type = 'service_control_policy'
|
43
|
+
struct.content = JSON.parse(CGI.unescape(@client.describe_policy({ policy_id: policy.id }).policy.content))
|
44
|
+
|
45
|
+
resources.push(struct.to_h)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
34
49
|
resources
|
35
50
|
end
|
36
51
|
end
|
@@ -13,7 +13,7 @@ class Shield < Mapper
|
|
13
13
|
|
14
14
|
struct = OpenStruct.new(response.subscription.to_h)
|
15
15
|
struct.type = 'subscription'
|
16
|
-
struct.arn = "arn:aws:shield:#{@region}:#{account}:subscription"
|
16
|
+
struct.arn = "arn:aws:shield:#{@region}:#{@account}:subscription"
|
17
17
|
|
18
18
|
resources.push(struct.to_h)
|
19
19
|
end
|
@@ -26,7 +26,7 @@ class Shield < Mapper
|
|
26
26
|
|
27
27
|
struct = OpenStruct.new
|
28
28
|
struct.type = 'contact_list'
|
29
|
-
struct.arn = "arn:aws:shield:#{@region}:#{account}:contact_list"
|
29
|
+
struct.arn = "arn:aws:shield:#{@region}:#{@account}:contact_list"
|
30
30
|
struct.contacts = response.emergency_contact_list.map(&:to_h)
|
31
31
|
|
32
32
|
resources.push(struct.to_h)
|
@@ -18,6 +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
22
|
|
22
23
|
resources.push(struct.to_h)
|
23
24
|
end
|
@@ -8,7 +8,7 @@ class Formatter
|
|
8
8
|
def custom(account_id, region, service, resource)
|
9
9
|
{
|
10
10
|
account: account_id,
|
11
|
-
name: resource[:arn]
|
11
|
+
name: resource[:arn],
|
12
12
|
service: service.name,
|
13
13
|
region: region,
|
14
14
|
asset_type: resource[:type],
|
data/lib/aws_recon/lib/mapper.rb
CHANGED
@@ -22,7 +22,8 @@ class Mapper
|
|
22
22
|
# S3 (unless the bucket was created in another region)
|
23
23
|
SINGLE_REGION_SERVICES = %w[route53domains s3 shield support organizations].freeze
|
24
24
|
|
25
|
-
def initialize(service, region, options)
|
25
|
+
def initialize(account, service, region, options)
|
26
|
+
@account = account
|
26
27
|
@service = service
|
27
28
|
@region = region
|
28
29
|
@options = options
|
data/lib/aws_recon/options.rb
CHANGED
@@ -17,6 +17,7 @@ class Parser
|
|
17
17
|
:threads,
|
18
18
|
:collect_user_data,
|
19
19
|
:skip_slow,
|
20
|
+
:skip_credential_report,
|
20
21
|
:stream_output,
|
21
22
|
:verbose,
|
22
23
|
:debug
|
@@ -45,6 +46,7 @@ class Parser
|
|
45
46
|
false,
|
46
47
|
false,
|
47
48
|
false,
|
49
|
+
false,
|
48
50
|
false
|
49
51
|
)
|
50
52
|
|
@@ -115,6 +117,11 @@ class Parser
|
|
115
117
|
args.skip_slow = true
|
116
118
|
end
|
117
119
|
|
120
|
+
# skip generating IAM credential report
|
121
|
+
opts.on('-g', '--skip-credential-report', 'Skip generating IAM credential report (default: false)') do
|
122
|
+
args.skip_credential_report = true
|
123
|
+
end
|
124
|
+
|
118
125
|
# stream output (forces JSON lines, doesn't output handled warnings or errors )
|
119
126
|
opts.on('-j', '--stream-output', 'Stream JSON lines to stdout (default: false)') do
|
120
127
|
args.output_file = nil
|
data/lib/aws_recon/services.yaml
CHANGED
data/lib/aws_recon/version.rb
CHANGED
data/readme.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+

|
1
2
|
[](https://badge.fury.io/rb/aws_recon)
|
2
3
|
|
3
4
|
# AWS Recon
|
@@ -26,18 +27,20 @@ Ruby 2.5.x or 2.6.x (developed and tested with 2.6.5)
|
|
26
27
|
|
27
28
|
### Installation
|
28
29
|
|
29
|
-
|
30
|
+
AWS Recon can be run locally by installing the Ruby gem, or via a Docker container.
|
31
|
+
|
32
|
+
To run locally, first install the gem:
|
30
33
|
|
31
34
|
```
|
32
35
|
$ gem install aws_recon
|
33
|
-
Fetching aws_recon-0.2.
|
36
|
+
Fetching aws_recon-0.2.8.gem
|
34
37
|
Fetching aws-sdk-resources-3.76.0.gem
|
35
38
|
Fetching aws-sdk-3.0.1.gem
|
36
39
|
Fetching parallel-1.19.2.gem
|
37
40
|
...
|
38
41
|
Successfully installed aws-sdk-3.0.1
|
39
42
|
Successfully installed parallel-1.19.2
|
40
|
-
Successfully installed aws_recon-0.2.
|
43
|
+
Successfully installed aws_recon-0.2.8
|
41
44
|
```
|
42
45
|
|
43
46
|
Or add it to your Gemfile using `bundle`:
|
@@ -49,9 +52,23 @@ Resolving dependencies...
|
|
49
52
|
...
|
50
53
|
Using aws-sdk 3.0.1
|
51
54
|
Using parallel 1.19.2
|
52
|
-
Using aws_recon 0.2.
|
55
|
+
Using aws_recon 0.2.8
|
56
|
+
```
|
57
|
+
|
58
|
+
To run via a Docker a container, pass the necessary AWS credentials into the Docker `run` command. For example:
|
59
|
+
|
60
|
+
```
|
61
|
+
$ docker run -t --rm \
|
62
|
+
-e AWS_REGION \
|
63
|
+
-e AWS_ACCESS_KEY_ID \
|
64
|
+
-e AWS_SECRET_ACCESS_KEY \
|
65
|
+
-e AWS_SESSION_TOKEN \
|
66
|
+
-v $(pwd)/output.json:/recon/output.json \
|
67
|
+
darkbitio/aws_recon:latest \
|
68
|
+
aws_recon -v -s EC2 -r global,us-east-1,us-east-2
|
53
69
|
```
|
54
70
|
|
71
|
+
|
55
72
|
## Usage
|
56
73
|
|
57
74
|
AWS Recon will leverage any AWS credentials currently available to the environment it runs in. If you are collecting from multiple accounts, you may want to leverage something like [aws-vault](https://github.com/99designs/aws-vault) to manage different credentials.
|
@@ -66,6 +83,39 @@ Plain environment variables will work fine too.
|
|
66
83
|
$ AWS_PROFILE=<profile> aws_recon
|
67
84
|
```
|
68
85
|
|
86
|
+
To run from a Docker container using `aws-vault` managed credentials (output to stdout):
|
87
|
+
|
88
|
+
```
|
89
|
+
$ aws-vault exec <vault_profile> -- docker run -t --rm \
|
90
|
+
-e AWS_REGION \
|
91
|
+
-e AWS_ACCESS_KEY_ID \
|
92
|
+
-e AWS_SECRET_ACCESS_KEY \
|
93
|
+
-e AWS_SESSION_TOKEN \
|
94
|
+
darkbitio/aws_recon:latest \
|
95
|
+
aws_recon -j -s EC2 -r global,us-east-1,us-east-2
|
96
|
+
```
|
97
|
+
|
98
|
+
To run from a Docker container using `aws-vault` managed credentials and output to a file, you will need to satisfy a couple of requirements. First, Docker needs access to bind mount the path you specify (or a parent path above). Second, you need to create an empty file to save the output into (e.g. `output.json`). This is because we are only mounting that one file into the Docker container at run time. For example:
|
99
|
+
|
100
|
+
Create an empty file.
|
101
|
+
|
102
|
+
```
|
103
|
+
$ touch output.json
|
104
|
+
```
|
105
|
+
|
106
|
+
Run the `aws_recon` container, specifying the output file.
|
107
|
+
|
108
|
+
```
|
109
|
+
$ aws-vault exec <vault_profile> -- docker run -t --rm \
|
110
|
+
-e AWS_REGION \
|
111
|
+
-e AWS_ACCESS_KEY_ID \
|
112
|
+
-e AWS_SECRET_ACCESS_KEY \
|
113
|
+
-e AWS_SESSION_TOKEN \
|
114
|
+
-v $(pwd)/output.json:/recon/output.json \
|
115
|
+
darkbitio/aws_recon:latest \
|
116
|
+
aws_recon -s EC2 -v -r global,us-east-1,us-east-2
|
117
|
+
```
|
118
|
+
|
69
119
|
You may want to use the `-v` or `--verbose` flag initially to see status and activity while collection is running.
|
70
120
|
|
71
121
|
In verbose mode, the console output will show:
|
@@ -109,6 +159,12 @@ $ AWS_PROFILE=<profile> aws_recon -s S3,EC2 -r global,us-east-1,us-east-2
|
|
109
159
|
$ AWS_PROFILE=<profile> aws_recon --services S3,EC2 --regions global,us-east-1,us-east-2
|
110
160
|
```
|
111
161
|
|
162
|
+
Example [OpenCSPM](https://github.com/OpenCSPM/opencspm) formatted output.
|
163
|
+
|
164
|
+
```
|
165
|
+
$ AWS_PROFILE=<profile> aws_recon -s S3,EC2 -r global,us-east-1,us-east-2 -f custom > output.json
|
166
|
+
```
|
167
|
+
|
112
168
|
#### Errors
|
113
169
|
|
114
170
|
An exception will be raised on `AccessDeniedException` errors. This typically means your user/role doesn't have the necessary permissions to get/list/describe for that service. These exceptions are raised so troubleshooting access issues is easier.
|
@@ -135,7 +191,7 @@ Most users will want to limit collection to relevant services and regions. Runni
|
|
135
191
|
```
|
136
192
|
$ aws_recon -h
|
137
193
|
|
138
|
-
AWS Recon - AWS Inventory Collector (0.2.
|
194
|
+
AWS Recon - AWS Inventory Collector (0.2.8)
|
139
195
|
|
140
196
|
Usage: aws_recon [options]
|
141
197
|
-r, --regions [REGIONS] Regions to scan, separated by comma (default: all)
|
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.12
|
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-
|
12
|
+
date: 2020-11-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk
|
@@ -137,6 +137,20 @@ dependencies:
|
|
137
137
|
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: 0.13.1
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: byebug
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - "~>"
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '11.1'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - "~>"
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '11.1'
|
140
154
|
description: AWS Recon is a command line tool to collect resources from an Amazon
|
141
155
|
Web Services (AWS) account. The tool outputs JSON suitable for processing with other
|
142
156
|
tools.
|
@@ -149,9 +163,12 @@ extensions: []
|
|
149
163
|
extra_rdoc_files: []
|
150
164
|
files:
|
151
165
|
- ".github/stale.yml"
|
166
|
+
- ".github/workflows/docker-build.yml"
|
167
|
+
- ".github/workflows/smoke-test.yml"
|
152
168
|
- ".gitignore"
|
153
169
|
- ".rubocop.yml"
|
154
170
|
- ".travis.yml"
|
171
|
+
- Dockerfile
|
155
172
|
- Gemfile
|
156
173
|
- LICENSE.txt
|
157
174
|
- Rakefile
|
@@ -159,9 +176,11 @@ files:
|
|
159
176
|
- bin/aws_recon
|
160
177
|
- bin/console
|
161
178
|
- bin/setup
|
179
|
+
- binstub/aws_recon
|
162
180
|
- lib/aws_recon.rb
|
163
181
|
- lib/aws_recon/aws_recon.rb
|
164
182
|
- lib/aws_recon/collectors.rb
|
183
|
+
- lib/aws_recon/collectors/accessanalyzer.rb
|
165
184
|
- lib/aws_recon/collectors/acm.rb
|
166
185
|
- lib/aws_recon/collectors/apigateway.rb
|
167
186
|
- lib/aws_recon/collectors/apigatewayv2.rb
|