{
	"id": "299c8803-24a5-490e-bf83-0832ab40fb22",
	"created_at": "2026-04-06T00:09:29.501323Z",
	"updated_at": "2026-04-10T03:19:57.666622Z",
	"deleted_at": null,
	"sha1_hash": "a3fe2faa6bf5db001fdfc0313fcf8455ebff5db4",
	"title": "FADE DEAD | Adventures in Reversing Malicious Run-Only AppleScripts - SentinelLabs",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 25393276,
	"plain_text": "FADE DEAD | Adventures in Reversing Malicious Run-Only\r\nAppleScripts - SentinelLabs\r\nBy Phil Stokes\r\nPublished: 2021-01-11 · Archived: 2026-04-02 11:04:11 UTC\r\nExecutive Summary\r\nmacOS.OSAMiner is a cryptominer campaign that has resisted full researcher analysis for at least five\r\nyears due to its use of multiple run-only AppleScripts.\r\nmacOS.OSAMiner has evolved to use a complex architecture, embedding one run-only AppleScript within\r\nanother and retrieving further stages embedded in the source code of public-facing web pages.\r\nCombining a public AppleScript disassembler repo with our own AEVT decompiler tool allowed us to\r\nstatically reverse run-only AppleScripts for the first time and reveal previously unknown details about the\r\ncampaign and the malware’s architecture.\r\nWe have released our AEVT decompiler tool as open source to aid other researchers in the analysis of\r\nmalicious run-only AppleScripts.\r\nBackground\r\nBack in 2018, reports surfaced on Chinese security sites[1, 2] about a Monero mining trojan infecting macOS\r\nusers. Symptoms included higher than usual CPU, system freeze and problems trying to open the system Activity\r\nMonitor.app. Investigations at the time concluded that macOS.OSAMiner, as we have dubbed it, had likely been\r\ncirculating since 2015, distributed in popular cracked games and software such as League of Legends and MS\r\nOffice.\r\nAlthough some IoCs were retrieved from the wild and from dynamic execution by researchers, the fact that the\r\nmalware authors used run-only AppleScripts prevented much further analysis. Indeed, 360 MeshFire Team\r\nreported that the malicious applications:\r\nA similar conclusion was reached by another Chinese security researcher trying to dynamically analyse a different\r\nsample of macOS.OSAMiner in 2020 [3], noting that “No reverse method has been found…so the investigation\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 1 of 31\n\nends here”\r\nIn late 2020, we discovered that the malware authors, presumably building on their earlier success in evading full\r\nanalysis, had continued to develop and evolve their techniques. Recent versions of macOS.OSAMiner add greater\r\ncomplexity by embedding one run-only AppleScript inside another, further complicating the already difficult\r\nprocess of analysis.\r\nHowever, with the help of a little-known applescript-disassembler project and a decompiler tool we developed\r\nhere at SentinelLabs, we have been able to reverse these samples and can now reveal for the first time their\r\ninternal logic along with further IoCs used in the campaign.\r\nWe believe that the method we used here is generalizable to other run-only AppleScripts and we hope this research\r\nwill be helpful to others in the security community when dealing with malware using the run-only AppleScript\r\nformat.\r\nA Malicious Run-Only AppleScript (or Two)\r\nWhile malware hunting on VirusTotal, we came across the following property list:\r\ncom.apple.FY9.plist\r\n9ad23b781a22085588dd32f5c0a1d7c5d2f6585b14f1369fd1ab056cb97b0702\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 2 of 31\n\nAs noted above, we have seen this before in 2018 and earlier in 2020. The older persistence agents are almost\r\nidentical save for the labels and names of the targeted executable. In the 2018 version, the malware tries to\r\ndisguise itself as belonging to both “apple.Google” and “apple.Yahoo”:\r\nThe tell-tale LaunchAgent program argument is odd for its redundant use of osascript to call itself via a do\r\nshell script command (Lines 11-13). However, pivoting on the program argument, com.apple.4V.plist , led\r\nus to this newer sample for the executable:\r\ndf550039acad9e637c7c3ec2a629abf8b3f35faca18e58d447f490cf23f114e8\r\nAs with earlier versions of this malware, the executable also uses a .plist extension and runs from the user’s\r\nLibrary LaunchAgents folder and, again, com.apple.4V.plist is not a property list file but a run-only\r\nAppleScript:\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 3 of 31\n\nWe can quickly confirm that this is a run-only AppleScript by attempting to decompile with osadecompile ,\r\nwhich returns the error: errOSASourceNotAvailable (-1756)\r\nStrings May Tell You Something, But Not Much\r\nThe best starting point with run-only scripts is to dump the strings and the hex. For strings, we generally find the\r\nfloss tool to be superior to the macOS version of the strings command line tool. This sample proves to be a\r\ncase in point, because what strings won’t show you but floss will is all the UTF-16 encoded hex that are\r\nburied in this file:\r\nAt this point we should look at the hexdump.\r\n% hexdump -C df550039acad9e637c7c3ec2a629abf8b3f35faca18e58d447f490cf23f114e8\r\nNotice, in particular the magic header: FasdUAS , which is 46 61 73 64 55 41 53 20 in hex. Compare that to\r\nthe embedded hex in the previous screenshot, or further down in our hexdump:\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 4 of 31\n\nThis shows that our run-only script has another run-only script embedded within it, encoded in hexadecimal, a\r\ntrick that was not seen in the earlier variants of this malware.\r\nOne of the nice things about AppleScript is not only does it have a magic at the beginning of an AppleScript file it\r\nalso has one to mark the end of the script:\r\nAnd equally, we can find the end of the embedded script within the parent script by looking for the hex fa de de\r\nad or FADE DEAD .\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 5 of 31\n\nWe can now pull out all the code of the embedded script and dump that into a separate file.\r\nWe can use file and osadecompile to confirm that we do indeed now have a second valid, run-only\r\nAppleScript:\r\nLet’s now call floss on the extracted script and see what we have. You will see the output contains a lot of\r\nApple Event (AEVT) codes and, at the end, a few UTF-16 encoded strings that were not revealed when we\r\ndumped the strings from the parent script:\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 6 of 31\n\nAlthough the first image above does not quite show all the AEVT codes in the output, it’s easy to be distracted by\r\nthe UTF-16 strings at the end, which immediately suggest something interesting: it looks like this script uses a\r\ngrep search to find a particular process and kill it. It’s also clear the script is targeting both System Events.app\r\nand Activity Monitor. And there’s a tantalizing “Installe” string there, too!\r\nThe really interesting content of the script lies in the disassembly and the AEVT codes, but it’s difficult to see that\r\nfrom extracting the strings and a hexdump for two reasons:\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 7 of 31\n\nWe don’t have any understanding of the structure or logic of the script\r\nWe don’t have human-readable translations of the AEVT codes.\r\nWe will solve the first problem by using Jinmo’s applescript-disassembler and the second problem by using our\r\nown aevt_decompile tool.\r\nDisassembling Run-only AppleScripts\r\nWe have two targets for disassembly, the parent script and the embedded script. Let’s start with the parent.\r\nOnce you’ve installed and built the applescript-disassembler project, simply call the target script against the\r\ndisassembly.py script and output to a text file for analysis:\r\n% ./disassembly.py df550039acad9e637c7c3ec2a629abf8b3f35faca18e58d447f490cf23f114e8 \u003e parent.txt\r\nThe beginning of the parent.txt file should look something like this:\r\nThe first thing to note is that the content is divided into functions, separated by the lines\r\n=== data offset ===\r\nFunction name :\r\nFunction arguments:\r\nThese correspond to AppleScript handlers. In this compiled script, there are three named handlers and one\r\nunnamed handler, which corresponds to the script’s “main” handler (i.e., the main function called on execution).\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 8 of 31\n\n=== data offset 2 ===\r\nFunction name : e\r\nFunction arguments: ['_s']\r\n=== data offset 3 ===\r\nFunction name : d\r\nFunction arguments: ['_s']\r\n=== data offset 4 ===\r\nFunction name : r_t\r\nFunction arguments: ['t_t', 's_s', 'r_s']\r\n=== data offset 5 ===\r\nFunction name : \u003cValue type=object value=\u003cValue type=event_identifier value='AEVT'-'oapp'-'null'-'x00\r\nFunction arguments: \u003cempty or unknown\u003e\r\nThe most interesting function for us at the moment is the second function, ‘d’, which we will rename as the\r\n‘decode’ function. This function is called multiple times later in the code and passed an obfuscated string of hex\r\ncharacters. Reversing this function will allow us to see the obfuscated strings in plain text. Even better, since the\r\nsame function is used in all samples we’ve come across since 2018, it’ll also allow us to decode the strings right\r\nacross the campaign and observe how it has changed.\r\nThe disassembler conveniently comments where this function is called. To find the first call, search for a\r\nPositionalMessageSend (i.e., handler call) with the name  ‘d’.\r\nFor example, the following hex string at offset 000d4 is passed to the decode function at 000d8:\r\n'x00xd4x00xd6x00xcdx00xd2x00xd8x00xcax00x84x00x8bx00x89x00xc6x00x8bx00x84x00x8b'\r\nNote that in the decode handler, there is a loop which iterates over each hexadecimal byte code and then subtracts\r\nx64 from it.\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 9 of 31\n\nIt then returns that number as an ASCII code, concatenating each result to produce a UTF-8 string (note the input\r\nis padded with x00 , indicating a UTF-16 string, but the function ignores any values that are not greater than\r\nzero). The first line of input hex is returned from the decode handler as the following UTF-8 string:\r\nprintf '%b' '\r\nBased on this, it’s easy enough to implement our own decode function to deobfuscate all the obfuscated strings in\r\nthe run-only scripts. We add this logic to our aevt_decompile tool as discussed further below.\r\nThe handler ‘e’ is never called in the malware code, but inspection reveals it to be the reverse of the ‘d’ function.\r\nIn other words, the function is used to encode plain UTF-8 strings to produce the obfuscated hex and is\r\npresumably used by the authors when building their malware.\r\nThe function ‘r_t’, which takes three parameters, is only called once. This function takes a target, a source and a\r\n‘delimiter’.\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 10 of 31\n\nOnce we substitute the constant hex values shown in the disassembler for the Apple Event codes (discussed\r\nbelow), we will see that its purpose is to find a target substring by separating the source string into components\r\ndivided by the delimiter. From our analysis below, it appears that this handler is used to format the embedded\r\nAppleScript before writing it out to file.\r\nThe fourth, nameless, function is in fact where all the executable code is called from in an AppleScript (think of it\r\nlike a ‘main’ function in other languages). Again, we’ll discuss this further below when we move on to\r\ndecompiling the Apple Event codes and annotating the output of the disassembler.\r\nDisassembling the Embedded AppleScript\r\n% ./disassembly.py f145fce4089360f1bc9f9fb7f95a8f202d5b840eac9baab9e72d8f4596772de9 \u003e em.txt\r\nThe embedded run-only AppleScript also contains four functions, ‘e’, ‘d’, ‘kPro’ and the nameless ‘main’ function\r\nwhere the script’s executable code is called. The first two are duplicates of the encode and decode functions in the\r\nparent script.\r\nThe ‘kPro’ is obviously a ‘killProcess’ function. We can determine this directly from the disassembler as much of\r\nthe functionality is revealed as hardcoded strings:\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 11 of 31\n\nWe will automate extraction of these strings in our decompiler below, but for now note that the code above\r\ncontains the following embedded strings:\r\nps ax | grep\r\ngrep -v grep | awk ‘{print $1 }’\r\nkill -9\r\nThe function is passed the name of a process as a string, which is concatenated to produce the shell command:\r\nps ax | grep \u003cname\u003e | grep -v grep | awk ‘{print $1}’\r\nThis command is then executed via the AppleScript do shell script command. If the command returns a PID\r\nfor the process name, a further do shell script command is executed to kill the PID.\r\nWe can see that the ‘killProcess’ function is called twice in the code. On the first call, it is passed a string\r\nconcatenated from “Activity Monitor” and “.app”, both of which are hardcoded in the source:\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 12 of 31\n\nThis call occurs only if “Activity Monitor” is returned in the list of System Events’ currently running processes.\r\nThe second call to ‘killProcess’ requires decoding a number of the script’s obfuscated hexadecimal strings by\r\npassing those through the ‘d’ or decode function as we did before.\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 13 of 31\n\nHere we show some of the output of the disassembler.py script after running it through our decompiler tool,\r\ndiscussed in the next section:\r\nps ax | grep -E '360|Keeper|MacMgr|Lemon|Malware|Avast|Avira|CleanMyMac' | grep -v grep | awk '{print\r\n$1}'\r\nBuilding a Decompiler on Top of the Disassembler\r\nWithout the AEVT codes and other decompiling, the output of the disassembler is obscure at best.\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 14 of 31\n\nRunning our decompile tool on the output from the disassembler, however, makes things much clearer. Not only\r\ndo we get each AEVT code’s command name and description in human readable form, our tool also automatically\r\nextracts and decodes the malware’s obfuscated hex strings.\r\nEmbedded strings, as well as hardcoded strings and number formats are also translated.\r\nFrom the disassembler output we get:\r\nBut after running it through the decompiler, we get a much more informative output for these lines:\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 15 of 31\n\nSimilarly, “Tell” blocks in AppleScript are much easier to understand after running the decompiler. From the\r\ndisassembly alone, it’s difficult to interpret the purpose of the following code between offset 00007 and 00018, for\r\nexample:\r\nThe decompiler makes it clear that the block targets System Events and returns the disk capacity of “/”, the startup\r\ndrive.\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 16 of 31\n\nOur tool attempts to return the human-readable code for an AEVT from all available sources. That can mean\r\nmultiple interpretations for a single line.\r\nYears of experience with AppleScript has taught us that this kind of verbosity is vital to make sense of complex\r\nscripts, where the meaning of AEVT codes can change depending on the target of the block they appear in. For\r\nthose less familiar with the vagaries of AppleScript, a little explanation here may be in order.\r\nInterlude: A Quick Guide to AEVT Codes\r\nAccording to Apple’s legacy documentation (I maintain a PDF repository here), Apple Event codes “are defined\r\nprimarily in the header files AppleEvents.h and AERegistry.h in the AE framework”. However, the word\r\n“primarily” is an important, and arguably misleading, qualifier as there are many other places where the codes can\r\nbe defined, depending on exactly what the script targets.\r\nMost AppleScripts will likely make use of the StandardAdditions.osax , which defines a whole range of codes\r\nthat add essential functionality to the base AppleScript language. In addition, malware scripts are likely to also\r\ntarget either or both of System Events and the Terminal, both of which have their own definitions for Apple Event\r\ncodes. Indeed, any application that is “scriptable” can define its own Apple Event codes. These definitions are\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 17 of 31\n\nnowadays located in an XML file with the extension .sdef inside each application’s own bundle Resources\r\nfolder.\r\nBecause of this architecture, you can only retrieve the codes for an AppleScript if you have the targeted\r\napplications on your system. Fortunately, in the case of malware, it is highly likely that the malware will only\r\ntarget system applications that can be found on every Mac, such as System Events and the Terminal, both because\r\nof their power to manipulate the system and because of their universality – an AppleScript that targets an\r\napplication that is not on the victim’s system will fail to execute fully or at all, and will thus have limited utility, at\r\nleast for commodity malware.\r\nThe paths we need for most Apple Event codes then can be found in the following locations:\r\nAEFramework:\r\nWe need the source for the AEFramework headers, and that requires installation of the Xcode Command Line\r\ntools. These should be found within the /Library/Developer/CommandLineTools/SDK s folder. For example on\r\nCatalina:\r\n/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/CoreServices.frame\r\nFor Big Sur,\r\n/Library/Developer/CommandLineTools/SDKs/MacOSX11.0.sdk/System/Library/Frameworks/CoreServices.framew\r\nAlternatively, you may find the path to these from the Terminal, via\r\n% xcode-select -p\r\nThe output of that command can then be extended with the following path that should take you to the Headers\r\ndirectory:\r\n/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/CoreServices.framework\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 18 of 31\n\nAppleScriptKit:\r\n/System/Library/Frameworks/AppleScriptKit.framework/Versions/A/Resources/AppleScriptKit.sdef\r\nStandard Additions OSAX:\r\n/System/Library/ScriptingAdditions/StandardAdditions.osax/Contents/Resources/StandardAdditions.sdef\r\nSystem Events.app:\r\n/System/Library/CoreServices/System Events.app/Contents/Resources/SystemEvents.sdef\r\nTerminal.app:\r\n/System/Applications/Utilities/Terminal.app/Contents/Resources/Terminal.sdef\r\nThere are, of course, many more .sdef files on any given system – as many as there are scriptable applications\r\non the current OS installation. The Script Editor’s Dictionary viewer lists all scriptable applications on a system:\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 19 of 31\n\nHowever, few of those will be targeted by malware. Even so, since the scripting definition file appears in a\r\npredictable location within each application bundle, our decompiler attempts to suggest further SDEFs for other\r\napplications targeted in the script if they exist on the analysis machine. Which code is the correct one given the\r\ncontext of the rest of the script is up to the analyst to interpret. The aim of our decompiler is to make this fairly\r\neasy to discern.\r\nUnderstanding the macOS.OSAMiner Campaign\r\nWith these tools to hand, our workflow will be as follows:\r\n% disassembler.py target.scpt \u003e target.txt\r\n% aevt_decompile target.txt\r\n -\u003e ~/Desktop/target.out\r\nThe aevt_decompile program will by default output to ~/Desktop/\u003cfilename\u003e.out (e.g.,  target.out), though this\r\ncan be changed in the code. The .out file can be opened or read in Vi, BBEdit or whatever happens to be your\r\npreferred text editor.\r\nRunning our tools on a number of samples from 2018 to 2020 now reveals more clearly how the\r\nmacos.OSAMiner campaign works. The parent script first checks the disk capacity of the victim’s machine via\r\nSystem Events and exits if there is not enough free space.\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 20 of 31\n\nNext, it writes out the embedded AppleScript to ~/Library/k.plist via a do shell script command, and\r\nthen executes the embedded script with osascript , again shelling out via do shell script . As we shall see,\r\nthe primary function of this embedded script is to take on evasion and anti-analysis duties.\r\nAfter writing out the embedded script, the parent script continues to execute, setting up a persistence agent and\r\ndownloading the first stage of the miner by retrieving a URL embedded in a public web page.\r\nIn our particular sample, the obfuscated, hardcoded URL is\r\nhxxp://www[.]budaybu10000[.]com:8080\r\nHowever, this URL currently does not resolve, which suggests either that the malware campaign for this particular\r\nURL has not been activated yet or for some reason has gone offline. Fortunately, we can use our disassembler and\r\ndecompiler on other samples to find a still live URL and see what it serves. In this case, we can find the following\r\nURL\r\nhxxps://www[.]emoneyspace[.]com/wodaywo\r\nhaving the same function in an older sample\r\n(ab4596d3f8347d447051eb4e4075e04c37ce161514b4ce3fae91010aac7ae97f) and still live. The URL takes us to\r\nthe following public web page:\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 21 of 31\n\nThe source code of the webpage is parsed by the malware to retrieve an embedded URL surrounded by the text\r\ndelimiters -=-=-= . Curiously, the code for extracting the URL is duplicated inline rather than being passed off to\r\nthe ‘r_t’ function at data offset 4.\r\nThe extracted URL is passed to the curl utility for downloading a remote file. Despite the .png extension, it is\r\nof course another run-only AppleScript, which is now written out to ~/Library/11.png on the infected device\r\nand executed at offset 00387.\r\nThe malware now has four components running (path names can vary across samples):\r\na persistence agent for the parent script at ~/Library/LaunchAgents/com.apple.FY9.plist\r\nthe parent script executing from ~/Library/LaunchAgents/com.apple.4V.plist\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 22 of 31\n\nthe embedded evasion/anti-analysis AppleScript running from ~/Library/k.plist\r\nthe miner setup script running from ~/Library/11.png\r\nBefore we turn to the latter two, note that the parent script has not finished its business yet. It continues to execute\r\nvarious tasks, including gathering the device serial number, restarting the launchctl job and killing the Terminal\r\napplication. This last action is one of the few that are not executed through do shell script commands; instead,\r\nthe script targets the Terminal directly through its own do script AppleScript command.\r\nMeanwhile, the embedded AppleScript looks for the Activity Monitor process among System Events’ process list.\r\nIf found, it passes the application’s name to its ‘kPro’ or ‘killProcess’ handler to prevent the user inspecting\r\nresource usage.\r\nEven more interesting, the embedded script also functions to perform evasion tasks from certain consumer-level\r\nmonitoring and clean up tools. It searches both for PIDs among running processes and it parses the operating\r\nsystem’s install.log for apps matching its hardcoded list, killing any that it finds along the way.\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 23 of 31\n\nDownloading and Configuring the Miner Component\r\nFinally, running our tools on the miner setup script reveals that it functions as a downloader and config for what\r\nappears to be an instance of the open-source  XMR-STAK-RX – Free Monero RandomX Miner software.\r\nThe setup script includes pool address, password and other configuration information but no wallet address.\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 24 of 31\n\nThis miner script also checks to ensure there is enough disk space, but this time using the Unix utility df rather\r\nthan the System Events application.\r\nThe miner setup script also uses the built-in caffeinate tool to prevent the Mac sleeping and also does some\r\nevasion checks. It parses the output of the built-in system_profiler tool to check whether the device has 4 cores, a\r\nrudimentary way of trying to ensure it is not running in a virtual machine environment.\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 25 of 31\n\nNext, a folder is created in ~/Library/Caches/ with the name “com.apple.” and two uppercase letters, which are\r\nhardcoded in the script. In this sample, those letters are ‘CM’, so the folder to be written is\r\n~/Library/Caches/com.apple.CM/ .\r\nInterestingly, we can see from reversing an older sample with our tools that previously the malware wrote its\r\ncomponents to the ~/Library/Safari/ folder, but as that is now prohibited by TCC restrictions since Mojave\r\n10.14, the malware authors have clearly had to adapt.\r\nVarious files are written to this folder:\r\nconfig.txt\r\ncpu.txt\r\npools.txt\r\nssl.zip\r\nThe last is a compressed folder which contains a file variously called ssl.plist, ssl3.plist, ssl4.plist and so on. In\r\nkeeping with the malware’s tactic of using misleading file extensions, this is of course not a plist but in fact a\r\nMach-O executable. The executable appears to be an instance of the XMR-STAK miner and is downloaded from a\r\nhardcoded and obfuscated URL:\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 26 of 31\n\n97febb1aa15ad7b1c321f056f7164526eb698297e0fea0c23bd127498ba3e9bb   ssl4.plist\r\nConclusion\r\nRun-only AppleScripts are surprisingly rare in the macOS malware world, but both the longevity of and the lack\r\nof attention to the macOS.OSAMiner campaign, which has likely been running for at least 5 years, shows exactly\r\nhow powerful run-only AppleScripts can be for evasion and anti-analysis. In this case, we have not seen the actor\r\nuse any of the more powerful features of AppleScript that we’ve discussed elsewhere [4,5], but that is an attack\r\nvector that remains wide open and which many defensive tools are not equipped to handle. In the event that other\r\nthreat actors begin picking up on the utility of leveraging run-only AppleScripts, we hope this research and the\r\ntools discussed above will prove to be of use to analysts.\r\nHashes and IoCs\r\nSHA1: d760c99dec3efd98e3166881d327aa2f4a8735ef\r\nSHA256: 35a83f2467d914d113f5430cdbede54ac96a212ed2b893ee9908e6b05c12b6f6\r\nOffice4mac.app.zip (Trojanized Application bundle, 2018 version)\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 27 of 31\n\nSHA1: 13382e8cb8edb9bfea40d2370fc97d0cbdbf61e7\r\nSHA256: 5619d101a7e554c4771935eb5d992b1a686d4f80a2740e8a8bb05b03a0d6dc2b\r\nInstall-LOL.app.zip (Trojanized Application bundle, 2018 version)\r\nSHA1: 93b2653a4259d9c04e5b780762dc4abc40c49d35\r\nSHA256: df550039acad9e637c7c3ec2a629abf8b3f35faca18e58d447f490cf23f114e8\r\ncom.apple.4V.plist (AppleScript, parent script dropped by trojanized application to ~/Library/LaunchAgents/\r\nfolder)\r\nSHA1: f2bdec618768e2deb5c3232f327fb3d6165ac84c\r\nSHA256: 9ad23b781a22085588dd32f5c0a1d7c5d2f6585b14f1369fd1ab056cb97b0702\r\ncom.apple.FY9.plist (Persistence launch agent for com.apple.4V.plist)\r\nSHA1: f3c9ecc8484ce602493652a923e9afdbb5b10584\r\nSHA256: b954af3ee83e5dd5b8c45268798f1f9f4b82ecb06f0b95bf8fb985f225c2b6af\r\nmain.scpt (AppleScript, parent script contained in trojanized application, 2018 version)\r\nSHA1: 562cb5103859e6389882088575995dc9722b781a\r\nSHA256: f145fce4089360f1bc9f9fb7f95a8f202d5b840eac9baab9e72d8f4596772de9\r\nk.plist (AppleScript, written to ~/Library/k.plist for evasion and anti-analysis;)\r\nSHA1: f3d83291008736e1f8a2d52e064e2decb2c893ba\r\nSHA256: ab4596d3f8347d447051eb4e4075e04c37ce161514b4ce3fae91010aac7ae97f\r\n001.plist (AppleScript, earlier version of k.plist, written to the LaunchAgents folder as “com.apple.Yahoo.plist”)\r\nSHA1: 13d65cb49538614f94b587db494b01273a73a491\r\nSHA256: 24cd2f6c4ad6411ff4cbb329c07dc21d699a7fb394147c8adf263873548f2dfd\r\nwodaywo.png\r\n(AppleScript, written to ~/Library/11.png , miner config / downloader script)\r\nSHA1: 1a662b22b04bd3f421afb22030283d8bdd91434a\r\nSHA256: f89205a8091584e1215cf33854ad764939008004a688b7e530b085e3230effce\r\nondayon.png\r\n(AppleScript, earlier version of the miner config / downloader script)\r\nSHA1: cfb1a0cd345bb2cbd65ed1e6602140829382a9b4\r\nSHA256: 97febb1aa15ad7b1c321f056f7164526eb698297e0fea0c23bd127498ba3e9bb\r\nssl4.plist (Mach-O, XMR-Stak miner, written to ~/Library/Caches/com.apple.XX/ssl4.plist , where “XX” is\r\nany two uppercase letters. Older samples write to ~/Library/Safari/ ).\r\nSHA1: 0756f251bc78bfe298a59db97a2b37aa3f2d3f96\r\nSHA256: 1ecbc4472bf90c657d4b27bcf3ca5f2ec2b43065282a8d57c9b86bdf213f77ed\r\nssl3.plist (earlier variant of above)\r\nObserved Parent Script Names\r\ncom.apple.4V.plist\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 28 of 31\n\ncom.apple.UV.plist\r\ncom.apple.00.plist\r\nPersistence Agent Labels\r\ncom.apple.FY9.plist\r\ncom.apple.HYQ.plist\r\ncom.apple.2KR.plist\r\nObserved URLs\r\nhxxps://www[.]emoneyspace[.]com/wodaywo\r\nhxxp://www[.]wodaywo65465182[.]com\r\nhxxp://wodaywo.com[:]8080\r\nhxxp://www[.]budaybu10000[.]com:8080\r\nSignificant Parent Script Strings:\r\n-o ~/Library/11.png\r\n;killall Terminal\r\n;launchctl start com.apple.\r\n/usr/sbin/system_profiler SPHardwareDataType | awk\r\n~/Library/LaunchAgents/com.apple.\r\nlaunchctl stop com.apple.\r\nosascript ~/Library/11.png \u003e /dev/null 2\u003e /dev/null \u0026\r\nosascript ~/Library/k.plist \u003e /dev/null 2\u003e /dev/null \u0026\r\nping -c 1 www.apple.com\r\nping -c 1 wwww.yahoo.com\r\nrm ~/Library/11.png\r\nrm ~/Library/k.plist\r\n-=-=-=\r\ntime=\r\nSignificant Evasion Script Strings:\r\n{print $1}\r\n/var/log/install.log\r\n360\r\nActivity Monitor\r\nAvast\r\nAvira\r\nCleanMyMac\r\nInstallation Log\r\nInstaller\r\nKeeper\r\nkill -9\r\nLemon\r\nMacMgr\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 29 of 31\n\nMalware\r\nps ax | grep -E\r\nSignificant Miner Setup Script Strings:\r\n\"call_timeout\" : 10,\"retry_time\" : 30,\"giveup_limit\" : 0,\"verbose_level\" : 3,\"print_motd\" : true,\"h_p\r\n\"cpu_threads_conf\" :[  { \"low_power_mode\" : false, \"no_prefetch\" : true, \"asm\" : \"auto\", \"affine_to\r\n\"cpu_threads_conf\" :[  { \"low_power_mode\" : true, \"no_prefetch\" : true, \"asm\" : \"auto\", \"affine_to_\r\n\"pool_list\" :[{\"pool_address\" : \"wodaywo.com:8888\", \"wallet_address\" : \"\", \"rig_id\" : \"\", \"pool_passw\r\n[ -e\r\n] \u0026\u0026 echo true || echo false\r\n/config.txt\r\n/cpu.txt\r\n/pools.txt\r\n/ssl.zip\r\n/ssl4.plist\r\n/usr/bin/ditto -xk\r\n/usr/sbin/system_profiler SPHardwareDataType | awk\r\n\u0026\u003e /dev/null \u0026 exit;\r\n~/library/Caches/com.apple.\r\nCaches/com.apple.\r\ncaffeinate -d \u0026\u003e /dev/null \u0026 echo $!\r\ncaffeinate -i \u0026\u003e /dev/null \u0026 echo $!\r\ncaffeinate -m \u0026\u003e /dev/null \u0026 echo $!\r\ncaffeinate -s \u0026\u003e /dev/null \u0026 echo $!\r\ncurl -L http:\r\ndf -g / | grep / | grep -v grep | awk\r\nmkdir ~/library/Caches\r\nmkdir ~/library/Caches/com.apple.\r\nores: 4\r\npgrep ssl4.plist\r\nsystem_profiler SPHardwareDataType\r\nReferences\r\n1. https://www.anquanke.com/post/id/160496\r\n2. https://www.codetd.com/article/2819752\r\n3. https%3A%2F%2Fwww.tr0y.wang%2F2020%2F03%2F05%2FMacOS的ssl4.plist挖矿病毒排查记录%2F\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 30 of 31\n\n4. https://www.sentinelone.com/blog/macos-red-team-calling-apple-apis-without-building-binaries/\r\n5. https://www.sentinelone.com/blog/how-offensive-actors-use-applescript-for-attacking-macos/\r\nResources\r\nhttps://github.com/SentineLabs/aevt_decompile\r\nhttps://github.com/Jinmo/applescript-disassembler\r\nhttps://applescriptlibrary.wordpress.com/\r\nSource: https://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nhttps://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/\r\nPage 31 of 31",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://labs.sentinelone.com/fade-dead-adventures-in-reversing-malicious-run-only-applescripts/"
	],
	"report_names": [
		"fade-dead-adventures-in-reversing-malicious-run-only-applescripts"
	],
	"threat_actors": [],
	"ts_created_at": 1775434169,
	"ts_updated_at": 1775791197,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/a3fe2faa6bf5db001fdfc0313fcf8455ebff5db4.pdf",
		"text": "https://archive.orkl.eu/a3fe2faa6bf5db001fdfc0313fcf8455ebff5db4.txt",
		"img": "https://archive.orkl.eu/a3fe2faa6bf5db001fdfc0313fcf8455ebff5db4.jpg"
	}
}