java代码审计中不能忽略的思路-持续更新

Posted 飘渺红尘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java代码审计中不能忽略的思路-持续更新相关的知识,希望对你有一定的参考价值。

  1.反射和动态加载

1.在java反序列化中,反射被频繁使用,使用反射修改,提取
2.动态代理的特性非常强大,java框架的过滤器就使用了动态加载这个特性
动态代理:https://juejin.cn/post/6844903591501627405

不仅在开发上,在安全领域,也广泛受用。

动态代理它的特点就是:被代理的类,调用任意方法,都会调用代理类的invoke方法。
利用这个tricks,我们可以寻找一些rce的利用链

   详细说下反射:

反射里面有两个函数,非常容易记混

1.newInstance 类似于new Class->实例化对象
2.invoke 从类中获取一个方法后,可以使用invoke() 来调用这个方法
参考:https://juejin.cn/post/6975888597865988127

  

一个个来,先看newInstance函数

newInstance和new创建实例化,虽然效果相同,但是原理差很多:

new是实例对象而newInstance是实用类的加载机制
new不用加载过就可用而newInstance需要加载并且有连接才可用

 

通过反射调用构造函数有两种方法:
调用无参构造函数:Class.newInstance()
调用带参数的构造函数:
通过 Class 类获取 Constructor
调用 Constructor 中的 newInstance(Object ... initarges) 方法

 

2.作用域和try catch细节点

理解java中的作用域非常重要,对代码审计,写代码都很有重要。
以一段代码为例子:

public static void main(String[] args) 
        try
            float j=23/0;
            System.out.println(123);
            System.out.println(345);
//            System.out.println(s.length());
         catch (ArithmeticException e) 
//            System.out.println(e);
            throw new ArithmeticException("123");
     
//        System.out.println(s.length());
        System.out.println(123);
    

 

这时候的报错是123,因为抛出了异常。因为 变量j在try这个异常处理作用域下。

 

 

 

拿出,把变量移出异常处理作用:

这时候报的就不是作用域中抛出的异常,而是自身的23/0的异常

 

 

再看个demo:

public static void main(String[] args) 
        try
            float j=23/0;
//            System.out.println(s.length());
         catch (ArithmeticException e) 
            System.out.println(e);
//            throw new ArithmeticException("123");
     
        System.out.println(123);
    

 

此时j变量在异常报错作用域内

此时会打印作用域外的内容,因为异常作用域处理了异常,会继续执行。

 

 

移除j变量到异常处理作用域外:

public static void main(String[] args) 
        float j=23/0;
        try
//            System.out.println(s.length());
         catch (ArithmeticException e) 
            System.out.println(e);
//            throw new ArithmeticException("123");
     
        System.out.println(123);
    

 

因为报异常,所以最后没有输出123

 

 

只要throw抛出,就一定会走catch流:

某段cms测试代码:

package com.demo.testbug;

public class catch_test 
    public static void main(String[] args) 
        try 
            String cls ="xxxx";
            if(cls!=null) 
                try 
                    Class.forName(cls).newInstance();

                 catch (ClassNotFoundException classNotFoundException) 
                    throw new Exception("123");
                
            
         catch (Throwable throwable2)
            System.out.println(444);
            System.out.println(throwable2);
    
    

 

这段代码,一定会走第二个catch流,因为第一个catch捕捉是抛出流,抛出必定要捕捉处理。

3.编译类型和运行类型:

 

定义变量左侧声明部分为编译类型,右侧运行类型是真实结果

 

运行属性,为编译类型。调用方法为运行类型

 

通常情况下,编译类型和运行类型一致。

 

使用多态的时候,编译类型和运行类型不一致

 

如:

Father f = new Son();
f.action(),调用函数是运行类型
f.属性 调用属性是看编译类型

牢记:调用方法走运行类型,调用属性走编译类型!!!

 

 

 

5.instanceof

tricks:
必须为引用类型,不能是基本类型
判断一个引用所指向的对象:instanceof
主要用来判断某个对象是不是某个类的实例。

son 和father有继承关系。此时s是子类,father是父类,是可以的。

 

 

 

6.request.getRequestDispatcher(

 

请求转发可以用来绕过过滤器,还可以读取包含文件

 

 

 

 

更多参考:

https://stackoverflow.com/questions/11187934/filter-mapped-on-forward-dispatcher-isnt-invoked-when-jsf-navigation-is-perform

https://www.yuque.com/pmiaowu/gpy1q8/pkzfug6spzrezz7k

https://blog.51cto.com/1031627059/1681958

 

7.再谈java项目各个配置文件

 

 

  

spring-mvc.xml:
sping-mvc.xml文件中主要的工作是:启动注解、扫描controller包注解;静态资源映射;视图解析(defaultViewResolver);文件上传(multipartResolver);返回消息json配置。

web.xml:
(1)web项目启动时,读取web.xml配置文件,首先解析的是applicationContext.xml文件,其次才是sping-mvc.xml文件
(2)web.xml中配置的加载优先级context-param -> listener -> filter -> servlet

spring.xml
类似于web.xml

 

 

 
springmvc配置文件详解:
 
 
未完待续。。。

 

以上是关于java代码审计中不能忽略的思路-持续更新的主要内容,如果未能解决你的问题,请参考以下文章

java源代码安全审计

2022 APMCM亚太数学建模竞赛 C题 全球是否变暖 思路及代码实现(持续更新中)

持续更新把.net代码转换为java代码的注意事项

C#Java中的一些小功能点总结(持续更新......)

IDEA 常用的小技巧汇总,JAVA 新手上路必备,快上车!(持续更新)

Java面试题(持续更新)