Atomic MacOS Stealer (AMOS) - Malware Analysis Lab

23 minute read

Technical Analysis of an encrypted Atomic MacOS Stealer (AMOS) Binary


The malware being analysed is actually Cuckoo as opposed to AMOS. This was brought to my attention after making the video and itโ€™s too late to turn back. For more in-depth analysis refer to the below blog posts.

Overview (AI generated from video):


The video script discusses the analysis of the AMOS (Atomic MacOS Stealer) malware, including its origin, capabilities, and dynamic analysis. It also explores the decryption of encrypted strings within the binary.

Key Highlights

๐Ÿ” The AMOS malware is distributed through a fake Homebrew domain, targeting macOS users.
๐Ÿ“Š The malwareโ€™s capabilities include stealing credentials and sensitive data from macOS systems.
๐Ÿ“‘ Dynamic analysis tools like BM Ray provide insights into the malwareโ€™s behavior and processes.
๐Ÿ“ The malware uses various techniques like manipulating system settings and prompting for authentication to gather user credentials.
๐Ÿ› ๏ธ Tools like XMCO Viewer and Gidra can be used to analyze the structure and code of the malware.
๐Ÿ”’ The decryption of encrypted strings in the binary reveals important information about the malwareโ€™s functionality and targets.
๐Ÿšจ The AMOS malware poses a significant threat to macOS users, highlighting the importance of cybersecurity measures.

Transcript (AI generated from video):

00:00:00	let's take a look at some new malware uploaded to malware Bazaar so this has been uploaded by ndae they state that this has come from what looks to be a home brew domain however it's home brew. CX not the legitimate brew. sh domain and we can actually see the comparison so brew. sh is the missing package manager for Mac OS or Linux you can probably equate this to something like yum or app except for Mac OS operating systems now the home brew. ux you can is masquerading as this domain so they're obviously serving up
00:00:34	some stuff typo squatting and trying to see how many victims they can get but what are they actually serving up it is reported that this was Amos or Amos Steeler which is the atomic Mac OS Steeler so it's a Steeler designed to grab credentials and other sensitive information from Mac OS systems now if we look at the home brew domain we can see that it is serving up this Brew installer so we have Intel for the x86 and x64 based operating systems and then we have arm 64 as well so we have both Intel and Arm based architectures that
00:01:10	this is supported for now the home brew domain was first reported by Shan Holo as far as I know now Atomic Mac OS Steeler has been around for just over a year now the earliest known reports that I can see is by PhD W they give a little bit of a Lowdown on what the atomic Mac OS Steeler is and the capabilities it's since evolved and the Steeler itself is trying to remain a lot more undetected than it was when the initial variants were found in the wild so let's do some analysis on this particular sample from
00:01:42	a dynamic analysis standpoint I don't actually have a copy of this in a sandbox that I can work with so I'm going to use a tool such as BM Ray this actually gives us a nice breakdown of the process Behavior we can see that there is a bash script being used to identify the Hardware type so in particular get some information about the system and use that in its identifier so this system profiler with SP Hardware data type if we see something like this coming up that's a probably a good sign that this is
00:02:15	related to some sort of malware and we can also see the system profiler with XML also being used to get that same type of information this is probably equivalent to your windows version of a system info spawning and using that to identify the infected system we can also see that the extended attributes command the xatr command is being used to delete com. apple. quarantine so this is essentially like the alternative data stream to show that something has been downloaded from the internet so it's
00:02:51	removing that from Brew installer so that there's not any kind of gatekeeper checks that may prevent this from running because it's removed the the entirety of that once again something very suspicious we also see launch CTL load and it's loading a pist file so it does look like this might actually be establishing persistence essentially setting up that com. brew. Brew updata pist file which is going to be a launch agent that runs when the computer starts up and then we see that Osa script coming up now this is presenting a
00:03:23	dialogue to the user that says Mac OS needs to access system settings and is basically sitting there ready to obtain the user credentials so this is like a prompt to say can you authenticate are you allowing this to occur and this is a way of socially engineering someone into entering their credentials so that the credential Harvester can take that now there's a lot of repeated prompting of that Osa script assuming this is because this was done in a non-interactive environment also this file being created
00:03:55	that is named with a full stop at the beginning which means it's going to be a hidden file on the end point so it's likely this is being used in some way shape or form as well but that seems to be it that's captured in this Dynamic analysis now if we actually look at The Objective C right up to do with atomic Steeler we can actually see some overlap so where it prompts and says Mac OS wants to access system preferences we can see that this is Mac OSS needs to access system settings looking down in
00:04:28	these strings we can actually see Osa script has a prompt which is Mac OS needs to access system settings please enter your password so it seems like that's slightly changed now and it's instead prompting without the please enter your password but it still has the same pretext of Mac OS needs to access system settings and we see that here in the actual execution so there's a good chance that this is directly related one of the tools that we can use to examiner is xmco viewer this was created by the
00:05:03	same person who created detected easy and we can actually open up the file and get a little bit of a Lowdown on the structure of it the segments in it and a lot of the strings associated with it as well as the symbols that come up in the binary this tool is a little bit obscure and it's a little bit older and actually there is something that's probably a little less known if we find the file that's of Interest using protected easy it has a lot of the same functionality you might not see it here you might see
00:05:35	that it identifies that it's a Maco fat file you might notice that some of the visual aspects of it are very similar and in fact if we go to advance and then we click Mao fat you will see a very similar interface to what we just saw before and that's because it seems to bundle the same capability as this other tool this is baked within detected easy so we can go and we can see the hashes associated with the segments we can see the strings that are in this binary we can look at the memory map now usually
00:06:04	there's a few other tools that I would use on an operating system like Mac OS to do some analysis and there are disassemblers such as Hopper also debuggers for Mac OS that you could use to get more information on this binary as well but let's just take a look at it through detected easy at this point in time we can see the entropy this probably doesn't look like a packed Maco binary we can use heuristic scan to see maybe xcode was used within it we can see that code sign was likely used to sign it so we have the Maco header here
00:06:34	as well and this provides us some more information about the Maco file in itself if we look at the sections there is a text section there is stubs stub helper constant and a few other things such as C string and a number of other sections in this if we look at the string table and the symbol table there's a few symbols in here that might be of interest such as curl we can see file open get environment get host name we can see the creation of threads sockets that are going on so network connections that are going to occur we
00:07:05	can see data in the code we can see the code signature as well now looking over at the strings tab there's a number of strings in here that may be of interest we can see it's definitely associated with Mac OS because we can see reference to this core foundation. framework which is used on the Mac OS operating system and this is within the libraries directory which is where we expect it to be seen there's probably a number of strings that don't mean a lot here or maybe they don't have any significance
00:07:31	there is this reference to a a a a a AA which may be indicative of a buffer overflow I don't believe it's used like that in this case but this is a common string used in kind of exploitation that's trying to overflow a buffer to exploit a vulnerability like I said I don't believe it's related to that but something that may be of interest is those characters and then we can see what probably looks like a b 64 alphabet so this is used for encoding and decoding of strings so there might be some sort of encoding that goes on in
00:07:59	this binary we can also see what's quite interesting so there seems to be a list of extensions that this might be targeting so we've got txt RTF doc docx key wallet Etc so this is very interesting and something that if it came up in a binary would definitely catch your eye now one of the strings in here seems to be the 7 m43 Etc this is a little bit interesting because it seems to come up as a string that may be concatenated and maybe of interest but it doesn't seem to be something logical so maybe this is a key
00:08:31	that's being used somewhere so one of the things that we can actually do is take a look at this through something like gidra to understand how the Maco binary is working but to do this we may need to actually extract the binary because the Maco format actually has both the Intel and the arm versions of the binary so we might want to extract that and we can do that with something like seven zip we can go right click seven zip extract files you can see it cannot be accessed because I'm already accessing it let's close this off and
00:08:59	it's says that it cannot open the file as a Maco archive that's all right cuz in this we can see that it has actually extracted arm 64 and x64 as the files so using gidra what I'm going to do is I'm going to open up the Maco binary of Interest so in this case I'm going to use the x64 and we can see that gas actually identify that this is little Indian based and it is actually compiled through GCC we have probably the language that needs to be used to interpret this properly so let's just go okay and we might notice a few errors
00:09:31	and that's because there are some symbols that may be unknown in this binary that's okay let's just click okay so what we're going to do is we're going to open this up in gidra and we're going to ask it to be analyzed we're probably going to leave the defaults on and just hit analyze so it doesn't take too long and we can see that the analysis has finished now if we look at the defined strings this is similar to what we saw before when we were looking at the binary so we can see that 74 string mentioned here so what I'm going to do
00:09:59	is actually just go into it and try to delve into this a bit further so if we take a look at where this string is used it seems like it's used in a number of functions if we go to the first cross reference of this so just click on this function it looks like that string is being used in a exo operation so that's what this carrot symbol is indicative of and then there is also a modulo operation so that's what this percent symbol is indicative of now if I was to look at how this seems to be in a graph
00:10:30	I can actually see that there is operations that occur in a looping fashion so this is telling me that the bytes are having these operations occur over them to change their contents in some way shape or form I really want to understand what is being passed to this particular function the reason is because we can see that it takes two parameters parameter 1 and parameter 2 and for parameter 1 it's going to take the btes for that and it's going to then do that EXO operation and then then have the modulo operation occur on it with
00:11:04	0x1b as the key so let's dive into this a little bit further and see how we can recreate this I'm going to create probably a python script to do this cuz it'll be quite simple so I've started a python script and the first thing I want to do is Define the encryption key that we know is going to be used now what I want to do is probably create a placeholder so for encrypted byes we're just going to specify this as nothing yet because we don't know what the encryp byes are that are being passed to
00:11:31	this function now I'm going to do probably decrypted bytes and for this I'm going to give it a bite array and probably just give it a size of I don't know maybe 100 depending on how big the strings are that are being passed to it we can just kind of use that as a placeholder now I'm going to define a function and I'm probably just going to call it decrypt and this is going to take in probably bytes is what I'm going to specify now for this I'm going to create a for Loop and we're going to do this in the range of the length of the
00:12:01	encrypted byes so that all of the byes are going to be combed over with this operation to ensure that they're all decrypted now I'm probably going to recreate what we had in the code browser so I might just take this as a bit of a referral so I don't forget what we're creating here so what I'm going to do here is try to recreate this particular operation that's occurring we know that the bites are going to have this occur over them so we are going to pump this out to the decrypted byes so I wanted to
00:12:33	find the decrypted byes now in this case we can see that it's parameter one now parameter one is going to be essentially the bytes that are passed to this function we can see that they're specified as bytes here so this uar 1 is increasing every time so uar 1 = uar 1 + 1 this is telling us that this is a for Loop so that is literally only being used to facilitate the for Loop now because we've actually got a for Loop here for this for I in range we actually don't need that so it would probably look more like this so we want to have
00:13:06	the bites and we're going to have to specify the one that's being used so the first bites in the range we are going to have this operation with the with the encryption key in this case the encryption key we can see here so we've recreated that and that uvar one was just for the for Loop so this is going to be I so we're going to do I we're going to do modulo and 0x1b now we've essentially recreated that operation I'm not sure 100% if there's going to be any issues here uh let's just try and actually see what we get so I'm going to
00:13:42	have to return for the decrypted byes and then I'm probably going to do a print statement to say I want the decrypt function to be run against the encrypted bites now if we get some encrypted bites this ideally should work but we should take a look back at our code to figure out what that's happening so we do have parameter 1 and parameter 2 being P this function let's take a look at what callus this on the left hand side we can see quite a lot do call this so looking at the first one it does seem like maybe this string is being
00:14:14	passed to it local 470 so it does seem to be that string here so that's a bit interesting because straight after that we have that run so ideally we should be able to use this as bite string to get this we could take this right click and go copy python B string if you haven't used that before you will have to go copy special and then click on python byte string and paste this in now if I was to run this script we can see that there's an error oh and that's because the operating types here that we're specifying is both
00:14:47	an integer and a string now to fix that all we'd have to do is specify that this is an ordinal pass it to an ordinal when the operation occurs and we can see that now that has come out as the number 76 so if I look at the calls to this method there does seem to be fair few functions there is a function now of a37 and if I was to examine that I can actually see that local AE is the parameter that's being passed to it and we have this dat that's being moved into that local variable now if I was to examine that I
00:15:20	can actually see that this seems to be a data stream that probably doesn't make a lot of sense so what I'm going to do is I'm actually going to take all of this all the way up to to the end of the definition and right click and use that copy special and we can go a python by string is really what we want so if I copy it as a python by string I can now go over to my script paste it in and run it and we can see that now the number 77 has come up and it's at this point I've just realized what I've done I'm going
00:15:47	to go back the reason why 76 came out before is cuz I'm actually only specifying one bite here that's being returned not the actual array I need to change that to include the array silly error on my behalf now the null values are because I've given it an arbitrary length of 100 but outside of that there is this a46 L probably in itself doesn't make a lot of sense but let's see what happens if we actually paste in this new bite Stream So now if I run with the new bite stream I actually haven't given it
00:16:16	a large enough size I could make this 150 I'm not sure how many characters are actually in this and now we can actually see a lot more I think for the sake of defining a bite stream and making it Dynamic I I might just make this the length of of the encoded byes and that way we shouldn't have any issues going forward so now if we actually run this we can see Osa script is being run and I could actually decode this as yeah utfa we'll leave that by default and now if I run it we can see a little bit more
00:16:46	clearly that there's an Osa script being defined saying tell application finder move posix file one file to another with replacing and then Intel so this looks like apple script that's being run to tell the finder application to move one file to another location little bit interesting let's see what else we can find in these strings so we could go back once again find the next function and it seems like there is a pretty clear string that's being defined to this one so what I might want to do is
00:17:18	actually find where that string is defined and now copy out all of this not sure if it includes this data down here so I might just take the whole lot given they're not really new definitions and once again copy that python by string now if I was to replace the encoded bytes because we've copied the B string we can once again just replace this with a new one and run it and you can see once again there seems to be that mention of Osa script tell finder this so once again seems to be something to
00:17:52	do with an Osa script that the strings have been encrypted using this method so when we're looking at cross references to our decoding functions so in this case this function I'm first just going to rename it so we can just call this function decrypt now we can actually see where this is used looking at the incoming references to that decryption function there's actually quite a lot that's having their strings decrypted so we could go through each of these functions figure out what strings being
00:18:19	passed to it and do the decryption using our new script one of the interesting things about this version of Amos Steeler is where we see the decription key we can see it here is this 7M if we scroll up just a little bit there are a number of strings that almost seem like they are encrypted and so we can actually leverage this to unveil some of the strings that are meant to be in this binary now there's quite a lot of these unfortunately but we can still for example take let's say the first one here and copy the B string and if we
00:18:55	make this the encrypted bytes we can now see that it comes out as system. txt and we can go through and do this for pretty much all of them so we've got base CFG and what seems to be formatting strings these strings are currently being found in the C string section of the Maco binary but there are some others that are sitting in the con section so we can see that that is the one with all the A's and some of those other strings associated with the Osa script that we saw before and so by going through the
00:19:30	strings of this binary and decrypting them shortly after we see this reference to home we actually have this string that starts with 9 at CW and if we copy that into our script and run it we can actually see that it comes out with 85217 22285 static. PHP so now we actually have the command and control associated with this malware so I've gone ahead and painstakingly extracted all of what appears to be encrypted strings in that binary and I've put them in an array and then I just added an iteration over that
00:20:10	array so you can see that there's ink bytes array for each of these I get the length and then I decrypt them and now if we run this across our binary we can actually see a lot of what is actually involved in this binary the Mystery Begins to unveil itself so we can see that there's Alias files I will mention probably the last character in all of these is going to be a dud character perhaps or something that isn't actually right and that's because of the null bites at the end of these but that's all
00:20:42	right we can see Alias file startup dis mentioned we can see launch agents we can see Brew upd dat we can see that launch CTL load and that string before that is likely going to be passed to it so that's going to be the launch agent being mentioned we can see evidence of it deleting files we can see the C2 we can see that the content encoding for the C2 is being specified as binary we can see that Osa script is setting the volume output muted values we can see this pw. dat so perhaps a password file
00:21:17	being mentioned we can see getting rid of the extended attributes that we saw we can see an identifier a goid identifier as well we can see user agents we can see mention of a screen capture the system profiler to get the hardware information we can see PS Orcs for understanding what processes are running on the system we can see login data we can see extensions we can see preference files cookies SQ lights so all associated with stealing session cookies or log on data from browsers we can see FTP filezilla recent servers
00:21:52	more cookie stuff and the list goes on we can see evidence of crypto wallets Discord tokens Wasabi wallets Exodus Opera Milla Firefox Google Chrome and we can see that duplicate file that we saw before this looks like it's actually prompting and saying that there was an execution error when you try to run the binary as a bit of a way of making the user unaware that they have actually run this credential stealer but that's it that's what I wanted to show you today thanks so much for hanging in there let
00:22:24	me know your thoughts feelings comments anything else in the comment section below if you found it useful let me know give us a like subscribe if you feel like it they're free they don't cost you anything and this video is free it also didn't cost you anything so it would be appreciated as it does help the algorithm and it does help get this educational material out there so thanks so much and I will catch you next time