Pros
- • Demonstrates the complete lifecycle of a high-stakes penetration test in a zero-downtime environment
- • Combines practical exploit commands with strategic risk analysis and decision matrices
- • Illustrates the maturity difference between simply 'running exploits' and acting as a trusted security advisor
- • Provides deep insight into how technical flaws (like JWT and TLS configs) translate directly into financial liability
- • Showcases collaborative red-blue team dynamics and expert reporting methodologies including remediation code
Cons
- • Assumes advanced knowledge of application architecture, authentication, and cryptography
- • Limits focus purely to logical attack paths rather than generic automated scanning
- • Requires understanding of compliance mandates (PCI-DSS, GLBA) to fully grasp the risk logic
Testing a Tier-1 financial institution is a completely different game than a standard assessment. In most environments, accidentally taking down a QA server might get you an awkward apology. In banking, disrupting a SWIFT gateway or interrupting a batch processing run means immediate termination and potential regulatory consequences.
This is a real penetration test of a banking infrastructure—restricted scope, zero tolerance for disruption. You’ll see both the technical exploitation techniques and the strategic mindset required to operate safely in an environment where a single mistake has business-critical consequences.
1. Rules of Engagement: Understanding the Blast Radius
The target is a newly built payment reconciliation API. I’ll be testing remotely through a hardened VDI jumpbox, and I know the SIEM and IDS are both watching.
Before I send a single packet, the first critical step is defining the Rules of Engagement. In banking, the most dangerous assumption is that a staging environment is isolated from production. Mainframe configurations and API endpoints are often hardcoded across DEV, UAT, and PROD—they’re not cleanly separated.
I start by studying the architecture diagram and tracing how this API connects to the legacy core banking system. Why? Because if a SQL injection payload cascades into a production database table and locks critical records during an overnight batch run, I’ve created a real outage. That reality shapes my entire testing strategy. Instead of aggressive payload fuzzing, I shift to surgical, carefully measured testing that validates the vulnerability without triggering a business impact.
2. Understanding the Business Logic
I’m not looking for open ports—I’m looking for business logic. This API reconciles ledger discrepancies throughout the trading day.
I skip over the load balancers and WAF for now. What I need to understand is what this API actually does:
- Where is authentication enforced?
- Does it use JWTs, external identity providers like Okta, or legacy session cookies?
- When you change an account parameter, does it trigger an automated batch job, or is it a direct database write?
This business context determines where the real vulnerabilities hide. A generic XSS finding means nothing here. What I’m hunting for are authorization weaknesses—IDOR flaws, authorization bypasses, anything that would let someone modify ledger records they shouldn’t touch.
3. Initial Access Strategy
This is internal-only testing, so I’m not trying to break in from the internet. Instead, I’m enumerating API endpoints from within the network, starting unauthenticated.
The tactical challenge: Speed vs. Detection. If I hammer the API with aggressive fuzzing (ffuf at 1,000 threads), the F5 load balancer will see the 404 spike, alert the SOC, and they’ll kill my VDI connection. So I slow down and prioritize.
I start with authentication endpoints. If I can break the auth mechanism, everything downstream typically trusts the authenticated session. WAF rules often don’t apply once you’re “authenticated.”
I use Burp Suite’s Intruder in slow mode—about one request every 3 seconds—just to map out the application structure without triggering alerts.
4. Reconnaissance: Finding the Weak Points
I map out the application flows manually and find a reporting endpoint:
GET /api/v1/reports/generate?report_type=summary&format=pdf HTTP/1.1
Host: internal-recon.bank.local
Authorization: Bearer <low_priv_token>
An automated scanner would flag report_type as “potential parameter tampering” and move on. But I notice format=pdf. PDF generation backends often use headless browsers like Puppeteer or older tools like wkhtmltopdf—and those are notoriously vulnerable to SSRF attacks.
Instead of blindly fuzzing, I craft specific payloads designed to test for Server-Side Request Forgery and Local File Inclusion:
GET /api/v1/reports/generate?report_type=<iframe src="file:///etc/passwd"></iframe>&format=pdf
If the PDF generator renders this, I might get the /etc/passwd file embedded in the PDF. Or better—I might be able to reach the AWS metadata endpoint at 169.254.169.254 and extract credentials.
5. Separating Signal from Noise
I find two issues:
- Noise: The API returns a
Server: Apache/2.4.41banner. - The Real Problem: The JWT token has no expiration claim (
exp), and worse—the server accepts unsigned tokens.
An automated scanner would flag the Apache banner as a medium-severity information disclosure. But in a banking environment, sitting behind three layers of proxies? That’s just noise. An attacker can’t reach the Apache server directly anyway.
The JWT issue is the real vulnerability.
Original Extracted JWT Header & Payload (Decoded):
// Header
{"alg": "RS256", "typ": "JWT"}
// Payload
{"user": "jdoe", "role": "readonly_analyst", "iat": 1712610000}
6. Crafting the Exploit
I intercept the request in Burp Suite and modify the token. I change my role from readonly_analyst to reconciliation_admin. Since I don’t have the server’s RSA private key to sign legitimately, I force the algorithm to none:
Forged JWT:
// Header
{"alg": "none", "typ": "JWT"}
// Payload
{"user": "jdoe", "role": "reconciliation_admin", "iat": 1712610000}
// Signature: (none)
Base64-url encoded:
eyJhbGciOiAibm9uZSIsICJ0eXAiOiAiSldUIn0.eyJ1c2VyIjogImpkb2UiLCAicm9
sZSI6ICJyZWNvbmNpbGlhdGlvbl9hZG1pbiIsICJpYXQiOiAxNzEyNjEwMDAwfQ.
The Critical Decision Point: I send this forged token to the /api/v1/admin/users endpoint. It returns HTTP 200—with a full list of system administrators.
Do I go further? Do I delete a user or modify production data to “prove” impact? No.
In banking, once you’ve validated a critical vulnerability logically, you stop. Modifying actual data crosses from assessment into disruption. I document the 200 response and cease exploitation immediately.
7. Cryptography Analysis
While mapping the infrastructure, I check the internal service-to-service communications:
sslyze --regular internal-db-mq.bank.local:5671
The middleware API talks to RabbitMQ using TLS 1.0 with weak CBC ciphers (TLS_RSA_WITH_AES_128_CBC_SHA).
This matters. Most enterprises assume an insider threat model—if someone phishes an employee and compromises their laptop, they’re now on the internal network. Weak internal cryptography means an attacker on that network can passively sniff credentials and payment data as they travel the wire, or exploit padding oracle vulnerabilities to decrypt traffic. This directly violates PCI-DSS requirement 4.1.
8. Prioritizing the Findings
I now have three vulnerabilities:
- Weak TLS 1.0 on internal message queues
- Blind SSRF in the PDF generation endpoint
- JWT algorithm bypass allowing privilege escalation
Which one matters most?
The JWT bypass is critical. Here’s why: The SSRF needs careful exploitation and internal egress filtering limits what I can reach. The TLS weakness requires me to already be in a network sniffing position. But the JWT bypass? Any internal user can do it with just a Burp proxy intercept. No special tools, no complex setup—just modify a header and gain admin access to critical financial systems.
9. Risk Assessment: Beyond CVSS Scores
I don’t just apply a CVSS formula. Context matters more than a number.
- Technical Severity: Complete authentication bypass
- Business Impact: Critical. This API reconciles payment batches. An admin attacker could suppress alerts on fraudulent outgoing SWIFT transfers
- Exploitability: Trivial—just modify a JWT header
Final Rating: CRITICAL
Yes, the application is internal-only. Yes, you need to be on the corporate network to access it. But that doesn’t matter. The business impact—an insider or compromised workstation gaining unfettered access to the payment reconciliation system—is a company-ending vulnerability.
10. Practical Remediation Steps
Telling a bank to “upgrade the JWT library” ignores the reality: they have deployment freezes, ITIL processes, and vendor dependencies. Real advice includes immediate steps they can actually take.
Immediate (24 Hours):
Add a WAF rule to the F5 load balancer that blocks any JWT with alg:none:
when HTTP_REQUEST {
if { [HTTP::header exists "Authorization"] } {
set auth_header [HTTP::header "Authorization"]
if { $auth_header contains "eyJhbGciOiAibm9uZS" } {
HTTP::respond 401 content "Unauthorized"
return
}
}
}
Next Sprint:
Update the authentication framework to enforce mandatory signature validation (RS256 or HS256) in the application code itself.
Long-Term: Replace stateless JWTs on financial APIs with stateful OAuth2/OIDC tokens. This lets you revoke access instantly if needed.
11. Reporting That Actually Matters
A junior tester writes reports sorted by technical category. A consultant writes reports sorted by what the board should care about.
The executive summary doesn’t mention JWTs or base64. It says: “Any internal employee or compromised workstation can authorize payment reconciliations without oversight. This breaks separation-of-duties and creates exposure to insider fraud.”
The technical details go to the architects—exact base64 payloads, exact WAF rules, exact reproduction steps.
12. Defending the Finding
During the debrief, DevOps pushes back: “It’s Critical how? The API is only accessible from the internal VPN.”
This is where technical credibility pays off. I don’t debate CVSS scores—I argue threat models.
“Your VPN has 12,000 users. One HR employee clicks a phishing email and their laptop gets compromised. Now the attacker is on the same VPN segment. Internal access restrictions can’t protect broken authentication on critical financial systems.”
The finding stays Critical.
13. Preventing the Same Mistake Twice
The real value isn’t just finding the JWT flaw—it’s understanding why it shipped in the first place.
The root cause: the CI/CD pipeline doesn’t test for weak authentication mechanisms. The fix: configure DAST to automatically reject pull requests that allow unsigned JWTs. Then this vulnerability never happens again, anywhere in the organization.
14. When Detection Works
Midway through testing, my SSRF payloads time out. Then my VDI connection drops.
The SOC caught me. They saw the rapid succession of anomalous payloads (file:///etc/passwd) and severed my access.
I don’t hide this in the report—I celebrate it. My job is to validate both offense and defense. I document when they detected me, note that their honeypot alerting worked perfectly, and recommend they keep doing exactly what they’re doing. That SIEM is earning its budget.
15. What a Real Attacker Would Do
Everything you just read is exactly how a RaaS affiliate operates once they’re inside your network.
The Attacker’s Playbook: Use the JWT bypass to silently explore payment routing systems, establish persistence, exfiltrate data, then deploy ransomware.
Your Defense: Endpoint detection tools won’t see this—a forged JWT looks like a legitimate HTTP request over port 443. You need identity analytics to detect admin accounts acting strange, strict logging to track what was accessed, and WAF rules to enforce protocol validation.
16. The Real Difference
A penetration tester runs scanners, logs CVE IDs, and hands you a spreadsheet.
A true security consultant does something different. They understand that a vulnerability is only as important as the damage it could cause to your business. In banking, that distinction is everything.
The consultant’s job is: find the critical flaws that matter most, execute the exploit safely without breaking anything, and tell the executives in plain language why they should care. That’s what separates the operators from the tool runners.