• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Java中的RASP机制实现详解

java 搞代码 4年前 (2022-01-09) 16次浏览 已收录 0个评论

RSAP

RASP是Gartner公司提出的一个概念,称:程序不应该依赖于外部组件进行运行时保护,而应该自身拥有运行时环境保护机制;

RASP就是运行时应用自我保护(Runtime application self-protection)的缩写,正如RASP字面意思一样,这是运行在运行时的一种防护技能;也就是说RASP能够在程序运行期间实施自我保护,监控与过滤有害信息,还能够拥结合程序的当前上下文实施精确、实时的防护;

Java中的RASP

不严格来说Java是半编译、半解释型语言,我们也都知道Java中也有运行时(Runtime)那Java的运行时在哪呢?

不急,我们先看看Java从编译到运行的流程图;

上图的流程为:Java编译程序如Javac编译.java源码文件,生成Java字节码文件.class,接着.class文件进入JVM中解释执行; 从中我们可以看到Java的最后执行阶段是在JVM中,也就可以说Runtime运行时是JVM的重要组成部分;除此之外我们还发现

Java中实现RASP的几个关键点:

1、 我们的防护程序必须能够分析、修改java的.class文件;

2、 必须在JVM解释执行.class文件时进行注入(Java Runtime);

通过上面的分析我们知道了要实现Java的RASP所要具备的能力,然后我们发现在Java中有Javassist、与ASM可以实现对Java字节码的修改;有了修改.class字节码文件的技能,还需要能够在Java运行期间注入我们的防护程序,通过上面我们发现Java运行时是发生在JVM中,通过查找相关资料与JVM参数发现在JVM参数中有-javaagent参数配置Java代理可以在 运行时注入我们的防护程序;

Java RASP实现

在上面的分析中我们发现只要在JVM的-javaagent参数 中配本文来源gaodaimacom搞#^代%!码&网*置我们的保护程序,就能够轻松实现Java的RASP;

Java代理程序入口类需要有名为premain的静态方法 ,还需要在jar的META-INF/MAINIFEST.MF文件中包含 Premain-Class配置,下面是RASP保护程序的入口类;

JavaRASPApp:

/**
 * @author linx
 * @date 2017-06-25
*/
public class JavaRASPApp {

 public static void premain(String agentArgs, Instrumentation instru) throws ClassNotFoundException, UnmodifiableClassException {
  System.out.println("premain");
  instru.addTransformer(new ClassTransformer());
 }
}

ClassTransformer类实现了Java的代理程序机制提供的ClassFileTransformer接口 ,能够在运行时(Runtime)对类的字节码进行替换与修改;

ClassTransformer也很简单,只有一个实现方法:transform,此方法中可以获取得到ClassLoader、className、classfileBuffer等,分别为类加载器、类名、字节码 ;

此时我们可以在transform方法中做文章,实现我们的防护程序;

/**
 * @author linxin
 * @version v1.0
 *     Copyright (c) 2017 by linx
 * @date 2017/6/23.
*/
 public class ClassTransformer implements ClassFileTransformer {
 public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){
  byte[] transformeredByteCode = classfileBuffer;
  try {

    if (className.equals("co/solinx/demo/Test")) {
      System.out.println(String.format("transform start %s",className));
      ClassReader reader = new ClassReader(classfileBuffer);
      ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
      ClassVisitor classVisitor = (ClassVisitor) createVisitorIns("co.solinx.demo.visitor.TestVisitor", writer, className);
      reader.accept(classVisitor, ClassReader.EXPAND_FRAMES);
      transformeredByteCode = writer.toByteArray(); 
    }
  } catch (Exception e) {
    e.printStackTrace();
  }catch (Throwable t){
    t.printStackTrace();
  }
  return transformeredByteCode;
}
 public Object createVisitorIns(final String name, ClassVisitor cv, String className)
    throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {
  Constructor<?> ctor = Class.forName(name).getDeclaredConstructor(new Class[]{ClassVisitor.class, String.class});
  ctor.setAccessible(true);
  return ctor.newInstance(new Object[]{cv, className});
 }
}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Java中的RASP机制实现详解
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址