zoukankan      html  css  js  c++  java
  • javaweb-codereview 学习记录-5

    1.关于URLConnection

     应用程序利用url与远程通信的所有类的超类

    jdk1.8中支持的协议包括以上这些,gopher在jdk8中取消了。

    java中默认对(http|https)做了一些事情,比如:
    
    默认启用了透明NTLM认证
    默认跟随跳转

    httpURLconnection可能jdk7低版本可能在win机器上导致ntlmrelay攻击https://zhuanlan.zhihu.com/p/64889695

    使用URLconnection的子类可能只适合http|https,对ssrf也有一定的限制

    HttpURLConnection
    HttpClient
    Request
    okhttp

    2.关于java agent

    Java中Instrumentation(Java Agent API)JVMTI(JVM Tool Interface)功能,允许JVM在加载某个class文件之前对其字节码进行修改,同时也支持对已加载的class(类字节码)进行重新加载(Retransform),rsap和iast都基于这个功能实现动态修改java字节码来插入检测代码

    java agent的两种运行模式:

    1.直接在命令添加运行参数 -javaagent(Instrumentation API实现方式)或-agentpath/  -agentlib(JVMTI的实现方式)

    2.attach方式,直接将agent加到对应的java进程

    helloWorld.java

    public class helloWorld {
        public static void main(String[] args){
            System.out.println("hello world");
        }
    }

    比如就上面一段简单的代码,编译后取修改器字节码让其输出hello world,想一下hello world在编译后存储在class文件中,那么此时已经编译成字节码,要输出的字符串肯定也是以字节码存储着,那么此时可以直接替换获取编译好的字节码进行修改

    testagent.java

    import java.lang.instrument.ClassFileTransformer;
    import java.lang.instrument.IllegalClassFormatException;
    import java.lang.instrument.Instrumentation;
    import java.security.ProtectionDomain;
    import java.util.Arrays;
    
    public class testagent {
    
        private static byte[] relaceBytes(String classname,byte[] classbuffer)
        {
            String bufferStr = Arrays.toString(classbuffer).replace("[","").replace("]","");
            System.out.println("classname:"+classname);
            System.out.println("byes:"+ bufferStr);
    
            byte[] findBytes = "hello world".getBytes();
            String findStr = Arrays.toString(findBytes).replace("[","").replace("]","");
            System.out.println("world"+findStr);
            byte[] replaceBytes = "hello agent".getBytes();
            String replaceStr = Arrays.toString(replaceBytes).replace("[","").replace("]","");
            System.out.println("agent"+replaceStr);
            bufferStr = bufferStr.replace(findStr,replaceStr);
    
            System.out.println(bufferStr);
    
            String[]  bytearr = bufferStr.split("\s*,\s*");
    
            byte[] bytes = new byte[bytearr.length];
    
            for(int i=0;i < bytearr.length;i++)
            {
                bytes[i] = Byte.parseByte((bytearr[i]));
    
            }
    
            System.out.println("new byte :"+Arrays.toString(bytes));
    
            return bytes;
    
    
    
    
        }
        public static void premain(String args,final Instrumentation inst){
            inst.addTransformer(new ClassFileTransformer() {
                public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
    
                className = className.replace("/",".");
                   if(className.equals("helloWorld")){
                     return   relaceBytes(className,classfileBuffer);
    
                   }
                    return classfileBuffer;
                }
            },true);
    
        }
    }

    这里的classfileBuffer就是要修改字节码的class文件,这里替换字节的函数可以自定义,只要返回一个字节数组即可

      测试的时候testagent.java编译后要包含MANIFEST.MF,声明premain-class

      然后使用jar命令打包

    jar -cvfm agent.jar MANIFEST.MF *.class

    之后再到helloWorld.class的目录运行agent即可

    java -javaagent:agent.jar helloWorld

     这里一般修改字节码用ASM库

    Instrumentation

    java提供的监测jvm程序的api,利用Instrumentation我们可以实现

    1.动态添加Transformer(addTransformer),上面的例子就是

    2.动态修改classpath(appendToBootstrapClassLoaderSearch、appendToSystemClassLoaderSearch)

    3.动态获取所有JVM已经加载的类(getAllLoadedClasses)

    4.动态获取某个类加载器已经实例化的所有类(getInitiatedClasses)

    5.直接修改已加载的类的字节码

    6.动态设置JNI前缀(setNativeMethodPrefix)

    7.重加载指定类字节码(retransformClasses)

    ClassFileTransformer

    转换类文件的代理接口,拿到Instrumentation后可以调用addTransformer方法添加自定义的类文件转换器,上面的例子实际上就自定义了一个Transformer,此时transform(类名,类加载器,类字节码等)方法就包含了我们要修改的目标类的一些信息,修改完再返回字节码,jvm对字节码进行验证后将决定是否加载。

    这里简单记录一下,后面有机会再深入学习。

  • 相关阅读:
    数据解压
    子区域数据合并
    数据压缩复制
    将Win10变回Win7/WinXP界面
    通过GP加载卫星云图-雷达图-降雨预报图
    Maven版本与JDK版本
    由输入法随想
    selinux开关
    android studio 配置
    NodeJS 笔记
  • 原文地址:https://www.cnblogs.com/tr1ple/p/12260662.html
Copyright © 2011-2022 走看看