
Now, our next speaker is just about to join us with a fantastic talk, and it's going to be about Captain Jack Sparrow, the pirate king, or more accurately, it's about massjacker, who is a type of very evasive malware. It's a cryptohacking, cryptojacking malware. And this is a speaker who has participated in Besides Tel Aviv in the past. So while we get ready, I just want to remind everybody that throughout the whole day, we're going to have coffee and food and we're going to have sponsor activities. We're going to have amazing CTF activities on site as well. So make sure you check out our capture the flag activities during the break. Ari, are you ready over there? Okay, so let me
introduce our next speaker, Ari. He is a malware researcher at Cyber Alarch Labs where he tracks emerging threats and investigates post exploit techniques with deep expertise in attack components and security solutions. Ari is going to bring us some real world malware intelligence to the bite stage. Again, this is the kind of content that you can only see here. Ari is going to see us to show us this incredible unknown malware called mass jacker. Okay, let uh let's switch over to Ari's presentation, please. Everybody, Ari, are you ready? Yep. >> Yeah. You good to go? Please, everybody, welcome Ari Novik to the B8 Tel Aviv stage. You got it. >> Hi everybody. Thank you for coming to my
talk, Captain Massjacker Sparrow, uncovering the malware's buried treasure. In this talk, we'll cover a previously unknown cryptojack and malware which we called massjacker. And we'll also talk about how we ended up finding over 750,000 unique crypto addresses belonging to the massjacker operators, all from a single sample of the malware. Before we begin, a little bit about myself. My name is Ari Novik. I'm a malware researcher at Cyber Arc. I have about seven years of experience in cyber security and in my free time, I'm an amateur scientist. So the talk itself will be divided into three main parts. We'll start with an introduction, a little bit about what cryptojacking is and how we ended up finding massjer. After that, we'll do a
deep dive into some of the anti-analysis techniques used in the infection chain leading up to the malware. And finally, we'll talk about maskjacker itself and the previously mentioned crypto. So starting with the introduction, what is cryptojacking? So I'll actually start from the very basics just to bring everyone up to speed. In terms of user experience, doing a wire transfer in a bank is very similar to doing transactions in crypto. Just like how for wire transfers we have bank accounts, in crypto a similar concept is called a wallet. And just like how bank accounts can hold various currencies like US dollars, Canadian dollars, Australian dollars, and a bunch of currencies that aren't necessarily called dollars. In crypto, you have your
bitcoins and your litecoins and your dogecoins, and a bunch of currencies that aren't necessarily called coins. Finally, to do a trans a wire transfer, you need the account number of the bank account you want to transfer money to. In crypto, sorry, in crypto, similar concept is called the address. And something to note about addresses is that they are a lot longer and more complicated than your typical bank account number. So, people tend to copy and paste them rather than actually type them out. And that's where cryptojacking comes in. Cryptojacking is a technique used by malware with the purpose of stealing cryptocurrencies from users on an infected machine. It's a relatively obscure technique. The term is often
used interchangeably with other terms like crypto mining or clipboard jacking. But for the purposes of our talk, what I mean when I say cryptojacking is stealing cryptocurrencies by manipulating the clipboard with the following flow. A user copies an address of a wallet they want to transfer money to. The malware then compares the copied content to a bunch of addresses belonging to the thread actors. And if they find something similar enough, they override the contents of the clipboard so that when the user actually pastes the address and transfers the money, they end up transferring it to the thread actors instead of their intended target. So that's cryptojacking. Now, how did we actually find mass checker? Well, we didn't start looking
specifically for cryptojackers. We had a completely different direction in mind originally. The thought was malware often targets pirates. Those people who download cracked programs and these kind of people might not know about platforms like virus total or anyone. and they probably don't have the most reliable anti virus or ADR solution either because they disable them to actually be able to download their cracked programs or maybe their antiviruses are in themselves a cracked program. But that kind of creates a blind spot for us researchers because two of the most common ways for us to actually go looking for malware are via shared platforms like uh virus total and any run or via our own uh product telemetry
like our anti viruses and ADRs. That means potentially there's malware out there that's completely unknown to us researchers because they exclusively target pirates and are therefore a bit harder for us to find. So we thought let's play the role of a pirate and see if we could find any such malware. And it's pretty much what we did. We went to Google and started googling cracked programs. We Googled cracked office, cracked antiviruses, a bunch of other cracked programs. And one website that repeatedly showed up in our search results, often even on the first page, was a website called Pestop. So looking at testtop, it was clearly malicious, but didn't do anything too out of the ordinary. Anytime we downloaded a
supposedly cracked program, the website would then redirect us to a page um with some link to get us to download something else. And each time the link would be different, but it would always result in some kind of malware infection. And that was perfect for our purposes because we were looking for new kinds of malware targeting pirates. And Pesttop made it very easy for us to look at a lot of different malares targeting pirates. So we looked at a bunch of different samples and eventually settled on mass checker. Now there's a couple reasons why we chose specifically to look at mass checker. For starters, when we ran in a sandbox, there was no obviously malicious behavior. There were
no files being encrypted suggesting it was some kind of ransomware or cookies being stolen suggesting it was some kind of info stealer. So we were kind of curious to see what we were dealing with. Second reason was the infection chain. Most of the binaries we downloaded from pesktop were either themselves the final payload or they were a packer that unpacked the second stage which was then the final payload. For maskjacker though the original executable ran a cmd script which ran a powershell script. The powershell script then downloaded three additional executables. The first one we quickly identified as the amade malware. But the other two were some kind of net malware. It seemed to have been the same executable just
once compiled for x86 and once compiled for x64. Continuing from there, they then downloaded a DL which unpacked a second DL which finally unpacked the mass checker payload. Now obviously going into a lot of steps into all of or into a lot of detail into all of these steps would be a bit much for a single talk. So we will instead focus on one of the steps, the first DL which we call packer D1 and from there move on to mass checker. So, Packard D1 comes with five embedded resources and each resource is obfuscated and it's used for its own advanced anti- analysis technique. Again, five is a bit much. So, we're going to only focus on two of them.
Starting with packer D1's first resource. It's used for a technique called just in time hooking. And just in time hooking is a net specific hooking technique. It works by uh hooking a special function called the compile method, which we'll talk more about in the next few slides. But basically the net effect of this technique is that it replaces a bunch of functions with a bunch of other functions during runtime. And this could kind of mess with static analysis because you can have a situation like in the diagram on the right where you have just in time hooking implemented and then some function fu is called. So you might think we should look at function fu but
during execution even though function fu is called a different function function goo is the one that actually executes. So to understand just in time hooking we need to start with the just in time compiler or just in time compilation. When you write a program in a net language like C or VB.NET and compile the code into a binary the code isn't directly compiled into assembly. Instead it's compiled into an intermediate language called IL code or sometimes CIL or MSL and then that code is further compiled into assembly during execution. The way it works is every time a new IIL code function is called that compile method I mentioned before is called. And what it does is it takes that I code
function and compiles it into an assembly function for execution. So this whole just in time compiler is implemented with a special class called the IORJIT compiler class which has a bunch of functions in it including the compile method and as you can see on screen the compile method takes five different parameters. We'll start with the second one. A strruct called core info method info. And yes, info shows up twice. Sometimes naming things is hard. Um, I think the clicker died. Ah, okay. Yeah. So, core info method info has a lot of different parameters in the strct. The two of interest to us are IL code and IL code size. Uh, I code will just be a pointer to the IL code
function that's supposed to be compiled. and IL code size is going to be the size of that function. Now once the compile method runs, it then compiles the code into assembly which is then saved in two more of the parameters of the compile method. Native entry will be a pointer to the newly created assembly function and native size of code will again be the size of the function but this time the assembly one instead of the IL code one. So just in time hooking works by hooking the compile method and stepping in right before it runs. Basically what it does is it replaces the pointer to the IL code that's supposed to be compiled with
a pointer to the replacement code and then it just calls the original compile method with this new replacement code resulting in some replacement assembly being compiled and executed instead. Now there is a bit of a catch to trying to hook the compile method. Typical hooking techniques use things like the get proc address win API to try and find the address of the function you want to hook. But this doesn't work for um the compile method. So instead we have to rely on a net component a DL called CLRJIT DLL which has a couple of exported functions. One of them is called getjit. And when you call that function you get a pointer to the IROJIT
compiler class. From there you can just find in the vtable the pointer to the compile method you want to hook. Another slight distinction compared to typical hooking techniques is that you don't actually have to modify the beginning of the compile method itself and then create a trampoline to return back to it. Instead, you could modify the pointer in the vable and then just directly call the compile method when you want it to run. So, tying this back to packer D1, we said packer D1 was one of these steps in the infection chain leading up to our main malware, Massjacker, and it comes with a bunch of embedded resources used for different advanced anti- analysis techniques. And we're now looking at the
first one which we said would be used for just in time hooking. So the way it works is Packard D1 has to deobuscate this first resource and then it parses it into a table like structure. The first column in the table is just going to be the list of the IL code functions or the addresses of the IL code functions that the malware wants to replace. The second column is just going to be the replacement functions. And the third one is simply going to be the sizes of these replacement functions. Now once the table is parsed the malware then hooks the compile method using the technique described earlier and from there anytime a new IIL code function is
called the hook method is triggered and what it does is it looks for the address of the IL code that's supposed to be compiled in the table and if it finds a matching address it then replaces that code with the the replacement code from the same row and calls the compile method with that. If however the original IL code is not in the table, it just calls the compile method with that pointer to the original IL code. So that was the first technique. I know it was a bit much. Hopefully you're all still with me. We got one more of these and then we're going to move on to mass checker. So we're actually going to jump
to the third technique, but the third resource. But before we do, we need to talk about a related technique which is very common in net malware. As far as I know, it doesn't really have a name, but I'm going to be calling it the four switch K subfuscation. Basically, the way it works is you start off with a block of code that would normally run top to bottom, you break it up into smaller parts, shuffle their order around, throw them inside of a switch case inside of a for loop. What this does is instead of the code running top to bottom, it runs based on the iterations of the for loop. The first iteration will jump to one of the cases,
execute some of the original code, and then it'll modify the variable going to the switch. That way, the next round in the for loop will jump to a different case. Again, execute part of the original code, and then again, it'll modify the variable going into the switch, resulting in the next round of the for loop jumping to yet another case. And this repeats over and over and over until finally a return instruction is called, and we step out of the for loop. So once we de obusiscated packerd's third resource, we got a strange looking list of sometimes numbers, sometimes pairs of numbers. It wasn't at all obvious what this would be used for. So we jumped right into the code which
happened to look like a for switchk subfuscation, but with a couple tweaks. Firstly, it was split up into two separate functions. There was an outer function running the for loop and each iteration of the for loop was running the inner function which ran the switch case. Second distinction is the variables going into the switch didn't actually get modified by the different cases. Instead, they all came from that list from Packard D1's third resource. Now, once we figured that this whole setup was a for switch case obuscation, we started looking at the different cases and we saw a couple of functions that were called from any of the cases. For now, we're going to call them funk a
and funk b and they seemed to operate on some second list by adding and removing values from it. So, this whole setup is kind of complicated and pretty weird, and I struggled with it for a while trying to make sense of what this whole thing was supposed to be used for. At some point, I was telling a colleague of mine about it. I don't remember the exact conversation, but I was saying something like, "Yeah, and it's very weird. There's these two extra functions that keep on adding and removing values from some second list, and I don't really understand what this whole thing is being used for." And his response was something like, "Oh, so you mean it's a
VM?" And as soon as he said that, everything became crystal clear and made a whole lot more sense. So now let's talk about the VM anti-analysis technique. For starters, VM like you might have guessed stands for virtual machine. Basically the way this technique works is that the thread actors have to invent their own kind of machine code or assembly like code and then they have to implement a virtual machine in some higher level language like C# to be able to execute their code. They need to create things like the uh stack and the register and they of course need to actually be able to implement the different kinds of instructions and keep track of an
instruction pointer and so on. And finally, the thread actors have to actually invent their or write their own script in their madeup language to actually feed into their virtual machine for execution. Now, this can be pretty tough to analyze. Starting with statically, if we only look at the higher level language, the C in our case, then you'll get an idea of what the virtual machine can do, but it won't actually tell you what the machine will do. For that, you need to look at the machine code script. But like I said, this is something made up by the thread actors. You generally won't have some publicly available parsing tool for it. So it kind of looks like a random mess
and you have to somehow make sense of it. Now dynamically things are a bit easier because you could just sort of follow along with what's happening in the stack and the registers and make some educated guesses about what the script is supposed to be doing. Still this isn't entirely trivial because you do have to spend a fair amount of time actually finding the uh stack and the registers before you actually are able to follow along with them. So quick recap because it was a bit confusing. We had two lists and two pairs of functions operating on these two lists. We started off with a list from packardd1's third resource and it was operated on by two functions that
seemed to be implementing some variation of the force switchk obfuscation and then in many of the different cases we saw two functions that showed up many times by that operated on some second list by adding and removing values from it. So it turns out this first list was actually the machine code script. I mentioned before that there was sometimes numbers and sometimes pairs of numbers and the cases where there were single numbers were simply instructions without any operands and pairs of numbers run instruction followed by the operand and this was of course fed into the virtual machine. The outer function running the for loop was just updating the instruction pointer to point to the next instruction. The inner function the
switch case was actually executing the different instructions. each different case in the switch case was a different kind of instruction to execute. The second list was a bit easier. It was just the machine stack and then funk a that was adding values to the stack was of course a push-like instruction and funk b removing values from the stack was just a pop-like instruction. So at this point I spent a fair amount of time talking about packer d1 and you might be wondering why I'm spending so much time on packer d1 if it's not even the final payload of our infection chain. And there's a couple reasons. Firstly, because I think the techniques are interesting and worth talking about
in themselves, but also because of a malware called mass logger. Not mass checker, mass logger. So mass logger is a malware from four or five years ago, which just so happens to have used many of the same anti- analysis techniques as the ones we were seeing in packerd in its own infection chain. In fact, looking at the code snippets provided in the articles about mass logger from way back when comparing it to what we were looking at, it was pretty much the same code up to names of functions and names of variables. So, for most of the rest of the reverse engineering process, we actually figured we were dealing with mass logger. But then we got to the
final payload and it was clear we were dealing with something else. Mass logger, which was a generic Trojan with all sorts of capabilities. It was a key logger. It could steal browsing data. It could do a bunch of other stuff. Whereas what we had was a single functionality malware. It was a cryptojacker and nothing else. Still, the two malware are clearly related. The code similarities suggest they were developed by the same thread actors. So, we figured since the key logger was named mass logger, an appropriate name for our cryptojacker would be massjer. So, now let's finally talk about massjer. So, like I said, massjer was a single functionality malware. So, the flow is actually pretty straightforward.
It starts by downloading a couple of encrypted files from a command and control server. Then since the files are encrypted, naturally the next step is to decrypt them. And that's how the malware actually gets its list of addresses belonging to the thread actors. From there, it's pretty much what I showed before. The malware sits and waits until a user copies some content to the clipboard. Then the malware compares the copied content to the set of addresses belonging to the thread actors. And if they find something similar enough, they override the contents of the clipboard. So that assuming a user copied an address in order to transfer money to a wallet, they end up pasting the thread
actor's address and transferring money to the thread actors. Now, the story of how we found so many unique addresses from a single sample of the malware kind of had its ups and downs. When we originally ran the whole infection chain in a sandbox, we saved all the different files it created, all the artifacts it created so that we can then use them later if we wanted to decide if we decided to use them in to go into deeper analysis into Massjacker. And of course, we did, but by the time we actually got to the Massjacker payload, we actually lost one of those files. It downloaded from a command control server. And that was a bit of a
problem because that's where some of the addresses belonging to the thread actors were, and that was a big part of the story. So we went to Virus Total hoping to find the file there and we found a file with the same name from a similar IP address. It was the same network but slightly different IP address. So we figured there's a chance it's still the same file and our sample of mass tracker will be able to decrypt it. So we downloaded it and gave it a shot and it worked. So we figured we probably found the original file, got lucky and started looking into the different uh addresses. But then something happened and we had
to revert back to a previous snapshot in our VM. Again, the snapshot didn't have the file, but this time we were a bit more organized. We went to our folder with all of the files, uh, the artifacts we got. We copied the file we downloaded from Virus Total back into the VM and got back to work. But we quickly noticed something strange. The addresses seem to have completely changed. After a bit of head scratching, we realized we were wrong. We didn't actually copy the file from Virus Total back into the VM. We found the original file. And that was actually a pretty big discovery because it told us there were at least two different files encrypted with the same
key. And that raised the question, if two of the files are encrypted with the same key, maybe all the files are encrypted with the same key. So we went back to Virus Total and downloaded all the files we could find with those same names and let Masser try and decrypt all of them. And it worked. And this was a pretty great success. Um, the original file we got from virus total gave us 50,000 addresses, which honestly is a pretty huge amount in itself. But this little trick ballooned that up to $778,531 addresses at the time in August 2024, they were holding around $95,000 worth. But if we added up the amount of money they were holding historically, it
would have been worth over $300,000. So now let's talk about a couple of notable addresses and we'll finish up starting with this one. It's the address of a Tron wallet. And the reason it's notable is that we were actually able to find it on Reddit. There were a bunch of posts on Reddit, all titled with the address of this wallet. Most of them were actually removed by moderators, but we were lucky enough to find one post that wasn't. It read something like, "Hello, I accidentally sent you some money. Please send it back to me. I needed desperately to settle some debt." Kind of reads like a scam, which it probably is. And that's interesting because it tells us that the thread
actors are probably trying to make money off of scams in addition to cryptojacking. One more thing about this wallet is that the user posting all of those posts on Reddit had one more post about why they love a project called Pikamoon. Now, a quick Google search told us Pikamoon is some kind of gaming platform that allows players to earn NFDs which they can then trade for crypto. And that ties us nicely into our next wallet. This is the address of a Solana wallet. And something nice about Salana is that you can actually trade in NFTs in Salana and people can see based on the history of your transactions which NFTs you held. So a few NFTs held
by the thread actors include the chilled ape NFD or that's sort of the classic ape or monkey that people talk about normally with NFTs but also a bunch of others. Still, the reason this address is actually interesting is because the vast majority of the money we found and in fact the vast majority of the transactions in general all came from this single wallet. In fact, the overall distribution of the profits and the transactions was kind of unexpected. The vast majority of the wallets we looked at had no h history of transactions whatsoever. They never held any money at all. And only 423 of them actually held any money at any point in time. And the
vast majority of the money and the transactions only came from just a handful of wallets. Most notably that Solana one I mentioned before. Some of this can actually be explained with cryptojacking. It's kind of a numbers game. The more wallets you have or the more addresses you have, the better shot you have at successfully stealing money. So, it makes sense there would be a lot of them and that most of them would actually be empty. But the ones that do successfully steal money, you wouldn't expect more than a handful of transactions because honestly, how many times in a row can someone accidentally transfer money before realizing something is wrong and stop doing it. So again, this hints at the possibility
that the thread actors are doing things other than just cryptotracking. We saw some evidence of scams, but it's possible they're doing other things as well. And that's pretty much all I got. So let me quickly summarize and we'll finish. Uh we started off with a website called Pesttop, which is distributing all kinds of different malware. We looked at one particular example and discovered a previously unknown malware called Massjacker which is tied to an older malware known as Mass Logger and we found many different wallets that might be interesting to explore further. And finally, if you are interested in exploring further to the right we have a link to our blog post about it and to
the left we wanted to upload the actual uh addresses but uh our legal team didn't like that. Um so instead we have the encryption information and the file names. So anyone who wants to then uh go to virus total and get them that way they can. And that's it. Thank you.