FrigidStealer is an information-stealing malware that emerged in January 2025. It targets macOS endpoints to steal sensitive user data through deceptive tactics. Unlike traditional malware, FrigidStealer exploits user trust in routine software updates, making it particularly insidious. As a significant threat, it underscores the need for extended security measures on macOS endpoints. The malware’s financial motivations, potentially linked to the EvilCorp syndicate, underscore its threat to both individual users and enterprises, with stolen data including credentials and cryptocurrency wallets posing risks of identity theft and financial fraud.

In this blog post, we explore the behavior of FrigidStealer and demonstrate how Wazuh, an open source SIEM and XDR platform, can be configured to detect this threat.

Understanding FrigidStealer

FrigidStealer is an information-stealing malware distributed via fake browser update pages hosted on compromised websites. It tricks users into downloading a malicious disk image file (DMG). The downloaded DMG file requires manual execution, often bypassing macOS Gatekeeper protections by prompting users to enter their password via AppleScript. Once installed, FrigidStealer targets sensitive data on the macOS endpoints for exfiltration.

The following activities are discovered upon execution of the malware:

  • It registers as an application, ddaolimaki-daunito, on the macOS endpoint, detected at the executable path Volumes/Safari Updater/Safari Updater.app.
  • It establishes persistence via launchservicesd as a foreground application with bundle ID, com.wails.ddaolimaki-daunito.
  • It targets sensitive data such as browser credentials, files, system information, and more using Apple Events for unauthorized inter-process communication.
  • It exfiltrates stolen data to a command-and-control (C2) server via DNS data exfiltration through mDNSResponder.
  • It terminates the ddaolimaki-daunito process after data exfiltration to evade detection, removing associated jobs.

Analyzed sample

Hash AlgorithmValue
SHA256e1202c017c76e06bfa201ad6eb824409c2529e887bdaf128fc364bdbc9e1e214
SHA1a8e3970d7d769abf98025bfaf94b516aacf92bd1
MD533ab50c5a076aad3571dd3c9d32c6e6a

Infrastructure

We use the following infrastructure to demonstrate the detection of the FrigidStealer malware on macOS endpoints with Wazuh:

  • Wazuh 4.11.2 central components (Wazuh server, Wazuh indexer, Wazuh dashboard) installed using the Quickstart guide on an Ubuntu server.
  • A macOS 12 endpoint as the victim’s endpoint. This endpoint has a Wazuh agent installed and enrolled to the Wazuh server.

Detection with Wazuh

Configuration

We use the Wazuh agent to monitor the system logs with the aid of the macOS unified logging system (ULS). We then create custom decoders and rules on the Wazuh server to detect FrigidStealer activities on the monitored macOS endpoint.

macOS endpoint

The macOS ULS centralizes the management and storage of logs across all system levels. Wazuh interfaces with the CLI log tool using the –style syslog format to collect logs from macOS ULS. 

Follow the steps below to configure the Wazuh agent to monitor activities related to the FrigidStealer malware.

  1. Add the following highlighted configuration to the existing  <localfile> block within the Wazuh agent /Library/Ossec/etc/ossec.conf configuration file:
<localfile>
    <location>macos</location>
    <log_format>macos</log_format>
    <query type="trace,log,activity" level="info">(process == "sudo") or (process == "sessionlogoutd" and message contains "logout is complete.") or (process == "sshd") or (process == "tccd" and message contains "Update Access Record") or (message contains "SessionAgentNotificationCenter") or (process == "screensharingd" and message contains "Authentication") or (process == "securityd" and eventMessage contains "Session" and subsystem == "com.apple.securityd") or (process contains "ddaolimaki-daunito" or process contains "bzip2" or process contains "open" or process contains "launchd") or (message contains "xpcproxy application.com.wails.ddaolimaki-daunito") or (process == "distnoted" and eventMessage contains "com.apple.LaunchServices.ShowAllExtensionsChanged") or (process == "launchservicesd" and eventMessage contains "ddaolimaki-daunito" or eventMessage contains "39183")or (process == "loginwindow" and eventMessage contains "com.wails.ddaolimaki-daunito") or (process == "mDNSResponder") or (process == "runningboardd" and eventMessage contains "application.com.wails.ddaolimaki-daunito")</query>
  </localfile>
  1. Restart the Wazuh agent to implement changes:
# /Library/Ossec/bin/wazuh-control restart

Wazuh server

Create custom decoders and rules on the Wazuh server to detect the activities of the FrigidStealer malware on the monitored macOS endpoint.

Custom decoders

  1. Create a file frigidstealer_decoders.xml in the /var/ossec/etc/decoders/ directory:
# touch /var/ossec/etc/decoders/frigidstealer_decoders.xml
  1. Add the following decoders to the /var/ossec/etc/decoders/frigidstealer_decoders.xml file:
<decoder name="macOS_launchservicesd">
  <program_name>^launchservicesd</program_name>
</decoder>

<decoder name="macOS_ddaolimaki-daunito">
  <program_name>^ddaolimaki</program_name>
</decoder>

<decoder name="macOS_mDNSResponder">
  <program_name>^mDNSResponder</program_name>
</decoder>

<decoder name="macOS_launchservicesd_child">
  <parent>macOS_launchservicesd</parent>
  <regex type="pcre2">\[com\.apple\.launchservices:(\w+)\]\s*DEATH: Removing app App:"ddaolimaki-daunito"\s*asn:([0-9a-fx-]+)\s*pid:(\d+)</regex>
  <order>subsystem_category,asn,pid</order>
</decoder>

<decoder name="macOS_launchservicesd_child">
  <parent>macOS_launchservicesd</parent>
  <regex type="pcre2">\[com\.apple\.launchservices:(\w+)\]\s*ADDING { "CFBundleExecutablePath"="([^"]+)", "CFBundleVersion"=[^,]+, "LSBundlePath"="([^"]+)", "ApplicationType"="(\w+)"[^}]+?"pid"=(\d+), "CFBundleIdentifier"="([^"]+)"</regex>  
  <order>subsystem_category,executable_path,bundle_path,application_type,pid,bundle_id</order>
</decoder>

<decoder name="macOS_ddaolimaki-daunito_child">
  <parent>macOS_ddaolimaki-daunito</parent>
  <regex type="pcre2">\(LaunchServices\)\s*\[com\.apple\.launchservices:(\w+)\]\s*LSApplicationCheckIn\(\)\s*,\s*app\s+being\s+registered\s+is:"([^"]+)"</regex>
  <order>category,executable_path</order>
</decoder>

<decoder name="macOS_ddaolimaki-daunito_child">
  <parent>macOS_ddaolimaki-daunito</parent>
  <regex type="pcre2">\(AE\)\s*\[com\.apple\.appleevents:(\w+)\]\s*eEntitlements\s*,\s*token\s*(\d+\/\d+), designatedCodeReq = {[^}]+, "kTCCCodeIdentityCanSendToAnyTarget"=(\w+), "kTCCCodeIdentityCSFlags"=(\d+), "kTCCCodeIdentityDesignatedRequirementData"=\$[A-F0-9]+, "kTCCCodeIdentityExecutableURL"="([^"]+)", "kTCCCodeIdentityIdentifier"="([^"]+)", "kTCCCodeIdentityIdentifierType"=\d+, "kTCCCodeIdentityPlatformType"=\d+, "kTCCCodeIdentityPromptPolicy"=(\d+)</regex>
  <order>subsystem_category,token,can_send_to_any_target,cs_flags,executable_url,sender_identity,prompt_policy</order>
</decoder>

<decoder name="macOS_ddaolimaki_daunito_child">
  <parent>macOS_ddaolimaki-daunito</parent>
  <regex type="pcre2">\(LaunchServices\)\s*\[com\.apple\.launchservices:(\w+)\]\s*CFDictionaryRef copyApplicationInformationDictionaryGivenASNUsingLocalCache\(LSSharedMemoryPageConstRef, LSASNRef\)\(\), information in shared memory with seed \d+ was still valid, so using cached info {[^}]+?"CFBundleExecutablePath"="([^"]+)"[^}]+?"LSBundlePath"="([^"]+)"[^}]+?"ApplicationType"="(\w+)"[^}]+?"LSASN"=([A-Za-z0-9:.-]+)[^}]+?"LSLaunchedWithLaunchD"=(\w+)</regex>
  <order>subsystem_category,executable_path,bundle_path,application_type,asn,launched_with_launchd</order>
</decoder>

<decoder name="macOS_ddaolimaki_daunito_child">
  <parent>macOS_ddaolimaki-daunito</parent>
  <regex type="pcre2">\(RunningBoardServices\)\s*\[com\.apple\.runningboard:(\w+)\]\s*Identity resolved as app\<application\.(com\.wails\.ddaolimaki-daunito)\.\d+\.\d+\((\d+)\)\></regex>
  <order>subsystem_category,bundle_id,uid</order>
</decoder>

<decoder name="macOS_loginwindow">
  <parent>macOS_loginwindow</parent>
  <regex type="pcre2">\[com\.apple\.loginwindow\.logging:(\w+)\]\s*-\[PersistentAppsSupport saveLogoutPersistentState:finalSnapshot:\]\s*\|\s*previouslyRunningApps:\s*\(\s*{\s*BackgroundState\s*=\s*(\d+);\s*BundleID\s*=\s*"([^"]+)";\s*Hide\s*=\s*\d+;\s*Path\s*=\s*"([^"]+)";\s*</regex>
  <order>subsystem_category,background_state,bundle_id,path</order>
</decoder>

<decoder name="macOS_mDNSResponder_child">
  <parent>macOS_mDNSResponder</parent>
  <regex type="pcre2">(?i)(DNSServiceQueryRecord).*mask\.hash: '(\S+)'.*PID\[(\d+)\].(\S+)\)</regex>
  <order>program_type,hash,pid,process_name</order>
</decoder>
  1. Change the ownership and permissions of the /var/ossec/etc/decoders/frigidstealer_decoders.xml file:
# chown wazuh:wazuh /var/ossec/etc/decoders/frigidstealer_decoders.xml
# chmod 660 /var/ossec/etc/decoders/frigidstealer_decoders.xml

Custom rules

  1. Create a file frigidstealer_rules.xml in the /var/ossec/etc/rules/ directory:
# touch /var/ossec/etc/rules/frigidstealer_rules.xml
  1. Add the following rules to the /var/ossec/etc/rules/frigidstealer_rules.xml file:
<group name="malware,frigidstealer,">

<!-- Initial execution -->
  <rule id="100101" level="11">
    <decoded_as>macOS_ddaolimaki-daunito</decoded_as>
    <match type="pcre2">(?i)app being registered is:(".*ddaolimaki-daunito")</match>
    <description>Possible FrigidStealer malware detected at $(executable_path)</description>
    <mitre>
      <id>T1204</id>
    </mitre>
  </rule>

<!-- DNS query -->
  <rule id="100102" level="11" frequency="2" ignore="60">
    <decoded_as>macOS_mDNSResponder</decoded_as>
    <field name="program_type" type="pcre2">DNSServiceQueryRecord</field>
    <field name="process_name" type="pcre2">ddaolimaki.*</field>
    <description>FrigidStealer malware is making a suspicious DNS query to $(hash). Possible data exfiltration to C2 server.</description>
    <mitre>
      <id>T1105</id>
      <id>T1041</id>
      <id>T1071.004</id>
    </mitre>
  </rule>

<!-- Data exfiltration -->
  <rule id="100103" level="11">
    <decoded_as>macOS_ddaolimaki-daunito</decoded_as>
    <field name="executable_url" type="pcre2">.*Finder</field>
    <field name="sender_identity" type="pcre2">.*</field>
    <description>FrigidStealer malware (ddaolimaki-daunito) is attempting to use Apple Events, potentially for unauthorized inter-process communication or data exfiltration.</description>
    <mitre>
      <id>T1543</id>
      <id>T1055</id>
      <id>T1559</id>
    </mitre>
  </rule>

<!-- Process termination -->
  <rule id="100104" level="11">
    <match type="pcre2">(?i)Removed job for.*ddaolimaki.*</match>
    <description>FrigidStealer malware process terminated after data exfiltration.</description>
    <mitre>
      <id>T1489</id>
    </mitre>
  </rule>

<!-- Persistence -->
  <rule id="100105" level="11">
    <decoded_as>macOS_launchservicesd</decoded_as>
    <match type="pcre2">(?i)(?i)"LSBundlePath"="(.*Safari Updater.app)"</match>
    <field name="application_type" type="pcre2">Foreground</field>
    <field name="bundle_id" type="pcre2">com.wails.ddaolimaki-daunito</field>
    <description>Possible FrigidStealer malware running in $(application_type)</description>
    <mitre>
      <id>T1541</id>
    </mitre>
  </rule>

</group>

Where:

  • Rule ID 100101 triggers an alert indicating possible FrigidStealer malware detected at the executable path.
  • Rule ID 100102 triggers an alert indicating that FrigidStealer malware is making suspicious DNS queries, potentially exfiltrating data to a command-and-control (C2) server.
  • Rule ID 100103 triggers an alert indicating FrigidStealer malware (ddaolimaki-daunito) attempting to use Apple Events, potentially for unauthorized inter-process communication or data exfiltration.
  • Rule ID 100104 triggers an alert indicating FrigidStealer malware process termination after data exfiltration.
  • Rule ID 100105 triggers an alert indicating possible FrigidStealer malware persistence via launchd, running in foreground execution.
  1. Change the ownership and permissions of the /var/ossec/etc/rules/frigidstealer_rules.xml file:
# chown wazuh:wazuh /var/ossec/etc/rules/frigidstealer_rules.xml
# chmod 660 /var/ossec/etc/rules/frigidstealer_rules.xml
  1. Restart the Wazuh manager for the changes to take effect:
# systemctl restart wazuh-manager

Visualizing alerts on the Wazuh dashboard

Follow the steps below to view the alerts generated on the Wazuh dashboard when the Frigidstealer malware is executed on the monitored macOS endpoint.

  1. Navigate to Threat intelligence > Threat Hunting, and click the Events tab.
  2. Click + Add filter. Then filter by rule.groups.
  3. In the Operator field, select is.
  4. Search and select frigidstealer in the Values field.
  5. Click Save.
Figure 1: Showing FrigidStealer activities on the Wazuh dashboard.

Conclusion

FrigidStealer represents a growing threat to macOS users, leveraging social engineering and sophisticated techniques to steal sensitive data. In this blog post, we demonstrated how to use Wazuh custom decoders and rules to detect the FrigidStealer malware on macOS endpoints.

Stay proactive, keep your systems monitored, and protect your macOS endpoints from emerging threats like FrigidStealer. To explore the full capabilities of Wazuh or refine your setup, consult the Wazuh documentation. If you have any questions about this blog post or Wazuh, we invite you to join our community, where our team can assist you.

References