---
title: "Detect malicious activity and protect your containerized workloads in Amazon EKS or AWS"
source: "https://www.tigera.io/blog/detect-malicious-activity-and-protect-your-containerized-workloads-in-amazon-eks-or-aws/"
description: "In this blog, we will go through a scenario where an attacker compromises a public-facing application and gains a foothold in the network of an application."
---

[Technical Blog](https://www.tigera.io/category/technical-blog/)

# Detect malicious activity and protect your containerized workloads in Amazon EKS or AWS

By [Ivan Sharamok](https://www.tigera.io/blog/author/ivan/) on May 16, 2023 • 14 min read

As containerized applications become increasingly complex, it can be challenging to design and execute an effective container security strategy. With the growing trend towards cloud-based applications and services, cyber criminals are also evolving their attack techniques, making container security solutions more critical than ever. Calico provides robust detection capabilities to detect known and zero-day container and network-based attacks. In this blog, we will look at Calico’s capabilities to detect network-based attacks.

Calico offers comprehensive protection against both known and zero-day network-based attacks. Using a combination of workload-based IDS/IPS, Calio can detect and block connections to known malicious IPs identified with AlienVault and custom threat intelligence feeds. Calico also uses heuristics-based learning to identify anomalous network activity and prevent zero-day attacks. To further protect against OWASP Top 10 attacks, Calico provides a web application firewall (WAF) that can intercept attacks and prevent them from reaching your applications. Additionally, Calico can also block requests from malicious IPs to prevent DDoS attacks from overwhelming your system.

## Malicious attack on cloud-native application and how to prevent it

In this blog, we will go through a scenario where an attacker compromises a public-facing application and gains a foothold in the AWS EC2 or EKS network of this application. Then he goes on to find his next target within the Kubernetes cluster, moving laterally to further his attack campaign. In parallel, let’s leverage Globalthreats with Calico on AWS and EKS to detect these malicious activities at each stage.

Our front-end website is using the Drupal application running on Drupal-pod in the default namespace, on port 80. And Webmin service is running under namespace ‘crown-space’ which is not exposed to the internet. Webmin controls and monitors server resources and is accessible on port 10000.

 

 

![Diagram of Drupal and Webmin services. Drupal runs on Drupal-pod in the default namespace, port 80. Webmin runs in](https://www.tigera.io/app/uploads/2023/05/image2-3.png)Figure 1: Diagram of the demo application stack

Step 1: Configure the Global Alerts around these critical apps to monitor these resources automatically. You can uncover an attacker’s behavior by observing the following:

Lateral movement attempt from Drupal-pod

- Any connection originating from Drupal-pod to internal network apart from approved flows

- Any connection made to Drupal-pod apart from its service port 80

Lateral movement attempt to Webmin-pod

- Any connection made to Webmin-pod apart from its service port 10000

- Any connection originating from webmin-pod apart from the approved flow

Threat feeds

- Monitor any connection made to suspicious IP or domains from the Kubernetes cluster

- The attacker or one of his pivoting tools may end up talking to suspicious IP or domain

Cloud metadata API requests from crown-space and default namespace

- To detect user-made cloud metadata API requests which are unusual in a Kubernetes pod

Step 2: You can apply the following manifests as you deploy the application (Figure 1) to protect for above observations

![Example "mysite" Drupal application, illustrating a default, unprotected state before applying manifests](https://www.tigera.io/app/uploads/2023/05/image12.jpg)Figure 2: Deployed application

## Lateral movement attempt from Drupal-pod

Let’s look at a front-end application on the cloud. The public drupal site is accessible on port 80 and serves the webpage in Figure 2.

![Diagram of the Drupal service on the cloud, showing ingress to Drupal service to pods, and connection to backend](https://www.tigera.io/app/uploads/2023/05/image9.png)Figure 3: Drupal site accessible on port 80

To find the version of Drupal, let’s connect to the site to look at HTTP headers. The banner grab, in Figure 4 indicates the installation is Drupal 8.

![HTTP headers showing "X-Generator: Drupal 8" indicating the site runs Drupal 8](https://www.tigera.io/app/uploads/2023/05/image14.jpg)

Drupal 8 has a ‘Form property injection’ vulnerability, i.e. CVE-2018-7600, and has an exploit module with metasploit ‘unix/webapp/drupal_drupalgeddon2’.

The exploit targets the Drupal form fields API. Unvalidated form fields on the page are used to inject malicious array into the form API so that drupal AJAX callback renders array by executing it.

By running the metasploit exploit on the Drupal server, you can see a reverse shell is spawned exploiting the vulnerability successfully on port 4444 in Figure 5.

 

![Metasploit's Drupalgeddon2 module exploits Drupal 8's form API vulnerability (CVE-2018-7600), showing a successful](https://www.tigera.io/app/uploads/2023/05/image1-4.png)

You will notice that a Drupal daemon process is running as non-root but backdooring tools like netcat and kubectl binaries can be copied on Drupal-pod as seen in Figure 6.

![Drupal-pod showing netcat binary copied and chmodded to 777, owned by www-data user](https://www.tigera.io/app/uploads/2023/05/image11.png)

![Terminal output showing shell access with user ID 'www-data](https://www.tigera.io/app/uploads/2023/05/image15.jpg)

 

```
`./kubectl auth can-i --list Resources Non-Resource URLs Resource Names Verbs globalnetworkpolicies.projectcalico.org [] [] [*] networkpolicies.projectcalico.org [] [] [*] stagedglobalnetworkpolicies.projectcalico.org [] [] [*] stagednetworkpolicies.projectcalico.org [] [] [*] selfsubjectaccessreviews.authorization.k8s.io [] [] [create] selfsubjectrulesreviews.authorization.k8s.io [] [] [create] [/api/*] [] [get] [/api] [] [get] [/apis/*] [] [get] [/apis] [] [get] [/healthz] [] [get] [/openapi/*] [] [get] [/openapi] [] [get] [/swagger-2.0.0.pb-v1] [] [get] [/swagger.json] [] [get] [/swaggerapi/*] [] [get] [/swaggerapi] [] [get] [/version/] [] [get] [/version] [] [get]`
```

There are three ways to proceed:

- Try to get root privileges at drupal-pod (which is not always possible) or

- Abuse service token in this case as it doesn’t have special privileges

- Find another target within the cluster and move laterally to gain greater privileges. - We will see the later part of the attack in the next section.

### Detection and Prevention

Use following yaml to do following:

- Check if there are any connections originating from Drupal-pod

- Whitelist any approved flow

- Add approved flows with ‘NOT’ operator in query

**Manifest 1**

```
`apiVersion: projectcalico.org/v3 kind: GlobalAlert metadata: name: global.lateral.from-drupal spec: description: "Lateral movement detected: Outgoing Connection from Drupal" summary: "[flows] [lateral movement] ${source_namespace}/${source_name_aggr} with label app=drupal initiated connection" severity: 100 period: 10m lookback: 10m dataSet: flows query: '"source_labels.labels"="app=drupal" AND proto="tcp" AND action="allow" AND reporter="src"' aggregateBy: [source_namespace, source_name_aggr] field: num_flows metric: sum condition: gt threshold: 0`
```

### Results

As soon as your felix interval is finished, you will see an alert with details of the reverse connection from drupal (Figure 7). You can take following steps:

- Use these details to track the flow in Elasticsearch and traffic at that time

- Observe the global.lateral.from-drupal alert being triggered

- Notify the incident response team to investigate and uncover the compromise

![Screenshot of Elasticsearch showing "global.lateral.from-drupal" alert with details of an outgoing connection from Webmin](https://www.tigera.io/app/uploads/2023/05/image19.jpg)

Example **Manifest1** after adjusting for allowed connections where “app: drupal-mysql” is a label on :

```
`apiVersion: projectcalico.org/v3 kind: GlobalAlert metadata: name: global.lateral.from-drupal spec: description: "Lateral movement detected: Outgoing Connection from Drupal" summary: "[flows] [lateral movement] ${source_namespace}/${source_name_aggr} with label app=drupal initiated connection" severity: 100 period: 10m lookback: 10m dataSet: flows query: '"source_labels.labels"="app=drupal" AND proto="tcp" AND action="allow" AND reporter="src" AND "dest_labels.labels"!="app=drupal-mysql"' aggregateBy: [source_namespace, source_name_aggr] field: num_flows metric: sum condition: gt threshold: 0`
```

## Lateral movement attempt to Webmin-pod:

Once an attacker has control of the Drupal pod, with the lack of privilege and access, they will look into other exposed resources that are reachable from this pod. By enumerating the network, you can see there is a Webmin application running on port 10000 in Figure 8.

![Diagram showing a compromised Drupal pod reaching out to a Webmin service and the Kubernetes API server](https://www.tigera.io/app/uploads/2023/05/image6.png)Figure 8: Webmin application running on port 10000

Now, the HTTP banner grab confirms MiniServ 1.910 is running. The attacker now has an interesting target as this version of MiniServ is backdoored which is identified by CVE-2019-15107.

**Side Note**: The backdoor was hidden for over a year and eventually discovered. The exploit targets the password change function where ‘old password’ is executed as a command. Metasploit has a module linux/http/webmin_backdoor which exploits this vulnerability.

![HTTP request and response to Webmin on port 5000, showing authentication is required. Illustrates a lateral movement attempt](https://www.tigera.io/app/uploads/2023/05/image5-1.png)

![HTTP request and response to Webmin on port 5000, showing authentication is required. Illustrates a lateral movement attempt](https://www.tigera.io/app/uploads/2023/05/image5-1.png) ![Terminal output showing a self-signed SSL certificate from a Webmin Webserver](https://www.tigera.io/app/uploads/2023/05/image4-2.png)

Now, to reach the Webmin application from the attacker machine, the compromised Drupal-pod can be used as a network relay. The following command will create a relay between the attacker and Drupal-pod so that the attacker’s requests will be forwarded to the Webmin application.

![Screenshot showing the attacker using port forwarding to relay requests to the Webmin application](https://www.tigera.io/app/uploads/2023/05/image16.png)

The attacker can reach the Webmin application by making requests to port 5000 locally from his machine as follows.

attacker#`curl -kv https://127.0.0.1:5000`

![Webmin login screen at 127.0.0.1:5000, likely accessed via curl -kv, requiring username and password](https://www.tigera.io/app/uploads/2023/05/image13.jpg)

Now an exploit to Webmin through Drupal-pod can be sent and listen for the reverse shell on Drupal-pod on port 2222. Why? There is no way for the Webmin-application to talk to the attacker directly as it’s an internal app and this is categorized as East-West traffic.

Let’s set the metasploit variables RHOST as 127.0.0.0 and RPORT as 5000 (relay to Webmin-application) and LHOST as Drupal-pod IP on attacker metasploit.

 

And on Drupal-pod, listen on port 2222 with the copied netcat binary.

![Terminal output showing successful netcat listener setup on port 2222 after Drupal exploit](https://www.tigera.io/app/uploads/2023/05/image8.png)

Note that the handler fails to bind on the attacker machine as the LHOST is set as drupal-pod’s IP. But there is a shell on Drupal-pod listening on port 2222. This implies that the exploit was successfully sent to the Webmin-application.

 

The attacker now has root access on the Webmin-pod (shown in the image above) with uid=0. With root access, the attacker can use this pod to make changes to the file system and cover his tracks by deleting logs. The attacker can also install malware, miners, and stealers and also use it as a pivot to launch further attacks.

### Detection and Prevention

Use following yaml

- Check if the Webmin-pod is accessed on non designated port i.e. apart from 10000

- Whitelist any approved flow

**Manifest 2**

Use the following YAML to check

- Any connection originating from webmin-pod

- A reverse shell or unapproved activity

- Use ‘NOT’ operator to exclude approved flows

**Manifest 3**

```
`apiVersion: projectcalico.org/v3 kind: GlobalAlert metadata: name: global.lateral.from-webmin spec: description: "Lateral movement detected: Egress connection from Webmin" summary: "[flows] [lateral movement] ${source_namespace}/${source_name_aggr} with label app=webmin made a egress connection" severity: 100 period: 10m lookback: 10m dataSet: flows query: '"source_labels.labels"="app=webmin" AND proto="tcp" AND action="allow" AND reporter="src"' aggregateBy: [source_namespace, source_name_aggr] field: num_flows metric: sum condition: gt threshold: 0`
```

### Results

- Check the Global Alerts tab on Calico Enterprise to view this lateral move from Drupal-pod to Webmin-pod

- Observe Manifests 2 and 3 triggered as shown in Figure 9 and 10

- Investigate connections, traffic, and movement at the same time using inputs from the alert in Dynamic Service Graph, Flow visualizer

Reverse shell from Webmin to Drupal:

![Screenshot of a security alert showing an outgoing connection from Drupal, indicating potential lateral movement. JSON data](https://www.tigera.io/app/uploads/2023/05/image3.jpg)

Drupal to Webmin attack connection:

![Screenshot of a security alert showing an outgoing connection from Webmin, indicating potential lateral movement after a](https://www.tigera.io/app/uploads/2023/05/image19-1.jpg)

## Additional Alerts

Calico provides a flexible alerting framework that allows security teams to configure various types of alerts targeting information provided in flow logs, dns logs, audit logs, or be triggered as a part of out of the box detection of suspicious behavior.

### ThreatFeeds

The attacker can use TOR/VPN, suspicious domain, or IP for an attack and the alert would look like the following for suspicious domain and IP using the following manifest.

- Suspicious Domains threat feed.

**Manifest 4a:**

```
`apiVersion: projectcalico.org/v3 kind: GlobalThreatFeed metadata: name: global.threat.domains spec: content: DomainNameSet pull: http: url: https://raw.githubusercontent.com/Dawsey21/Lists/master/main-blacklist.txt`
```

- Suspicious IP Threat feed.

**Manifest 4b:**

```
`apiVersion: projectcalico.org/v3 kind: GlobalThreatFeed metadata: name: global.threat.ipfeodo spec: pull: http: url: https://feodotracker.abuse.ch/downloads/ipblocklist.txt globalNetworkSet: labels: feed: feodo --- #Policy to block using above feeds apiVersion: projectcalico.org/v3 kind: GlobalNetworkPolicy metadata: name: default.block-feodo spec: tier: default selector: app == 'webmin' types: - Egress egress: - action: Deny destination: selector: feed == 'feodo' - action: Allow`
```

![Traffic blocked by the global threat feed policy. Details show a suspicious DNS query to pagaldaily.com](https://www.tigera.io/app/uploads/2023/05/image10.png)

## Denial of Service

If the number of DNS requests exceeds the organizational threshold for a time interval, leverage this manifest to be alerted.

```
`apiVersion: projectcalico.org/v3 kind: GlobalAlert metadata: name: dns.dos spec: description: "Alerts when DNS DOS attempt is detected" summary: "[dns] DOS attempt detected by ${client_namespace}/${client_name_aggr}" severity: 100 lookback: 10m period: 10m dataSet: dns aggregateBy: [client_namespace, client_name_aggr] field: count metric: sum condition: gt threshold: 50000`
```

Cluster state change – Globalnetworkpolicy

If network policy is modified by service account

**Manifest 5:**

```
`kind: GlobalAlert metadata: name: policy.globalnetworkpolicy spec: description: "Alerts on any changes to global network policy" summary: "[audit] [privileged access] change detected for ${objectRef.resource} ${objectRef.name}" severity: 100 period: 5m lookback: 5m dataSet: audit query: (verb=create OR verb=update OR verb=delete OR verb=patch) AND "objectRef.resource"=globalnetworkpolicy aggregateBy: [objectRef.resource, objectRef.name] metric: count condition: gt threshold: 0`
```

### Cloud API attacks

The following configuration detects any attacks on a cloud API from a default namespace. It can be modified for cloud etcd, RBAC, and other cloud resources.

- Detects any requests made to cloud provider’s metadata API from application namespace

- This is very suspicious within a cloud environment if the namespace isn’t supposed to use this API for any legitimate activity

**Manifest 6:**

```
`apiVersion: projectcalico.org/v3 kind: GlobalNetworkSet metadata: name: metadata-api spec: nets: - 169.254.169.254 --- apiVersion: projectcalico.org/v3 kind: GlobalAlert metadata: name: global.metadata.requests spec: description: "Metadata API: Connection to metadata service from default namespace" summary: "[flows] [Metadata access] ${source_namespace}/${source_name_aggr} accessed metadata api" severity: 100 period: 10m lookback: 10m dataSet: flows query: '(dest_name_aggr="metadata-api" OR dest_name_aggr="kse.kubernetes") AND action="allow" AND proto="tcp" AND reporter="src" AND (source_namespace="default")' aggregateBy: [source_namespace, source_name_aggr] field: num_flows metric: sum condition: gt threshold: 0`
```

The earlier attacker made a request to the cloud metadata service from compromised Drupal-pod to determine token privileges and Calico Enterprise Global Alerts detected the attempts as follows:

![Calico Enterprise detected a metadata API connection from the Drupal pod, showing source labels "app=drupal" and allowed](https://www.tigera.io/app/uploads/2023/05/image17.jpg)

Snort IDS engine is a single click deployment to monitor containers for malicious activity. Custom snort signatures can be added as given below through configmap. Once the malicious activity is detected inside container traffic, the alerts with necessary details and Kubernetes context is provided for incident response.

Enable snort engine for a specific namespace by deploying the DeepPacketInspection resource:

```
`apiVersion: projectcalico.org/v3 kind: DeepPacketInspection metadata: name: webmin-dpi namespace: crown-space spec: selector: all()`
```

If needed, one can create cusom rulesets for snort engine. Following custom snort rule selects all the ICMP Echo requests and responses from a container.

```
`apiVersion: v1 kind: ConfigMap metadata: name: localrule namespace: tigera-intrusion-detection data: rules: | alert icmp any any -> any any (msg:"ICMP Echo Request"; itype:8; sid:1000000;) alert icmp any any -> any any (msg:"ICMP Echo Reply"; itype:0; sid:1000001;)`
```

![Alerts UI showing "Encountered suspicious traffic matching snort rule," triggered by ICMP traffic as defined in the ConfigMap](https://www.tigera.io/app/uploads/2023/05/image7.png)

## Conclusion

With Calico on AWS EC2 self-managed Kubernetes and EKS, you can monitor any Kubernetes resource or situation for Pod/deployment/daemonset/cronjob/job/webhook/networkpolicy (any Kubernetes object), failed requests to Kubernetes API server, failed attempt to create roles/rolebindings/clusterrole and clusterrolebindings, anonymous access to k8s api server and, service account access by public IP. You can detect the attack and produce a high-value alert with information that enables the team to readily analyze the threat and prevent the attack from propagating.

Using Calico and Global Alerts together, users can easily monitor their services and applications in AWS EC2 and EKS, quickly identify malicious behavior, and significantly reduce time to address the security threats. Users can address the following:

Lateral movement by the attacker for traffic in AWS EKS deployment
Monitor all flows within your AWS or EKS cluster for threat and lateral movement detection

Botnet, Command and Control, VPN-TOR
Ingest threat feeds in AWS environments to identify IP addresses for known bad actors such as botnets. Any ingress or egress traffic to those IPs is automatically blocked and can be configured to generate alerts. In addition, traffic to VPNs and TOR exit nodes is blocked and triggers alerts when detected

Malicious DNS queries
Use suspicious domain feeds to flag any DNS requests to a malicious domain from your AWS or EKS based Kubernetes workload

Cloud Metadata API attacks
Identify workload flows that attempt to connect to cloud resources like metadata API if you are on Kubernetes etcd, RBAC, etc. where an attacker attempts to enumerate access and elevate his/her privileges

Snort IDS for containers
Monitor network traffic to the container and identify malicious traffic by utilizing snort signatures

Calico with Global Alerts on AWS and EKS provides advanced threat and lateral movement detection capabilities in AWS and EKS for preventing any malicious activities in your environment.

To try it yourself, register for [Calico Cloud on the AWS marketplace.](https://aws.amazon.com/marketplace/pp/prodview-pq3tgvtlj3wce)

[Best Practices](https://www.tigera.io/tags/best-practices/)[How-To](https://www.tigera.io/tags/how-to/)[Kubernetes Vulnerabilities](https://www.tigera.io/tags/kubernetes-vulnerabilities/)

## Related posts

[![The Safest Place to Run an AI Agent Is On a Cluster That Doesn’t Trust It](https://www.tigera.io/app/uploads/2026/08/The-Safest-Place-to-Run-an-AI-Agent-Is-On-a-Cluster-That-Doesnt-Trust-It.png)](https://www.tigera.io/blog/the-safest-place-to-run-an-ai-agent-is-on-a-cluster-that-doesnt-trust-it/)

#### [The Safest Place to Run an AI Agent Is On a Cluster That Doesn’t Trust It](https://www.tigera.io/blog/the-safest-place-to-run-an-ai-agent-is-on-a-cluster-that-doesnt-trust-it/)

By [Alister Baroi](https://www.tigera.io/blog/author/alister-baroi/)
on Aug 27, 2026

Every organization running AI agents has already made a hosting decision. Most made it by accident. The sales team switched on the agent built into their CRM. Engineering is piloting a coding agent in a...

[Read more](https://www.tigera.io/blog/the-safest-place-to-run-an-ai-agent-is-on-a-cluster-that-doesnt-trust-it/)

[![AI Red Team Agents Automate Attacks on your AI Agents. Runtime Policies Automate their Defense.](https://www.tigera.io/app/uploads/2026/08/AI-Red-Team-Agents-Automate-Attacks-on-your-AI-Agents.-Runtime-Policies-Automate-their-Defense.png)](https://www.tigera.io/blog/ai-red-team-agents-automate-attacks-on-your-ai-agents-runtime-policies-automate-their-defense/)

#### [AI Red Team Agents Automate Attacks on your AI Agents. Runtime Policies Automate their Defense.](https://www.tigera.io/blog/ai-red-team-agents-automate-attacks-on-your-ai-agents-runtime-policies-automate-their-defense/)

By [Alister Baroi](https://www.tigera.io/blog/author/alister-baroi/)
on Aug 24, 2026

The AI red teaming market grew up fast this year. OpenAI bought Promptfoo, Cisco and Microsoft shipped automated attack suites, and a seed-stage startup publicly compromised 50 of 55 live customer service bots. These platforms...

[Read more](https://www.tigera.io/blog/ai-red-team-agents-automate-attacks-on-your-ai-agents-runtime-policies-automate-their-defense/)

[![VM Migration – What Happens to Your NSX Segments in Kubernetes?](https://www.tigera.io/app/uploads/2026/08/VM-Migration-What-Happens-to-Your-NSX-Segments-in-Kubernetes.png)](https://www.tigera.io/blog/vm-migration-what-happens-to-your-nsx-segments-in-kubernetes/)

#### [VM Migration – What Happens to Your NSX Segments in Kubernetes?](https://www.tigera.io/blog/vm-migration-what-happens-to-your-nsx-segments-in-kubernetes/)

By [Veronika Smolik](https://www.tigera.io/blog/author/veronika-smolik/)
on Aug 5, 2026

Planning a migration off NSX usually starts with a networking conversation. Segments, VLANs, routing topology and BGP peering are not things that map cleanly to Kubernetes-native constructs the way the NSX distributed firewall maps to...

[Read more](https://www.tigera.io/blog/vm-migration-what-happens-to-your-nsx-segments-in-kubernetes/)

<!-- plugin=object-cache-pro client=phpredis metric#hits=3467 metric#misses=35 metric#hit-ratio=99.0 metric#bytes=1572696 metric#prefetches=190 metric#store-reads=47 metric#store-writes=9 metric#store-hits=198 metric#store-misses=24 metric#sql-queries=25 metric#ms-total=865.94 metric#ms-cache=23.08 metric#ms-cache-avg=0.4197 metric#ms-cache-ratio=2.7 sample#redis-hits=1754649 sample#redis-misses=592650 sample#redis-hit-ratio=74.8 sample#redis-ops-per-sec=33 sample#redis-evicted-keys=0 sample#redis-used-memory=144163136 sample#redis-used-memory-rss=114888704 sample#redis-memory-fragmentation-ratio=0.8 sample#redis-connected-clients=1 sample#redis-tracking-clients=0 sample#redis-rejected-connections=0 sample#redis-keys=115018 -->
