CVE-2024-3400
Ref: Unit. (2024, April 12). Threat Brief: Operation MidnightEclipse, Post-Exploitation activity related to CVE-2024-3400 (Updated). Unit 42. https://unit42.paloaltonetworks.com/cve-2024-3400/
Summary of the writing process: As soon as PAN announced the CVE along with other information security information providers like TheHackerNews, I was really interested and tried to learn what I could about this CVE but was only informed about it. troubleshooting methods and basic quick actions that the supplier instructs. On April 17, 2024, I received a newsletter from Unit42 and got a sample from MalwareBazaar.
First, update.py
writes to the /site-packages/system.pth
path with the Base64-encoded script. The site-packages directory in Python is where manually built Python packages are installed. When you build and install Python packages from source (using distutils
, typically by executing python setup.py
), the installed modules are placed in the site-packages directory by default.
Below is the Base64 decoding process using CyberChef.
This embedded python script has two main functions: protect
and check
. This protect function ensures that if the system.pth
file is deleted or modified, it will be restored to its original state when a SIGTERM
signal is received, likely as a persistence mechanism.
The check()
function reads the file /proc/self/cmdline
to determine if the current process is running with monitor mp
. If this condition is met, it will execute another Python script embedded in Base64 encoding, potentially acting as a functional backdoor. The monitor mp
command provides a snapshot of the MP’s (Management Plane) resource utilization, including memory and CPU usage, similar to the top
command in Linux.
After the appetizer comes the main course, where the real work this backdoor does:
- Read CSS File Information: It reads the contents of the CSS file located at
/var/appweb/sslvpndocs/global-protect/portal/css/bootstrap.min.css
. Additionally, it retrieves the access and modification times of the CSS file using theos.path.getatime()
andos.path.getmtime()
functions. - Indefinite loop: Within an indefinite loop, the function continuously checks a log file located at
/var/log/pan/sslvpn_ngx_error.log
. It searches each line of the log file for a specific pattern using a regular expression ("img\[([a-zA-Z0-9+/=]+)\]"
). Upon finding a match, it proceeds to execute a command extracted from the matched string, which is base64 decoded. If successful, the output of the command is appended to the CSS file.
Restore function: new thread will be started by the script to carry out the restore
operation. This function provides the original content of the bootstrap.min.css
file, as well as the timestamps for its initial access and update. The function then pauses for 15 seconds before resetting the access and modification timestamps to their initial values and adding the file’s original contents back. The goal of this strategy is to keep the command output from being accessible for analysis. Additionally, the presence of a 15-second window suggests that the threat actor has automated this backdoor’s client-side, giving users only a short window of time to view the results before the file is changed.
For details on IOCs and other more detailed information, please read Unit42’s post. Here I just present my personal monitoring and analysis process and IOCs are something I don’t have, special thanks to my friends MalwareBazaar and Unit42 for providing me and the information security community with IOCs.