Module: PWN::AWS::IAM

Defined in:
lib/pwn/aws/iam.rb

Overview

This module provides a client for making API requests to AWS Identity and Access Management.

Constant Summary collapse

@@logger =
PWN::Plugins::PWNLogger.create

Class Method Summary collapse

Class Method Details

.authorsObject

Author(s)

0day Inc. [email protected]



168
169
170
171
172
# File 'lib/pwn/aws/iam.rb', line 168

public_class_method def self.authors
  "AUTHOR(S):
    0day Inc. <[email protected]>
  "
end

.connect(opts = {}) ⇒ Object

Supported Method Parameters

PWN::AWS::IAM.connect( region: 'required - region name to connect (eu-west-1, ap-southeast-1, ap-southeast-2, eu-central-1, ap-northeast-2, ap-northeast-1, us-east-1, sa-east-1, us-west-1, us-west-2)', access_key_id: 'required - Use AWS STS for best privacy (i.e. temporary access key id)', secret_access_key: 'required - Use AWS STS for best privacy (i.e. temporary secret access key', sts_session_token: 'optional - Temporary token returned by STS client for best privacy' )



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/pwn/aws/iam.rb', line 21

public_class_method def self.connect(opts = {})
  region = opts[:region].to_s.scrub.chomp.strip
  access_key_id = opts[:access_key_id].to_s.scrub.chomp.strip
  secret_access_key = opts[:secret_access_key].to_s.scrub.chomp.strip
  sts_session_token = opts[:sts_session_token].to_s.scrub.chomp.strip

  @@logger.info('Connecting to AWS IAM...')
  if sts_session_token == ''
    iam_obj = Aws::IAM::Client.new(
      region: region,
      access_key_id: access_key_id,
      secret_access_key: secret_access_key
    )
  else
    iam_obj = Aws::IAM::Client.new(
      region: region,
      access_key_id: access_key_id,
      secret_access_key: secret_access_key,
      session_token: sts_session_token
    )
  end
  @@logger.info("complete.\n")

  iam_obj
rescue StandardError => e
  raise e
end

.decode_key(opts = {}) ⇒ Object

Supported Method Parameters

PWN::AWS::IAM.decode_key( key: 'required - key to decode', key_type: 'optional - key type :access_key_id|:secret_access_key|:sts_session_token (Default: access_key_id)', )



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/pwn/aws/iam.rb', line 54

public_class_method def self.decode_key(opts = {})
  key = opts[:key].to_s.scrub.chomp.strip.upcase
  raise 'ERROR: Key is required' if key == ''

  key_type = opts[:key_type] || :access_key_id
  key_type = key_type.to_s.scrub.chomp.strip.to_sym

  decoded_key = {}

  prefix = key[0..3].to_s.downcase.to_sym
  case prefix
  when :abia
    resource_type = 'AWS STS Service Bearer Token'
    decoded_key[:prefix] = prefix
  when :acca
    resource_type = 'Context Specific Credential'
    decoded_key[:prefix] = prefix
  when :agpa
    resource_type = 'Group'
    decoded_key[:prefix] = prefix
  when :aida
    resource_type = 'IAM User'
    decoded_key[:prefix] = prefix
  when :aipa
    resource_type = 'EC2 Instance Profile'
    decoded_key[:prefix] = prefix
  when :akia
    resource_type = 'Access Key'
    decoded_key[:prefix] = prefix
  when :anpa
    resource_type = 'Managed Policy'
    decoded_key[:prefix] = prefix
  when :anva
    resource_type = 'Version in a Managed Policy'
    decoded_key[:prefix] = prefix
  when :apka
    resource_type = 'Public Key'
    decoded_key[:prefix] = prefix
  when :aroa
    resource_type = 'Role'
    decoded_key[:prefix] = prefix
  when :asca
    resource_type = 'Certificate'
    decoded_key[:prefix] = prefix
  when :asia
    resource_type = 'Temporary (AWS STS) Keys'
    decoded_key[:prefix] = prefix
  else
    resource_type = 'Secret Access Key' if key_type == :secret_access_key
    resource_type = 'STS Session' if key_type == :sts_session_token
  end

  decoded_key[:resource_type] = resource_type

  case key_type
  when :access_key_id
    suffix = key[4..-1]
    decoded_suffix = Base32.decode(suffix)
    trimmed_decoded_suffix = decoded_suffix[0..5]
    z = trimmed_decoded_suffix.bytes.inject { |total, byte| (total << 8) + byte }
    mask = 0x7FFFFFFFFF80
    key = (z & mask) >> 7
    decoded_key[:account_id] = key
  when :secret_access_key, :sts_session_token
    decoded_key[:decoded_key] = Base64.strict_decode64(key)
  else
    raise "ERROR: Invalid Key Type: #{key_type}.  Valid key types are :access_key_id|:secret_access_key|:sts_session_token"
  end
  decoded_key[:key_type] = key_type

  decoded_key
rescue StandardError => e
  raise e
end

.disconnect(opts = {}) ⇒ Object

Supported Method Parameters

PWN::AWS::IAM.disconnect( iam_obj: 'required - iam_obj returned from #connect method' )



155
156
157
158
159
160
161
162
163
164
# File 'lib/pwn/aws/iam.rb', line 155

public_class_method def self.disconnect(opts = {})
  iam_obj = opts[:iam_obj]
  @@logger.info('Disconnecting...')
  iam_obj = nil
  @@logger.info("complete.\n")

  iam_obj
rescue StandardError => e
  raise e
end

.helpObject

Display Usage for this Module



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/pwn/aws/iam.rb', line 176

public_class_method def self.help
  puts "USAGE:
    # Run connect and return its result
    #{self}.connect(
      region: 'required - region name to connect (eu-west-1, ap-southeast-1, ap-southeast-2, eu-central-1, ap-northeast-2, ap-northeast-1, us-east-1, sa-east-1, us-west-1, us-west-2)',
      access_key_id: 'required - Use AWS STS for best privacy (i.e. temporary access key id)',
      secret_access_key: 'required - Use AWS STS for best privacy (i.e. temporary secret access key',
      sts_session_token: 'optional - Temporary token returned by STS client for best privacy'
    )

    # Run decode key and return its result
    #{self}.decode_key(
      key: 'required - key to decode',
      key_type: 'optional - key type :access_key_id|:secret_access_key|:sts_session_token (Default: access_key_id)'
    )

    # TODO: Implement this method
    #{self}.disconnect(
      account_id: 'required - AWS Account ID',
      prefix: 'optional - prefix for the key :abia|:acca|:agpa|:aida|:aipa|:akia|:anpa|:anva|:apka|:aroa|:asca|:asia (Default: akia)',
      iam_obj: 'required - iam_obj returned from #connect method'
    )

    # Print the AUTHOR(S) string for this module.
    #{self}.authors
  "
  constants.sort
end