使用极限网关来处置 Elasticsearch 的 Apache Log4j 漏洞 [转载]

一.查看elasticsearch对应log4j版本
cd /opt/elasticsearch-7.8.1/lib
ll

在这里插入图片描述

二.修复
vim config/jvm.options
-Dlog4j2.formatMsgNoLookups=true

昨日爆出的 Log4j 安全漏洞,业界一片哗然,今天给大家介绍一下,如何使用极限网关来快速处置 Elasticsearch 的 Apache Log4j 漏洞。

【CVE 地址】

https://github.com/advisories/GHSA-jfh8-c2jp-5v3q

【漏洞描述】

Apache Log4j 是一款非常流行的开源的用于 Java 运行环境的日志记录工具包,大量的 Java 框架包括 Elasticsearch 的最新版本都使用了该组件,故影响范围非常之大。

近日, 随着 Apache Log4j 的远程代码执行最新漏洞细节被公开,攻击者可通过构造恶意请求利用该漏洞实现在目标服务器上执行任意代码。可导致服务器被黑客控制,从而进行页面篡改、数据窃取、挖矿、勒索等行为。建议使用该组件的用户第一时间启动应急响应进行修复。

简单总结一下就是,在使用 Log4j 打印输出的日志中,如果发现日志内容中包含关键词 ${,那么这个里面包含的内容会当做变量来进行替换和执行,导致攻击者可以通过恶意构造日志内容来让 Java 进程来执行任意命令,达到攻击的效果。

【漏洞等级】:非常紧急

此次漏洞是用于 Log4j2 提供的 lookup 功能造成的,该功能允许开发者通过一些协议去读取相应环境中的配置。但在实现的过程中,并未对输入进行严格的判断,从而造成漏洞的发生。

【影响范围】:Java 类产品:Apache Log4j 2.x < 2.15.0-rc2,Elasticsearch 当前所有版本。

【攻击检测】

可以通过检查日志中是否存在 jndi:ldap://、jndi:rmi 等字符来发现可能的攻击行为。

处理办法
最简单的办法是通过修改 config/jvm.options,新增以下参数,重启集群所有节点即可。

-Dlog4j2.formatMsgNoLookups=true
不过,如果集群规模较大,数据较多,业务不能中断,不能通过修改 Elasticsearch 配置、或者替换 Log4j 的最新 jar 包来重启集群的情况,可以考虑使用极限网关来进行拦截或者参数替换甚至是直接阻断请求。

通过在网关层对发往 Elasticsearch 的请求统一进行参数检测,将包含的敏感关键词 ${ 进行替换或者直接拒绝, 可以防止带攻击的请求到达 Elasticsearch 服务端而被 Log4j 打印相关日志的时候执行恶意攻击命令,从而避免被攻击。

极限网关是透明代理,只需要在应用端,将以往配置指向 Elasticsearch 的地址替换为现在网关的地址即可,其他都不用动。

参考配置
下载最新的 1.5.0-SNAPSHOT 版本http://release.elasticsearch.cn/gateway/snapshot/

使用极限网关的 context_filter 过滤器,对请求上下文 _ctx.request.to_string 进行关键字检测,过滤掉恶意流量,从而阻断攻击。

新增一个配置文件 gateway.yml

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.to_string
      action: redirect_flow
      status: 403
      flow: log4j_matched_flow
      must_not: # any match will be filtered
      regex:
      - ${.?}
      - "%24%7B.
      ?%7D" #urlencode
      contain:
      - “jndi:”
      - “jndi:ldap:”
      - “jndi:rmi:”
      - “jndi%3A” #urlencode
      - “jndi%3Aldap%3A” #urlencode
      - “jndi%3Armi%3A” #urlencode
    • 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
      启动网关:

➜ ./bin/gateway -config /tmp/gateway.yml


/ _ \ /\ /__ /__/ / /\ \ /\ /_/
/ ////\ / //\ \ / / //\_ /
/ /
\/ _ / / //__ \ /\ / _ / \
___/_/ _// _/ / /_/ _/_/

[GATEWAY] A light-weight, powerful and high-performance elasticsearch gateway.
[GATEWAY] 1.0.0_SNAPSHOT, 2021-12-10 23:55:34, 2212aff
[12-11 01:55:49] [INF] [app.go:250] initializing gateway.
[12-11 01:55:49] [INF] [instance.go:26] workspace: /Users/medcl/go/src/infini.sh/gateway/data/gateway/nodes/0
[12-11 01:55:49] [INF] [api.go:261] api listen at: http://0.0.0.0:2900
[12-11 01:55:49] [INF] [reverseproxy.go:253] elasticsearch [es-server] hosts: [] => [localhost:9200]
[12-11 01:55:49] [INF] [entry.go:296] entry [es_entrypoint] listen at: http://0.0.0.0:8000
[12-11 01:55:49] [INF] [module.go:116] all modules started
[12-11 01:55:49] [INF] [app.go:357] gateway is running now.
[12-11 01:55:49] [INF] [actions.go:236] elasticsearch [es-server] is available
将要使用的测试命令 ${java:os} 使用 urlencode 转码为 %24%7Bjava%3Aos%7D,构造查询语句,分别测试。

不走网关:

~% curl ‘http://localhost:9200/index1/_search?q=%24%7Bjava%3Aos%7D’
{“error”:{“root_cause”:[{“type”:“index_not_found_exception”,“reason”:“no such index”,“resource.type”:“index_or_alias”,“resource.id”:“index1”,“index_uuid”:“na”,“index”:“index1”}],“type”:“index_not_found_exception”,“reason”:“no such index”,“resource.type”:“index_or_alias”,“resource.id”:“index1”,“index_uuid”:“na”,“index”:“index1”},“status”:404}%
查看 Elasticsearch 端日志为:

[2021-12-11T01:49:50,303][DEBUG][r.suppressed ] path: /index1/_search, params: {q=Mac OS X 10.13.4 unknown, architecture: x86_64-64, index=index1}
org.elasticsearch.index.IndexNotFoundException: no such index
at org.elasticsearch.cluster.metadata.IndexNameExpressionResolver W i l d c a r d E x p r e s s i o n R e s o l v e r . i n f e ( I n d e x N a m e E x p r e s s i o n R e s o l v e r . j a v a : 678 )   [ e l a s t i c s e a r c h − 5.6.15. j a r : 5.6.15 ] a t o r g . e l a s t i c s e a r c h . c l u s t e r . m e t a d a t a . I n d e x N a m e E x p r e s s i o n R e s o l v e r WildcardExpressionResolver.infe(IndexNameExpressionResolver.java:678) ~[elasticsearch-5.6.15.jar:5.6.15] at org.elasticsearch.cluster.metadata.IndexNameExpressionResolver WildcardExpressionResolver.infe(IndexNameExpressionResolver.java:678) [elasticsearch5.6.15.jar:5.6.15]atorg.elasticsearch.cluster.metadata.IndexNameExpressionResolverWildcardExpressionResolver.innerResolve(IndexNameExpressionResolver.java:632) ~[elasticsearch-5.6.15.jar:5.6.15]
at org.elasticsearch.cluster.metadata.IndexNameExpressionResolver W i l d c a r d E x p r e s s i o n R e s o l v e r . r e s o l v e ( I n d e x N a m e E x p r e s s i o n R e s o l v e r . j a v a : 580 )   [ e l a s t i c s e a r c h − 5.6.15. j a r : 5.6.15 ] 可 以 看 到 查 询 条 件 里 面 的 q = WildcardExpressionResolver.resolve(IndexNameExpressionResolver.java:580) ~[elasticsearch-5.6.15.jar:5.6.15] 可以看到查询条件里面的 q= WildcardExpressionResolver.resolve(IndexNameExpressionResolver.java:580) [elasticsearch5.6.15.jar:5.6.15]q={java:os} 被执行了,变成了 q=Mac OS X 10.13.4 unknown, architecture: x86_64-64, index=index1,说明变量被解析且执行,存在漏洞利用的风险。

那走网关之后呢:

~% curl ‘http://localhost:8000/index1/_search?q=%24%7Bjava%3Aos%7D’

Apache Log4j 2, Boom!%
可以看到请求被过滤掉了,返回了自定义的信息。

还有一些其他测试命令,大家也可以试试:

#{java:vm}
~% curl ‘http://localhost:9200/index/_search?q=%24%7Bjava%3Avm%7D’
[2021-12-11T02:36:04,764][DEBUG][r.suppressed ] [INFINI-2.local] path: /index/_search, params: {q=OpenJDK 64-Bit Server VM (build 25.72-b15, mixed mode), index=index}

~% curl ‘http://localhost:8000/index/_search?q=%24%7Bjava%3Avm%7D’
Apache Log4j 2, Boom!%

#{jndi:rmi://localhost:1099/api}
~% curl ‘http://localhost:9200/index/_search?q=%24%7Bjndi%3Armi%3A%2F%2Flocalhost%3A1099%2Fapi%7D’
2021-12-11 03:35:06,493 elasticsearch[YOmFJsW][search][T#3] ERROR An exception occurred processing Appender console java.lang.SecurityException: attempt to add a Permission to a readonly Permissions object

~% curl ‘http://localhost:8000/index/_search?q=%24%7Bjndi%3Armi%3A%2F%2Flocalhost%3A1099%2Fapi%7D’
Apache Log4j 2, Boom!%
另外不同版本的 Elasticsearch 对于攻击的复现程度参差不齐,因为 es 不同版本是否有 Java Security Manager 、不同版本 JDK 、以及默认配置也不相同,新一点的 es 其实同样可以触发恶意请求,只不过网络调用被默认的网络策略给拒绝了,相对安全,当然如果设置不当同样存在风险,见过很多用户一上来就关默认安全配置的,甚至还放开很多暂时用不上的权限,另外未知的攻击方式也一定有,比如大量日志产生的系统调用可能会拖垮机器造成服务不可用,所以要么还是尽快改配置换 log4j 包重启集群,或者走网关来过滤阻断请求吧。

使用极限网关处置类似安全事件的好处是,Elasticsearch 服务器不用做任何变动,尤其是大规模集群的场景,可以节省大量的工作,提升效率,非常灵活,缩短安全处置的时间,降低企业风险。

参考:https://elasticsearch.cn/article/14444

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值