Introduction
The cloud is a rented infrastructure. When we say a company "runs in the cloud", we mean they pay a provider (AWS, Azure, Google Cloud, or another) for compute, storage, and networking delivered through an API. Instead of buying servers and racking them in a room, the customer clicks a button and receives a virtual machine minutes later.
That matters to a penetration tester for one reason: almost every engagement now crosses cloud boundaries. A company's public-facing web app might run on a cloud virtual machine, its files in an object storage bucket, and its identities in a cloud directory. If we do not understand the primitives attackers abuse in these environments, we miss findings, or worse, we write recommendations that do not apply.
This room will present the concepts in a cloud-agnostic way. Each task will introduce concepts using generic terms that convey the same general idea across different clouds. The flow will cover service deployment models, identity, storage, networking, and compute. You will also have a practical, hands-on exercise at the end in a simulated cloud environment that will walk you through port scanning, pivoting, SSRF chaining, and exfiltration.
Learning Objectives
- Explain the Shared Responsibility Model and map responsibilities across IaaS, PaaS, and SaaS
- Read an IAM policy, identify roles as the attackable primitive, and spot an over-permissive wildcard
- Recognize publicly exposed cloud storage and articulate how an attacker enumerates it
- Describe cloud networking primitives and common exposed-service and lateral-movement patterns
- Explain the Instance Metadata Service and the SSRF-to-credentials attack chain
- Walk a guided, cloud-agnostic attack against a simulated cloud environment
Learning Prerequisites
- Basic Linux commands - Linux Fundamentals
- HTTP basics - Web Application Basics
- General attacker mindset from earlier rooms in the Jr Penetration Tester path
?Answer the questions below
- The cloud is just someone else's computer.
Cloud Service and Deployment Models
Every cloud engagement starts with a simple question: What is the customer actually renting, and where does the provider's responsibility stop? Answer that, and we know where to look for misconfigurations. Service and deployment models are the vocabulary for that conversation.
Service Models
Three abbreviations cover most of what we meet in practice, and we can ground each one with an analogy.
- IaaS (Infrastructure as a Service) is renting raw computing hardware. The provider gives us a virtual machine, a virtual disk, and a virtual network, and we install and run everything on top. Think of it as renting an empty apartment: the walls and plumbing are there, everything else is on us. A cloud virtual machine running our own web stack, for example.
- PaaS (Platform as a Service) is renting a managed runtime. The provider handles the operating system, the runtime, and, often, scaling. We upload our code or data, and it runs. Think of it as renting a semi-furnished apartment: the basics are already set, and you can move in and focus on living, not installing all the infrastructure. Cloud-hosted email or a collaboration suite are typical examples.
- SaaS (Software as a Service) is renting a fully managed application. The provider runs everything: the infrastructure, the platform, and the software itself; we log in through a web interface, configure a few settings, and use it. Think of it as renting a hotel room: everything is ready to use, and cleaning, maintenance, and all services are handled for you. Cloud-hosted email or a collaboration suite are good examples.
Deployment Models
Deployment models describe who else shares the infrastructure:
- Public cloud: shared infrastructure operated by a provider, our workloads live alongside other customers' workloads, separated by the hypervisor and network controls
- Private cloud: infrastructure dedicated to one organisation, either run on-premises or hosted
- Hybrid cloud: a mix of the two, with some workloads in the public cloud and some on-premises, connected by a private link or VPN
- Community cloud: shared infrastructure between organisations with common requirements, for example, a government or regulated-industry cloud
The Shared Responsibility Model
Many cloud security incidents happen because customers misunderstand where their responsibility begins and ends. The provider always secures the physical data centre, the hardware, and the hypervisor. The customer always owns their data, their identities, and the access policies on their resources. The interesting part, the place where misconfigurations cluster, is the middle: the operating system, the runtime, the network configuration. That middle shifts based on the service model.
| Layer | IaaS | PaaS | SaaS |
|---|---|---|---|
| Physical datacentre | Provider | Provider | Provider |
| Hardware and hypervisor | Provider | Provider | Provider |
| Network Configuration | Customer | Shared | Provider |
| Operating system | Customer | Provider | Provider |
| Runtime and middleware | Customer | Provider | Provider |
| Application code | Customer | Customer | Provider |
| Data | Customer | Customer | Customer |
| Identities and access | Customer | Customer | Customer |
As attackers, we do not find bugs in the hypervisor on a normal engagement. We find bugs or plain mistakes where the customer was supposed to do something, but did not. A virtual machine left with a default password, a storage bucket made public, and a policy given a wildcard action. The Shared Responsibility Model is the map that tells us where to search.
Provider Callouts
Every provider has their own names for the same ideas. Here are a few examples you will most often meet.
| Model | AWS example | Azure example | Google Cloud example |
|---|---|---|---|
| IaaS | EC2 instance | Azure Virtual Machine | Compute Engine VM |
| PaaS | RDS, Elastic Beanstalk | Azure SQL Database, App Service | Cloud SQL, App Engine |
| SaaS | Amazon WorkMail | Microsoft 365 | Google Workspace |
?Answer the questions below
- A company runs its own web stack on a cloud virtual machine but does not manage the physical hardware. Which service model describes this arrangement?
- In the Shared Responsibility Model, who is always responsible for securing the physical datacentre and hardware?
Identity and Access Management (IAM)
Identity is where most cloud compromises start. A leaked access key or a role with too many permissions beats a memory-corruption exploit nine times out of ten on a real engagement. Let's build the minimum mental model we need to read a policy, recognise what roles actually let us do, and know what to ask first when we land a set of credentials.
Policies Are Just Documents
A cloud IAM policy is a JSON document that specifies who can do what to which resources. Three fields carry most of the meaning:
- Effect:
AlloworDeny - Action: the operations the policy covers, such as
storage:GetObjectoriam:CreateUser - Resource: the specific resource the action applies to, usually expressed as a provider-specific identifier
Here is a small example of a well-scoped policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "storage:GetObject",
"Resource": "bucket/reports/*"
}
]
}
This grants a single action on a single bucket prefix. Compare it to this one:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
Same structure, very different blast radius. The wildcard (*) on Action and Resource means the identity holding this policy can do anything to anything. When we read a policy, the first thing we look for is wildcards in those two fields.
Two notes before we move on. The storage: prefix in these examples is a generic stand-in we use throughout the room, real providers use their own service prefixes (s3: on AWS, different naming conventions on Azure and Google Cloud). And the JSON shape shown above is the AWS IAM policy language; Azure RBAC and Google Cloud IAM express the same ideas with different structures, but the reading discipline of finding Effect, checking Action, and Resource transfers everywhere.
Roles and Role Assumption
Users and groups look familiar from any corporate directory. The primitive that matters most to us is the role. A role is a named bundle of permissions that an identity can temporarily assume. Instead of giving a long-lived user every permission it might ever need, organizations create roles, attach policies to them, and let users or workloads assume the role when they need the permissions.
When an identity assumes a role, the cloud provider hands back temporary credentials scoped to that role's policies. As attackers, we care about role assumption for two reasons:
- A compromised user or workload often has the right to assume a more privileged role, which is our privilege escalation path
- The Instance Metadata Service hands out temporary credentials for the role attached to a virtual machine. Grab those credentials, and we are now in that role.
The IAM Enumeration Mindset
Whenever we land a set of cloud credentials, whether from a leaked .aws/credentials file, an SSRF response, or a compromised service, the first question should be "What can I do with these?".
At the concept level, our mental checklist looks like this:
- Which identity do these credentials belong to?
- What policies are attached, directly or through a group?
- Which roles can this identity assume?
- Are any of those policies over-permissive (wildcards)?
- Which resources are in scope: a single resource or the whole account?
Every provider has commands and API calls that answer these questions. We skip the tooling here because the pattern matters more than the syntax, and the Jr Penetration Tester path has provider-specific rooms coming for the tools.
The One Weakness Pattern Worth Knowing
If we only remember one IAM attack pattern, it is this: over-permissive policies combined with exposed keys.
Access keys end up in the wrong place constantly and attackers scrape all of these:
- Committed to public code repositories.
- Embedded in container images pushed to a public registry.
- Written in a config file that got backed up to a public bucket.
- Printed in a screenshot posted on a ticket.
The keys themselves are just strings. They become a breach when the identity behind them has an over-permissive policy. A developer's key with a wildcard action on the company's main bucket is one mistake away from a data leak. That is the shape of most cloud incidents that hit the news, and it is the combination we hunt for on every engagement.
Provider Callouts
| Concept | AWS | Azure | Google Cloud |
|---|---|---|---|
| Identity service | IAM | Microsoft Entra ID | Cloud IAM |
| Long-lived credential | Access Key ID + Secret | Client ID + Secret, or user login | Service account key, or user login |
| Role equivalent | IAM Role | Managed Identity | Service Account |
?Answer the questions below
- In an IAM policy statement, which field states whether access is allowed or denied?
- A named, temporary bundle of permissions that an identity can assume is called what?
Cloud Storage and Data Exposure
Public cloud storage buckets are the single most common source of breach headlines. The pattern is always the same: someone created a bucket, uploaded something they did not want the world to see, and left the access controls wrong. Our job as attackers is to find those buckets and make use of whatever they serve up.
Object Storage Basics
Object storage is a flat namespace of containers (called buckets on AWS and Google Cloud, and containers on Azure) that hold objects. An object is a file plus metadata. Every object is accessible by a URL shaped like https://<provider-endpoint>/<bucket-name>/<object-key>.
Three access-control primitives show up on every platform:
- Bucket policies (IAM-style): the main access rule, a JSON document similar to what we saw in Task 3
- ACLs (Access Control Lists): legacy per-object access rules, simpler but more error-prone
- Signed URLs (also called pre-signed URLs): time-limited links that anyone with the URL can follow, even without credentials
Each one fails differently. Bucket policies fail when someone writes "Principal": "*". ACLs fail when someone sets "public read" without realising the bucket is already public. Signed URLs fail when the signing key leaks or the expiry is set to a decade from now.
How Buckets End Up Public
Four patterns cover most real incidents:
- Defaults that are left alone during development. A developer creates a bucket for testing, makes it public to avoid running into permission issues, and forgets to restrict it before the bucket is filled with real data.
- Block-public-access being disabled on purpose. Providers now ship a top-level switch that blocks public access even when individual policies allow it. Turning it off to make something work exposes everything.
- Wildcard principals in policies. A policy with
"Principal": "*"means any identity on the internet. - Leaked or long-lived signed URLs. A URL valid for five years posted in a ticket ends up indexed by search engines.
Attacker Workflow
Our approach to discovering exposed storage is methodical:
- Identify bucket names. Bucket names often follow patterns:
<company>-backups,<company>-dev,<company>-prod,<company>-assets. We combine a company name with common suffixes and probe. - Probe provider endpoints. We send an HTTP request to the provider's public URL shape for each candidate name. If the bucket exists and is public, we get a listing or a confirmation.
- List the bucket. When the listing is public, a plain GET request to the bucket URL returns an index of all objects. We grep for filenames that look interesting.
- Download the goods. Anything that lists is ours to read, no credentials needed.
Tools like s3scanner, cloud_enum, and simple curl one-liners automate this. The technique is mostly patience and a good wordlist, not a clever exploit.
What Ends Up In Open Buckets
The artefacts we prioritise, in rough order of value:
- Backups. Database dumps, full-disk snapshots, config backups. Everything in one file.
- Source code and build artefacts. Hardcoded secrets, internal API documentation, unreleased features.
- Configuration files.
.envfiles,credentials.json, Kubernetes config, CI/CD secrets. - Logs. User emails, session tokens, internal IPs, and sometimes passwords are included in error messages.
- Customer data. Tables of emails, addresses, payment identifiers, and personal documents.
A single publicly listable backup file is often more impactful than every other technique combined.
Provider Callouts
| Concept | AWS | Azure | Google Cloud |
|---|---|---|---|
| Storage service | Amazon S3 | Azure Blob Storage | Google Cloud Storage |
| Unit of storage | Bucket | Container | Bucket |
| Public URL shape | https://<bucket>.s3.amazonaws.com/<key> | https://<account>.blob.core.windows.net/<container>/<blob> | https://storage.googleapis.com/<bucket>/<object> |
| Access document | Bucket Policy, IAM policy, ACL | Shared Access Signature, RBAC, public access level | IAM policy, ACL, signed URL |
?Answer the questions below
- A bucket policy that sets "Principal": "*" effectively makes the bucket what? (one word, used throughout this task)
- From the list of artifacts worth prioritizing in an open bucket, which single type tends to hold the most sensitive data in one file?
Cloud Networking
Once we know what the target rents from the cloud, the next question is simple: what is actually reachable, and what can we do once we have a foothold inside. Cloud networking answers both. The primitives are similar across providers even when the names differ.
The Building Blocks
A virtual network (sometimes called a VPC, for Virtual Private Cloud) is the private network a customer carves out within the provider's network. It has its own IP address range and is isolated from other customers' virtual networks unless someone intentionally connects them.
A subnet is a slice of that virtual network. Subnets are usually split into public and private. A public subnet has a route to the internet via an Internet Gateway (IGW), which allows resources inside to reach the outside world. A private subnet has no such route. Resources in a private subnet can reach each other, but nothing from the internet can reach them directly.
Two firewall primitives sit on top of that structure:
- Security Groups (SGs) act as instance-level firewalls. They are stateful, which means if an outbound request is allowed, the response is allowed back automatically. Security groups default to implicit deny, and rules can only allow traffic, meaning that if traffic does not match a rule, it is dropped automatically.
- Network ACLs (NACLs) sit at the subnet level. They are stateless, so both directions must be allowed explicitly. NACLs have both allow and deny rules, which makes them useful for broad blocks.
The practical difference is that security groups are the main control we meet in the wild, and NACLs are a coarser safety net that many customers never change from defaults.
Attacker Focus 1: Exposed Ports
The most common cloud misconfiguration in the wild is a security group rule that allows 0.0.0.0/0 (the whole internet) on a port it should not. When we see a cloud target, our first question is always what is exposed, and to whom.
Typical examples that appear on reports:
- SSH (port 22) open to
0.0.0.0/0on a bastion host that should only accept a jump server's IP - Database ports (3306 for MySQL, 5432 for PostgreSQL, 27017 for MongoDB) open to the whole internet
- Admin panels on ports 8080 or 9000 are reachable without a VPN
- Old RDP (3389) rules added during a migration and never removed
We find these with ordinary port scans and HTTP probes. The cloud does not change the tooling; it changes how easy it is to introduce the mistake.
Attacker Focus 2: Lateral Movement
The other thing a cloud network offers us is lateral movement. Once we compromise an instance in a virtual network, we usually find that the internal network is flat, and every instance can reach every other instance on most ports by default. That is very different from a well-segmented on-premises network where firewalls sit between every zone.
Practically, this means a single compromised front-end web server in a virtual network often has direct access to:
- Internal databases and caches
- Other application servers
- Internal-only admin panels
- Service metadata endpoints
Our post-foothold checklist starts with "what else in this virtual network can I reach?", and the answer is usually "more than expected".
Provider Callouts
| Concept | AWS | Azure | Google Cloud |
|---|---|---|---|
| Virtual network | VPC | Virtual Network (VNet) | VPC |
| Subnet | Subnet | Subnet | Subnet |
| Internet Access | Internet Gateway | Public IP (or NAT Gateway) | default route + external IP (Cloud NAT for outbound-only private VMs) |
| Instance firewall | Security Group | Network Security Group (NSG) | Firewall Rule |
| Subnet firewall | Network ACL (NACL) | NSG at subnet scope | Firewall Rule at network tag scope |
?Answer the questions below
- In a security group rule, which CIDR notation indicates a port is open to the entire Internet?
- What two-word term describes moving from one compromised instance to another reachable service inside the same virtual network using the same permissions?
Compute and Metadata Services
Cloud computing is where our familiar skills meet new primitives. A virtual machine in the cloud still runs Linux or Windows, still has open ports, and still has users. What is genuinely new is the Instance Metadata Service, the small internal endpoint that hands out the instance's identity. Understanding IMDS turns a common web vulnerability into a full cloud compromise.
Instances and Images
A cloud instance is a virtual machine rented from the provider. We pick an image (the template operating system and preinstalled software), pick a size, and the provider hands us back a running virtual machine with a public or private IP address. Everything we know about attacking Linux and Windows still applies: running services, weak passwords, unpatched kernels, misconfigured applications, all of it.
The Instance Metadata Service
Every cloud instance can query a small HTTP endpoint to learn about itself. This endpoint is called the Instance Metadata Service (IMDS). It is reachable only from inside the instance, typically at the link-local address 169.254.169.254. This applies to AWS and Azure, while Google Cloud uses the hostname metadata.google.internal.
The reason this endpoint exists is sensible. A workload running on an instance often needs to know its own identifiers (region, instance ID), its startup configuration (the script the user asked the instance to run on boot), and, most importantly, the temporary credentials for any role attached to the instance. Hardcoding credentials into the application would be worse; anyone who reads the source code would also see the credentials. IMDS lets the workload pick them up on demand instead.
From an attacker's point of view, IMDS is a small HTTP server that hands out credentials to anyone who requests them.
IMDSv1 Is What Lands On Reports
IMDS has two versions on AWS, and the distinction is what every pentest report on a cloud environment eventually mentions.
IMDSv1 responds to any plain HTTP GET. No authentication, no session token, no required headers. Requests go in, credentials come out. This is the version that matters to us because it can be directly reached via server-side vulnerabilities.
IMDSv2 requires a session token obtained through a preceding PUT request with a special header. That extra step blocks the most common SSRF payload. AWS has pushed customers toward IMDSv2 for years, but IMDSv1 still ships as a fallback on older images, and customers often have not disabled it.
The SSRF-To-Credentials Chain
This is the attack chain we see on almost every cloud engagement that has a web application in scope:
- We find a web application that fetches URLs on the server's behalf. An image importer, a webhook tester, and a "preview link" feature. Anything that takes a URL from us and has the server get it.
- We submit the IMDS URL as the target, typically
http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>. The role name is discoverable by first querying the parent path/latest/meta-data/iam/security-credentials/, which returns it. - The instance fetches the URL. Because the request comes from inside, the metadata service answers.
- The server returns the metadata response to us, which contains a JSON document with
AccessKeyId,SecretAccessKey,Token, and an expiration time. - We are now the role attached to that instance, with every permission its policy grants, from outside the environment.
The Capital One breach in 2019 was a textbook example of this chain. A misconfigured web application firewall allowed an attacker to trigger an SSRF to IMDS, pull role credentials, and read data from over 100 million customer records.
Other Compute Forms Worth Knowing
Three more compute forms have their own identity and metadata stories. We touch them briefly here and go deeper on each in later rooms.
- Disk snapshots are point-in-time copies of an instance's disk. Customers sometimes share snapshots publicly (intentionally or by mistake). A public snapshot is essentially an open hard drive.
- Serverless functions run code on demand without a persistent virtual machine. AWS Lambda, Azure Functions, Google Cloud Functions. Each function has its own identity and environment variables, and SSRF inside a function targets the function's metadata endpoint rather than an instance's.
- Containers run on managed services (AWS ECS and EKS, Azure Container Instances and AKS, Google Cloud Run and GKE). Each container typically has its own identity and a metadata-style endpoint, and the same SSRF pattern reappears with different URLs.
Provider Callouts
| Concept | AWS | Azure | Google Cloud |
|---|---|---|---|
| Instance | EC2 | Virtual Machine | Compute Engine VM |
| Metadata endpoint | http://169.254.169.254/latest/meta-data/ |
http://169.254.169.254/metadata/instance?api-version=... (requires Metadata: true header) |
http://metadata.google.internal/ (requires Metadata-Flavor: Google header) |
| Metadata with token | IMDSv2 requires PUT + session token | Header required by default | Header required by default |
| Serverless | Lambda | Azure Functions | Cloud Functions, Cloud Run |
| Managed containers | ECS, EKS, Fargate | ACI, AKS | Cloud Run, GKE |
?Answer the questions below
- What is the link-local IP address AWS and Azure use for the Instance Metadata Service?
- Which IMDS version responds to a plain HTTP GET with no session token, making it vulnerable to classic SSRF?
Practical, Attacking a Cloud-Like Environment
A fictional startup has left its staging environment exposed to the internet. In this task, we walk the attack chain end to end: we port-scan the instance, list a public bucket, pivot via SSRF to the metadata service, pull temporary credentials, read an overly permissive IAM policy, and retrieve the final flag. Every step uses nmap and curl on the AttackBox, no provider CLI required.
Deploy the lab using the green Start Machine button and the Attack Box. Wait for the machine to finish booting, then note its IP address. We refer to it as MACHINE_IP throughout the rest of the task.
Step 1: Network Reconnaissance
Start with a port scan of the target to identify what is exposed.
nmap MACHINE_IP
The scan shows ports 8080 and 9000. Port 9000 is the object-storage service. Port 8080 is a small web application called ImageFetcher. That application is our SSRF candidate.
Step 2: Public Bucket Enumeration
The object-storage service on port 9000 lists buckets when accessed without credentials. Start with the root listing.
curl http://MACHINE_IP:9000/
The root shows two buckets, dev-assets and prod-secrets. The dev-assets bucket is listable.
curl http://MACHINE_IP:9000/dev-assets/
A file named dev-notes.txt stands out in the listing. Let's read it.
curl http://MACHINE_IP:9000/dev-assets/dev-notes.txt
The note tells us about the ImageFetcher app on port 8080 and mentions it has a URL-fetch feature at /fetch?url=. It also mentions the role name attached to the instance:web-app-role. That is the piece we need for the next step.
Step 3: SSRF Against the Metadata Service
The ImageFetcher app fetches any URL we give it and returns the response body. That is exactly the primitive we need to reach the metadata service at 169.254.169.254. Point the URL parameter at the IAM credentials path for the web-app-role role.
curl "http://MACHINE_IP:8080/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/web-app-role"
The response is a JSON document containing AccessKeyId, SecretAccessKey, Token, and Expiration fields. The AccessKeyId is the value we need to hold onto.
Step 4: Read the IAM Policy
The storage service has an admin endpoint that returns the IAM policy attached to our role, but it requires a valid token. In this simulator, the token is carried in the X-Simulated-Token header. Pass the access key we just acquired.
curl -H "X-Simulated-Token: AKIATHM1234FAKEKEY0" http://MACHINE_IP:9000/admin/policy.json
The policy is a JSON document. Inside, one statement grants "Effect": "Allow", "Action": "storage:*", "Resource": "bucket/prod-secrets/*". The storage:* wildcard is the over-permissive pattern we learned to spot in Task 3. It means this role can do anything with the prod-secrets bucket, the one we couldn't read earlier.
Hint: In a real cloud engagement, the value passed here would be a full AWS SigV4 signature. We simplify to a single header for the lab, so the teaching stays on the wildcard rather than the signing algorithm.
Step 5: Retrieve the Flag
Use the same header to read the flag file from the prod-secrets bucket.
curl -H "X-Simulated-Token: AKIATHM1234FAKEKEY0" http://MACHINE_IP:9000/prod-secrets/flag.txt
The file returns the final flag.
What Just Happened
We chained five themes into one attack. Networking told us which services to probe. Storage held a hint we could read because someone left the bucket public. The web app handed us a server-side request primitive. The metadata service handed us temporary credentials. The IAM policy included a wildcard that allowed those credentials to read the secret bucket. Change one of those five mistakes, and the chain breaks. Real engagements look like this more often than they look like memory corruption.
?Answer the questions below
- Run the port scan. Which port is the ImageFetcher web application running on?
- The public bucket contains a file with hints about the next target. What is the filename?
- Retrieve the IAM policy. What type of resource is the wildcard present in that provides full access?
- Follow the policy to the flag. What is the flag value?
Conclusion
We walked the classic beginner cloud kill chain end to end: network exposure, public storage, an SSRF into instance metadata, temporary credentials, and an over-permissive IAM policy. Every step used ordinary tools, nmap and curl, and every idea transfers to AWS, Azure, or Google Cloud, regardless of which provider we meet next.
Five themes form the checklist we run through on any cloud-facing target:
- Shared responsibility: the provider secures the physical layer, the customer owns data, identities, and configuration
- IAM: policies grant permissions, roles package them, wildcards break them
- Storage: public buckets are the most common cloud breach; enumerate them first
- Networking: flat internal networks and wide-open security groups make lateral movement easy
- Compute and metadata: IMDS hands out credentials, SSRF turns a web bug into a full cloud compromise
From here, the provider-specific rooms further along the Jr Penetration Tester path will show the tools that automate what we did by hand today. The Intro to SSRF room is a good follow-up for deeper practice on the technique at the center of Task 7.
?Answer the questions below
- Going to cloud nine next.