class IAM

Collect IAM resources

Public Instance Methods

collect() click to toggle source

Returns an array of resources.

# File lib/aws_recon/collectors/iam.rb, line 10
def collect
  resources = []

  #
  # get_account_authorization_details
  #   list_mfa_devices
  #   list_ssh_public_keys
  #
  opts = {
    filter: %w[User Role Group LocalManagedPolicy AWSManagedPolicy]
  }
  @client.get_account_authorization_details(opts).each_with_index do |response, page|
    log(response.context.operation_name, page)

    # users
    response.user_detail_list.each do |user|
      struct = OpenStruct.new(user.to_h)
      struct.type = 'user'
      struct.mfa_devices = @client.list_mfa_devices({ user_name: user.user_name }).mfa_devices.map(&:to_h)
      struct.ssh_keys = @client.list_ssh_public_keys({ user_name: user.user_name }).ssh_public_keys.map(&:to_h)
      struct.user_policy_list = if user.user_policy_list
                                  user.user_policy_list.map do |p|
                                    {
                                      policy_name: p.policy_name,
                                      policy_document: p.policy_document.parse_policy
                                    }
                                  end
                                end

      resources.push(struct.to_h)
    end

    # groups
    response.group_detail_list.each do |group|
      struct = OpenStruct.new(group.to_h)
      struct.type = 'group'
      struct.group_policy_list = if group.group_policy_list
                                   group.group_policy_list.map do |p|
                                     {
                                       policy_name: p.policy_name,
                                       policy_document: p.policy_document.parse_policy
                                     }
                                   end
                                 end

      resources.push(struct.to_h)
    end

    # roles
    response.role_detail_list.each do |role|
      struct = OpenStruct.new(role.to_h)
      struct.type = 'role'
      struct.assume_role_policy_document = role.assume_role_policy_document.parse_policy
      struct.role_policy_list = if role.role_policy_list
                                  role.role_policy_list.map do |p|
                                    {
                                      policy_name: p.policy_name,
                                      policy_document: p.policy_document.parse_policy
                                    }
                                  end
                                end

      resources.push(struct.to_h)
    end

    # polices
    response.policies.each do |policy|
      struct = OpenStruct.new(policy.to_h)
      struct.type = 'policy'
      struct.policy_version_list = if policy.policy_version_list
                                     policy.policy_version_list.map do |p|
                                       {
                                         version_id: p.version_id,
                                         document: p.document.parse_policy,
                                         is_default_version: p.is_default_version,
                                         create_date: p.create_date
                                       }
                                     end
                                   end

      resources.push(struct.to_h)
    end
  end

  #
  # list_instance_profiles
  #
  @client.list_instance_profiles.each_with_index do |response, page|
    log(response.context.operation_name, page)

    # instance_profiles
    response.instance_profiles.each do |profile|
      struct = OpenStruct.new(profile.to_h)
      struct.type = 'instance_profile'
      struct.arn = profile.arn
      struct.roles = []

      profile.roles&.each do |role|
        role.assume_role_policy_document = role.assume_role_policy_document.parse_policy
        struct.roles.push(role.to_h)
      end

      resources.push(struct.to_h)
    end
  end

  #
  # get_account_password_policy
  #
  begin
    @client.get_account_password_policy.each do |response|
      log(response.context.operation_name)

      struct = OpenStruct.new(response.password_policy.to_h)
      struct.type = 'password_policy'
      struct.arn = "arn:aws:iam::#{@account}:account_password_policy/global"

      resources.push(struct.to_h)
    end
  rescue Aws::IAM::Errors::ServiceError => e
    log_error(e.code)

    raise e unless suppressed_errors.include?(e.code) && !@options.quit_on_exception
  end

  #
  # get_account_summary
  #
  @client.get_account_summary.each do |response|
    log(response.context.operation_name)

    struct = OpenStruct.new(response.summary_map)
    struct.type = 'account_summary'
    struct.arn = "arn:aws:iam::#{@account}:account_summary/global"

    resources.push(struct.to_h)
  end

  #
  # list_server_certificates
  #
  @client.list_server_certificates.each_with_index do |response, page|
    log(response.context.operation_name, page)

    response.server_certificate_metadata_list.each do |cert|
      struct = OpenStruct.new(cert)
      struct.type = 'server_certificate'
      struct.arn = cert.arn

      resources.push(struct.to_h)
    end
  end

  #
  # list_virtual_mfa_devices
  #
  @client.list_virtual_mfa_devices.each_with_index do |response, page|
    log(response.context.operation_name, page)

    response.virtual_mfa_devices.each do |mfa_device|
      struct = OpenStruct.new(mfa_device.to_h)
      struct.type = 'virtual_mfa_device'
      struct.arn = mfa_device.serial_number

      resources.push(struct.to_h)
    end
  end

  #
  # generate_credential_report
  #
  unless @options.skip_credential_report
    status = 'STARTED'
    interval = 5

    # wait for report to generate
    while status != 'COMPLETE'
      @client.generate_credential_report.each do |response|
        log(response.context.operation_name)
        status = response.state
      end

      sleep interval unless status == 'COMPLETE'
    end
  end

  #
  # get_credential_report
  #
  begin
    @client.get_credential_report.each do |response|
      log(response.context.operation_name)

      struct = OpenStruct.new
      struct.type = 'credential_report'
      struct.arn = "arn:aws:iam::#{@account}:credential_report/global"
      struct.content = CSV.parse(response.content, headers: :first_row).map(&:to_h)
      struct.report_format = response.report_format
      struct.generated_time = response.generated_time

      resources.push(struct.to_h)
    end
  rescue Aws::IAM::Errors::ServiceError => e
    log_error(e.code)

    raise e unless suppressed_errors.include?(e.code) && !@options.quit_on_exception
  end

  resources
end

Private Instance Methods

suppressed_errors() click to toggle source

not an error

# File lib/aws_recon/collectors/iam.rb, line 224
def suppressed_errors
  %w[
    ReportNotPresent
    NoSuchEntity
  ]
end