昨日爆出的 Log4j 安全漏洞,业界一片哗然,极限实验室第一时间进行了跟进,对 Elasticsearch 的影响范围进行了分析,为大家提供如下应对策略。
【漏洞描述】
Apache Log4j 是一款非常流行的开源的用于 Java 运行环境的日志记录工具包,大量的Java 框架都使用了该组件,故影响范围非常之大。
近日, 随着 Apache Log4j 的远程代码执行最新漏洞细节被公开,攻击者可通过构造恶意请求利用该漏洞实现在目标服务器上执行任意代码。可导致服务器被黑客控制,从而进行页面篡改、数据窃取、挖矿、勒索等行为。建议使用该组件的用户第一时间启动应急响应进行修复。
简单总结一下就是,在使用 Log4j 打印输出的日志中,如果发现日志内容中包含关键词 ${,那么这个里面包含的内容会当做变量来进行替换和执行,导致攻击者可以通过恶意构造日志内容来让 Java 进程来执行任意命令,达到攻击的效果。
【漏洞等级】:非常紧急
此次漏洞是用于 Log4j2 提供的 lookup 功能造成的,该功能允许开发者通过一些协议去读取相应环境中的配置。但在实现的过程中,并未对输入进行严格的判断,从而造成漏洞的发生。
【影响范围】:Java 类产品:Apache Log4j 2.x < 2.15.0-rc2
可能的受影响应用及组件(包括但不限于)如下:
Apache Solr
Apache Flink
Apache Druid
Apache Struts2
srping-boot-strater-log4j2
Elasticsearch
flume
dubbo
Redis
logstash
kafka
更多组件可参考如下链接:
https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core/usages?p=1
不受影响版本:Apache log4j-2.15.0-rc2
【Elasticsearch 受影响范围】
Elasticsearch 的影响范围为全系列版本!!!包括最新的未发布 v8.0 版本.
【攻击检测】
1. 可以通过检查日志中是否存在 “jndi:ldap://”、“jndi:rmi” 等字符来发现可能的攻击行为。
攻击者在利用前通常采用dnslog方式进行扫描、探测,对于常见利用方式可通过应用系统报错日志中的"javax.naming.CommunicationException"、"javax.naming.NamingException: problem generating object using object factory"、"Error looking up JNDI resource"关键字进行排查。
2. 攻击者的数据包中可能存在:"${jndi:}" 字样,攻击代码举例如下:
【修复建议】
目前漏洞 POC 已被公开,官方已发布安全版本,建议使用 Java 开发语言的系统尽快确认是否使用 Apache Log4j 2 插件。禁止使用 log4j 服务器外连,升级 JDK 11.0.1 8u191 7u201 6u211 或更高版本。
请尽快升级 Apache Log4j2 所有相关应用到最新的 log4j-2.15.0-rc2 版本,地址: https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2
截止发稿为止还没有 2.15.0 正式版 jar 包可以下载,需要自己下载源文件来进行编译。
【Elasticsearch 漏洞复现】
在 Elasticsearch 里面通过构造特定查询,输出带攻击指令的日志,比如执行如下指令:
可以看到 Elasticsearch 的日志里面成功输出了我们的攻击日志!!!
关于进一步的漏洞利用,暂未展开,不建议生产环境上进行测试。
【紧急补救措施-1】
(1) 修改 JVM 参数 -Dlog4j2.formatMsgNoLookups=true
(2) 修改配置 log4j2.formatMsgNoLookups=True
(3) 将系统环境变量 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为 true
(4) 重启 Elasticsearch 节点
【紧急补救措施-2】
(1)将 Elasticsearch lib 目录下对应的log4j jar 包更新至最新的 2.15 版本。
(2) 重启 Elasticsearch 节点
【紧急补救措施-3】
如果 Elasticsearch 不能升级或者替换 Log4j 的 jar 包,可以使用极限网关、Nginx 等其他 API 网关来进行拦截或者参数替换甚至是直接阻断请求。通过在网关层对发往 Elasticsearch 的请求统一进行参数检测,将包含的敏感关键词 ${ 进行替换或者直接拒绝,可以防止带攻击的请求到达 Elasticsearch 服务端而被 Log4j 打印相关日志的时候执行恶意攻击命令,从而避免被攻击。
下面以极限实验室的数据网关产品:极限网关的使用为例来为大家介绍如何快速进行该漏洞的处置:
使用 context_filter 来进行关键字检测,过滤掉恶意流量,从而阻断攻击,过滤器文档地址:
https://极限网关.com/docs/references/filters/context_filter/
path.data: data
path.logs: log
entry:
- name: es_entrypoint
enabled: true
router: default
max_concurrency: 20000
network:
binding: 0.0.0.0:8000
router:
- name: default
default_flow: main_flow
flow:
- name: main_flow
filter:
- context_filter:
context: _ctx.request.path
message: "request not allowed."
action: redirect_flow
status: 403
flow: log4j_matched_flow
must_not: # any match will be filtered
contain:
- "${jndi:}"
- "${jndi:ldap:}"
- "${jndi:rmi:}"
- elasticsearch:
elasticsearch: es-server
- name: log4j_matched_flow
filter:
- echo:
message: 'Apache Log4j 2, Boom!'
elasticsearch:
- name: es-server
enabled: true
endpoints:
- http://localhost:9200
上面的示例只判断了path,其他如body类似,通过拦截关键字,可以将流量路由到额外的分支,还可以是记录告警或者直接拒绝。
重新测试前面的攻击语句,得到效果如下:
完美阻断!
关于极限网关的基础安装和配置,这里不详细展开,大家可以前往网关的网站查看:
https://极限网关.com
安全无小事,大家尽快处理吧!