Log4j漏洞?一行代码都不改就能永久修复?
共 4073字,需浏览 9分钟
·
2022-01-02 12:20
△Hollis, 一个对Coding有着独特追求的人△作者 l Hollis来源 l Hollis(ID:hollischuang)这篇文章我周一发过,但是因为一些"人在江湖、身不由己"的原因,原文删除了,但是很多人找我还是想看看内容,所以我改了一点内容,重新发一下:Apache Log4j2 远程代码执行漏洞的问题最近闹得沸沸扬扬的,很多人都被大半夜叫起来紧急修复这跟问题。有很多人在微信上问我:这种漏洞还能怎么修?下次有问题还要再升级版本吗?有没有啥一劳永逸的办法?就没啥办法避免吗?其实,是有的。有一种技术,可以针对这类漏洞做定向拦截。可以让开发者不用急急忙忙修这个漏洞,甚至你如果完全不想修都可以。这就是RASP技术。其实这个技术已经诞生很久了,在安全圈也应用很广泛。应用范围也很广泛了。
RASPRASP 是 Runtime Application Self-Protection 的缩写,这是一种应用安全保护技术。他的原理是将保护程序注入到应用程序中,与应用程序融为一体,能够起到实时监测、阻断攻击的作用,使程序自身拥有自保护的能力。听起来是不是很高大上?其实,RASP就是拦截从应用程序到系统的所有调用,确保它们是安全的,并直接在应用程序内验证数据请求。Web和非Web应用程序都可以通过RASP进行保护。该技术不会影响应用程序的设计,因为RASP的检测和保护功能是在应用程序运行的系统上运行的。
RASP 技术非常是和对于0Day 漏洞的防护,如反序列化漏洞、JNDI 注入漏洞、表达式注入漏洞、SQL 诸如漏洞、远程代码执行漏洞等。
WAF 和 RASP在安全防护上,很多人都知道WAF(Web Application Firewall),俗称防火墙,那么,和防火墙相比,RASP 技术其实有着很多的优点。传统的 WAF 主要通过分析流量中的特征过滤攻击请求,并拦截携带有攻击特征的请求。但是因为 WAF 只能基于流量规则进行防御,无法根据应用上下文进行检测,所以存在误报率高、容易绕过等问题。但是,RASP 则不同,他就像疫苗会注入到人体一样,RASP 是运行在应用之中的,与应用融为一体,可以获取到应用运行时的上下文,根据请求上下文进行拦截可以对攻击进行精准的识别和拦截。
防火墙就像为簇拥在大人物周围的保镖,大人物去哪里都带着保镖,看起来防御力爆棚,但是大人物本人肌肉不发达也没有武功,一旦保镖被突破或者保镖被调虎离山,那么这个大人物就没有任何保护了,就非常危险了。而RASP 则是让没有武功的人在很短的时间并且付出的代价不高的情况下拥有很高的自我保护能力。
RASP 具有以下优点:- 1.误报率低。
- 2.可以防护0Day级别的漏洞攻击。
实现原理不同于基于流量特征的检测,RASP 主要关注应用自身的行为,而非流量本身。当 RASP 发现一个应用,做了它不应该做的事情时,大概率意味着当前应用已经被攻击者利用漏洞攻陷并做了一些高危操作。以这次 Log4j的漏洞来看,RASP 并不关注请求中的流量是否包含了恶意的 payload,而是去关注 Log4j2 究竟使用 JNDI 功能去做了什么。如果进行正常的 JNDI 查询,就没有问题;但如果企图使用 JNDI 功能进行命令执行,就是一个显而易见的危险行为。RASP 要将自己注入到被保护的应用中,基本思路类似于 Java 中的 AOP 技术,将 RASP 的Hook代码注入到需要进行检测的地方,根据上下文和关键函数的参数等信息判断请求是否为恶意请求,并终止或继续执行。想要实现RASP,在 Java中逃不开 Agent 技术,Agent是一个运行在目标JVM的特定程序,它的职责是负责从目标JVM中获取数据,然后将数据传递给外部进程。在Java SE 5之前,要实现一个Agent只能通过编写Native代码来实现。从Java SE 5开始,可以使用Java的Instrumentation接口(java.lang.instrument)来编写Agent。使⽤ Instrumentation,开发者可以构建⼀个独⽴于应⽤程序的代理程序(Agent),用来监测和协助运行在 JVM 上的程序,甚至能够替换和修改某些类的定义。
Java Agent支持目标JVM启动时加载,也支持在目标JVM运行时加载,这两种不同的加载模式会使用不同的入口函数,如果需要在目标JVM启动的同时加载Agent,那么可以选择实现下面的方法:
public static void premain(String agentArgs, Instrumentation inst);
public static void premain(String agentArgs);
public static void premain(String agentArgs, Instrumentation inst)
throws ClassNotFoundException, UnmodifiableClassException {
inst.addTransformer(new ClassTransformer());
}
public byte[] transform(ClassLoader loader, String className, Class> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
byte[] transformeredByteCode = classfileBuffer;
if (Config.moudleMap.containsKey(className)) {
try {
ClassReader reader = new ClassReader(classfileBuffer);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor visitor = Reflections.createVisitorIns((String) Config.moudleMap.get(className).get("loadClass"), writer, className);
reader.accept(visitor, ClassReader.EXPAND_FRAMES);
transformeredByteCode = writer.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
}
return transformeredByteCode;
}
使用 Java实现的,代码不多,很容易理解。
开源工具RASP作为一个相对成熟的技术,现在已经有很多开源的产品了,国内外都有很多。如国外的Micro Focus、Prevoty、OWASP AppSensor、Shadowd等等。国内也有很多厂商也有类似的工具。如:
- 安百科技——灵蜥
- http://www.anbai.com/lxPlatform/
- 百度——OpenRasp
- https://rasp.baidu.com/
- 椒图科技——云锁
https://www.yunsuo.com.cn
往期推荐