The Google-born GoLang is widely used for many cloud-native operations in production such as Google Cloud and Amazon Web Servers. As such, one must ensure that there’s no vulnerability left open in the application’s codebase for exploitation. Since a large chunk of these project components is often reused in different products across an organization, even a single vulnerability in any element can compromise potentially any app on the infrastructure. That's why we need to constantly monitor these microservice applications and block access whenever the packages exhibit malicious behavior.
This blog will explore a common vulnerability called unsafe pointer and mitigate it. To know more about the CVE, check out the following link
About the Vulnerability
This vulnerability revolves around creating a buffer overflow which we can later leverage to inject arbitrary code and spawn a shell in the host machine. We shall be using a bunch of exploit files here.
The exploit file runs the program and supplies a carefully crafted input to overwrite the stack. The stored return address is a series of ROP gadgets (small fragments of assembly code that end with a return instruction). Thus, chaining the gadgets is as simple as concatenating their addresses.
Defenders have multiple options when trying to mitigate vulnerabilities. Each must be balanced with severity of impact and risk to the business, time and complexity, cost, and risk of potential unintended impacts.
- Apply additional security controls. But where/how? This requires considerable evaluation
- Do nothing & Accept the risk
Accuknox Run-time Security With KubeArmor
AccuKnox enables effective, efficient mitigation for any runtime security threat. This is what we’ll walk through below.
We will see how we can protect ourselves using KubeArmor. If we look into the exploit payload, it uses the mprotect syscall to mark a memory region as rwx, then the read syscall to write data to that memory region. It supplies assembly code that spawns a shell using the system syscall to the read syscall and finally jumps to the memory region. The mprotect call prevents DEP, and because Go binaries are statically linked to a rather large binary that contains lots of ROP gadgets, ASLR is not adequate.
So, let us now see an overview of the testing environment and the exploit codes. In our case, we use one python and GoLang exploit script. We will be deploying the ubuntu pod and executing the application and the exploit scripts in our scenario.
In the python script [exploit_rop.py], we use convenient functions that can be used from pwntools to run the exploit file efficiently. So the first half of the code contains the syscall instruction, addresses, and values. So all these inputs will execute memory pages with read-write execute permissions. The second half of the program is about the shellcode. Here we will create the registers; the shellcode contains the bytes assembly program that spawns the shell access.
Let’s deploy the application in the Ubuntu pod now.
Deployment File in YAML:
We will clone a vulnerable Go code to demonstrate the attack and get inside the golang-code-injection directory.
Before we start the application, we need to install the following prerequisites:
Enough with the explanation, let us now fire up the application and dive straight into the interesting part. Simply copy and paste the following commands in your terminal:
As we see above, our exploit script has successfully spawned up a shell.
Therefore, let’s patch this vulnerability now by applying a policy and blocking access to the dependencies used in our exploit files, and we can mitigate it.
Here’s the code snippet for the exploit we have used here:
Below is the sample policy we are going to apply using KubeArmor.
KubeArmor Security Policy:
This policy can further be enhanced to match configMaps or ingress with certain labels. If your organization policy requires labels for each application you deploy, you can update this policy to match the resources with certain labels that can be read about here.
Copy and paste the following commands into your terminal:
Run the application now.
Now, after applying the policy, we see that the dependencies used to run the application have been blocked. Thus we have completely mitigated the vulnerability.
Protecting against a broader range of attacks with MITRE policies
There are many ways an attacker could compromise the organisation.
The Mitre attack model show’s adversarial behaviour into matrices to show relations between different tactics and techniques used by attackers.
Organizations can use the mitre policy from our KubeArmor open source. We provide a wide range of system, host, and cilium-based policies.
To check more, visit the following Link
Generating a zero-trust profile with Auto Policy Generation Tool.
The auto policy tool will generate system and host-based policies. Let us see how we can install and view the generated policy.
Step 1: we will install the Daemonsets and Services. Just copy and paste the following in your terminal
Step2: We have already deployed the application. So now we can able to get the auto-discovery policy. Just copy and paste the following in your terminal.
You can see 31 policies have been generated by AccuKnox open-source auto policy generation tool. This will generate the policy according to the workloads you are running. You can able to view the file in your terminal.
In a perfect world, applications would never have such unsafe pointers in their backend. But in real-life scenarios, it’s very challenging to determine which variables/pointers your application is using in what way. Lets ensure that the codebase is entirely secure.
KubeArmor Slack: Join the KubeArmor community on Slack!
Now you can protect your workloads in minutes using AccuKnox, it is available to protect your Kubernetes and other cloud workloads using Kernel Native Primitives such as AppArmor, SELinux, and eBPF.
Let us know if you are seeking additional guidance in planning your cloud security program.