Loading

java代码审计学习笔记(二)

一、java EE的核心技术简介
参考链接:https://zhuanlan.zhihu.com/p/85608263
JAVA核心技术有很多,包括JDBC、JNDI、EJB、RMI、Serverlet、JSP、XML、JMS、JavaIDL、JTS、JTA、JavaMail和JAF
Java数据库连接(JDBC)在Java语言中用来规范客户端程序如何访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。
Java命令和目录接口(JNDI)是Java的一个目录服务应用程序界面(API),它提供了一个目录系统,并将服务名称域对象关联起来,从而使开发人员在开发过程中可以用名称来访问对象。
企业级JavaBean(EJB)是一个用来构筑企业级应用的、在服务器端可被管理的组件。
远程方法调用(RMI)是Java的一组拥有开发分布式应用程序的API。
Servlet是使用Java编写的服务端程序
JSP部署在网络服务器上,可以响应客户端发送的请求,并根据请求内容动态生成HTML、XML或其他格式文档的Web网页,然后返回给请求者。
可扩展标记语言(XML)是被设计用于传输和存储数据的语言
Java消息服务(JMS)是一个Java平台中关于面向消息中间件(MOM)的API,用于两个应用程序之间或分布式系统中发送消息,进行异步通信。
二、Java Web的核心技术---Servlet
1、基于Web.xml
在web.xml中,Servlet的配置在Servlet标签中,Servlet标签是由Servlet和Servlet-mappping标签组成,两者通过在Servlet和Servlet-mapping标签中相同的Servlet-name名称实现关联。
2、基于注解方式
Servlet3.0以上的版本中,开发者无须在Web.xml里面配置Servlet,只需要添加WebServlet注解即可修改Servlet的属性。
三、Servlet的访问流程
首先在浏览器地址栏中输入user,即访问url-pattern标签中的值;然后浏览器发起请求,服务器通过servlet-mapping标签中找到文件名为user的url-pattern,通过其对应的servlet-name寻找servlet标签中的servlet-name相同的servlet;再通过servlet标签中的servlet-name,获取servlet-class参数;最后得到具体的class文件路径,继而执行servlet-class标签中class文件的逻辑。
四、Java Web过滤器---filter
filter的配置类型于Servlet,由两组标签组成。基于web.xml或注解方式的配置。
五、Java反射机制
Java反射机制可以无视类方法、变量去访问权限修饰符(如protected、private等),并且可以调用任何类的任意方法、访问并修改成员变量值。
1、什么是反射
反射是Java的特征之一。C/C++语言中不存在反射,反射的存在使运行中的Java程序能够获取自身的信息,并且可以操作类或对象的内部属性。
2、不安全的反射
如果使用Java反射来重构此代码以减少代码行

String name = request.getParameter("name");
Class ComandClass = Class.forName(name + "Command");
Command command = (Command) CommandClass.newInstance();
command.DoAction(request);

实际上,攻击者甚至不局限于本例中的Command接口对象,而是使用任何其他对象来实现,如调用系统中任何对象的默认构造函数,或者调用Runtime对象去执行系统命令,这可能导致远程命令执行出现漏洞。
六、ClassLoader类加载机制
在程序运行时,并不会加载所有的class文件进入内存,而是通过Java的类加载机制(ClassLoader)进行动态加载,从而转换成Java.lang.Class类的一个例子。
1、ClassLoader类
ClassLoader是一个抽象类,主要的功能是通过指定的类的名称,找到或生成对应的字节码,返回一个java.lang.Class类的实例。

protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            //查找.class是否被加载过
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                try {
                //查看父加载器有没有加载过
                    if (parent != null) {
                        c = parent.loadClass(name, false);
                    } else {
                    //还没找到的话查找根加载器,这里就是双亲委派模型的实现
                        c = findBootstrapClassOrNull(name);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }

                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    //找到根加载器依然为空,只能子加载器自己加载了
                    long t1 = System.nanoTime();
                    c = findClass(name);

                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            // 解析class文件,就是将符号引用替换为直接引用的过程
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }

2、自定义的类加载器
根据loadClass()方法的流程,可以发现通过重写findClass()方法,利用defineClass()方法来将字节码转换成java.lang.class类对象,就可以实现自定义的类加载器。
3、loadClass()方法与Class.forName的区别
loadClass()方法只会对类进行加载,不会对类进行初始化。Class.forName会默认对类进行初始化。
4、URLClassLoader
URLClassLoader类是ClassLoader的一个实现,拥有从远程服务器上加载类的能力。通过URLCLassLoader可以实现对一些Webshell的远程加载、对某个漏洞的深入利用。
七、Javassist动态编程
Javassist就是一个用来处理Java字节码的类库,其主要有点在于简单、便捷。用户不需要了解虚拟机指令,就可以直接使用Java编码的形式,并且可以动态改变类的结构,或者动态生成类。
安全人员能够利用Javassist对目标函数动态注入字节码代码。

posted @ 2022-01-22 16:48  Ctrl_C+Ctrl_V  阅读(160)  评论(0编辑  收藏  举报