核弹级漏洞,把 log4j 扒给你看!

149633c3f548f94fecfdfa0ca28fd8f6.gif

作者 | 轩辕之风O

来源 | 编程技术宇宙

相信大家这两天应该被这么一条新闻刷屏了:

6c1bc02ce048e349495c56d2f225e3ca.png

这个漏洞到底是怎么回事?

核弹级,真的有那么厉害吗?

怎么利用这个漏洞呢?

我看了很多技术分析文章,都太过专业,很多非Java技术栈或者不搞安全的人只能看个一知半解,导致大家只能看个热闹,对这个漏洞的成因、原理、利用方式、影响面理解的不到位。

这篇文章,我尝试让所有技术相关的朋友都能看懂:这个注定会载入网络安全史册上的漏洞,到底是怎么一回事!

log4j2

不管是什么编程语言,不管是前端后端还是客户端,对打日志都不会陌生。

通过日志,可以帮助我们了解程序的运行情况,排查程序运行中出现的问题。

在Java技术栈中,用的比较多的日志输出框架主要是log4j2logback

今天讨论的主角就是log4j2。

我们经常会在日志中输出一些变量,比如:

logger.info("client ip: {}", clientIp)

现在思考一个问题:

假如现在想要通过日志输出一个Java对象,但这个对象不在程序中,而是在其他地方,比如可能在某个文件中,甚至可能在网络上的某个地方,这种时候怎么办呢?

log4j2的强大之处在于,除了可以输出程序中的变量,它还提供了一个叫Lookup的东西,可以用来输出更多内容:

0312d0819bc232792de4bfd81a74c65a.png


lookup,顾名思义就是查找、搜索的意思,那在log4j2中,就是允许在输出日志的时候,通过某种方式去查找要输出的内容。

lookup相当于是一个接口,具体去哪里查找,怎么查找,就需要编写具体的模块去实现了,类似于面向对象编程中多态那意思。

好在,log4j2已经帮我们把常见的查找途径都进行实现了:

3fde9a44c6ba96abec540e6c06632da3.png

具体每一个的意思,这里就不详述了,这不是本文的重点。

JNDI

主要来看其中那个叫JNDI的东西:

ec5b70b8ccdc6c23beb978f50c18cfb5.png

JNDI即Java Naming and Directory Interface(JAVA命名和目录接口),它提供一个目录系统,并将服务名称与对象关联起来,从而使得开发人员在开发过程中可以使用名称来访问对象。

看不懂?看不懂就对了!

简单粗暴理解:有一个类似于字典的数据源,你可以通过JNDI接口,传一个name进去,就能获取到对象了。

那不同的数据源肯定有不同的查找方式,所以JNDI也只是一个上层封装,在它下面也支持很多种具体的数据源。

92d637998f980c67a43680c1ff694731.png

LDAP

继续把目光聚焦,咱们只看这个叫LDAP的东西。

LDAP即Lightweight Directory Access Protocol(轻量级目录访问协议),目录是一个为查询、浏览和搜索而优化的专业分布式数据库,它呈树状结构组织数据,就好象Linux/Unix系统中的文件目录一样。目录数据库和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好像它的名字一样。

看不懂?看不懂就对了!

这个东西用在统一身份认证领域比较多,但今天也不是这篇文章的重点。你只需要简单粗暴理解:有一个类似于字典的数据源,你可以通过LDAP协议,传一个name进去,就能获取到数据。

漏洞原理

好了,有了以上的基础,再来理解这个漏洞就很容易了。

假如某一个Java程序中,将浏览器的类型记录到了日志中:

String userAgent = request.getHeader("User-Agent");
logger.info(userAgent);

网络安全中有一个准则:不要信任用户输入的任何信息

这其中,User-Agent就属于外界输入的信息,而不是自己程序里定义出来的。只要是外界输入的,就有可能存在恶意的内容。

假如有人发来了一个HTTP请求,他的User-Agent是这样一个字符串:

${jndi:ldap://127.0.0.1/exploit}

接下来,log4j2将会对这行要输出的字符串进行解析。

首先,它发现了字符串中有 ${},知道这个里面包裹的内容是要单独处理的。

进一步解析,发现是JNDI扩展内容。

再进一步解析,发现了是LDAP协议,LDAP服务器在127.0.0.1,要查找的key是exploit。

最后,调用具体负责LDAP的模块去请求对应的数据。

如果只是请求普通的数据,那也没什么,但问题就出在还可以请求Java对象!

Java对象一般只存在于内存中,但也可以通过序列化的方式将其存储到文件中,或者通过网络传输。

如果是自己定义的序列化方式也还好,但更危险的在于:JNDI还支持一个叫命名引用(Naming References)的方式,可以通过远程下载一个class文件,然后下载后加载起来构建对象。

PS:有时候Java对象比较大,直接通过LDAP这些存储不方便,就整了个类似于二次跳转的意思,不直接返回对象内容,而是告诉你对象在哪个class里,让你去那里找。

注意,这里就是核心问题了:JNDI可以远程下载class文件来构建对象!!!

危险在哪里?

如果远程下载的URL指向的是一个黑客的服务器,并且下载的class文件里面藏有恶意代码,那不就完犊子了吗?

还没看懂?没关系,我画了一张图:

eb7025d73f96445fbc677e1abdb68392.png

这就是鼎鼎大名的JNDI注入攻击!

其实除了LDAP,还有RMI的方式,有兴趣的可以了解下。

JNDI 注入

其实这种攻击手法不是这一次出现了,早在2016的blackhat大会上,就有大佬披露了这种攻击方式。

0da8a391d4038916aa63df61c51fe3e2.png

回过头来看,问题的核心在于:

Java允许通过JNDI远程去下载一个class文件来加载对象,如果这个远程地址是自己的服务器,那还好说,如果是可以被外界来指定的地址,那就要出大问题!

前面的例子中,一直用的127.0.0.1来代替LDAP服务器地址,那如果输入的User-Agent字符串中不是这个地址,而是一个恶意服务器地址呢?

影响规模

这一次漏洞的影响面之所以如此之大,主要还是log4j2的使用面实在是太广了。

一方面现在Java技术栈在Web、后端开发、大数据等领域应用非常广泛,国内除了阿里巴巴、京东、美团等一大片以Java为主要技术栈的公司外,还有多如牛毛的中小企业选择Java。

另一方面,还有好多像kafka、elasticsearch、flink这样的大量中间件都是用Java语言开发的。

在上面这些开发过程中,大量使用了log4j2作为日志输出。只要一个不留神,输出的日志有外部输入混进来,那直接就是远程代码执行RCE,灭顶之灾!

修复

新版的log4j2已经修复了这个问题,大家赶紧升级。

下面是log4j2官网中关于JNDI lookup的说明:

24184cca8f3a8c61eacd6e8710234d9d.png


我通过搜索引擎找到了缓存的12月10号前的快照,大家对比一下,比起下面这个缓存,上面那一版多了哪些东西?

995154047d81c972eba2c23b4f38d7c5.png


答案是:修复后的log4j2在JNDI lookup中增加了很多的限制:

  1. 默认不再支持二次跳转(也就是命名引用)的方式获取对象

  2. 只有在log4j2.allowedLdapClasses列表中指定的class才能获取。

  3. 只有远程地址是本地地址或者在log4j2.allowedLdapHosts列表中指定的地址才能获取

以上几道限制,算是彻底封锁了通过打印日志去远程加载class的这条路了。

最后,手机前的各位Java小伙伴儿们,你们写的程序中有用到log4j2吗,有没有某个地方的输出,有外部的参数混进来呢?

赶紧检查检查哦!

8b7ba6c467b7c991e7d0927172d89e67.gif

f8c2a1b359ba7a4e6659db1334143764.png

往期推荐

虚幻引擎5上的《黑客帝国》全新体验,爱了爱了

Web兴起3.0之际,元宇宙这杯羹怎么分?

Redis会遇到的坑,你踩过几个?

通盘无妙手,恒生电子落子Light云

5edba2a1f6d4f9f4ce71f9aa0afc8dc6.gif

点分享

357cde435265f9123b9e39582ddf50a9.gif

点收藏

688578485c5662d2527473b44faa4dc5.gif

点点赞

fd885b007f238e068fd9d474deb3e2e3.gif

点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512835.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外部工具连接SaaS模式云数据仓库MaxCompute实战——商业BI分析工具篇

简介: MaxCompute 是面向分析的企业级 SaaS 模式云数据仓库,以 Serverless 架构提供快速、全托管的在线数据仓库服务,消除了传统数据平台在资源扩展性和弹性方面的限制,最小化用户运维投入,帮助企业和大数据开发者经济…

java api csdn_java api函数读出当前机器名以及版本号 csdn

展开全部参考一下:import java.util.*;public class YourJavaProperties {public static void main(String args[]){Properties propsSystem.getProperties();System.out.println("Java的运行环境版本:"props.getProperty("java.version&…

挑战程序设计竞赛_我系首次参加第六届中国大学生程序设计竞赛网络预选赛

点击上方蓝字关注 「龙外信息工程系」讲述有温度的故事 传递有态度的思想2020年9月20日12时至17时,第六届中国大学生程序设计竞赛网络赛预选赛在杭州电子科技大学OJ成功举办,黑龙江外国语学院(信息工程系)参赛队与来自清华大学、上海交通大学、复旦大…

如何用阿里云实行全链路数据追踪

简介: 阿里云采用了日志服务,帮助畅捷通构建了用户体验感知、业务安全合规、用户业务链路追踪、成本预算的使用场景,实现了对用户、业务、成本、安全等方面的全维度感知,使得运维效率提升了30%。 在日常生活中,遇到电…

谷歌能否赶上「元宇宙」这趟快车?

整理 | 禾木木出品 | CSDN云计算(ID:CSDNcloud)大多数人认为 Google Glass 只是领先于时代。虽然 Glass 不再出售给日常消费者(它仍然存在于企业版本中),但它在很多方面都是公众对混合现实体验的首次介绍。…

java join 源码_java并发:join源码分析

joinjoinjoin是Thread方法,它的作用是A线程中子线程B在运行之后调用了B.join(),A线程会阻塞直至B线程执行结束join源码(只有继承Thread类才能使用)基于openjdk1.8的源码public final void join() throws InterruptedException {join(0);}public final sy…

Flink on Zeppelin 流计算处理最佳实践

简介: 欢迎钉钉扫描文章底部二维码进入 EMR Studio 用户交流群 直接和讲师交流讨论~ 点击以下链接直接观看直播回放:https://developer.aliyun.com/live/247106 开源大数据社区 & 阿里云 EMR 系列直播 第十二期 主题:Flink on Zeppelin…

python windows自动化 爬虫_使用Python实现自动化截取Windows系统屏幕

文章首发于我的技术博客:你可以在上面看到更多的Python教程和python爬虫自动化截屏有什么用呢?为什么要实现自动化截屏呢?其实,在某些特殊的场景下,记录电脑使用者的操作还是很有必要的。比如,银行记录柜员…

储留香:一个智能运维系统就是一个中枢神经系统,我说的!

简介: 运维系统可以像神经系统一样,首先,做到数据的统一汇总;其次,可以对数据进行识别筛选输出有效信息;再次,可以预先感知到异常风险,并进行有效规避。而日志服务SLS凭借出色的数据…

携程发布2021第三季度财报:营收53亿元 国际国内旅游市场“攻守”同发力

2021年12月16日,携程集团(纳斯达克:TCOM及香港联交所:9961)发布截至2021年9月30日第三季度未经审计的财务业绩。第三季度实现营收53亿元,经调整EBITDA(税息折旧摊销前利润)为5.37亿元…

java线性表源代码_线性表java实现之顺序存储源码

源码:class SequenceList{private int size0;//表大小private int max_length;//表长private final int default_length 20;//默认长度private Object[] o;//初始化public SequenceList(){max_length default_length;o new Object[max_length];}public SequenceL…

云上资源编排的思与悟

简介: 在传统软件架构下,撇开业务层代码,都需要部署计算节点、存储资源、网络资源,然后安装、配置操作系统等。而云服务本质上是实现 IT 架构软件化和 IT 平台智能化,通过软件的形式定义这些硬件资源,充分抽…

不用网关或代理的单点远程办公如何实现,Aruba推出EdgeConnect Microbranch

Aruba日前宣布推出全新EdgeConnect Microbranch解决方案,针对混合办公环境的家庭办公室和小型办公室的网络解决方案,可供远程工作人员通过单个Wi-Fi接入点 (AP) ,安全地访问办公室内所有的传统办公服务,而无需在远程站点部署网关、…

阿里云力夺FewCLUE榜首!知识融入预训练+小样本学习的实战解析

简介: 7月8日,中文语言理解权威评测基准CLUE公开了中文小样本学习评测榜单最新结果,阿里云计算平台PAI团队携手达摩院智能对话与服务技术团队,在大模型和无参数限制模型双赛道总成绩第一名,决赛答辩总成绩第一名。 作…

java 线程 内存分配内存_漫谈JAVA语言的内存分配

在说JAVA语言的内存分配之前,我们先聊聊OS的Memory Management,这是学习操作系统课程的一个重要内容。从这里开始理解内存分配有利于理解的更深入。我们知道物理内存是由page 和segment 方式混合管理的,映射的过程如下图所示:从物…

【产品干货】经典营销模型的产品化介绍

简介: 为什么说Quick Audience是集数据资产构建、用户分析、精准营销投放、跨端社交互动和全域会员管理为一体的全域消费者运营平台,其中一个很大的原因是置入了经典营销模型,如RFM模型与AIPL模型,由方法论支撑消费者运营&#xf…

python 多线程 廖雪峰_python中多线程与多进程中的数据共享问题

之前在写多线程与多进程的时候,因为一般情况下都是各自完成各自的任务,各个子线程或者各个子进程之前并没有太多的联系,如果需要通信的话我会使用队列或者数据库来完成,但是最近我在写一些多线程与多进程的代码时,发现…

填平数据、产品、模式需求鸿沟,浪潮云发布新一代行业云 MEP战略

围绕安全这一核心,浪潮云从新模式(New Model)、新要素(New Essential Factor)、新产品(New Product)三大方面出发,提出新一代行业云MEP战略。 出品 | CSDN云计算 12月16日&#xff0…

hpsocket java代码_HPSocket介绍与使用

一、HPSocket介绍HP-Socket是一套通用的高性能TCP/UDP/HTTP 通信框架,包含服务端组件、客户端组件和Agent组件,广泛适用于各种不同应用场景的TCP/UDP/HTTP通信系统,提供C/C、C#、Delphi、E(易语言)、Java、Python等编程语言接口。HP-Socket对…

Dapr 在阿里云原生的实践

简介: Faas 场景下,比较吸引用户的是成本和研发效率,成本主要通过按需分配和极致的弹性效率来达成。而应用开发者期望通过 FaaS 提供多语言的编程环境,提升研发效率,包括启动时间、发布时间、开发的效率。​ 作者&…