Created
January 20, 2026 01:59
-
-
Save RajChowdhury240/53b019408aeeeef2d0c319fb07ff9d4e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| title = "SSTI RCE Final Findings" | |
| url = "/ssti-findings" | |
| layout = "default" | |
| == | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <title>SSTI RCE Research - Final Findings</title> | |
| <style> | |
| body { font-family: monospace; background: #0a0e27; color: #c9d1d9; padding: 20px; } | |
| .box { border: 1px solid #30363d; padding: 15px; margin: 15px 0; background: #0d1117; } | |
| h1 { color: #f85149; text-shadow: 0 0 10px #f85149; } | |
| h2 { color: #ffa657; } | |
| h3 { color: #79c0ff; } | |
| pre { background: #000; padding: 10px; border-left: 3px solid #58a6ff; white-space: pre-wrap; font-size: 12px; } | |
| .success { color: #3fb950; } | |
| .fail { color: #f85149; } | |
| .warn { color: #d29922; } | |
| ul { line-height: 1.8; } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>π¬ TWIG SSTI RCE RESEARCH - COMPREHENSIVE FINDINGS</h1> | |
| <p><strong>Environment:</strong> October CMS 4.x with Safe Mode ENABLED</p> | |
| <p><strong>Objective:</strong> Achieve Remote Code Execution via Twig Template Injection</p> | |
| <hr> | |
| <div class="box"> | |
| <h2 class="success">β CONFIRMED WORKING: Information Disclosure Vectors</h2> | |
| <h3>1. PHP System Information</h3> | |
| <pre>PHP Version: {{ constant('PHP_VERSION') }} | |
| PHP OS: {{ constant('PHP_OS') }} | |
| PHP SAPI: {{ constant('PHP_SAPI') }} | |
| Directory Separator: {{ constant('DIRECTORY_SEPARATOR') }}</pre> | |
| <h3>2. October CMS Context Access</h3> | |
| <pre>Environment: {{ this.environment() }} | |
| Locale: {{ this.locale() }} | |
| Session ID: {{ this.session.getId() }} | |
| Session Name: {{ this.session.getName() }}</pre> | |
| <h3>3. Request Object Information</h3> | |
| <pre>Request URL: {{ this.request.url() }} | |
| Request Method: {{ this.request.method() }} | |
| Request IP: {{ this.request.ip() }} | |
| Request User-Agent: {{ this.request.header('User-Agent') }}</pre> | |
| <h3>4. Collection Functionality</h3> | |
| <pre> | |
| {% set testcol = collect(['alpha', 'beta', 'gamma']) %} | |
| Collection count: {{ testcol.count() }} | |
| Collection first: {{ testcol.first() }} | |
| Collection last: {{ testcol.last() }} | |
| Collection contains 'beta': {{ testcol.contains('beta') ? 'YES' : 'NO' }} | |
| Collection toArray: {{ testcol.toArray()|json_encode|raw }}</pre> | |
| </div> | |
| <div class="box"> | |
| <h2 class="warn">β οΈ PARTIALLY WORKING: Limited Exploitation Vectors</h2> | |
| <h3>1. XSS via |raw Filter</h3> | |
| <pre>{{ '<b>HTML injection works</b>'|raw }} | |
| {{ '<script>alert("XSS")</script>'|raw }}</pre> | |
| <h3>2. Template Macros</h3> | |
| {% macro testmacro(input) %} | |
| Macro received: {{ input|raw }} | |
| {% endmacro %} | |
| <pre>{{ _self.testmacro('<i>Macro execution confirmed</i>') }}</pre> | |
| <h3>3. Carbon Date Manipulation</h3> | |
| <pre> | |
| {% set now = carbon('now') %} | |
| Carbon: {{ now.format('Y-m-d H:i:s') }} | |
| Carbon timestamp: {{ now.timestamp }} | |
| {# Could be used for timing attacks or date-based logic bypass #}</pre> | |
| </div> | |
| <div class="box"> | |
| <h2 class="fail">β BLOCKED: Failed RCE Attempts</h2> | |
| <h3>1. PHP Superglobals - NOT EXPOSED</h3> | |
| <pre>_GET: Not available in Twig context | |
| _POST: Not available in Twig context | |
| _SERVER: Not available in Twig context | |
| _COOKIE: Not available in Twig context | |
| _ENV: Not available in Twig context</pre> | |
| <h3>2. Page Object Methods - BLOCKED by SecurityPolicy</h3> | |
| <pre>{# this.page.getAttributes() - BLOCKED #} | |
| {# this.page.getContent() - BLOCKED #} | |
| {# this.page.getAttribute('code') - BLOCKED #} | |
| Error: "Calling any method on a Cms\Classes\Page object is blocked."</pre> | |
| <h3>3. Collection Callable Exploitation - FAILED</h3> | |
| <pre> | |
| {% set attempt = collect(['whoami']) %} | |
| groupBy('shell_exec'): {{ attempt.groupBy('shell_exec')|json_encode|raw }} | |
| {# Result: {"":["whoami"]} - NOT EXECUTED #} | |
| {# Explanation: SafeCollection filters out callables even in hybrid methods #} | |
| {# The string callable is passed but Laravel's groupBy doesn't execute it as expected #} | |
| </pre> | |
| <h3>4. source() Function - NOT AVAILABLE</h3> | |
| <pre>{# source('.env') - Function does not exist #} | |
| {# Template file reading blocked #}</pre> | |
| <h3>5. include with Path Traversal - FAILED</h3> | |
| <pre>{# {% include '../../../../.env' %} - View not found #} | |
| {# Template inclusion is restricted to theme directory #}</pre> | |
| <h3>6. env() and config() Functions - BLOCKED in Safe Mode</h3> | |
| <pre>{# env('APP_KEY') - Function not available in Safe Mode #} | |
| {# config('app.key') - Function not available in Safe Mode #}</pre> | |
| <h3>7. Controller Access - BLOCKED</h3> | |
| <pre>{# this.controller exists but is CmsController (not in allowlist) #} | |
| {# Cannot call methods on it due to SecurityPolicy #}</pre> | |
| </div> | |
| <div class="box"> | |
| <h2 class="warn">π SECURITY POLICY ANALYSIS</h2> | |
| <h3>Allow-Listed Objects (Methods Callable)</h3> | |
| <ul> | |
| <li>Carbon\Carbon</li> | |
| <li>Illuminate\View\View</li> | |
| <li><strong>Illuminate\Http\Request</strong> β Can call methods</li> | |
| <li><strong>Illuminate\Session\Store</strong> β Can call methods</li> | |
| <li><strong>Illuminate\Support\Collection</strong> β Wrapped in SafeCollection</li> | |
| <li>Illuminate\Database\Query\Builder</li> | |
| <li>Illuminate\Database\Eloquent\Model</li> | |
| <li>SimpleXMLElement</li> | |
| </ul> | |
| <h3>CallsAnyMethod Interface (Complete Bypass)</h3> | |
| <ul> | |
| <li><strong>ThisVariable</strong> - But limited scope</li> | |
| <li><strong>ComponentBase</strong> - Would need custom component</li> | |
| <li><strong>ComponentVariable</strong> - Forwards to query builder</li> | |
| </ul> | |
| <h3>Blocked Methods (Global)</h3> | |
| <ul> | |
| <li>__call, __callStatic</li> | |
| <li>extend, extendableCall</li> | |
| <li>macro, mixin</li> | |
| <li>bindEvent, bindEventOnce</li> | |
| </ul> | |
| <h3>Property Access</h3> | |
| <pre>checkPropertyAllowed(): DOES NOTHING! | |
| β ALL properties on ALL objects are accessible | |
| β But most useful properties are protected/private</pre> | |
| </div> | |
| <div class="box"> | |
| <h2 class="warn">π‘ THEORETICAL RCE VECTORS (Untested/Unconfirmed)</h2> | |
| <h3>1. Custom Component Creation</h3> | |
| <pre>Strategy: Create malicious plugin with component implementing CallsAnyMethod | |
| Risk: Requires backend admin access to install plugins | |
| Impact: Could expose dangerous methods bypassing SecurityPolicy</pre> | |
| <h3>2. Session Deserialization</h3> | |
| <pre>Strategy: Manipulate session data to inject serialized PHP objects | |
| Risk: Need to find gadget chain in October/Laravel codebase | |
| Impact: Potential RCE via unsafe deserialization</pre> | |
| <h3>3. Cache Poisoning</h3> | |
| <pre>Strategy: Inject malicious serialized objects into cache | |
| Risk: Requires writable cache and deserialization vulnerability | |
| Impact: RCE when cache is read and unserialized</pre> | |
| <h3>4. File Upload + Path Traversal</h3> | |
| <pre>Strategy: Upload PHP file as image, include via template | |
| Risk: Requires media upload access + path traversal vulnerability | |
| Impact: Direct PHP code execution</pre> | |
| <h3>5. Database Template Injection</h3> | |
| <pre>Strategy: If CMS_DB_TEMPLATES=true, inject via database | |
| Risk: Requires database write access | |
| Impact: Bypass file-based Safe Mode checks</pre> | |
| </div> | |
| <div class="box"> | |
| <h2 class="success">π― COMPARISON: PHP vs Twig SSTI</h2> | |
| <h3>Pre-Existing PHP Code Pages (Before Safe Mode)</h3> | |
| <pre class="success">β Full RCE via shell_exec(), system(), exec() | |
| β Interactive web shell | |
| β File system access | |
| β Database access | |
| β Complete server compromise | |
| Method: Create page with PHP code BEFORE enabling Safe Mode | |
| Result: Code continues executing even after Safe Mode is enabled | |
| CVSS: 10.0 CRITICAL</pre> | |
| <h3>Twig SSTI (With Safe Mode Active)</h3> | |
| <pre class="warn">β Information disclosure (PHP version, OS, paths) | |
| β Session data access | |
| β Persistent XSS | |
| β Template manipulation | |
| β Direct command execution | |
| β File read/write | |
| β PHP code execution | |
| Method: Create new page with Twig templates while Safe Mode is ON | |
| Result: Can gather information and launch XSS, but NOT achieve RCE | |
| CVSS: 6.5 MEDIUM (Information Disclosure + XSS)</pre> | |
| </div> | |
| <div class="box"> | |
| <h2 class="fail">π¨ FINAL CONCLUSION</h2> | |
| <h3>Primary Finding:</h3> | |
| <p><strong class="warn">Twig SSTI CANNOT achieve direct RCE when Safe Mode is properly enabled.</strong></p> | |
| <p>The October CMS Security Policy effectively prevents:</p> | |
| <ul> | |
| <li>β Calling methods on CMS objects (Page, Layout, Partial)</li> | |
| <li>β Accessing dangerous PHP functions</li> | |
| <li>β Exploiting Collection callables (SafeCollection wrapper)</li> | |
| <li>β Reading arbitrary files via source() or include</li> | |
| <li>β Accessing env() or config() functions</li> | |
| </ul> | |
| <h3>What IS Possible:</h3> | |
| <ul> | |
| <li class="success">β Creating pages with Twig templates (Safe Mode doesn't block page creation)</li> | |
| <li class="success">β Information disclosure (system info, session data)</li> | |
| <li class="success">β Persistent XSS attacks</li> | |
| <li class="success">β Template logic manipulation</li> | |
| </ul> | |
| <h3>Critical Vulnerability:</h3> | |
| <p class="fail"><strong>THE REAL VULNERABILITY: Safe Mode Only Blocks PHP During SAVE, Not EXECUTION</strong></p> | |
| <pre class="fail">If an attacker has admin access BEFORE Safe Mode is enabled: | |
| 1. Create CMS page with malicious PHP code | |
| 2. Admin enables Safe Mode for "security" | |
| 3. Pre-existing PHP code continues to execute indefinitely | |
| 4. Result: Full RCE despite Safe Mode being "ON" | |
| This is the CRITICAL flaw - not Twig SSTI.</pre> | |
| <h3>Recommendation:</h3> | |
| <p class="warn">Safe Mode should enforce runtime checks, not just save-time checks.<br> | |
| All existing PHP code sections should be disabled when Safe Mode is enabled.</p> | |
| </div> | |
| <hr> | |
| <div class="box"> | |
| <h2>π Research Summary</h2> | |
| <p><strong>Total Pages Created:</strong> 10+ test pages</p> | |
| <p><strong>Attack Vectors Tested:</strong> 25+</p> | |
| <p><strong>Security Policy Bypasses Found:</strong> 0 (for RCE)</p> | |
| <p><strong>Information Disclosure Vectors:</strong> Multiple confirmed</p> | |
| <p><strong>XSS Vectors:</strong> Confirmed working</p> | |
| <p><strong>RCE via Twig SSTI:</strong> <span class="fail">NOT ACHIEVABLE</span></p> | |
| <p><strong>RCE via Pre-Existing PHP:</strong> <span class="success">CONFIRMED (Primary Vulnerability)</span></p> | |
| </div> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment