Affected platforms: All platforms where PyPI packages can be installed
Impacted parties: Any individuals or institutions that have these malicious packages installed
Impact: Leak of credentials, sensitive information, etc.
Severity level: High
Vigilance is paramount in cybersecurity, especially when it comes to understanding and dissecting potentially malicious code. In this blog post, we'll delve into a piece of code designed (discordpy_bypass-1.7 ) to extract sensitive data from user systems. We'll analyze its components, functions, and methodologies to understand its purpose and approach.
FortiGuard Labs uses a proprietary, AI-driven OSS malware detection system to hunt for and monitor threats. Using this approach on the Python Package Index (PyPI) supply chain platform, we unearthed a malicious PyPI package named discordpy_bypass-1.7, published on March 10, 2024, and detected on March 12, 2024.
This code aims to covertly extract sensitive information from unsuspecting victims using a blend of persistence techniques, browser data extraction, and token harvesting. Understanding the origins and propagation methods of malicious code is paramount in its analysis. Authored by theaos, the author produced seven versions of the package, including versions 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, and 1.7. The upgrade-colored_0.0.1 also exhibits similar malicious content as discordpy_bypass, indicating a consistent behavior pattern across versions.
Figure 1: discordpy_bypass-1.7
"discordpy_bypass-1.7" highlights the sort of ongoing threats seen across the cybersecurity landscape. This PyPI package version exhibits similar malicious behavior to previous malicious packages, focusing on extracting sensitive data from user systems through obfuscated code and evasion techniques targeting analysis environments. The code employs various checks to detect debugging or analysis environments and terminates itself if detected, showcasing the author's effort to evade scrutiny.
The code has three layers. The original Python code is encoded using base64 (the innermost layer). The encoded strings are then broken into separate pieces and encoded once again with some obfuscation techniques (intermediate layer). The obfuscated file is then compiled using pyinstaller into an exe (the last layer) put on a remote URL. The code in discordpy_bypass/discordpy_bypass.py fetches the code from the URL and runs it on the user's device. This underscores the critical need for vigilance and proactive measures to effectively detect and mitigate cybersecurity threats.
One of the first lines of defense code developers use against reverse engineering is detecting debugging or analysis environments. The code segment employs multiple techniques, listed below, to identify such environments and terminate the program’s “self-destruct” if detected.
Figure 2: The program exits in self_destruct
Block listed Processes: These iterate over the running processes and terminates them if their names match those in the blocked process list (“blacklistedProcesses”). These processes include debugging tools like Wireshark, OllyDbg, and IDA64
Figure 3: Blocked processes
Network-related Checks: Compares system IP and MAC addresses against block lists (“blackListedIPS”, “blackListedMacs”). If the IP or MAC address is found in a block list, it returns “True,” indicating a debugging environment.
Figure 4: Block listed IPs and MACs
System-related Checks: Compares system username, hostname, and hardware ID against block lists. (“blackListedUsers,” “blackListedPCNames,” and “blackListedHWIDS”)
Figure 5: blackListedUsers, blackListedPCNames, and “blackListedHWIDS
The code initializes a number of variables and sets up Socket.IO events to handle connections, disconnections, frame adjustments, and more. It enables remote control and monitoring of a system, facilitating actions such as directory navigation, file operations, and command execution.
Several functions handle commands received over Socket.IO, executing various actions based on the command received. These actions include listing directory contents, sending files to the server, displaying alerts, listing processes, terminating processes, gathering system information, and more.
Browser Data Extraction and Token Harvesting: The code's core functionality revolves around extracting sensitive information from browsers and harvesting authentication tokens, particularly from Discord.
Browser Data Extraction: It utilizes techniques to extract data such as login credentials, cookies, web history, and more from various browsers.
Token Harvesting: This process also decrypts and validates authentication tokens extracted from files, particularly Discord tokens, before uploading them to a remote server.
Figure 8: Actions the hacker can take
Figure 9: The “upload” class collects data from various sources, including browser data such as login credentials, cookies, web history, and credit card information
Figure 10: After collecting the data, the “upload” class compresses it into a ZIP file. This Is often seen in malware to bundle stolen data or payloads for exfiltration
Figure 11: The ‘send’ method attempts to send the compressed ZIP file to a server
Our investigation into the "discordpy_bypass-1.7" code has uncovered a clever and sneaky cyber threat to secretly steal important information from people's computers. What makes this code especially dangerous is how it tries to trick computer systems and experts who attempt to analyze it. It's like a master of disguise that can escape from being caught.
This discovery reminds us that the internet isn't always a safe place. We need to stay alert to protect ourselves from such threats. Understanding them helps us build stronger defenses and stay safe in our digital world. By working together and staying cautious, we can keep our personal information and digital lives secure.
FortiGuard AntiVirus detects the malicious files identified in this report as
upgrade-colored-0.0.1/colored/call.py: Python/Agent.COL!tr
upgrade-colored-0.0.1/colored_payload: Python/Agent.0337!tr
discordpy_bypass-1.0/discordpy_bypass/discordpy_bypass.py: Python/Disco.BYP!tr.dldr
discordpy_bypass-1.1/discordpy_bypass/discordpy_bypass.py: Python/Disco.BYP!tr.dldr
discordpy_bypass-1.2/discordpy_bypass/discordpy_bypass.py: Python/Disco.BYP!tr.dldr
discordpy_bypass-1.3/discordpy_bypass/discordpy_bypass.py: Python/Disco.BYP!tr.dldr
discordpy_bypass-1.4/discordpy_bypass/discordpy_bypass.py: Python/Disco.BYP!tr.dldr
discordpy_bypass-1.5/discordpy_bypass/discordpy_bypass.py: Python/Disco.BYP!tr.dldr
discordpy_bypass-1.6/discordpy_bypass/discordpy_bypass.py: Python/Disco.BYP!tr.dldr
discordpy_bypass-1.7/discordpy_bypass/discordpy_bypass.py: Python/Disco.BYP!tr.dldr
discordpy_bypass-1.7/discordpy_bypass/discordpy_bypass_payload.exe: Python/Agent.514A!tr
discordpy_bypass-1.7/discordpy_bypass/discordpy_bypass_python.py: Python/Agent.C77E!tr
discordpy_bypass-1.6/discordpy_bypass/discordpy_bypass_payload.py: Python/Agent.7684!tr
The FortiGuard AntiVirus service is supported by FortiGate, FortiMail, FortiClient, and FortiEDR. Customers running current AntiVirus updates are protected.
The FortiGuard Web Filtering Service detects and blocks the download URLs cited in this report as Malicious.
The FortiDevSec SCA scanner detects malicious packages, including those cited in this report that may operate as dependencies in users' projects in test phases, and prevents those dependencies from being introduced into users' products.
If you believe these or any other cybersecurity threat has impacted your organization, please contact our Global FortiGuard Incident Response Team.
File |
Hash (sha256) |
Detection |
upgrade-colored-0.0.1/colored/call.py |
ba2ceb9b1c6942617e4aaf76f12674acec0f072fde85249ebb7f0255b0681d8a |
Python/Agent.COL!tr |
upgrade-colored-0.0.1/colored_payload |
21ce98a759d413a94487d76b4a37574787bba4695bde5444909f85c40b6a96dd |
Python/Agent.0337!tr |
discordpy_bypass-1.0/discordpy_bypass/discordpy_bypass.py |
3428cfe2de2d415fbdb74b6d099af2061b8af2b21c432ed28b95f360090c80a2 |
Python/Disco.BYP!tr.dldr |
discordpy_bypass-1.1/discordpy_bypass/discordpy_bypass.py |
3818b238229a40c64dd1cf07d064d5f6580d1887113691cdae23b55364ce572e |
Python/Disco.BYP!tr.dldr |
discordpy_bypass-1.2/discordpy_bypass/discordpy_bypass.py |
49e74d6ee9ff330db385ac50c398b31ff96bdc88631a3ba4231c9cb11b91f91b |
Python/Disco.BYP!tr.dldr |
discordpy_bypass-1.3/discordpy_bypass/discordpy_bypass.py |
6259496c7bf20f7b1cca959cd2807538f7e1f735a5bdef487de31c6f7c535645 |
Python/Disco.BYP!tr.dldr |
discordpy_bypass-1.4/discordpy_bypass/discordpy_bypass.py |
66776b62992ab3a9801293852113e882822bb12cba4d8e89104aa60fbf83ee6d |
Python/Disco.BYP!tr.dldr |
discordpy_bypass-1.5/discordpy_bypass/discordpy_bypass.py |
164f75859cbfe3d1dd78304de69d6d969df7f681a93b95162c98644425a9c4d2 |
Python/Disco.BYP!tr.dldr |
discordpy_bypass-1.6/discordpy_bypass/discordpy_bypass.py |
1ebdd85a61edb7dde0e2ab59eb58325afd271cff3d364be95c142ed6fa312fae |
Python/Disco.BYP!tr.dldr |
discordpy_bypass-1.7/discordpy_bypass/discordpy_bypass.py |
31c1c3530655fb6da70368fd6c462893ff1b85feda7e5ecbdd9c5ec600e4edb1 |
Python/Disco.BYP!tr.dldr |
discordpy_bypass-1.7/discordpy_bypass/discordpy_bypass_payload.exe |
8fd185a5499d728eef4cd181477b0720a60c8be143ff2628941bb2a5985b1f73 |
Python/Agent.514A!tr |
discordpy_bypass-1.7/discordpy_bypass/discordpy_bypass_python.py |
d937aaf9f8a35687a5397aa9a657094c53553afba15953bc8c75fc9955a82b4c |
Python/Agent.C77E!tr |
discordpy_bypass-1.6/discordpy_bypass/discordpy_bypass_payload.py |
e6ccaa47337109d0bec65c573c9d6956e30c893e6bee5fc3bd6ab19f26ba558d |
Python/Agent.7684!tr |