Log4Shell - identify vulnerable external-facing workloads in AWS

Last week, we all heard about the new Log4j vulnerability (CVE-2021-44228), and how it can easily be used for Remote Code Execution due to a misconfigured library. Now there's a new Log4j vulnerability, CVE-2021-45046 in the updated version. While most companies spent the past weekend searching for the existence of the library in their systems, the cloud-based systems should also be thoroughly searched. But this is a daunting task, since you need to search each and every compute instance, from the biggest EC2 instance to the smallest Lambda function. This is where we can come in to help.

In this short tutorial, we are going to provide DevOps and security teams with a quick recipe to identify cloud workloads that may be vulnerable to the Log4j vulnerability in their AWS account. The recipe enables security teams to identify external-facing AWS assets by running the exploit on them, and thus be able to map them and quickly patch them.

Remember, while a full remediation plan should map the full spectrum of cloud workloads that use the Log4j library and then prioritize and patch them, this tutorial takes a lean and mean approach that could be used as a first measure.

The following tutorial:

  • Only requires specific IAM actions
  • Does not require additional deployments or resource creation
  • Does not rely on visibility or understanding of business logic

Instead of theoretical scenarios, this approach actually tries to find accessible vulnerable assets and then exploit them! 😎

Step 1: Compile a list of external-facing assets and URLs

Prerequisites

Verify that you have all the following actions assigned to your IAM principal:

  • ec2:DescribeInstances
  • ec2:DescribeSecurityGroups
  • elasticloadbalancing:DescribeLoadBalancers
  • elasticloadbalancing:DescribeListeners
  • elasticloadbalancing:DescribeRules
  • elasticloadbalancing:DescribeTargetGroupAttributes
  • elasticloadbalancing:DescribeTargetGroups

Compiling a list of URLs served from EC2 instances

Compile a list of all the EC2 instances using the filter of EC2 instances that are associated with public IP address using the following API: DescribeInstances - Amazon Elastic Compute Cloud

Note: By checking the security groups attached to the EC2 instances, you can learn which ports to use to connect to the EC2 instance: DescribeSecurityGroups - Amazon Elastic Compute Cloud

Consider an EC2 instance that is associated with the public IP address x.y.z.r,  a security group for that EC2 instance, and an ingress rule: FromPort: 8888, CidrIp: 0.0.0.0/0. The final URL addresses to check are “http://x.y.z.r:8888/“ and “https://x.y.z.r:8888/“

Here is a link to snippet code that collects EC2 instances URL addresses, which is a part of a bigger project that will be published later:

https://github.com/mitiga/Log4Shell-snippet/blob/main/snippet_get_ec2_urls.py

Compiling a list of URLs accessible from AWS load balancers

AWS uses four types of load balancers:

  • Network Load Balancer (NLB)
  • Application Load Balancer (ALB)
  • Gateway Load Balancer (Not covered in this tutorial)
  • Classic Load balancer (Not covered in this tutorial)

You can list all of your load balancers (DescribeLoadBalancers - Elastic Load Balancing).

For every load balancer, check that its schema is “public facing” and the security group used contains an ingress security group with CidrIp: 0.0.0.0/0.

For Network Load Balancer, compiling the list is the same as with EC2 instances. You need to compile the Public DNS name and the port used in each listener.

Consider a network load balancer that is public facing with the domain: 'test.elb.us-east-1.amazonaws.com' with the port: 8888. The URL addresses we attempt to exploit are “https://test.elb.us-east-1.amazonaws.com:8888/“ and “http://test.elb.us-east-1.amazonaws.com:8888/“.

Finding valid URL addresses in ALB can be tricky. ALB can create multiple HTTP Listeners (DescribeListeners - Elastic Load Balancing) with rules (DescribeRules - Elastic Load Balancing) that, for example, depend on a request header or a URI to target a different resource.

For example, you can create an ALB listener with a header condition rule: "User-Agent"="*Safari*" that sends the request to an EC2 instance and another listener with a host condition rule that supports sub-domains (such as “subdomain.test.elb.us-east-1.amazonaws.com”) to send the request to a different EC2 instance. Without matching the rules, we can miss important URL addresses that are open to the internet.

For ALB, it is also important to check ‘Conditions’ of the listeners. The following link contains a full list of rule condition types: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html#rule-condition-types

Step 2: Install and configure an attack proxy

In this step, we install the attack proxy that simulates the exploit. When the exploit is successfully executed, the victim machine initiates a connection to an endpoint of our choice.

In order to perform “Out-of-Band“ testing, you can:

Interactsh-client
  • Execution of interactsh  provides a URL that the vulnerable endpoint initiate is connected to

Step 3: Document the URLs

We recommend saving the resource identifiers for each URL, so later you can match which resource is vulnerable and update the security team in your company about the execution of the POC.

Step 4: Execute the exploit Proof-of-Concept

Here's our open source project that you can use to identify cloud workloads that may be vulnerable to the Log4j vulnerability (Log4Shell) in your AWS account.

Step 5: Examine all the responses

When the exploit is successful, you should see the connection initiation of the vulnerable endpoints in the selected proxy tools/servers. By matching the URL address with the resource id in step 2, you can assume that the resource may be vulnerable.

Interactsh client: Example of connection initiation from a vulnerable endpoint
Example of connection initiation from a vulnerable endpoint

After performing the recipe, you should update the security teams on all the endpoints that were discovered and patch them.

This vulnerability and many others like it show that our system may always contain breaches that we are not even aware of. This is why we need to consider that we might always be breached and be prepared for it. Last year, Mitiga launched IR², an incident readiness and response solution that prepares organizations to deal with the inevitable.

Disclaimer

This blog is for educational purposes and does not replace a consultation and the creation of a client-tailored approach by a Mitiga security professional, which considers the client specific circumstances, including the client technology, environments, architecture, and other factors. The  information provided in the blog is of the date of the post and may be updated as more information becomes available.

* Originally published 12/13/2021, updated 12/17/2021 to indicate that we now support detecting endpoints that are vulnerable to CVE-2021-45046, which was reclassified from DoS to RCE.

Don't miss these stories: