Free YouTube Transcribe

Video transcript

NPM malware now has multiple targets!

John Hammond · 11,826 words · 54 min read

WhatsAppTelegramX

Want to search this transcript, jump the video from any line, or download it as TXT, SRT, or VTT?

Open in the transcript tool

Full transcript

0:00Alrighty. Hi everyone. Thanks so much for tuning in. Hey, I'm super excited to get together with some new friends over at Invoke RE. Honestly, they were just super excited about some of the malware that we got to dig into in a previous video. City Skylines 2, some mod malware shenanigans, what I think we had dubbed as Exotickler, but sounds like there are

0:19other communities that are calling it Scavenger. So, super excited to hear from Josh Reynolds, one of the founders over at Invoke RE and Humpty. Cool handle, alias, and nickname for him. But hey, I guess we can dive in, my friends. What do you What do you got? >> I'd say like something like a month ago or something like that. So, I'm a sock

0:35analyst in my free time. Well, in my free time for for work and as any good like suck anist, I have some connections to folks within the industry and we you know, we try to share a bit of intelligence sometimes just because it helps us be ahead of the curve and things like that. A friend in the

0:50banking sector ended up telling us that espint config prettier which is a JavaScript package that a lot of front-end developers use was actually dropping malware on some workstations. So that quickly kind of nerds night me just because we hear about some new malware and you know you quickly get curious about it and we were kind of quick to just try to submit it to tools

1:10like Virus Total and Joe Sandbox and things like that. And what kind of caught my eye on this one was that virus total was flagging it fairly low in terms of detection. So it wasn't raising a ton of suspicion through your kind of run-of-the-mill anti virus that people tend to use. And the other thing that kind of noded at me was that ESL config

1:29prettier is like a very big package in the front-end community. It's essentially just a tool that kind of manages your configuration a bit so that different tools don't overlap each other and you can use like prettier for specific stuff and then other tools for your linting for example or various developer things. So that kind of led to

1:48us wanting more information because it's something new that's not super well documented. It's something that we know for a fact is malicious just from the intel that we gathered and that is very common within the industry. So the impact had a potential to be very very large. So the first kind of things that we ended up wanting to look at was how

2:06it was getting dropped. And thankfully the community was very quick to also report it through other channels. So someone quickly opened an issue to the repo essentially to notify the maintainer that something was going wrong. And thankfully for us, they also ended up including the diff that looked odd to them. They weren't sure exactly what was going on. As we can see here,

2:24you know, they're asking is this expected or not. So by going through a web archive because sadly those link don't work anymore since the version has been killed thankfully for the community. We were kind of quick to identify that some stuff got added between version 10.1.5 and 10.1.7 where they would run a script through node install.js and then two files were added

2:44which was the install.js and nodejip.dll. And if we dig a bit into the actual install js file we see that it is fairly big. There's quite a bit of code in there, but it's nothing too unmanageable. And if we look specifically at the function log dispace function, we see that it's trying to like do a bit of concatenation, which is

3:03a bit weird for something that should be legit. And then we see the reference to nodejip.dll. And then it just essentially executes it as a child process. So it's going to spawn run DL32 and have it execute nodejip.dll and call its main export, which is essentially just a function that you can use within DLS. So for this specific case, you see

3:22this and your kind of sock analyst radar goes off screaming at you because this isn't normal for an npm package that's generally used by the wider public. So this kind of confirmed to us that we had some malware on our own, right? Like this isn't normal. We should investigate into this a bit closer. And shortly after the maintainer of the project

3:42actually ended up making a tweet where they stated that they got fished. Essentially, he states like, "I was tricked by a fishing email and a new npm token was added and leaked. Then some popular packages I'm maintaining were released with malicious software. I've deleted the leaked token and marked all affected bad version as duplicated and released new version. So, we have

4:00confirmation that all of this was malicious. So, at this point, a thing that was interesting was to look at the actual fishing attack that was done against them because he provides two very like insightful screenshot. One of them being where we can see the actual domain that was used. In this case, it might be a bit hard to see, but it's

4:17nPNJS.com rather than npmjs.com. This is often referred to as typo squatting. It's super super standard in terms of attack patterns. You're essentially just trying to fool the user into believing that this is a real domain. From there, the user just clicks on it, follows the authentication procedure, and sadly gets spawned, which is pretty much what happened. And then

4:38the other interesting thing that we notice is that they have created an npm token. This is most likely just to kind of keep persistence within the system because once you've hacked the bris and share you have their password but they could rotate the password or add them fa or things like that but in this specific case within the npm environment having a

4:54direct API access token just gives you free rang over the account depending on the permissions that were given to it obviously. So this is this was most likely just a kind of persistence step that they put in to make sure that even if they got detected they had a kind of back door into the account. So all in

5:10all, this gives us a kind of better picture at exactly what they were trying to do. And it's interesting because this kind of brings up the the subject of supply chain attacks in general, which is something that it's been known for quite a while. There's multiple reports going as far back as like 2013 and things like that about companies being

5:27breached. I think Solar Flare was a big big example of this where it ended up affecting tens of thousands of companies. Sadly, there's uh also more deventcentric supply chain attacks that were found in like 2022 where you see like PyTorch, the famous the well infamous XZ backdoor that was planted somewhere in 2024 and then it kind of

5:46raised attention a bit. So, companies are paying more attention to it and are diving deeper into that phenomenon and socket.dev for example, you know, they've identified like 60 compromised packages just in 2025, which is a fairly big number considering that software depends on other software, right? It's a kind of big spiderweb of connections and often times it's a bit hard to kind of

6:06deal with. So knowing this, it kind of just like reinforced the scale of this attack and the potential reach. And obviously throughout our research, we ended up like tweeting a bit about it to see what the community potentially had to offer. And interestingly, her core at O Labs ended up running the sample and various like bites of the sample through

6:24his detection engine. And they ended up finding quite a bit of other samples like similar samples that were related to this. One of them being the the famous City Skyline 2 malware samples that you guys ended up finding. And shout out to Nord Garren also for mentioning this in the Twitter feed. It was pretty interesting to make the

6:40connection with the older vid and and everything. And this ended up having us finding that Shers City skyline 2 was affected, but the American Road mod for B&G was also affected. And there was even a GTA 5 mod that was affected. So we were seeing like more and more patterns of this in different ecosystems if we can kind of put it that way

6:58because gaming and supply chain dependencies and things like that are are quite different topics. And uh obviously the the CS2 community ended up making a full disclosure about what was going on and they confirmed that the dev that made this mod ended up getting hacked. After a bit of digging around, we ended up finding that B and G also

7:16made a statement that the mod was infected, but they didn't give as much detail or weren't as transparent as City Scan 2 was. And this was kind of interesting to to see, but I ended up digging a bit deeper and the GTA 5 mod was similar where there was just a disclosure of breach. But after crawling through the the web archive and Reddit

7:35and everything, we ended up finding that the modus operendi of the attacker was the same. So what they would do is attack the developer of that mod. Often times it was a trusted developer with like potentially millions of downloads for their mods and everything. They would compromise their account and then they would infect a trusted mod. So this

7:52kind of puts us in weird situation because you want to trust mod authors. You you want to trust them that they're going doing the right thing and everything. And obviously you can go and read all of their code because it gets like pretty bloated and and hard to deal with. But at the same time, you know, you you you just got to go along with it

8:07and potentially put yourself at risk because a mod all in all is it's software, right? It's something that just gets installed on your system and is executed as any other software or potentially malware would. So, this kind of made us take a step back as to like what's the the correlation between both. We have on one end dependencies that are

8:25getting breached through developer accounts and we have game mods that are being breached through mod authors accounts. And all in all, it's it's kind of a supply chain for both. Essentially, there's like an odd connection where they are operating in the same way for both types of attacks despite the community being vastly different. And obviously, there's quite a bit of

8:44speculation that could be done here on, you know, why they're attacking the gaming community and everything like that. But we we try to keep it to the facts as much as possible when doing thread intel just not to mislead anyone and things like that. So, I can show you guys. We kind of put up a a timeline

8:58that showcases fairly well exactly what went on. So if we look at it through the full image, we see that in mid-occtober, City Skylines 2 mod was compromised. A month later, John, you put up the video about City Skylines, which was super super interesting because it gave us a lot of insight to into previous payloads that they were using. After that, the

9:19GTA visual car spawner mod was also found to be compromised in end of March 2025. And then right after we see that B andG also gets compromised. So there's a kind of very tight correlation for the games. And then a month and a half later we end up with the npm compromise. So they pivoted from the gaming community

9:37into the software development community through these dependencies. And then there was the is npm package that got compromised a bit later on and it just kept like going and going. it it was usually a bit more focused on the npm ecosystem, but at the very end of July, someone ended up tagging us on Twitter saying that they found a scavenger in a

9:56Pi project, which was something new. They they moved again ecosystems, which is super super interesting. So, we're kind of seeing that the thread actors here are somewhat versatile. You know, they're able to adapt to different environment and target different people. So, I think that was a super interesting tidbit of info and it it shows like a very close timeline of what happened.

10:14And finally, I I think it's also worth mentioning the potential scale of this attack because obviously we ended up as a community finding about this fairly quickly, but it could have been much much worse. I ended up crunching a few numbers. And if we just look at the pi package uh that was compromised in two words one, it's a package that is hosted

10:33in something like 37,000 files within GitHub. And that's just Pi. And then we have the npm packages combined. If we combine all of the weekly downloads that they get, we're looking at something like 59 million weekly downloads, which is, you know, it is fairly big. And even the the gaming mod community, the affected packages, well, the affected

10:51mods, should I say, ended up accumulating something like 3 million downloads. So, they were very smart about what they were targeting. They weren't targeting something that was just used by like one or two user. They were kind of trying to go at it with a bang. Essentially, they're just trying to make maximum damage. So, that that was super super interesting to find.

11:07>> Wow. I had no idea that even like City Skylines was just sort of the tip of the iceberg. I mean, the supply chain aspect is absolutely insane. Just as you mentioned, it was interesting to me as you were looking through install.js and seeing the node code, it was like, oh, strictly if you're running Windows, like if the operating system is is Windows,

11:25so Node of course could kind of run wherever, Linux or otherwise, but when we got to dig into it, I think there were some silly shenanigans for a crypto wallet at the very end of the day. But it sounds like what would have been the DLL or now the more okay next stage payload Windows specific that's probably

11:41what we're going to be digging into next. Right Josh I know hey you're an absolute wizard with binary ninja. Is it that every single one of these variants has ended up in a DLL or Windows equivalent executable to follow down the exact same code path or sort of thing or I'm happy to let you take it away.

11:57>> Yeah. Yeah, absolutely. So it's what I wanted to show you all today. So I'm just going to be switching back and forth a little bit here. So, I just wanted to show you a few different things. So, just for some preliminary background, we obviously took a look at your video. You had basically gone through the entire unpacking stage that

12:11led to that Exodus crypto wallet stealer. And what we found was actually quite interesting because in the npm package, and this actually happened with the GTA mod as well, they introduced what we call or refer to as a loader stealer combination or combo in which the loader will actually reach out to a command and control server. It will ask

12:31for additional modules to execute and it will download and execute those but only if they have certain software installed that they want to steal from. So I'm going to show you what that looks like. And what was also interesting is these loader variants which also happened in the pi instance would steal tokens related to these development environments. So in the npm instance

12:50there was an npmrc file. In the pi instance I can't remember what the pi one was off top of my head. We'll take a look at the dl to see what it was. Essentially, these are lane text configuration files that contain those authentication tokens that can be used to modify projects. So, not only are they looking to steal crypto and steal

13:06these other things that we're going to look at in just a second, but they're also looking to spread their access in order to continue to do this. So, that's what that was one of the the big findings that we had. So, first and foremost, just have my little terminal open here. So, there's a bunch of stuff that we took a look at. Before I get

13:21into the hashes here, I will open up Binary Ninja. What we found when we opened this is that again it's C++. Again, they're using this hashing algorithm that you saw, but they've modified it a little bit. This is a CRC 32 hashing algorithm that they're using for what's called dynamic function resolution. So, just some background for those folks who haven't seen the other

13:41video. And basically, they'll use this in order to resolve functions that the malware needs at runtime in order for it to execute. And the reason that it'll do this is that more often than not, antivirus will fingerprint import functions that it has within the import header of the DLL, executable, whatever, in order to try and identify if it's

13:59going to perform malicious functionality. So more often than not, malware will want to find these at runtime in order to use them. I can walk through an example of this. First, we have the process environment block or PB. As John went through in the previous video, they'll basically walk the inmemory order module list, which is the loaded modules or DLS in memory at

14:20runtime. And then they will acquire the full DLL name buffer that is then hashed using that CRC32 algorithm. So they do that down here. Before they do that, here they're actually just lowercasing that DLL name. And then here's the CRC32 algorithm. So what is interesting about this instance is that they are using a

14:40custom CRC32 value table. So for those of you who are familiar with CRC32, they use a table of constants. So they've actually modified the original CRC32 table in order for these hashes to be different because there's a whole bunch of projects that have pre-calculated a lot of these malware hashes such as hashdb. Shout out Sergey O Labs and

15:00malware authors don't want those constants to be in the malware because then they'll be easily found by things like antivirus rules etc etc. So kind of interesting in that case. The biggest difference as well with this loader from what you looked at John is that they have a whole bunch of anti-analysis techniques. So I have actually set a

15:17bunch of bookmarks on the left hand side here just to walk through these quickly because it would take quite a while because there's so much code in this one function that Binga actually goes really slow. So I didn't want us to be sitting here forever. But if we scroll down here, the first thing that will come across other than this dynamic function

15:32resolution is the fact that they are again using those exor techniques that you went through in the last video. So again, they don't want to embed plain text strings within the binary because then you can just run tools like strings etc. So more than often than not, malware authors will use things like string offiscation techniques which basically means techniques that are used

15:52to hide the original strings that are then recovered at runtime for them to be used. So in this instance, we found that they were using these crazy exor inline algorithms. And we weren't actually sure what project this was or if it was an actual project until we were talking to somebody else online. And it actually turns out to be this C++ offiscation

16:10project for quite a while ago just called exor string. So if we look at this exor string project, this is the description is pretty short. It's just a heavily vectorzed C++ 17 compile time string encryption. Effectively all this does is it will take all the strings embedded in a C++ binary that's being compiled and then it will use this

16:30compile time vectorized encryption technique to basically replace all these strings throughout the binary with those obuscated values which are then exor to recover the strings. So here's an example that they have here and again if we go back to that binary ninja instance we can see okay that this looks quite similar to that. Obviously, this is the

16:47pseudo C. So, this is a highle representation of those assembly instructions, but this looks very similar to what we see within that project. So, in this instance, they're recovering the scavenger value without vowels obviously, but this is actually a constant that's used to determine as to whether or not there is a scavenger loader already running. And then if we

17:05scroll down here, so you might be wondering how I recovered these. John had a video again that he went through and he exored all of these values together in order to recover the original strings. So, one of my favorite pastimes, believe it or not, is to actually write deoffiscators for malware using binary ninja. So, when I saw this,

17:23I was like, hey, I could probably write some scripts to figure this out for us. So, if I just open up my I wrote this binary ninja script. So, binary ninja is a reverse engineering platform that's very similar to, you know, IDA and gedra and pari and all these tools. But what I really like it for is its API. So in

17:41this instance basically what I'm doing is if I go to low-level intermediate language the cool thing about binary ninja it has all of these levels of abstractions from the assembly instructions. So I've just entered the lowest level of abstraction which is called low-level IL or low-level intermediate language. And I like writing automation at this level because it can actually help with some of the

18:02higher level abstractions that might take things away that I want in order to deobiscate values or might perform some optimizations that might make my automation harder etc etc. So what I've done in this case so there's a bunch of these XME registers. As you can see, this is really hard to read. Uh, and they've done this on purpose to make it

18:19hard to reverse engineer. But see how there's these large value assignments, and this is what John was manually taking and putting into cyershe and then exoring these together because of how these values look at their intermediate language level. I can actually capture these using automation and their basic blocks etc etc. So that's essentially what the script is doing is I've

18:39basically provided it with every function within the database. It will iterate through every single instruction within each function and then it just uses a very simple fingerprint technique in order to look for those large value assignments and then it creates what I call a stack but it's basically just a collection of those value assignments and then I exor them together

18:58automatically. So that's basically what this is doing. It's looking for the low-level operation in this case a registry that is being set by a value. It then looks for a constant. And then there's a 32-bit variant that I've created because there's actually, spoiler alert, there's a 32-bit variant of this malware. So, if I run this with our current database that's open, we can

19:18see that this is actually going through all the functions. Like I just mentioned before, it's looking for those for those exor operations and the initialization values. And it's just going to take a few seconds here just because there is quite a few functions in this database because it is C++ >> for me to uh regurgitate if that's okay.

19:33What I had done was manually going through kind of oh cherrypicking just the stuff that I saw as it happened through the code operations. But you get to do this through everything correct that that's the obuscating all possible functions that could have been in the binary your libraries etc. >> Yeah. So I haven't actually used that project directly but it looks like

19:53they've only used it for the strings that are relevant to the malware itself. For example, here's a bunch of strings that will become permanent pretty soon here. Here we have those command and control addresses. These are actually to do with the JSON that they use to download from those command and control and then there's these other functions

20:11that are used later on in order to enumerate the file system. Basically what the code is doing if I go back is once it decrypts those string values it will actually assign them as a comment in the database. So again this is really cool stuff that you can do with binary ninja. Um you can also do this with IDA

20:26etc. And what's nice is then I can basically go through the binary and see that okay a comment has been made in order for me to be able to read what those deoffiscated string values are now. So instead of me scrolling through all of this low-level Ile code I'm going to go back to pseudo C and we might have

20:41to switch back and forth because again some of those comments get abstracted away. That's kind of one annoying part about binary ninja. Sometimes the comments get abstracted away. The other thing that I wanted to show you in addition to that string automation and I'll show you why that string automation is so important later is that there's all those anti- analysis techniques that

20:58I alluded to earlier. So let's take a look at a few of those. So if we take a look at this anti- close anti- analysis here, they're basically using that dynamic function resolution to resolve NT close which is a low-level function that's commonly used and hooked by sandboxes, antivirus, etc. to know when a file has been closed. So in this

21:15instance, they're basically checking whether Yeah. Okay. This is where the uh the hash is is checked for. I should have left this as the hash, but this is an enumeration that I will also show you how to resolve in just a second here. But basically, they're just checking that the first bite of n close does not equal this 4C value. So, this is likely

21:31associated with some hooking framework that is performing some things that or no, I think this is actually the value it wants to be. So, it's actually verifying that it wants to be 4 C in order to continue. But if this if any of these anti-analysis checks fail, this is al this also took us a while to figure

21:46out because it looks really weird. If we scroll down here even more, then they'll resolve this function get ACP. And this is just some esoteric Windows function that they probably picked out of a hat. Nothing super interesting, but they'll actually use this to crash the loader. So their anti-analysis technique basically is once they discover that they're being analyzed in some way,

22:05shape, or form, then they'll just crash themselves. So it's not like a it's not like a typical exit that you would see with a lot of anti- analysis techniques. So that was kind of interesting. So a few of a few of these other ones we can see that it's checking is debugger present is a very common anti- analysis

22:18technique. They're basically again checking to see if that scavenger VM value already exists and then they'll exit. They'll do things like check whether or not the being debugged flag is present from the process environment block. Again very common. They'll do things like enumerate the system firmware table using this BMSR value and

22:38this is all BIOS related stuff and then they'll check for things like VMware and then they check for things like QMU which is another virtualization platform. They look for uppercase QMU and then just a whole bunch of different things that they're basically using to deter analysis within sandboxes. The next thing that they did quite interesting is they're looking for

22:57specific DLL names within their memory space. So this is often used by things like sandboxes, antivirus that might have a DLL sitting in that memory space. I guess they didn't want to execute on systems with these specific antiviruses. Maybe because they thought they would get caught or something. So they're basically looking for these specific DL names in memory. Then if I continue

23:14here. Okay, so this is quite interesting. I think this was in your previous video as well. I don't know how deep you got into the nitty-gritty of this, but what is interesting is they also do what's called indirect sys calls. So in Microsoft Windows when you get down to the NLLL NTDL layer of these function calls they are performing what

23:33are called SIS calls in order to get from user lines to kernel line and that's basically to perform low-level pieces of functionality that interact with core pieces of the operating system etc etc. So in this instance they didn't want to call nquery system information directly. So they'll actually dynamically resolve antiquery system information using that dynamic function resolution. And then they'll acquire the

23:55offset of antiquery system information plus 4. So this is again trying to avoid those hooks that are in memory that could be in place by antivirus etc etc. And then once they get past that point they'll actually capture a bunch of the bites associated with the function and then reconstruct a separate sys call in memory for themselves to perform. So

24:14they can basically avoid any hooks that might be in place in the original function that that is in memory. So this isn't super easy to read, but this is actually them constructing a SIS call in memory using the values that they've read from ntquery system information. They actually perform the call here, which will then return a structure that

24:33they are let's see this is the system basic information structure that they are querying and then they're doing all of that just to check how many processors there are on the system. So a lot of stuff to just get to that result, but basically indirect sys call query system information to check the process. >> That's kind of wild. Is that is that

24:48fair to say? Am I wrong in that? Like I know oh that's a technique that you can do and you see stuff talk about oh and maldev and malware development training silly courses and stuff like this, but I've never been able to see that in a real sample cracked open with binary ninja. Am I am I overreacting?

25:04>> No, it's it's like it's pretty sophisticated. If you there's a few examples online that you can find of red team projects. Like I doubt they wrote this themselves. They probably took it from something. But yeah, it's it's pretty cool. Like it's quite sophisticated. What was a giant pain with this loader is I didn't have a hardened VM when I was performing this

25:20analysis when I was doing dynamic analysis which I needed to for the command and control stuff. I needed to like step through every single layer to get to to get to where we needed to be. And then I needed to like change the flags. And I know you've had guests on that have shown that before, but yeah,

25:32it was kind of a giant pain. Then we get to the C2 domain deoffiscation. So these are three different domain names. I know your your sample also had three separate domain names that they're reaching out to. And then this is kind of where we get into the network communication stuff. So this is this is where it gets

25:47pretty important because this is like the loader part of the of the loader. So the first URL that they query using those sets of domains/C2s that they just resolved using that exory offiscation is this C/ K2. So this is a bunch of null bites. It's kind of hard to read, but this is important because it creates a

26:04domain that looks like this. So, in order I don't want to just step through static analysis the whole time cuz it's pretty boring. So, I kind of made a little demo here of what the C2 columns looks like. So, I just have my development environment here. And what is pretty interesting about this command and control communications is they'll

26:21use what's called the XXT encryption algorithm in order to encrypt these packets or these HTTP payloads that are going back and forth. And this is pretty common obviously to see encryption, but XXT is kind of weird. It's I think it's like a Chinese algorithm that some folks use. And in this instance, they will actually provide, if I go back to Binga

26:40here, down to this other bookmark I made. And it took us a bit to figure this, right? Just to cater to people who are just getting into reverse engineering, you know, that that's not something that was just like, oh, we saw that we immediately knew what was going on. It took us quite a few hours of kind

26:54of grinding into the sample to actually end up finding what was going on. So this value is actually a key segment. So this is a constant value that's used for that XXT encryption algorithm. But what they also do is they'll acquire a value from the C2 to make up a second part of the key. So they'll basically like

27:11append the keys that constant value and the key from the C2 together to make a session key. Then uh so I've just said the key portion there. And then this is actually going to read a pcap that I've captured from a sandbox. And this is just going to decrypt all the values in real time for us from the pcap to just

27:28look at what the command and control communications look like and then lay them out for us. So we're just going to hit run here. Hopefully everything works. So this is just parsing the HTTP packets that are communicating with the command control address. And we just have to wait here cuz it actually goes it does like two iterations. It collects

27:44the HTTP packets and then all the associated TCP packets and then gets the the requests and replies. This is actually using Pyark. So it's like a Python interface on top of T-shark which is like the super cool. >> Okay. So if we look at some of these packets here >> and if I may ask this is all going

27:59through your pcap file previously recorded. These domains are no longer online I hope. >> Yeah. I didn't check the domains today but I I would assume >> presumably okay. Yeah. Yeah. But this is all data in retrospect. Cool. >> Yeah. Yeah. Exactly. So okay. So if we look at so there's that C K2 value. So this is actually the key portion that

28:20it's responding with. So this is the response body. It's B 64 encoded. So they B 64 decode that and then get the key portion. And then this is actually the full key. And then if I keep scrolling down here, they send these these weird request values, but these are actually I think they're just like challenge responses. So the first thing

28:36is a challenge response, but this actually contains the epoch time encrypted with that key and then the plain text epoch time. I don't really know why they did this, but it looks kind of weird, but um that's essentially what they're doing here. This is the challenge response that they are first doing. So, basically, they just make sure that that session key is working

28:53between the command control. And then if we scroll down here, then we start to get some into the meat and potatoes here. So, you can't see this here, but this PL command and control value is actually going to be sending that npm RC configuration. So, if that does exist on the system, then it's actually going to send that to the C2. So, this is that

29:10stealer part of the loader. So this didn't exist on the system that I ran this on the sandbox that I ran this on. So that's blank. But then if we look at the body down here, we get some ooh this is pretty interesting. This is a big B 64 value. So again, this is being XT decrypted and then we can see that there

29:25is a big JSON blob here. So okay, so what is this? So when you did the video back in November, there was only one module. So that was that Exodus module that would basically target that specific crypto wallet. Now they have three modules. So, it's pretty interesting because not only are they targeting that Exodus wallet still, they're targeting Electrum, which is

29:45another crypto wallet, and then they're actually targeting Chromium. So, there's a whole bunch of Chromium derivative browsers. And then my de I have a little demo set up and I'm not going to be going through the Chromium one just cuz it's it's quite complex. But basically they're actually targeting specific add-ons or Chromium plugins within Chromium that they will then hook using

30:03injected JavaScript in order to get more again you guessed it crypto secrets and seed values and passwords etc. So this is basically the JSON body that tells the loader what to look for on the system in order to get which module. So here basically there's one of the modules is called shiny. That's that Chromium one I was just talking about.

30:23And then basically it looks for this notification helper exe on the disc. And then it just has like a few other values that it'll look for. So it looks for a file containing the word manifest.xml. I'm assuming it actually has manifest whatever. And then if it finds that it will actually drop this executable within that Chromium directory that is

30:41then similar to what you saw it will actually be loaded by the Chromium browser when it executes. So, similarly what you saw with the Exodus wallet, with the Electrum wallet, they're using DLL search order hijacking in order to load their custom DLL um pdc.dll in order to steal the passphrase and the

31:01seed phrase for the Electrum crypto wallets. So, that's that's essentially what they're looking for here is those to be installed. Otherwise, they don't even deliver those modules, which is, you know, kind of interesting OBS/operational security stuff that they could be doing. So, yeah. So they're basically looking for that prof API. DLL which you saw in your previous video. That was the DLL

31:20that they were writing to disk and then moving afterwards into that fixed path, but now they're actually looking for that on the system before they even deliver that. Happy to share this code with folks. It's nothing super complicated. Cedric, do you have any comments or do either of you have any comments? I feel like I've been talking

31:33a lot. >> I just think the idea of the loader stealer kind of thing is neat. Just as you mentioned like that opsseack kind of thing of oh do we even need to perform this operation to info steal and get whatever data if it's even applicable to that target or to that victim. You got to give the devil his due, right? Like I

31:52think that's that's kind of smart. >> Yeah. And I think like a lot of red teamers and stuff use these types of techniques as well or they'll only deliver portions of their payload or what have you in their operations. So yeah, it's definitely quite interesting. So if we move over here, I actually acquired each of these modules and I

32:08have them in binary ninja. So >> can I ask how had you acquired them? Is that oh getting the response back from C2 testing? >> Yeah, yeah, it was in one of those sandbox environments. So it wasn't too bad. So okay, so if we look at some of this here, so this is electric, which I wanted to talk about a little bit. So

32:26this is one of the 32-bit modules. So this is quite interesting cuz this is compiled specifically for Electrum. And at the time when this was released, Electrum was only using 32-bit DLS and like 32-bit executables, but now they're using 64-bit. So, I don't think this had anything to do with this malware or what we wrote about or whatever. But when I

32:44was trying to create this demo, I was like, "Oh man, this isn't working at all cuz it's 64-bit and it's trying to load a 32-bit DL." But just something interesting to make note of. And then again, they're doing the the exact same stuff basically that we saw before. So, they're they have the global CRC 32 table. This is actually the exact same

32:59as the one we saw before. And then they have the exact same encryption stuff here. So if I scroll down, maybe I can find one. Okay, so uh there is a profanity in this command and control address. So I apologize for anybody who's sensitive. You might see that on the screen there. But yeah, so there's this like poker easy one as well, but

33:16these are actually the modules from the Pi Pi compromise as well. I forgot to mention that. So these have different command control addresses, but when the when the loader downloads the modules, they have the same command and control addresses. They just have different URL paths that they're talking to in order to do the dealer stuff. So if I look at

33:30this module here, say we wanted to recover these hash values that are being resolved like similar to what you did on stream. I'll just show you all like a really fast way to do this. So not only can we do similar to what you did where you like reimplemented the hashing algorithm and you got like a list of

33:47hashes, but we can actually create enumerations of these. This one I left unresolved on purpose so we can do this together. Okay. So I have a bunch of scripts here and Cedric/Humpty wrote these so I won't take credit for them. But basically all this does is it will essentially take that CRC32 table. So I just basically copied it out of Binga.

34:07So if I want to show you how we can do that, we just have the global table here. I select the whole thing. And then what's cool about Binga is it has like a whole bunch of different copy as options. So I can rightclick, copy as, and then just do like a C C array with 32-bit little Indian elements. And then

34:22if I were to paste that back in our VM here, uh if I just do like an example here, then we can see that's just like a standard C table. So I just converted that into C or into a Python array here. And then basically Cedric reimplemented the CRC32 hashing algorithm here. And then essentially what this does is it

34:42opens each of these Windows modules with binary ninja and then it will get the exports of that DLL perform the hashes or the hashing algorithms in order to recover those and then puts them into that enumeration format. So I'll kind of show you what that looks like here. But before I do that, I'm actually going to open up hash32 cuz we have the other

35:01module. This is a spoiler alert, but they're resolving python 10.dll. So why would they be resolving Python 10.dll? So let's run this guy here. Hopefully this works. ashes demo.h or something. >> So you have all the Windows DLS inside the folders and yeah even on Ubuntu or whatever Linux you're just firing up binary ninja and trying to cut it up.

35:21>> Yeah. So what we can do here now is I can just rightclick go to create types from cours which you also did on your video as well but I think you were doing it with one of the window structures that wasn't present. And then if we hit create then it's created this final hashes hashes and this actually has all

35:36the enumerations with all the hashed function names associated with them. So this is cool because I actually don't think I have python 310. So I'm just going to get that too. So I made this other one hash single.py and let's just do that. I need this. So this is that AFBB one. If we go back to Binga here

35:56then I'm going to add this to my malware hashes here. So, not only can we add them, but we can edit ones that we have here. So, this is just going to be our Python 310 deal. Okay. All right. So, then if I go back here into this guy, I can hit the M key in order to map an

36:11enumeration to a value. And then we can see, okay, this hash corresponds to Python 30, which is not 100% correct, but that's okay. And then if we scroll down here, then we start getting some other important values associated with this DL. So if I scroll down, scroll down, we can see that this function is being resolved pi eval eval code. So

36:31pretty interesting, right? So what have we not done yet for this module? We haven't figured out what strings are inside it by decryting them with our handydandy binary ninja script. So if I go back to this guy here and I hit run, hopefully everything just works. >> Now we'll get to see some Python code. Yeah, >> dude, we've been everywhere.

36:48>> This is the problem with being a reverse engineer. You have to understand like 20 different languages at least a little bit. So >> question for you both as you mentioned. Hey, you two are spending hours trying to cut up or understand or dig into something. What is it that you kind of do when hey, you feel like you're

37:02running out of options or you you know you got to do something but you you just open up Biner engine and you don't you don't know what to do. How can you approach stuff like this? >> Reach out to Josh. But kidding aside, reaching out to the community often times is super super helpful. Josh has the Invogari Discord.

37:19John, you have one too. There's plenty of communities out there with people just kind of curious to help others. So that's always a great great resource. And then surprisingly, Twitter/X is also a good source of community knowledge or blog posts are also great when you see different malware variants get analyzed by people. Sometimes there's quite a few

37:38tips and tricks that you can pick up by just reading those blogs. And just by doing that, eventually you kind of build a small mental map of all of those tricks. And you don't remember them exactly, but you know where to search for them, which is the key. So, it's it's kind of like having a good Google

37:51Fu, if you can put it that way, but I don't know, Josh, if you have any more tips as a teacher yourself. >> Yeah, I was going to say Obsidian capture everything in a a note-taking app. I use Obsidian and you can make like mine graphs and whatever. But yeah, a really good example of that is that

38:04C++ Exoruscator, I think it was Hexorus. I think that's his handle. He pointed out to us that it was actually a public project that they were leveraging. So yeah, always really good to have the community cuz there's I don't know, I've been doing reverse engineering for like 12 years or something and people teach me stuff all the time. So having the

38:21community is is super important just to yeah be able to bounce stuff off and like working with Cedric. So even though I know he's humble, but Cedric only started doing this anything security related like four years ago and now he's doing this hardcore stuff. So >> cool. Sorry, I didn't mean to pull us away. >> No, no, it's all good. Another quick

38:37thing that we've noticed so far is we see a lot of different techniques happening like even between the plugins that they deploy and everything. We see a lot of variance between how they operate. And this is something that was super interesting while looking at older samples because we saw a skill progression. Skill progression isn't the right word, but we saw kind of evolution

38:55within the sample where we're seeing new features being added. We're seeing new anti-debugging techniques slapped on top of the the sample and everything. So that was very very interesting to notice. Yeah, completely agree and it made the analysis a lot harder. Um, again because that gant analysis stuff in these modules. So our little decryption deoffuscation script finished

39:15and we see some pretty interesting values in here. So if you scroll down, this is actually one big string that was deoffiscated. So maybe I can take this out and make it. It's pretty easy to read here actually. So if we look at this, we can see import a whole bunch of stuff, but uh import types, funk tools,

39:29cis requests, which is used for HTTP communications and then we have C types. So this is the important part. So we have a bridge module. So if I haven't done like a ton of Python C interoperability stuff, but from what I understand, this gives the ability for the Python to talk back to the DL. And then if we look at the trace calls here,

39:48they're using this function called or this technique called set trace, which will actually allow them to hook a specific Python function in memory. And if you can guess what this wallet is written in, it's written in Python. So what they've basically done here is written a routine that will basically trace these calls. So it looks for a

40:08call event within the Python code and then acquires the frame. I don't know what F code is exactly, but it probably has to do with the wallet itself. >> Yeah, I think like the function specifically or something. >> Yeah. And then the co name within the function name, it verifies the function name being called is get EC key from

40:24password and then they will acquire the local variables from the frame password. Otherwise there is no value the default if you can't get that value and then it also hooks the function name has seed in order to acquire the self variable within that frame and then it acquires the seed using the password from the key

40:44store. So then it gets the seed phrase and then it sends that seed phrase back to the calling module. So pretty interesting. >> That's cool. >> Yeah. So yeah, we thought that one was pretty neat when it just spat out that little Python script. We're like, "Oh, okay. Well, this isn't too hard. >> So, one thing that we do notice if you

41:00scroll down just a bit is sometimes malware authors like to mess with reverse engineers. And this is the domain that Josh, the nasty domain that Josh was referring to earlier. So, often times they'll leave just some insults left and right or sometimes even shout outs to some reverse engineers as a kind of note that they will just hide in the

41:18thing for us to find. >> Yeah. And then another thing we can actually see in this is this is the key portion for that session key, but for this the pi pie campaign. So this is a little a little bit different than the first one we saw. And then >> and all the different like get URL. >> Yeah.

41:30>> Yeah. Exactly. So and then they're specifying that this is the electric module that's communicating the stolen content back as well. So we don't really have to re this too much. But what is quite interesting is that basically they're using the dynamic function resolution like we saw before, but they're actually using it for the modules that are embedded within the

41:48wallet in order to resolve that Python execution function within the the modules within the wallet. So if I open up my other window here, I've actually pulled up the instance in which the wallet has loaded the Python 310 module. And this is actually the malicious DLL that I've placed within the path that it

42:09would be expecting for the search order hijacking to occur. So if I scroll up here, kind of did some cooking show magic before this just so we wouldn't be sitting through all this module loading and stuff cuz it took me a while to do this. But if I go to C program files x86 and then go to electrum and then we can

42:24see here that if I go back to JSON that's down here. Okay. So again just a reminder it's putting the UMPDC DLL in the directory that it finds this electrum servers.json. So if I open up my PowerShell here I can just go to program files x86. And if I go to

42:44electrum then this is actually another thing that is sent from the command and control is what to look for and where. So if you can see that later on they are sending see we can see C program files C program files x86 local app data and app data. So these are the directories in which they're going to look for those

43:03files and then if I go to our windows instance here and then if I just do like get child item recurse filter servers.json then we can see that electrum electrum servers.json JSON exists in this directory. So this is basically where it's going to drop that file. And then if I go to Electrum, then you can see where I put the UMPDC. DLL.

43:22So this is basically what the loader would do, but I didn't do the full chain here just cuz it would take quite a while to walk through in a debugger. And then I basically used x64 debug or x32 bug in this instance to wait for that module to be loaded or sideloaded by the Electrum wallet. And that's what's being

43:37shown here. So essentially if we were to break on the area in which this passphrase is used actually so it might not work cuz it's calling the command and control server but effectively what should occur is this script is being deoffiscated. So it's this giant deopiscation sequence just for this one Python script and then it's going to be

43:57executed down here. So it's being passed to this function. So there's a whole bunch of C++ setup stuff. So, I know uh we probably don't want to get into the nitty-gritty here, but um effectively it's being passed off to that dynamically resolved Python execution function and then it'll execute that Python script as we described there. So, yeah, just kind of wanted to give you an

44:17idea of what it looked like on the system itself once it would be infected by the loader and then that module is delivered. So, if I hit play here, then we can actually see this is the Electra wallet. And then in our case, I just set up like a random wallet. And then if we wanted to, I don't think this is

44:33actually going to hit our module, but we could probably break on our module execution here to see if it gets called back when we put in the password. As you can see, Python, it loads like 10,000 dependencies. So, >> I think you might have scrolled past it. We're looking for our UPMC CD thing, correct? >> Yeah, >> just a bit above. Okay. Okay. So, I'm

44:50just going to set a memory access breakpoint on the text section. And then if we enter our password here, let's see if it calls back. So, we hit that bridge function there. And then there's the C phrase. >> And there's your seed phrase. All right. >> Demo works. Awesome. >> That's crazy. >> So, that's pretty cool. So, yeah, hit

45:06the bridge function and then has that Cphrase that it decrypts on the fly using the Python within the interpreted environment. >> Craziness. >> Yeah. All this just for cryptocurrency, but I guess like what's Bitcoin at? Like 120 grand or something. So, well, you put this into, you know, Pi Pi dependencies, npm libraries, video game mods, and Grand Theft Auto and City

45:25Skylines, and you get to like the crazy like 59 million downloads a week or something wild. You'll probably get a few whales, I think. >> Yeah. So, I think this is probably the best illustration possible to never ever keep wallets on your Windows system or any computer connected to the internet ever. I don't even want to say get a

45:41hardware wallet because then there's like supply chain attacks on the hardware wallets and then I don't know, maybe just keep your money in the bank like a normal person. They have insurance. >> Now, we've already ripped through shiny, right? That the approach in Chrome. Is that right? I mean, I know we just did the one specific to Electrum. It's

45:57basically kind of all the same. Is that fair to say? >> Yeah. So, I um I didn't have that demo ready just because Dr. Web did a really good write up on these. They did like this article, gamers get ready, scammers disguise cryptocurrency and >> and you all had dubbed this scavenger for one thing because of literally the

46:14the string that was unraveled and deopated like it's they named it themselves the bad actor sort of the scavenger without vowels, right? >> Yeah. And even then that that's something that we also ended up noticing by looking at like previous samples is that some of the older samples had mistakes in them. So they forgot to strip some information from the binary

46:34and things like that where one of the mistakes that they did is they left the PDB file path in the binary which is essentially just a debug information uh file path that gets generated when you compile a binary and in that PDB file path we could clearly see the name scavenger written letter for letter. >> So they called it themselves scavenger

46:53so we kind of went along with that when naming it. >> Totally. >> Yeah. So, I think the shiny one that I hadn't done a demo for is this one. It is looking for a version. DLL though, so I think I do need to triple check this before I say it is the exact same, but I'm pretty sure it is the same. So, this

47:08is actually looking for like it'll hook get command line W. So, then when Chromium is loaded, I don't know if this actually works in the official Chrome, they'll they'll hook command line W to append no sandbox. So, this allows like external processes to interact with it. And then test type launches the browser in a special mode in which various auto

47:25starts from extensions are disabled. So I think I'm not entirely sure what that has to do with it. >> Just to to add to this, the test type one, we ended up finding that they were actually modifying Chrome extensions. So they weren't installing new Chrome extensions. What they were doing was just hijacking them and modifying them and the test flag allowed them to modify

47:42them without Chrome locking the events essentially. >> Yeah, exactly. And then they are looking for this particular callback function. And I think this also has to do with content verification when interacting with the browser extensions. So Chrome's built in like a whole bunch of these protection mechanisms for well I I also don't think you should use a crypto

47:59wallet browser extension but a lot of people do. And then they're looking for the specific extension identifiers >> and those clearly map to a browser extension wallet manager, right? >> Yeah. I think they go over the JavaScript that's injected in five here I think. >> Wow. >> Yeah. So yeah. Okay. So Phantom/Bit Warden. Oh, so they're also looking at

48:19password managers, MetaMask. And then this is the JavaScript that they inject. So this is provided for this is like the config that's provided from the C2. So this is why I didn't set this up as a demo cuz it would have needed like I would have basically needed to rebuild the C2. And then it looks like this

48:33would basically get this data grab analytics JavaScript. So yeah, I don't know. I I haven't actually gone over all of this myself. >> Those are probably tracking victims and all. And then yeah, stealing the key data. Wow, this is huge. Yeah. So, I don't know what is Japanese has to do with anything, but >> in this case, it was interesting because

48:52what they're doing is they identify a specific file name that they're looking to inject code into and then they use a specific match that they're looking for to get the localization of the code they want to replace. So this is kind of how they're just like doing a kind of reg x match essentially in the file to know

49:09exactly where to inject the code because obviously you don't want this to break the extension either because if the extension is broken then the user knows and if the user knows you're kind of done. Wow. Yeah. Pretty cool. Pretty cool stuff. Pretty complex infection chain. I definitely think that we're probably going to see a trend in this

49:25direction especially with you know VS Code extensions. And I don't know if you saw earlier, but this was cursor that was opened earlier and they have like their own extension store because Microsoft effectively blocked them from using theirs. And then like I feel like we're going to move in a direction where like I know the Chromium and Chrome

49:43plug-in store. I don't know if that does any vetting for developers, but like I don't think these extensions are being vetted for malware right now. For example, the npm package environment. I think they're trying to do like things like CBE scanning and whatever, but like I don't know if they're doing things like malware scanning, you know what I

49:59mean? So, >> embedded payloads that do all this crazy sinister wild stuff. >> Yeah, I know Cedric actually works as a sock analyst, so I don't know if you had any more concrete thoughts. >> It's kind of a complicated problem because it's a web of webs dependencies in general. You know, it's just generating a bomb. So a bill of material

50:16essentially for your software is very difficult just because of the depth at which you need to go through and then you will need something to review all of those dependencies to find something malicious. So some companies do try to do some more like static scans uh on those assets. But what other companies are trying to do without name dropping

50:34too much is that they are trying to fingerprint the build process of those dependencies to make sure that the build process remains the same over time. So nothing special happens. If something weird happens, then the fingerprint is going to be different and you're going to get an alarm. And other things that they are doing is similar to what anti

50:52viruses and EDRs do, but specifically for GitHub actions, for example, where they are monitoring within the GitHub action with network calls are being made, if it's accessing environment variables and things like that to make sure that a dependency within the project isn't interacting with potential malware. And then it it's also up to the developers to an extent to kind of make

51:12sure that they're safe, right? If we take for example the uh game developer, the game mod developers, one could speculate that they could have potentially made their account a bit safer by, for example, en enabling MFA and things like that or potentially even using pass keys or or just making sure that they're less at risk because as a

51:29developer, especially for popular packages or popular software in general, you're putting all of your users at risk if you don't secure your very own account. But it's super super important to kind of take a step back and and try to think of the potential impact because sometimes it's easy to just try to you know cut a few corners just because you

51:47know it's just a small project. It probably won't get big or whatever but at the same time you don't know if it is going to get big or not and you only end up knowing that you made a mistake after the fact which is usually always too late. You know some people will have been affected by that especially with

52:02with crypto we're talking about potential folks's livelihood. People put a lot of cash into crypto in general, so there's quite a lot of things to do. Obviously, the easy answer would be to tell everyone, you know, just check what you use, but that's not super reasonable. You can't expect everyone to start looking through hundreds of thousands of lines of code just to make

52:20sure there's nothing malicious. So, just being cautious as developers and as users in general and obviously the general tip of, you know, having your AV enabled on your computer is always helpful. >> Well, goodness gracious, guys. This Thank you. Thank you. Thank you for that wild ride. I know there's a whole lot to go through, but my goodness, thank you

52:40for taking us on the tour as to how this thing has changed and evolved through all the months and potentially, you know, what it's going to still be doing in the future. More pops up just like this. >> Hopefully not. Yeah. Yeah. Hopefully not. >> On that note, I guess my last question for you all is, hey, how could folks

52:54that are tracking this or folks that are interested or folks that just kind of want to learn more, how can they reach out to you? How could they get a hold of anything that you're up to or anything else that you're chasing? And where can anyone see what else you all are doing? >> Yeah, definitely check out the

53:07invoke.com website. Then it has links to all of our socials and we have a YouTube channel. We have live streams. We have a whole bunch of different things like a Discord community that you can join if you register for our training. There's just a link. It's just to keep bots out and stuff like that. And if you also want to

53:23talk to me directly, I'm gir on Twitter. And then I was actually going to plug our blogs as well. So our blogs go into a lot more technical detail about a lot of these techniques. So definitely check out the blog on the invoke website. And then Cedric, do you want to >> I do have a very small blog post that I

53:39I try to do stuff on once in a while, but it's c-b.io. I I try to keep it simple and from there you can find all of my social, the articles that I wrote and everything. >> Well, I have seen a lot of your streams, Josh, flying by and a lot of the incredible stuff you've been up to with

53:55Invoke RE. So hey, my hat off to you. That's seriously phenomenal work and all the blog posts, collaboration, everything that we're all up to. It's just so so cool, Humpty. And hey, Cedric, I haven't been able to take a look through your blog quite yet, but I'm super glad now I know it exists and all the sweet stuff. We'll definitely

54:11get that and take a look through these. Thank you. Thank you. Thank you again and again. I can't say it enough. I'm really glad that we're able to dive into a lot more of the oh hey elite stuff, diving into debuggers, disassemblers, and really seeing it for real and doing it. Thank you for helping us do it and

54:25not always just talk about it as I think we maybe see Sue way too often on the internet airwaves on the YouTube as a platform. >> So, thank you. Thank you. Thank you for making sure we do it for real. Yeah, >> absolutely. Thanks so much for having us. Yeah, I really appreciate it.

More from John Hammond

All 86 transcripts from John Hammond

Recently added transcripts

Browse the whole transcript library Browse all English transcripts

This transcript was generated from the captions YouTube publishes for this video. Get the transcript of any YouTube video atfreeyoutubetranscribe.com, free, unlimited, no sign-up.