Cracking the Storage Shell: How Misconfigurations Exposed an Azure Blob Flag

Cracking the Storage Shell: How Misconfigurations Exposed an Azure Blob Flag

December 8, 2025 5 min read

A CTF walkthrough demonstrating how Azure Logic Apps, Base64 role tampering, and permissive SAS tokens exposed sensitive blob data.




Disclaimer (Educational Use Only)

This walkthrough describes a challenge from a controlled CTF environment. The concepts are for educational and defensive purposes only. Never test cloud infrastructure without explicit authorization.


Introduction

Some of the most instructive cloud security lessons appear where least expected. The Storage Showdown Remastered challenge at BSidesCharm 2025’s Cloud Village demonstrated exactly how a chain of small misconfigurations on Azure can snowball into full data exposure.

Nothing exotic.
Nothing overly technical.

Just:

  • a public logic app endpoint,
  • a manipulable Base64 parameter,
  • a permissive SAS token, and
  • subtle request-format nuances.

Pieced together, these gave complete read access to a protected Azure Blob container holding the CTF flag.

This write-up breaks down the full exploitation flow and what it teaches about securing cloud workloads.

Screenshot of the CTF challenge introduction page outlining the scenario.


Understanding the Challenge Setup

Participants were shown a static Azure-hosted website with tiles describing storage services. It looked harmless-marketing-like, simple, and intentionally unremarkable.

But inspecting the HTML uncovered something unusual: a hidden iframe pointing to a Logic App invoke URL.

Logic App URLs should never be publicly exposed because they execute workflow logic on behalf of an Azure tenant. Yet here, one was embedded directly in the page.


Step 1 - Investigating the Hidden Iframe

Inside the HTML source existed a tag like this:

<iframe class="hidden" src="https://prod-15.northeurope.logic.azure.com/workflows/b3c7.../invoke?api-version=2016-10-01&sp=%2Ftriggers%2FStorageShowdown%2Frun&sv=1.0&sig=hzu2t1h..."></iframe>
HTML

Screenshot of the main homepage of the target application in the CTF challenge.

Browser developer tools inspect panel showing the HTML structure of the homepage.

Screenshot showing the contents of an iframe opened in a new browser tab.

When accessed directly, the iframe URL returned JSON-like internal logs.
This was the first major finding: a backend workflow responding publicly.

But then one parameter in the URL stood out:

uid=Y3RmcGxheWVyPXVzZXI=
Plain text

Screenshot highlighting a suspicious Base64 encoded string within the URL parameter.

That looked Base64.

Decoding it produced:

ctfplayer=user
Plain text

Screenshot showing the result of decoding the Base64 string, revealing a JSON object with user role information.

A clear indicator that user roles were handled through this parameter-revealing a critical design flaw.


Step 2 - Testing the Base64 Role Parameter

If ctfplayer=user dictated access level, what would happen if it were changed?

Diagram illustrating the process of decoding a Base64 string, modifying the role from user to admin, and re-encoding it to escalate privileges in a cloud workflow.

Transforming:

ctfplayer=admin
Plain text

Screenshot showing the process of modifying the decoded JSON to elevate the role to 'admin' and re-encoding it to Base64.

Encoding it back to Base64:

Y3RmcGxheWVyPWFkbWlu
Plain text

Replacing the original parameter with this new value triggered a completely different server response.

Instead of generic values, the Logic App returned detailed internal logs:

  • session IDs
  • handler names
  • workflow timestamps
  • cleanup tasks
  • operational checklists

And most importantly:
a reference field with a Shared Access Signature (SAS) URL to an Azure Blob container named admin.

Example snippet:

"reference": {
  "note": "keep internal, delete after use",
  "url": "https://storageshowdownstorage.blob.core.windows.net/admin?sp=rl&st=2025-03-03T00:25:24Z&se=2026-07-09T07:25:24Z&spr=https&sv=2022-11-02&sr=c&sig=cfxY1WKDbfIFwvyRwbrVKMxU4Sx9CGXI/aNVZu04Xtw="
}
JSON

Screenshot of the Azure Logic App response after sending the modified admin Base64 token, showing elevated access details.

This was the pivot point:
Role tampering → Logic App privilege escalation → SAS token leak.


Step 3 - Understanding the SAS Token

Azure SAS tokens define delegated permissions.

Educational infographic breaking down the components of an Azure Shared Access Signature (SAS) token, including permissions, scopes, timestamps, and signatures.


This one contained:

  • sp=rl → read + list
  • sr=c → container-level scope
  • st/se → start & expiry timestamps
  • sig → HMAC signature

This meant anyone with the URL could enumerate blobs and read them-provided they formatted the request correctly.

Attempting to visit the SAS URL directly produced:

{
  "error": "AuthenticationFailed",
  "message": "Signature did not match"
}
JSON

This was expected: Azure was interpreting the request differently than the SAS token allowed.

Time to correct the request structure.

Screenshot showing an Azure "AuthenticationFailed" error message due to an incorrect SAS signature format.


Step 4 - Fixing the SAS Request Format

Container-level SAS tokens require the request to explicitly specify:

restype=container&comp=list
Plain text

Appending these parameters instructed Azure to interpret the request as a container listing operation.

However, another subtle issue appeared:

The signature ended with %3D (URL-encoded =).
Azure requires the raw base64 padding character, not the URL-encoded version.

After replacing %3D with =, the corrected request became:

curl "https://storageshowdownstorage.blob.core.windows.net/admin?restype=container&comp=list&sp=rl&st=2025-03-03T00:25:24Z&se=2026-07-09T07:25:24Z&spr=https&sv=2022-11-02&sr=c&sig=cfxY1WKDbfIFwvyRwbrVKMxU4Sx9CGXI/aNVZu04Xtw="
Bash

This time Azure returned:

<EnumerationResults>
  <Blobs>
    <Blob>
      <Name>flag.txt</Name>
    </Blob>
  </Blobs>
</EnumerationResults>
XML

The container listing was now fully accessible.

Screenshot showing a successful Azure storage container listing after correcting the SAS token format.


Step 5 - Retrieving the Flag

With confirmation that flag.txt existed, the next step was simply making a direct blob request.

Removing:

restype=container&comp=list
Plain text

And appending:

/flag.txt
Plain text

Final request:

curl "https://storageshowdownstorage.blob.core.windows.net/admin/flag.txt?sp=rl&st=2025-03-03T00:25:24Z&se=2026-07-09T07:25:24Z&spr=https&sv=2022-11-02&sr=c&sig=cfxY1WKDbfIFwvyRwbrVKMxU4Sx9CGXI/aNVZu04Xtw="
Bash

Output:

FLAG-{jAOUSd0CosCizQ2gfHDa42bxL8g01Z0x}
Plain text

Challenge solved.

Screenshot showing a successful Azure storage container FLAG.


What This Teaches About Secure Cloud Configurations

Real cloud systems fail in the exact ways this CTF simulated. Each step mirrored common misconfigurations found during professional assessments.

1. Never expose Logic App Invoke URLs publicly

Logic Apps should require:

  • authentication,
  • IP allowlists,
  • private endpoints,
  • or API Management in front.

Direct exposure risks execution of internal workflows.

2. Never trust client-side role indicators

A Base64 string determining access level is a catastrophic anti-pattern.
Authorization must always be server-controlled.

3. SAS tokens must be treated like secrets

They should follow:

  • minimum permissions,
  • short expiry windows,
  • container- or blob-specific scoping,
  • strict logging and rotation.

Leaked SAS tokens are equivalent to leaked credentials.

4. Request interpretation matters

Azure strictly validates:

  • canonicalized resource paths,
  • signature byte order,
  • correct request type markers.

Small mismatches can inadvertently grant unintended access.

5. Internal logs should never be returned to clients

The Logic App response leaked:

  • operational notes,
  • workflow internals,
  • administrative references,
  • and sensitive URLs.

Debug output belongs in logs-not HTTP responses.


Troubleshooting Notes & Pitfalls

SAS signature mismatches

Usually caused by:

  • URL-encoded = characters,
  • incorrect canonical resource string,
  • wrong HTTP verb,
  • missing restype/comp parameters.

Logic App URL leakage

Happens frequently in:

  • exposed JavaScript bundles,
  • mobile apps,
  • embedded iframes,
  • CI/CD artifacts.

Base64 encoding mistakes

Extra whitespace or missing padding (=) breaks backend behavior-sometimes in exploitable ways.


Final Thoughts

The Storage Showdown Remastered challenge showcased a realistic exploitation chain:

  1. Hidden Logic App endpoint
  2. Manipulable role parameter
  3. Privilege escalation
  4. SAS token extraction
  5. Signature correction
  6. Blob enumeration
  7. Flag retrieval

This was not luck-it was a sequence of predictable failures.

Cloud security is rarely about a single fatal flaw.
It’s about how small cracks align into a breach path.

Ensuring secure defaults, strict validation, and careful token handling can prevent misconfigurations like this from ever reaching production.

Join the Security Intel.

Get weekly VAPT techniques, ethical hacking tools, and zero-day analysis delivered to your inbox.

Weekly Updates No Spam
Herish Chaniyara

Herish Chaniyara

Web Application Penetration Tester (VAPT) & Security Researcher. A Gold Microsoft Student Ambassador and PortSwigger Hall of Fame (#59) member dedicated to securing the web.

Read Next

View all posts

For any queries or professional discussions: herish.chaniyara@gmail.com