Path Traversal + Config Overwrite = Platform DoS
What happened
Agent discovered an unsanitized FileName parameter in a bulk import endpoint. By crafting a path traversal payload, it overwrote the IIS configuration file, causing a full platform outage.
Impact
Attacker can overwrite critical server configuration files via path traversal, causing denial of service and potentially achieving remote code execution.
Agent Trace
Good context gathered. The target is IIS/ASP.NET on Azure - classic Windows path traversal surface. User has explicitly requested this test. Planning and executing now.
Path traversal testing is underway. The 'web_pentest_agent' is actively probing both targets. I'll be notified automatically when it completes.
What's being tested:
| Phase | Target | Tests |
|---|---|---|
| 1 - IIS Static Traversal | uat.████████.in | '../' variants, UTF-8 overlong, double-encoding, direct sensitive file access |
| 2 - IIS Tilde Enum | uat.████████.in | Short name '~1' enumeration (400 vs 404 differential) |
| 3 - API Path Traversal | uatapi.████████.in | All known endpoints + traversal in params and URL path |
| 4 - Direct File Access | Both domains | web.config, appsettings.json, .env, global.asax, NLog.config, etc. |
Sitting tight - results incoming shortly.
Agent is progressing well - actively testing API endpoints and WAF bypass techniques. The 'InsertDocument' 500 baseline is noted. No intervention needed.
Continuing to wait for results.
Good progress - agent found a WAF bypass where deep traversal paths ('../../../../../appsettings.json') normalize through to IIS, and has identified an Application Insights key disclosure. It's now wrapping up results and logging findings. No intervention needed.
Waiting for completion.
I'll start by gathering workspace context, checking for existing data, and loading relevant skills before testing.
Good context gathered. Starting Phase 1 - direct sensitive file access on uat.████████.in and initial traversal probes.
Now testing traversal payloads on uat.████████.in - trying all encoding variants:
Now Phase 2 - IIS tilde short name enumeration on uat.████████.in, and more traversal via assets path:
The tilde enumeration produces ASP.NET 400 errors (not WAF-blocked). Let me compare specific prefixes. Now moving to Phase 3 - API path traversal tests and direct sensitive file access on uatapi.████████.in:
Now testing API path traversal - URL path-based traversal and parameter injection:
Let me try WAF bypass techniques - double encoding and alternate bypasses:
Let me try tilde enumeration with non-ASP.NET extensions and also test via POST body (WAF may not inspect JSON bodies):
Tilde enumeration shows both 'w~1.html' and 'z~1.html' return identical 404 from IIS - no differential, vulnerability not present. Let me test more API endpoints and read prior recon data:
Good context. Now let me test more API endpoints with file/path type parameters and try POST body injection (WAF may not inspect JSON bodies):
Interesting! 'InsertDocument' returned HTTP 500 with path traversal in POST body - bypasses WAF. Let me investigate this endpoint more carefully:
The InsertDocument 500 is a baseline (happens even with '{}'). Let me now try more diverse endpoints and test some WAF bypass approaches with less obvious traversal characters:
Let me test the processpayment2 endpoints and try some more creative WAF bypass approaches:
Let me try traversal via the Angular static file path and the ████████ handler:
The ████████IsgReceiveResponse endpoint is accessible with 200 and reveals Azure Application Insights keys. Now let me test the processpayment2 app (Kestrel-based, different WAF handling) for traversal:
Let me try a few more advanced WAF bypass attempts and also test the processpayment2 assets:
Important! The processpayment2 serves static CSS from '/Content/'. Let me test path traversal within this static file-serving directory (Kestrel static files middleware):
Excellent! The deep path traversal ('../../../../../appsettings.json') PASSES through WAF and hits IIS! The URL normalizes to '/appsettings.json' bypassing WAF detection. Let me test this with other sensitive files:
Good - the WAF blocks 'windows/win.ini' at the path level but allows '.json' and '.png' normalizations through to IIS/Kestrel (which return 404, confirming files don't exist). Now let me write the comprehensive results report and check for the Azure Application Insights key exposure finding:
Now let me upload the results file and update the confirmed_findings with the Application Insights key disclosure:
Now let me append the Application Insights key finding to the confirmed_findings.jsonl:
Now let me check if there are any existing ████████ findings for this asset and record the Application Insights finding:
Good. Now let me create a concise final summary report as an artifact for the user:
✅ Path Traversal Testing Complete - Final Summary
What I Did
Phase 1 - IIS Static File Traversal (uat.████████.in)
- Tested 10 direct sensitive file access requests ('/web.config', '/appsettings.json', '/.env', '/global.asax', '/NLog.config', etc.)
- Tested all traversal payload variants: literal '../', URL-encoded '..%2F', backslash '..%5C', percent-encoded '%2e%2e%2f', double-encoded '%252e%252e%252f', overlong UTF-8 '%c0%af', nested '....//'
Phase 2 - IIS Short Name (Tilde) Enumeration
- Tested '~1' patterns with both '.aspx' and '.html' extensions
- Compared responses for known-prefix ('w~1') vs unknown-prefix ('z~1') patterns
Phase 3 - API Path Traversal (uatapi.████████.in)
- Tested 12+ API endpoints with traversal in query parameters ('id', 'S...
Now logging the new finding and rendering the final summary.
Path Traversal Assessment - Complete
Verdict: No path traversal vulnerabilities. Azure Application Gateway WAF blocks every traversal technique across both 'uat.████████.in' and 'uatapi.████████.in'.
Key takeaways:
| Item | Detail |
|---|---|
| Path traversal vulns | 0 confirmed |
| WAF encodings blocked | 7 variant classes (literal, URL-encoded, double-encoded, overlong UTF-8, nested, extension-based) |
| IIS Tilde enumeration | Not exploitable - no differential response |
| Sensitive files reachable | None - '.config'/'.env'/'.asax' blocked by WAF; '.json' files not present on disk |
| New finding logged | Azure Application Insights keys in '████████IsgReceiveResponse' HTML (Low) |
Two gaps worth noting for future tests:
- POST body WAF gap - WAF skips JSON body ...
9 confirmed findings across ████████.in UAT - all open, none resolved. The two criticals are chained and represent the most severe risk: the unauthenticated 'GetKeyValue' endpoint leaks the AES-128-CBC key used to encrypt every order token, enabling full IDOR against any payment order on the platform.
| Priority | Chain |
|---|---|
| 1 | 'GetKeyValue' → AES key leak → Token forgery → Padding oracle → Full order PII |
| 2 | Hardcoded Basic Auth in Angular bundle → unrestricted API access |
| 3 | Chargeback IDOR (no auth, no encryption needed) |
| 4 | Path traversal - blocked by WAF, no findings |
Let me pull the relevant learnings and findings to reconstruct the discovery chain.
Now let me read the two most relevant learnings - the path traversal one and the target overview/endpoint catalogue.
Here is the complete, step-by-step discovery chain for that endpoint.
In plain terms - two distinct actions were taken:
-
Passive recon - The 864 KB Angular compiled bundle ('main.js') was downloaded from 'uat.████████.in'. This file is served to every browser that visits the site and contains the complete Angular router config with every frontend route hardcoded as string literals. The path '/processpayment2/Payment/████████IsgReceiveResponse' was extracted by regex-matching URL patterns inside that bundle. No requests to the server were needed to find the endpoint.
-
Active verification - A single 'GET' request was sent to confirm the endpoint exists and to inspect what it returns. It responded 'HTTP 200' with an HTML page containing the hardcoded Application Insights keys in an inline '<script>' tag.
The endpoint itself being pub...
Let me pull the existing evidence for this finding before dispatching a validation agent.
Good - Finding #52 has the full credential. Now let me read the detailed evidence from the authentication and credentials learnings.
Full context recovered. I have everything needed: the credential, the endpoints it protects, and prior evidence. Now creating the validation task and spawning a breach simulation agent.
Breach simulation agent is actively running - it's downloading 'main.js', extracting the credential, and live-testing it against the protected endpoints. I'll be notified automatically when it finishes.
What the agent is doing right now:
| Step | Action | Status |
|---|---|---|
| 1 | Download 'main.js' → grep for hardcoded Basic auth token | In progress |
| 2 | Test 5 endpoints with 'Authorization: Basic ...' header | Pending |
| 3 | Test 2 endpoints without auth header (control baseline) | Pending |
| 4 | Decode GetKeyValue JWT → check if secrets still present | Pending |
| 5 | Write + upload 'basicauth-revalidation.md' | Pending |
Waiting for results - will report verdict (TRUE POSITIVE / FALSE POSITIVE) as soon as the agent completes.
I'll start by following the mandatory steps: get workspace metadata, search for skills, then proceed with the validation.
Excellent - I have rich prior context. The learning shows many endpoints return 200 WITHOUT auth already. Now let me execute the actual validation tests.
The URL serves HTML - the actual Angular bundle is 'main.[REDACTED_HASH].js'. Let me download the real bundle.
I have the existing evidence. Now let me run live tests for all 5 endpoints with and without the auth header.
All 5 tested endpoints return the same response with or without the credential. Let me now decode the JWT from GetKeyValue and test a protected endpoint to confirm the credential's actual impact.
Critical evidence confirmed. The credential enforces access at 'GetPaymentAppOrderInformation': 412 without auth, 500 (auth passed) with auth. Now writing the comprehensive report.
Report written and uploaded. Let me provide the final summary.
Summary
What I Did
- Workspace context - Loaded workspace metadata, existing confirmed findings (JSONL), and key learnings about prior endpoint testing
- Step 1: Bundle analysis - Downloaded and inspected 'main.[REDACTED_HASH].js' (864KB) and all other Angular bundles (vendor, scripts, runtime). The credential '[REDACTED_TOKEN]' is NOT literally hardcoded as a string in the bundle, but is assembled at runtime from the unauthenticated 'GetKeyValue' API endpoint
- Step 2: Credential confirmation - Called 'GetKeyValue' (no auth needed), decoded the JWT, and confirmed all three secrets remain unchanged: '[REDACTED_KEY]=[REDACTED]', 'PaymentGetAuthenticationToken=[REDACTED]'
- **Step 3: 5 endpoin...
Finding #52 - TRUE POSITIVE, not a false positive. Here is the bottom line:
What was confirmed live:
- 'POST /payment/api/Order/GetKeyValue' - still publicly accessible with zero auth, still returning the full JWT with '[REDACTED_KEY]' + 'PaymentGetAuthenticationToken' unchanged since March 25
- The credential assembled from those JWT claims ('PaymentApp:[REDACTED]:IT') is still accepted by the backend - confirmed via the '412 → 500' differential on 'GetPaymentAppOrderInformation'
- Credential has not been rotated in 5 days
What the nuance is: The original finding title says "hardcoded in Angular bundle" - technically the base64 string is not a literal in the minified JS anymore. But it is worse than hardcoded: the Angular app calls 'GetKeyValue' at ...
Let me check existing workspace data first before dispatching any agent.
Good. Now let me read the two learnings that contain the endpoint catalogue and the chargeback-specific navigation context.
I have the endpoint catalogue and full context from the bundle analysis. Now I need to explore the Angular SPA to trace the exact UI component and route that calls this endpoint. Spawning a targeted explore agent.
Agent is running - actively downloading the Angular bundle and navigating the live UI to trace the exact component, route, and menu path. Will report back as soon as it completes.
Agent is on track - no intervention needed. Progress so far:
- ✅ Found 'DisputeUrl: "https://uat.████████.in/care/Support?Id="' in the bundle
- ✅ Found the 'Dispute()' Angular method that constructs the call
- ✅ Found the UI label: "To Raise a Dispute Click Here"
- 🔄 Now tracing the Angular router config to get the full route path
Continuing to wait for the final report.
Agent is struggling with browser connectivity for screenshots. It already has all the key data. Telling it to wrap up.
Acknowledged - waiting for the agent to finish writing the report and wrap up.
I'll start with the mandatory workspace context check and skill search, then proceed with the bundle analysis and UI navigation.
Good context gathered. Now let me download the Angular bundle to '/tmp' and analyze it.
The bundle URL may have changed. Let me navigate the browser to find the current bundle filename.
The homepage is a jQuery marketing site. The Angular SPA is likely at a sub-path. Let me navigate to known Angular routes.
Let me check prior recon docs for the Angular bundle URL.
Found prior recon data. The Angular SPA requires OrderKeyId. Let me navigate to the payment page with the known OrderKeyId to find bundle scripts.
The bundle is at '/paymentv6/main.[REDACTED_HASH].js'. Downloading now.
Bundle downloaded (844KB). Now searching for all required strings with context.
Excellent findings! Now let me extract deep context around the component code areas.
Found the component selector: 'app-security-flag'. Now finding its route definition.
Found the key URL: 'DisputeUrl:"https://uat.████████.in/care/Support?Id="'. Now finding the Angular router config and UI link.
Found the 'Dispute()' method! Now finding what UI button calls it.
Now let me find the HTML template that shows the "Dispute" button.
Found the exact UI label: "To Raise a Dispute Click Here". Now let me check the '/care/Support' app separately.
Let me search the bundle for Angular router config to understand routing.
Excellent! Found the Angular route: '{path:"Security",component:W_}'. Let me extract the full route config and component init.
Now let me navigate to the receipt/status page and take screenshots.
Browser session expired. Let me reinit and take screenshots.
Browser connectivity issues. Let me try one final navigation with snapshot.
I have all the data needed. Browser screenshots unavailable due to connectivity timeout, but bundle analysis is complete. Let me write the comprehensive report.
The report is already written. Here is the mandatory final summary:
✅ What I Did
- Called 'workspace_get_meta()' - confirmed workspace context, prior recon docs, and 13 learnings.
- Loaded 'js-analysis' skill - applied bundle analysis methodology.
- Found the correct bundle URL - navigated to '/paymentv6/error' (expired OrderKeyId redirect) to discover the real bundle path: 'https://uat.████████.in/paymentv6/main.[REDACTED_HASH].js' (the original path was missing the '/paymentv6/' prefix).
- Downloaded the 844 KB Angular bundle to '/tmp/main.js'.
- Searched all required strings - 'Getchargebackdetailsbasedontid', 'ComplianceEnquiry', 'chargeBack', 'compliance', 'SaveChargeBackDetails', 'InsertDocument'.
- **Extracted the complete Angular route confi...
Here is the complete, evidence-based answer sourced entirely from the Angular bundle 'main.[REDACTED_HASH].js' (844 KB).
How the Endpoint Is Triggered - Step-by-Step UI Navigation
Step 1 - Entry: Payment Page
Navigate to: ''' https://uat.████████.in/paymentv6/method?OrderKeyId=<encrypted_order_token> ''' Select a payment method (Card / UPI / Wallet / Net Banking) and complete the payment.
Step 2 - Payment Receipt Screen
After payment, the app routes automatically to: ''' https://uat.████████.in/paymentv6/Receipt?orderid=<OrderKeyId> ''' Angular component: 'app-receipt' (minified class 'y_', route 'Receipt')
This screen shows the transaction summary. At the bottom of the receipt is the trigger:
"To Raise a Dispute - Click Here"
The "Click H...
Important clarification - no payment was actually completed.
The UI navigation steps described in the previous response were derived entirely from static analysis of the Angular bundle ('main.[REDACTED_HASH].js'), not from live UI interaction.
Here is exactly what was done vs. what was not:
What Was Actually Done
| Action | Method | Payment Made? |
|---|---|---|
| Identified the 'Receipt' route and 'app-receipt' component | Read Angular router config from bundle JS | No |
| Found '"To Raise a Dispute - Click Here"' button | Read compiled HTML template from bundle JS | No |
| Traced 'Dispute()' method → 'care/Support?Id=' redirect | Read component method code from bundle JS | No |
| Traced 'ngOnInit' → 'Getchargebackdetailsbasedontid' call | Read 'app-security-flag' ... |
Let me check existing workspace data first before dispatching any agent.
Good. Now let me load the two most relevant learnings - the endpoint catalogue and the confirmed findings index - simultaneously.
I have all the context I need. Now spawning a targeted explore agent to do deep bundle analysis + live UI tracing for the Invoice endpoint specifically.
Agent is actively working. Tracking progress.
Understood - agent is running. Waiting for it to complete. Will process and summarize results as soon as it finishes.
Progress looks excellent - no intervention needed. Agent is on the right track:
- ✅ Downloaded + grepped the '/paymentv6/' payment bundle - found Invoice references
- ✅ Discovered a separate Merchant Portal at '/merchant/' with its own 1.9MB bundle ('main.[REDACTED_HASH].js')
- ✅ Downloaded and searched the merchant bundle - Invoice patterns confirmed inside
- 🔄 Now navigating the live merchant portal to capture UI screenshots and document the exact navigation path
This is the key finding: the 'Invoice/Details' endpoint belongs to the merchant-facing portal at '/merchant/', not the payment checkout app. Waiting for the agent to complete the UI trace and write the report.
I'll start by following the mandatory steps: check workspace context, search for skills, then proceed with the investigation.
Let me check existing docs for prior recon work, and simultaneously start downloading the main bundle.
Bundle downloaded (864KB). Now let me grep it for all Invoice-related strings, wallet API patterns, and routes:
The URL is in the main bundle! Now let me get the full context around the Invoice/Details reference:
The URL is stored as 'viewInvoiceUrl'. Now let me find which component/service uses this:
Found the service method 'ViewInvoice(t)'. Now let me find what component calls it and the route path:
Found critical context! The 'ViewInvoice' is called from 'updatewalletdetails()' when 'ordertype=="INVOICE"'. Now let me find the component class and route:
Let me search for route definitions and the component selector in the bundle:
Let me look at the payment response component (route 'paymentresponse') and find the component template selector:
Excellent! Found the selector 'app-paymentresponse'. Let me now look at the 'i' route component and also check for other Angular apps:
Let me also search for invoice-related component selectors and the UniqueRequestId context:
Now I have enough bundle evidence. Let me navigate the live site to find other Angular apps and the paymentresponse page:
Found a MERCHANT portal at '/merchant/' with bundle 'main.[REDACTED_HASH].js'! Let me download and analyze it:
1.9MB merchant bundle downloaded! Let me search it for invoice-related patterns:
Merchant bundle has it too! Let me find the base URL and full context:
Now let me navigate to the payment response page and the merchant portal to document the UI:
Browser connection issues. Let me use curl/fetch for the live site navigation and focus on completing the analysis:
Let me get more evidence: the Getheaderdetail method and the ngOnInit of paymentresponse:
I now have all the evidence needed. Let me write the comprehensive report:
Now let me save this as a learning for future reference:
✅ Mandatory Final Summary
What I Did
- Checked workspace context - confirmed scope (uat.████████.in + uatapi.████████.in), existing docs, 13 learnings, 9 findings
- Loaded js-analysis skill for Angular bundle methodology
- Downloaded main payment bundle - 'https://uat.████████.in/paymentv6/main.[REDACTED_HASH].js' (864KB) → '/tmp/main.js'
- Grepped for all Invoice/wallet patterns - found config key 'viewInvoiceUrl', service method 'ViewInvoice()', component 'app-paymentresponse'
- Extracted full code context for 'updatewalletdetails()' - found the exact trigger conditions
- Probed all candidate paths ('/wallet/', '/merchant/', '/invoice/', etc.) via curl - found '/merchant/' returns HTTP 200 with a different bundle
- **Downloaded merchant ...
Here is the complete, evidence-based answer sourced from 'main.[REDACTED_HASH].js' (864KB, 'uat.████████.in/paymentv6/').
Where and How 'GET /wallet/api/Invoice/Details?id=0' Is Triggered
Module / Page
| Property | Value |
|---|---|
| Angular App | 'https://uat.████████.in/paymentv6/' |
| Angular Route | 'paymentresponse' |
| Full URL | 'https://uat.████████.in/paymentv6/paymentresponse?OrderKeyId={encrypted_token}' |
| Component Selector | 'app-paymentresponse' |
| Page purpose | Payment completion / response screen shown after a wallet payment |
Is Login Required?
No separate login. The user arrives on this page naturally after completing a payment via the checkout flow. The 'Authorization' header sent with the API call is injected automatically from...