A collection of reverse engineering snippets from October 2025.
Why?
Although posts on Twitter/X can be effective for communicating new or existing malware, it is not easily searchable and probably not the best approach to provide a way for others to learn how to reverse engineer.
So this blog will be used to capture RE efforts that have been shared by me. Also, huge shoutout to MalwareHunterTeam - @malwrhunterteam for sharing many of these samples with me! Feel free to download samples from the malwarebazaar links and follow along. I’ve also included YouTube videos if I covered the sample. Enjoy :)
10/27/25 - Another Stealer - Telegram and Steam - Drop Dead Resolvers (DDR)?
sha256: 7a8fc48ce4df4448b91a1e6b66410cca6993ac072cb12860b9cfa6438b25ed8e
sample link: https://bazaar.abuse.ch/sample/7a8fc48ce4df4448b91a1e6b66410cca6993ac072cb12860b9cfa6438b25ed8e/
Another awesome share by MalwareHunterTeam. This one was one of my favorite to analyze recently since it included many steps and actually showed malicious usage of Telegram and Steam accounts to host the C2. The accounts at the time of writing this are still active after multiple requests for takedowns submitted by me….

💡RE Notes:
First screenshot is pretty straight forward. We see the killall Terminal command string being passed to system() (annoying when debugging) and we also see the creation of the LaunchAgents directory via mkdir() to write a plist file for persistence.

Looking closely, we can see two links being used with curl to set the domain variable in the osascript. The first link is for Telegram and the second for Steam. There is code to handle the resolving of the Command and Control server URL that was hosted on these two accounts. This is ongoing. But what was most intereting in the osascript was the usage of backdoor code.

First, we have this function called listenCommands() which calls system_profiler and also sets a variable named taskData to the return of getTask().

This getTask() then reaches back out to the C2 and is able to get commands that are returned. Pretty cool!
link to x post: https://x.com/L0Psec/status/1982917057500065893
10/26/25 - More MacSync with Simpler XOR
sha256: 0d5c59fb86a094f4b2d5c170e9fa4a8c401de6267b6d6cd12af45003690aba0b
sample link: https://bazaar.abuse.ch/sample/0d5c59fb86a094f4b2d5c170e9fa4a8c401de6267b6d6cd12af45003690aba0b/
💡RE Notes:

In the screenshot above you can see multiple For Loops that are used to iterate through encoded strings using 0x93 as the XOR key. This approach was simpler than the one I analyzed on October 25, 2025 but worth covering. I added the result of each loop as comments within the decompilation. Next, I cover how we can try to prove this is related to the other MacSync sample.

A snprintf() call is used to create a string used in a curl request header. This string is for the api-key and is the same key value as the sample from before: hash - b9ef067ffa09d325a7e378f5495b405d2a6c798795df64ae7cf2fffd8dd2ed4e. This makes it easy to connect these two even if they used different obfuscation.

I mentioned before that the use of launchctl asuser <uid> osascript was unique to me and this sample used the same command string that is passed to the popen() function.
link to X post: https://x.com/L0Psec/status/1982446241943306277
10/25/25 - New MacSync Variant (many of these lately)
sha256: b9ef067ffa09d325a7e378f5495b405d2a6c798795df64ae7cf2fffd8dd2ed4e
sample link: https://bazaar.abuse.ch/sample/b9ef067ffa09d325a7e378f5495b405d2a6c798795df64ae7cf2fffd8dd2ed4e/
YouTube link:

💡RE Notes:
In the screenshot above, I changed the name of the function that is in charge of the XOR operations after seeing how it works. By changing the argument names of the XOR function to encodedString and KEY, we can easily see how X0 = pointer to the encoded string and X1 = key. Each call to this function uses a different key which makes it slightly more time consuming to decode each string. Next we have some cool curl usage.

Once the string decoding is completed, we can see that there are calls to curl APIs. snprintf() is used to replace the format string of https://%s/%s with the complete command and control (C2) URL. Once the URL is decoded, we can change the variable name to reflect this as the argument passed to the curl_easy_setopt(CURL *handle, CURLoption option, parameter) function. Normally, the options will be displayed in hex values which correspond to the options enum. But you can add a header file for curl in binary ninja and make the code prettier. :) Below is the full URL, user-agent, and api-key used.

After this setup, we get some osascript as usual with many of these infostealers. Moonlock reported on a similar MacSync sample in September 2025. We can see the version within the osascript below.

The part of this analysis that stood out the most to me was the usage of launchctl to execute osascript. I don’t remember if I’ve seen that used by an infostealer recently.

We can see a call to snprintf() again to replace the "launchctl asuer %d osascript" command being relaced with the return value of getuid(). This is then passed to the popen() command to execute.
Additonal Context: This is the first of many MacSync related samples I analyzed. MalwareHunterTeam shared this with me and I also decided to record a short video covering some of the fun analysis.
link to X post: https://x.com/L0Psec/status/1982059740688732229
10/22/25 - Potential Odyssey Sample
sha256: 9a4b14a7ff3cc6443a2b9e3a95a2259295d5809b81cd5829d12fa87d4e60ed71
sample link: https://bazaar.abuse.ch/sample/9a4b14a7ff3cc6443a2b9e3a95a2259295d5809b81cd5829d12fa87d4e60ed71/

💡RE Notes:
Osascript code snippet shows the use of a LaunchDaemon for persistence and the command and control server. This osascript command is decoded prior to passing to the system() function.
system(const char *command);
This allows you the ability to use LLDB and set a breakpoint at the call to system() and inspect the command that is passed via the first argument to system() which in the case of arm64 would be in register X0. This file was inside of a DMG so to analyze via command line you can use hdiutil to attach the DMG and navigate to the file.
hdiutil attach <pathToDMG>.dmg
Additonal Context:
This example was seen being hosted on https[:]//security-att[.]com//downloads/ATTActiveArmor.dmg and was shared by MalwareHunterTeam. The C2 at 185.93.89[.]62 and source URL were reported.
link to X post: https://x.com/L0Psec/status/1980965563636789444