00:00:01.199 --> 00:00:02.160
Hello, hello.
00:00:02.319 --> 00:00:04.799
It is Thursday, August 20th.
00:00:06.160 --> 00:00:11.919
We have a kind of last-minute list of things to talk about.
00:00:12.160 --> 00:00:13.599
Hot breaking news.
00:00:14.000 --> 00:00:18.160
There was a compromise in the Rust ecosystem that we're going to get into.
00:00:18.399 --> 00:00:28.960
We're going to talk about some research that we did earlier this week on a dual ecosystem compromise in NPM and Ruby.
00:00:29.440 --> 00:00:33.600
And uh a little bit uh around binary payloads.
00:00:33.759 --> 00:00:35.280
Paul, where do you want to start?
00:00:36.159 --> 00:00:37.439
Oh, just pick one.
00:00:38.079 --> 00:00:39.920
We're yo we're YOLOing it today.
00:00:40.240 --> 00:00:40.799
YOLOing it.
00:00:40.880 --> 00:00:45.840
Why don't we start with the Rust one since I know you were looking at that right before we got online?
00:00:46.399 --> 00:00:59.119
So to kind of just uh summarize in brief, um, it was discovered today that a maintainer, uh D Roundy, Drundy, I don't know how you pronounce it.
00:00:59.280 --> 00:00:59.600
DR.
00:01:00.560 --> 00:01:04.719
Yeah, uh, was compromised by threat actors in an account takeover.
00:01:04.959 --> 00:01:32.239
Um, they did something that we've kind of generally seen in the account takeover playbook this year, where they didn't actually push malware in the existing uh legitimate packages, but what they did instead was they published um six net new packages that were all malicious and then uh linked those to the existing packages as malicious dependencies.
00:01:32.400 --> 00:01:37.200
So again, if you're scanning the top level package, everything looks fine.
00:01:37.280 --> 00:01:43.200
But if you're not looking at the dependencies, uh, then you wouldn't necessarily know that you were pulling in malware.
00:01:43.439 --> 00:01:52.159
Um, so we've published on our LinkedIn and we'll um share some more details the uh IOCs to look for.
00:01:52.319 --> 00:01:59.599
There's a nice little script from uh Rust that can help you find out if you're using any of these packages.
00:01:59.840 --> 00:02:02.239
Um Paul, what do you what do you want to share?
00:02:02.319 --> 00:02:03.439
What do you know so far?
00:02:03.920 --> 00:02:07.840
Yeah, well, so the interesting thing is this actually dropped last night before I was going to bed.
00:02:07.920 --> 00:02:10.560
And so I stayed up late um working on it.
00:02:10.719 --> 00:02:13.520
So they've been in, they've been in open source malware.
00:02:13.680 --> 00:02:22.560
Well, most of them have been in open source malware because, like all attacks, you know, when the initial word came out, we only thought this was like two packages.
00:02:22.639 --> 00:02:26.719
Um and then of course, over um we realized there's more, yada, yada.
00:02:27.280 --> 00:02:28.879
But um, yeah, you're right.
00:02:29.039 --> 00:02:36.400
This follows kind of the the npm kind of playbook, and we'll get to that in a second because I've got something I haven't because we're YOLOing today.
00:02:36.479 --> 00:02:43.680
I didn't even send Jen this link from Wiz, but um no, I actually did see the whiz when I just didn't have time to write in.
00:02:44.000 --> 00:02:48.639
Yeah, I was doing a little research before the show, so I I think I know what you're gonna talk about.
00:02:48.960 --> 00:02:49.439
Yeah, cool.
00:02:49.599 --> 00:02:50.080
Sick.
00:02:50.319 --> 00:02:51.039
Um, yeah.
00:02:51.120 --> 00:03:01.759
So basically, this attack compromised uh one maintainer and it compromised three of their existing legitimate packages, one of which is a Ray Ref, which is a very popular Rust package.
00:03:01.840 --> 00:03:03.919
It's been downloaded 250 million times.
00:03:04.000 --> 00:03:06.479
Um downloaded several million times a week.
00:03:06.719 --> 00:03:14.000
It is so popular that it that by some accounts, I saw somebody say that it was in 76% of Rust projects.
00:03:14.159 --> 00:03:19.919
I have not verified that, but let's just let's just it's safe to assume this is a very, very popular package, right?
00:03:20.000 --> 00:03:29.520
So there's a there's probably a better than even chance that the uh or worse than even chance if we think about it that way, that you've got this in your Rust project.
00:03:29.759 --> 00:03:35.520
Um and yes, it was up for 90 90 minutes, it was online for 90 minutes.
00:03:35.680 --> 00:03:39.120
Um, but some of the ancillary packages were up longer.
00:03:39.280 --> 00:03:41.840
Um, and so you know, total time.
00:03:42.159 --> 00:03:42.960
Anyhow.
00:03:43.280 --> 00:03:51.599
All right, so when I was looking at this last night, I I thought to myself, you know, I was sleepy, and I was like, this kind of feels like other things that I've seen, but then I went to bed.
00:03:51.680 --> 00:04:11.599
And in the meantime, um, Rami and the Wiz team has have come out with a blog post basically tying this attack, this Rust Array ref attack, to um the same DPRK North Korean threat actor that's behind Mastra and some of the other.
00:04:12.080 --> 00:04:12.400
Yeah.
00:04:13.840 --> 00:04:18.160
Now, and they're they're basing this on a couple of things.
00:04:18.399 --> 00:04:22.000
First, you know, the look and the feel of TTPs.
00:04:22.079 --> 00:04:24.480
Like I said, I my spidey sense last night was going off like this.
00:04:24.959 --> 00:04:26.480
Yeah, why don't you talk a little bit about it?
00:04:26.560 --> 00:04:29.680
Because the um intel I have is pretty thin.
00:04:29.839 --> 00:04:31.199
What does the malware do?
00:04:31.360 --> 00:04:38.079
What's what's unique about it, other than this pattern that we're seeing of a direct dependency calling it transitive?
00:04:38.160 --> 00:04:39.759
What can you tell us about the malware?
00:04:40.000 --> 00:04:41.839
And and I think that's the first thing.
00:04:41.920 --> 00:04:47.519
It's a it's unique where they add that that's that follows the kind of the um the master playbook.
00:04:47.600 --> 00:04:49.199
Um what other what's the other group?
00:04:49.279 --> 00:04:53.519
Let me just really quickly here look at what's the other group of those NPM packages that all followed.
00:04:53.600 --> 00:04:56.079
I'm trying to remember, they all blend together now, right?
00:04:56.160 --> 00:04:58.800
So it's like um all right.
00:04:58.879 --> 00:04:59.600
Well, anyhow.
00:04:59.759 --> 00:05:02.720
Uh so yeah, what does the malware do?
00:05:02.879 --> 00:05:04.879
Um, it is not focusing on CI.
00:05:05.040 --> 00:05:11.040
Continuous integration does not, it's this is focusing on smash and grab on an endpoint.
00:05:11.120 --> 00:05:16.240
Um, and so um it's been kind of modified to do that better.
00:05:16.399 --> 00:05:27.279
So stripped out a lot of the things that were there for worm versions of the malware you would typically see like this in in worms, a lot of that's been stripped out in this case.
00:05:27.519 --> 00:05:38.160
So it's an info stealer, it's a crypto stealer, it's fast, it's efficient, it's not great, but you know, I mean, uh I've already seen people say that they were compromised by it, right?
00:05:38.240 --> 00:05:42.240
So the reality is that unfortunately it was um it was effective.
00:05:42.480 --> 00:05:45.759
And when you can you getting back to your question about what does it do?
00:05:45.839 --> 00:05:56.480
When you zoom out a little bit, it looks really, really similar to these like B grade DPRK, B and C grade DPRK campaigns that we see all the time.
00:05:56.639 --> 00:05:58.079
Um B grade.
00:05:58.240 --> 00:06:07.600
Um so is this similar malware to what you see in DPRK typosquats, or is it different from what you tend to see there?
00:06:08.000 --> 00:06:10.079
Yes, it is it is very similar.
00:06:10.240 --> 00:06:24.240
Uh and so, you know, because there's this whole pantheon, this whole like kind of grouping of DPRK, all the way from the low-end stuff, which is really simplistic and stuff that's built to be brought in from other packages.
00:06:24.399 --> 00:06:29.600
And then there's the big complex packages that have like the six, seven stages in the kill chain.
00:06:29.839 --> 00:06:31.680
This feels like it's somewhere in the middle.
00:06:31.839 --> 00:06:37.519
Um, and so uh that's part that's partly what Rami talks about in this article.
00:06:37.680 --> 00:06:40.800
Um, I loosely agree with with the things that they've said.
00:06:40.879 --> 00:06:50.959
You know, I haven't read it, I mean I've I've read it a couple times, but uh I think the most important thing is they have tied it to some specific shared IOCs.
00:06:51.199 --> 00:06:58.000
And I think the look and the feel of the TTPs, that spidey sense that I got, this is what you get as a researcher when you you smell something.
00:06:58.160 --> 00:06:59.839
You're like, oh, there's some blood in the air right here.
00:06:59.920 --> 00:07:09.120
And you're well, it's like I think we'll actually talk about this later, what we saw with the Rust and NPM camp or uh Ruby and NPM campaign earlier this week.
00:07:09.279 --> 00:07:09.439
Right.
00:07:09.759 --> 00:07:21.120
I'm just kind of flipping through uh the Wiz blog, and I see it's got shared C2 endpoint pattern, not exactly the same endpoint uh as with the Master campaign.
00:07:21.199 --> 00:07:22.240
So that's interesting.
00:07:22.480 --> 00:07:35.360
Um, like you said, sometimes these patterns uh may not 100% match, but it's close enough and unique enough that we can kind of like, you know, let our eyes go fuzzy and be like, oh yeah, those things look the same.
00:07:35.839 --> 00:07:36.160
Yeah.
00:07:36.319 --> 00:07:51.120
And one of the things that we're seeing a lot, and we saw this with with Team PCP and other non-DPRK threat actors, is we're starting there's starting to be a move away from IPs at the at the earlier stages of the kill chain to like the use of these throwaway domains.
00:07:51.360 --> 00:08:00.160
And I think part of that is because dprk and other threat actors have found ways to buy domains from registrars using crypto.
00:08:00.319 --> 00:08:14.319
And that's why I was I was bird dogging in GoDaddy earlier, uh sorry, last week, trying to figure out is is there a way now to buy, and it looks like there is a way now to buy domains in GoDaddy's registrar via crypto through these other payment processes.
00:08:14.480 --> 00:08:19.839
So we're seeing an increase in this, which is good because they're great little indicators to have, right?
00:08:20.000 --> 00:08:28.399
Um, but uh it's just you know, when you're watching the kind of tradecraft, this does feel like DP DPRK-ish.
00:08:28.639 --> 00:08:33.120
Is that uh is that an authoritative attribution statement?
00:08:33.279 --> 00:08:34.240
No, it's not.
00:08:34.559 --> 00:08:47.759
Yeah, well, it does say in the Wiz blog that um a victim has reported C2 traffic to an IP that's also from the Axios attack back in what March or April?
00:08:47.919 --> 00:08:54.080
So that yeah, we're seeing multiple indicators of shared threat actors.
00:08:54.159 --> 00:09:04.159
And maybe this is a good place to pause when the Axios attack happened, when the Mastra attack happened, these were unknown threat actors at the time.
00:09:04.240 --> 00:09:09.200
Uh, they did happen around the same cluster as major account takeovers by Team PCP.
00:09:09.279 --> 00:09:26.960
They were not claimed by Team PCP, uh, but we've seen um people attributing those attacks to North Korean threat actors with a degree that um of credibility that we trust, in addition to chalk and debug.
00:09:27.200 --> 00:09:35.600
So we've got a pattern here where North Korea is effectively taking two different um strategies.
00:09:35.679 --> 00:10:00.399
Like if we were talking about this as a company and their go-to-market strategy, you know, their first go-to-market strategy was that typos squatting contagious interview, now Paul and Writer, very targeted on getting into an individual developer's account, getting persistence on an individual developer's machine, quietly spreading, trying to stay on the radar.
00:10:00.720 --> 00:10:22.559
The other uh part of their go-to-market strategy are these higher profile smash and grab account takeovers where they know that they're not going to uh maintain control for very long, and they're not going to uh they're there.
00:10:22.960 --> 00:10:31.360
This is not a typos squat that hangs out for months, or you know, people don't know necessarily that they consume something bad for months.
00:10:31.679 --> 00:10:37.679
So interesting to see them using both tactics, not necessarily surprising.
00:10:37.840 --> 00:10:40.159
Um, both tactics have merit.
00:10:40.399 --> 00:10:55.039
The things that we do to protect ourselves against an account takeover broadly have no uh protective uh elements for this other, you know, typosquatted type package attack.
00:10:55.200 --> 00:11:12.639
Whereas, you know, if you're focused on, I don't know, um, making sure you're only consuming packages from legitimate sources, then you know, you're more likely to have that implicit trust in a package like the array ref that got compromised today.
00:11:13.519 --> 00:11:14.960
Yeah, I mean, I totally agree.
00:11:15.120 --> 00:11:27.840
I mean, I think we've we've said it before, and the reality is that the DPRK, you know, spreads themselves, you know, they're like they're like Paul Molliff, they've got products in all the areas.
00:11:28.480 --> 00:11:34.879
It's like when you call when you call Samsung, press one for a microwave product, press two for an automotive product.
00:11:34.960 --> 00:11:36.320
I mean, DPRK has got you covered.
00:11:36.399 --> 00:11:38.480
If you want sneaky and long lived, they got that.
00:11:38.639 --> 00:11:44.639
If you want to never mind the IT workers and everything else that they've got, right?
00:11:44.879 --> 00:11:48.399
Right, they are very adaptive and they are spreading themselves across the whole.
00:11:48.879 --> 00:11:53.279
And I love your use of go to market because I coined the term last week, go to target.
00:11:53.440 --> 00:11:55.600
This is they they found their you know, they're constant.
00:11:55.679 --> 00:11:57.440
That's why they use all these campaign marketers.
00:11:57.840 --> 00:11:59.679
Sorry, campaign markers.
00:11:59.840 --> 00:12:03.440
They're trying to figure out what are the most successful ways that they can compromise people.
00:12:03.679 --> 00:12:08.960
Yeah, you gotta have your uh metrics so you know what's successful, right?
00:12:09.120 --> 00:12:12.879
DPR Pyong Peng has got his kit KPIs, baby.
00:12:13.200 --> 00:12:16.480
Okay, shall we move on to Stub Maker?
00:12:16.799 --> 00:12:17.600
Let's do it.
00:12:17.919 --> 00:12:18.240
Okay.
00:12:18.639 --> 00:12:26.240
Uh to summarize, over the weekend, uh we did some research specific to Ruby Gems.
00:12:26.480 --> 00:12:30.320
Uh, we found a cluster of packages.
00:12:30.480 --> 00:12:32.399
It started with two packages initially.
00:12:32.480 --> 00:12:34.720
That's what you sent me when we started our write-up.
00:12:35.120 --> 00:12:45.120
And then as I started poking at it, I was like, oh wait, uh, they've managed to resuscitate, revive one of these packages, and spread even further.
00:12:45.279 --> 00:12:52.399
So, long story short, um a whole bunch of Ruby typosquats were published over the weekend.
00:12:52.720 --> 00:12:56.399
Uh, they managed to do it across multiple accounts.
00:12:57.120 --> 00:13:10.399
And uh uh maybe a trick that's unique to the Ruby ecosystem is when Ruby killed those first two packages, they seemed to figure out pretty quickly that they were malicious, you know, even at the same time as we were analyzing them.
00:13:10.799 --> 00:13:25.759
Uh so they killed those two initial packages, but uh they don't seem to have a security mechanism in place to make sure a known malicious package doesn't get reactivated.
00:13:26.000 --> 00:13:41.440
And so the threat actor was able to create a new account, come back into Ruby and resuscitate one of these packages that had been taken down and publish a new malicious version to that package that always should have stayed dead.
00:13:41.759 --> 00:13:46.720
So I thought that was some really interesting Ruby specific behavior.
00:13:46.960 --> 00:14:01.200
The other thing as I was looking at this campaign and looking at every package page side by side is they were all um they had the owner account and then they had the author account listed.
00:14:01.600 --> 00:14:06.159
And the owner account that's tied to an actual account with a login and everything.
00:14:06.480 --> 00:14:08.240
The author's account.
00:14:08.399 --> 00:14:10.080
Yes, a Ruby Gems account.
00:14:10.559 --> 00:14:14.639
The author is what I would describe as like a vanity label.
00:14:14.720 --> 00:14:17.279
It can be anything that you want.
00:14:17.440 --> 00:14:27.440
Uh, there is no mechanism to force you to make the author, you know, the same as somebody who is in the ownership group, anything like that.
00:14:27.519 --> 00:14:34.159
And so we had, you know, things like an owner with sort of a random string of letters and numbers.
00:14:34.399 --> 00:14:43.039
And then the author name would be something like Blake Miller or Taylor Gray or Avery Collins or Quinn Parker.
00:14:43.279 --> 00:14:57.200
And at least to me, being American, I saw those names in a in a list and I was like, gosh, it's like they they had like a random name generator targeting children of, I don't know, young Gen Xers or millennials.
00:14:57.840 --> 00:15:04.879
You know what I when I saw those names, I thought somebody's created a random name generator based on the country music awards.
00:15:05.840 --> 00:15:06.879
It could be.
00:15:07.360 --> 00:15:08.639
It seems so.
00:15:08.720 --> 00:15:17.120
I mean, there were some like very clear indicators that these were sketchy before you even pulled the payloads, but we proactively scan Ruby.
00:15:17.200 --> 00:15:19.919
So as things come into Ruby, we're looking at it.
00:15:20.000 --> 00:15:23.039
That's how your uh detection got set off.
00:15:23.120 --> 00:15:27.919
So why don't you talk a bit about the malware and then we'll segue into the NPM part of the campaign?
00:15:28.240 --> 00:15:28.799
Oh my gosh.
00:15:28.960 --> 00:15:30.159
But now you're putting me on a spot.
00:15:30.240 --> 00:15:31.200
Like I've I've I've forgotten.
00:15:31.679 --> 00:15:35.120
I know our brains have like wiped, and that was the four days ago.
00:15:35.200 --> 00:15:36.399
Why would we think about that?
00:15:36.720 --> 00:15:37.200
It was.
00:15:37.360 --> 00:15:43.200
Let me real quick, uh, let me just cheat here in the background and just uh bring up the blog post so I can remind myself.
00:15:43.360 --> 00:15:44.960
Um I uh there we go.
00:15:45.039 --> 00:15:45.679
I'm I'm here.
00:15:45.919 --> 00:15:52.559
Um yeah, so I mean, I think the the all the things that Jen said uh are true.
00:15:52.799 --> 00:15:56.080
Um this uh campaign.
00:15:56.399 --> 00:16:19.440
Um I'm trying to remember exactly how the oh yeah, so basically they were targeting um I-18 and um uh bundler, uh other reputable, like well-adopted, like active support was in there.
00:16:22.159 --> 00:16:34.480
The vast majority of them were like simplistic I-18 um kind of uh you know, uh just uh brute force kind of typosquats, right?
00:16:34.639 --> 00:16:36.720
Not particularly well thought out.
00:16:37.039 --> 00:17:04.880
But the and Jen and I talked about this behind the scenes, that the the malware itself was actually pretty decent, you know, for you you and and this I think something that stood out about this is that um the the typosquats themselves inside of Ruby gems were kind of meh, but then the malware sitting behind it um uh you know was was more mature than we were expecting based on that initial part.
00:17:04.960 --> 00:17:38.559
So um I think that um the again this kind of you know looked and felt at a high level DPRK, not trading this to DPRK, um, but you know, the the endpoints and the ports used and some of those kind of high-level tradecraft bits felt kind of DPRK-ish, but you know, I mean that's not to say that other people aren't doing that, but you know, it was the kind of typical info stealer and um crypto stealer that everybody does now.
00:17:38.799 --> 00:17:50.400
Um uh I think it it had a couple of functions in it that specifically looked for credit card um strings in in files, which you don't see that often anymore.
00:17:50.559 --> 00:17:51.680
People don't really do that.
00:17:51.839 --> 00:18:06.240
Um that kind of that kind of um uh grepping through files looking for things like that are things that can get caught by you know even simplistic EDR um or or antivirus.
00:18:06.319 --> 00:18:09.039
Um so threat actors tend not to do it.
00:18:09.200 --> 00:18:20.400
But yeah, I mean that sorry, that's not like that not a super high uh quality analysis, but um it did feel to go ahead.
00:18:20.799 --> 00:18:36.160
Maybe we can go through what the malware does uh because I think it's a little bit unique in that it uses whatever language the package started in, and then it goes into Rust, and then there's some Go in there.
00:18:36.559 --> 00:18:39.200
It's very specifically targeting Windows.
00:18:39.519 --> 00:18:45.519
So essentially it starts out with the victim installing the typosquatted package.
00:18:45.680 --> 00:19:02.240
Uh Ruby has a mechanism that's a little bit similar to what we've seen in NPM and in VS Code, where it can let you automatically do some a series of things without having an import or a require.
00:19:02.319 --> 00:19:07.920
So it's this uh extonf.rb.
00:19:08.000 --> 00:19:16.000
I'm not a Ruby person, so I don't know how you say that file name, but there's a special file name that essentially is kind of like an auto-install function.
00:19:16.960 --> 00:19:18.880
There's a hook from there, right?
00:19:20.400 --> 00:19:30.319
Yep, and then you know a couple steps down, it's looking to see, you know, it's pinging the host and saying, hey, what kind of operating system are you?
00:19:30.880 --> 00:19:34.079
Oh, Windows, hi, we'd like to, you know, stay here.
00:19:34.319 --> 00:19:39.119
Linux, mac OS, uh telemetry only and exits.
00:19:39.279 --> 00:19:43.680
But if it's Windows, then it downloads a Rust-based loader.
00:19:44.160 --> 00:19:52.880
Um and something that was very uh specific there is it's a 22 megabyte file size.
00:19:53.039 --> 00:19:56.880
So that 22, let's let's remember that and we'll come back to it.
00:19:57.279 --> 00:20:11.839
Uh again, it's gonna detect uh WSL, it's gonna bridge out to PowerShell, it's gonna launch a loader that's a Go-based info stealer, and then it's X filling a password protected zip file.
00:20:12.079 --> 00:20:12.799
Yeah, let me jump out.
00:20:12.960 --> 00:20:17.920
I'm gonna let you talk while I let my cat out of my office because he's he's not happy.
00:20:18.000 --> 00:20:19.200
So I'll be right back.
00:20:19.359 --> 00:20:19.839
You talk.
00:20:20.079 --> 00:20:23.519
Yeah, I mean, uh in the meantime, I've been able to remind myself of what was going on here.
00:20:23.599 --> 00:20:27.200
I just see so many different attack chains, kill chains that they kind of all blend together.
00:20:27.279 --> 00:20:28.720
So I had to kind of remind myself.
00:20:28.799 --> 00:20:34.480
But I think um this was interesting because it did use like multiple stages.
00:20:34.559 --> 00:20:38.880
There's like five or six stages, and each one of those stages is actually written in a different language.
00:20:39.039 --> 00:20:43.279
So like the first loader, this 22 meg file, is is Rust, right?
00:20:43.359 --> 00:20:50.480
But then inside of it, there's an embedded Go uh second stage, and that's where the infostealer kind of kicks off.
00:20:50.640 --> 00:20:54.000
Um, but there's also JavaScript components and there's Ruby components.
00:20:54.160 --> 00:21:03.920
Um, and I think that that Rust loader with the embedded Go um info stealer in it is a pattern that we're seeing a lot from DPRK.
00:21:04.000 --> 00:21:07.519
And so that's one of those things that just kind of made me feel like, oh, this kind of could be there.
00:21:07.680 --> 00:21:11.279
But then there's a bunch of things that don't align with DPRK trade critics.
00:21:11.440 --> 00:21:16.880
Well, like candidly, they are much better at typosquat targeting than what we saw with this campaign.
00:21:16.960 --> 00:21:20.960
And I'm not saying that means it's not them, but these were pretty bad.
00:21:21.359 --> 00:21:33.920
Yeah, and and there's not, you know, you bad guys are gonna emulate other bad guys, and right so and the fact that the the point I was just gonna make is that it pulls that that 22 meg file from a GitHub repo.
00:21:34.079 --> 00:21:35.200
That's really unusual.
00:21:35.359 --> 00:21:44.720
Like DPRK traditionally doesn't want to pin and pivot off a specific GitHub repo because that's just something that I can kill the repo, it's gone, right?
00:21:44.880 --> 00:21:48.319
Yeah, yeah, and it's also something that I can sit there and I can watch, right?
00:21:48.559 --> 00:21:50.559
Um, so that was unusual.
00:21:50.640 --> 00:21:56.160
And the fact that they didn't hide the loader, it's just main.exe, right?
00:21:56.799 --> 00:21:59.680
I'll also note that when we were looking at the object.
00:22:00.160 --> 00:22:07.839
Obfuscation, and I'm going to say obfuscation and air quotes uh IP address was kind of hilarious.
00:22:08.000 --> 00:22:10.880
All they did was take the periods out.
00:22:11.200 --> 00:22:18.880
So they had the bracketed IP address without periods and with spaces instead, and then with a join period after it.
00:22:18.960 --> 00:22:23.359
So, you know, anybody who's visually looking through there is like, oh, there's an IP address.
00:22:24.400 --> 00:22:28.160
Yeah, you know, so like it's sending us these mixed signals, right?
00:22:28.240 --> 00:22:35.279
Like the IP address thing and like the fact that they're just sticking it clearly in a GitHub repo, the main loader, so it can get torn down.
00:22:35.359 --> 00:22:38.000
So here's a here's something to learn by bad guys.
00:22:38.160 --> 00:22:46.000
What you don't want to do is you don't want to make the first stage really easy to take down because then all the other stages don't run, right?
00:22:46.240 --> 00:22:51.680
You can you can get a little bit loose when you're down at stage four or stage five, but stage one you want to be hiding in.
00:22:51.759 --> 00:23:03.119
That's why DPRK uses things like ether hiding and null receiver in that second stage after the npm package of the GitHub repo, is because that's just that it's you know very effective at hiding and being letting them be able to iterate.
00:23:03.279 --> 00:23:20.160
But another thing that I just thought about, Jen, was that like the mixed signals that this attack was sending us, it actually had a pretty well done um uh bypass around the the Google Chrome app bound encryption um control, which I think surprised a lot of people.
00:23:20.319 --> 00:23:31.279
Like there are multiple people on LinkedIn and and Twitter, you know, mentioned oh, because we've only started seeing that um these bypasses recently, and other people are doing it, so it's not like this is super unique.
00:23:31.599 --> 00:23:37.759
Um, but what it does is it makes it that much more powerful in stealing stuff out of the browser, right?
00:23:37.839 --> 00:23:44.640
It's bypassing this significant control that Google added in like 1.127 or something.
00:23:44.720 --> 00:23:48.000
I'm sorry, uh version 127 a couple months ago.
00:23:48.240 --> 00:23:55.359
Um so yeah, all in all, mixed bag kind of looks like TPRK, kind of looks like vibe coding.
00:23:55.519 --> 00:23:58.160
Um, used all kinds of languages, right?
00:23:58.240 --> 00:24:10.960
And something I pointed out in my blog post is that this kind of casual polyglot, and if anybody's not familiar with this term polyglot, it basically means somebody that can speak multiple languages, or in this case, write multiple languages, use multiple languages.
00:24:11.200 --> 00:24:19.119
Well, people don't have to actually understand multiple languages anymore because Claude and Codex and whatever other agents they're using are writing all this stuff for them.
00:24:19.200 --> 00:24:31.279
So for whatever reason, they say, hey, write me a you know, follow the pattern from DPRK and write me a Rust wrapper, right, around the Go and then Better Go and or it's just following the patterns that it knows from the DPRK.
00:24:31.359 --> 00:24:32.079
Who knows?
00:24:32.319 --> 00:24:34.240
Very yeah, lots of mixed signals there.
00:24:34.559 --> 00:24:49.359
Well, speaking of languages, uh, maybe two days after we published this research, I was in LinkedIn because I'm in there way too much, and I saw somebody's post about, and I'll quote, a 37-package typosquatting campaign on NPM.
00:24:49.440 --> 00:24:51.279
And so I always click when I see those kind of things.
00:24:51.359 --> 00:25:02.000
It was from somebody from Open Hack, and they in the initial description described a 22 megabyte Rust loader carrying an embedded Go info stealer.
00:25:02.160 --> 00:25:04.079
And I was like, ding, ding, ding.
00:25:04.319 --> 00:25:06.160
That sounds awfully familiar.
00:25:06.400 --> 00:25:08.480
And seems like a pattern I've seen recently.
00:25:08.720 --> 00:25:09.440
Yeah, yeah, yeah.
00:25:09.519 --> 00:25:11.359
That's that's very recent.
00:25:11.440 --> 00:25:14.480
So I took a second to compare it to your write-up.
00:25:14.880 --> 00:25:17.359
Uh, we pulled the payloads, it's identical.
00:25:17.519 --> 00:25:24.400
Um, the only difference being because it's npm and not Ruby, the uh firing mechanism is different.
00:25:24.480 --> 00:25:34.799
They took advantage of the npm post install scripts, which at this point are infamous uh in the community as a way to auto-install your malware.
00:25:34.960 --> 00:25:44.079
And then uh ultimately I found a total of 40 packages that were associated with the npm branch of this attack.
00:25:44.240 --> 00:25:48.559
Uh, the shape here was actually slightly different than what we saw in Ruby.
00:25:48.799 --> 00:25:59.680
Instead of these, as you say, country music name generator names, uh, it was five different uh NPM accounts that published the set of 40 packages.
00:25:59.920 --> 00:26:05.839
None of the names on these accounts are look like real human names for the most part.
00:26:06.000 --> 00:26:16.079
It tends to be a string of maybe 10 to 15 uh alpha characters or you know, letters, and then a series of numbers.
00:26:16.240 --> 00:26:23.759
Um, one of them is what is this app live 2023 8261?
00:26:23.920 --> 00:26:27.920
Another one is full basket property website 53a.
00:26:28.400 --> 00:26:35.599
Uh so very different in terms of naming conventions, but same deal with the really clumsy typosquats.
00:26:35.680 --> 00:26:44.240
They were um targeting Axios, chalk, commander, uh Lodash, and uh TypeScript.
00:26:44.559 --> 00:26:51.279
And there's probably, I don't know, 10 different TypeScript ones where they've transposed letters or added a letter and like it.
00:26:51.920 --> 00:27:01.759
I can see in some ways how somebody might, you know, fat finger the keyboard and accidentally type one of these things, but still it's a brute force style attack.
00:27:01.920 --> 00:27:13.359
Now, what I forgot to tell you, Paul, um, is one of the email addresses has some kind of like superfluous throughout the email address.
00:27:13.599 --> 00:27:28.000
And that's another thing that did remind me of DPRK because we've seen that uh in some DPRK NPM accounts where they'll have a username and then their email address is kind of similar, but has like random periods.
00:27:28.720 --> 00:27:30.160
Um weird.
00:27:30.640 --> 00:27:34.480
So we know for sure that it's hit two ecosystems.
00:27:34.720 --> 00:27:43.680
I was chatting with someone from the hacker news the last couple of days about it, and he emailed me last night and he's like, you know, have you seen it cross into any other ecosystems?
00:27:43.839 --> 00:27:45.519
And I was going to type no.
00:27:45.839 --> 00:27:49.200
And I haven't caught you up on this yet, so I don't know if you know what I'm gonna tell you.
00:27:49.440 --> 00:28:03.680
Um, and then I got tagged in a post overnight about the same campaign hitting PowerShell, and we haven't had an opportunity to take a look at it yet, but we're having multiple people say, hey, it's it's the same shape, it's just in PowerShell.
00:28:05.119 --> 00:28:10.079
Yeah, and you know, the funny thing is I didn't even know that PowerShell gallery existed.
00:28:10.240 --> 00:28:12.640
I was like, oh my god, a registry for PowerShell.
00:28:12.880 --> 00:28:19.279
Yay! Add it to the pantheon of Microsoft things that are probably far too insecure.
00:28:19.519 --> 00:28:23.920
Um, so yeah, we have yet to kind of go down that road and we're going to.
00:28:24.240 --> 00:28:30.240
Um, but I feel like I would say I have no reason to think they're wrong at this point.
00:28:30.400 --> 00:28:32.640
I'm seeing some screenshots in X.
00:28:33.359 --> 00:28:36.160
Um it probably is in PowerShell.
00:28:37.680 --> 00:28:47.039
I feel like I last night before I went to bed, I feel like I saw one come in um in VS Code or one of the other ecosystems that was labeled stub makers.
00:28:47.119 --> 00:28:48.720
So we're gonna we're gonna see these things.
00:28:48.799 --> 00:28:56.880
I mean, we typically do, you know, with many of these big campaigns that, you know, after the initial uh kind of wave, then we see additional stuff coming in.
00:28:57.039 --> 00:28:58.559
Um, so stand by.
00:28:58.640 --> 00:29:01.519
There might be some other ecosystems to add to that list as well.
00:29:06.480 --> 00:29:08.160
Potentially in this campaign.
00:29:08.240 --> 00:29:40.960
And you know, as you and I talked about behind the scenes, we're not seeing the uh traditional hallmarks of AI written code, but uh that it was hitting the number of ecosystems that it seems to at the same time, and in some cases, you know, rapidly evolving, it seems possible, you know, given the number of different languages and ecosystems, like you said, nobody's expected to be an expert in I don't know, NPM Ruby, and PowerShell.
00:29:42.799 --> 00:30:10.319
Yeah, I mean, the it makes sense that if you, you know, if you start out with an NPM or one of these high profile you know registries where things get taken down relatively quickly, you can take that same attack and just repackage it for some of these smaller, less, you know, with with less volume, less voluminous, anyhow, less popular or whatever ecosystems, repackage it there and maybe get you know some a longer tail out of it.
00:30:10.400 --> 00:30:11.759
So not surprising.
00:30:12.720 --> 00:30:13.039
Okay.
00:30:13.440 --> 00:30:22.880
Last topic, uh, you've been telling me for a little bit now that you've been seeing an increase in what you're calling DIY binary payloads.
00:30:22.960 --> 00:30:29.039
So taking a step back, we don't actually see a lot of binary payloads in malicious open source.
00:30:29.279 --> 00:30:31.680
Typically, it's in an interpreted language.
00:30:31.759 --> 00:30:38.640
That's why things like hashes tend not to be very useful with malicious open source.
00:30:38.880 --> 00:30:45.920
Uh, you are seeing uh maybe like a little bit of a Frankenstein where some of it's interpreted and some of it's binary.
00:30:46.000 --> 00:30:47.519
So talk about what you're seeing.
00:30:47.920 --> 00:30:49.759
I mean, Stub Maker is the perfect example.
00:30:50.079 --> 00:31:02.240
This is a great segue from the Stub Maker conversation here, where Stub Maker had you know five or six languages used in binaries in at least uh three languages, C Rust, and Go.
00:31:03.279 --> 00:31:14.799
So basically, yeah, I've been saying on the podcast and other places for years that like, you know, I I have I don't have to do a lot of dynamic or or sandbox analysis because most of the stuff we look at is interpreted.
00:31:14.880 --> 00:31:23.519
And as long as you have a built-for-purpose static analysis harness, you know, you can kind of you know take care of 99% of it.
00:31:23.599 --> 00:31:36.640
But just in the last two weeks alone, I've just seen the increase in software supply chain attacks that are using you know binaries in stages two through four or whatever, has just increased dramatically.
00:31:36.799 --> 00:31:45.680
And I've just spent a lot of time over the last two weeks doing stuff that I typically don't have to do, you know, reviving some of these skills from my heyday.
00:31:45.759 --> 00:31:48.559
But um, I think this is evidence of a couple things.
00:31:48.720 --> 00:31:54.079
I think it's evidence of first the use of agents and LLMs to write or help write your malware.
00:31:54.400 --> 00:32:10.640
Two, because you're not a mature uh uh open source malware or software supply chain malware writer author, the way that you think that you have to hide your malware is by putting it in a binary and kind of following that traditional path, right?
00:32:10.720 --> 00:32:22.480
So you're new, you're like this newbie malware author, and you're looking at you know, like VX Underground and this whole thing that tells you that you got to build uh binaries to hide your shit, your stuff, and that's what you do.
00:32:22.720 --> 00:32:24.799
That's the pattern that you you follow, right?
00:32:25.119 --> 00:32:30.559
Um I and I think the reality is those stick out like a uh like a sore thumb.
00:32:30.640 --> 00:32:40.079
When you see a npm or RubyGems package installing a binary, either with that binary in the package itself, which makes it bloated, right?
00:32:40.160 --> 00:32:45.839
As we were just talking about with Stunmaker, or downloading that, immediately downloading that from a URL or an IP.
00:32:46.000 --> 00:32:47.599
I mean, these are pretty big flags.
00:32:47.680 --> 00:32:53.839
So you might think that you're hiding it in the binary, but the fact that you're adding the binary itself is the biggest red flag.
00:32:54.079 --> 00:32:58.880
So uh tip all school malware.
00:32:59.200 --> 00:32:59.519
Yeah.
00:33:01.119 --> 00:33:10.880
I'm gonna I'm gonna give you bad guys a little tip here, which is you you don't use binaries, they like you think that they're helping you and they're not, right?
00:33:11.119 --> 00:33:12.079
Dum dums.
00:33:12.400 --> 00:33:14.559
Um, anyhow, we'll leave it to that.
00:33:14.720 --> 00:33:18.400
I um I also wanted to throw in classic YOLO style.
00:33:18.559 --> 00:33:27.279
I also want, and I think this is probably something we can talk about more next week, but Jen and I have been seeing the number of people affected by Pollen Rider like being reinfected.
00:33:27.359 --> 00:33:30.079
Just I was checking that that GitHub community.
00:33:30.640 --> 00:33:37.759
I meant to tell you, I'm I am subscribed to updates, and uh I was gonna read this one.
00:33:38.000 --> 00:33:43.440
Uh I think uh after I took a screenshot of it for exactly that purpose too, as well.
00:33:43.759 --> 00:33:50.559
After nearly two months of inactivity, the malware has started pushing changes to all repositories and branches again.
00:33:50.799 --> 00:33:51.599
Womp womp.
00:33:51.680 --> 00:33:52.160
That's my ad.
00:33:52.880 --> 00:33:54.000
Womp womp is me.
00:33:54.319 --> 00:33:58.480
Um they found that it's using you know an Ethereum address.
00:33:58.720 --> 00:34:03.519
Uh it's that same reinfection cycle that we've been seeing.
00:34:04.079 --> 00:34:09.519
Interestingly enough, this is the first time that we've seen null receiver used in well, actually, that's not true, right?
00:34:09.599 --> 00:34:12.800
I think we have seen null receiver in the pawn rider, but it has not much, right?
00:34:12.960 --> 00:34:18.159
So this is clearly the use of null receiver at stage two um in to replace ether hiding.
00:34:18.239 --> 00:34:34.639
In fact, this kill chain, um, you know, when we initially saw null receiver at stage two, which is basically hiding the IP address for for the next stage in um in the uh response, uh the destination response, which didn't exist.
00:34:34.960 --> 00:34:38.079
Um, we saw ether hiding in the next stage, right?
00:34:38.159 --> 00:34:40.000
So there was no receiver and then there's ether hiding.
00:34:40.079 --> 00:34:40.880
We don't see that anymore.
00:34:41.039 --> 00:34:44.559
Ether hiding is gone, uh, and it's been replaced by no receiver.
00:34:44.639 --> 00:34:53.440
And so this is Pollen Rider, DPRK, is now using null receiver as a primary hiding methodology uh instead of ether hiding.
00:34:53.519 --> 00:34:55.519
So, you know, gone are the days of ether hiding.
00:34:56.159 --> 00:34:58.159
How is this possible conversation?
00:34:58.320 --> 00:35:06.320
You know, you've got a person here in the GitHub community saying uh they, you know, of reading between the lines, they think they got rid of the malware.
00:35:06.480 --> 00:35:07.760
Two months later it's back.
00:35:08.000 --> 00:35:09.280
How does this happen?
00:35:09.440 --> 00:35:12.800
Um, how is DPRK pushing updates?
00:35:12.960 --> 00:35:16.559
How are they, you know, putting in new parts of their kill chain?
00:35:16.639 --> 00:35:19.760
Because obviously null receiver wasn't there two months ago.
00:35:20.000 --> 00:35:33.199
Um, this comes back to the way that Paul and Writer works from a basic level is this is not a threat actor, you know, using your credentials 100% of the time, hanging out on your machine.
00:35:33.280 --> 00:35:49.199
So, like maybe you have rotated your credentials, maybe you've even replaced your machine, but you go and you know, accidentally reinfect yourself uh using your repo, or the other way around, it's still hanging out on your machine.
00:35:49.519 --> 00:35:53.519
It's able to get whatever credentials you have locally.
00:35:54.079 --> 00:36:04.400
And the I guess brilliant part about this malware is it can make commits to your repo without leaving a trail.
00:36:04.559 --> 00:36:08.239
So you won't see a suspicious commit necessarily.
00:36:08.320 --> 00:36:12.320
Sometimes you will, but um, sometimes you won't see a suspicious commit at all.
00:36:12.480 --> 00:36:22.559
Uh, they're able to hide that so that you can't just have an alert set up that says, hey, let me know if something new comes in here that I didn't authorize.
00:36:22.960 --> 00:36:23.199
Yeah.
00:36:23.280 --> 00:36:36.480
I mean, to say this a different way, what we hear again and again and again from these victims is that they're looking at their commit history in GitHub and they are unable to reconcile in a brain because they just don't understand how it works.
00:36:36.719 --> 00:36:45.840
How they're looking at a git a commit history that hasn't changed or it doesn't appear to have changed, and yet they're looking at a file and there's a new malicious payload there.
00:36:46.000 --> 00:36:48.960
They just can't comprehend that, and that's because of one thing.
00:36:49.119 --> 00:36:57.519
And the funny thing is that there's usually like an engineering uh misunderstanding or uh or an uh infosecse ops misunderstanding.
00:36:57.679 --> 00:37:06.559
In this case, both of these you know personas don't have an understanding, which is that the git commit history happens on your machine.
00:37:06.880 --> 00:37:11.039
GitHub just expresses that as a luxury to you, right?
00:37:11.119 --> 00:37:17.760
It just accepting the git commit commit history that's coming from your machine when you push up to origin.
00:37:18.400 --> 00:37:26.239
So what happens is dprk is overwriting existing older commits three years ago, five years ago, ten years ago, doesn't matter.
00:37:26.400 --> 00:37:33.360
They overwrite those, put the new malicious payload in there, then they wait for you to go ahead and do your work, and then you push it up again.
00:37:33.519 --> 00:37:38.400
And here's the other thing, and this is uh continuing our YOLO trend.
00:37:38.480 --> 00:37:43.519
Uh, DPRK has now found a way to infect NPM itself, the package manager.
00:37:43.679 --> 00:37:46.639
We will talk about this next week because we got to do a blog post about it.
00:37:46.800 --> 00:37:56.159
But the reality is that DPRK is ever innovating in this space, and that's why Pollenwriter continues to be this just massive human bot network that keeps infecting people.
00:37:56.320 --> 00:38:01.199
So they buy a new MacBook and they set it up and they're infected within a day or two.
00:38:01.360 --> 00:38:02.639
So it's crazy.
00:38:03.360 --> 00:38:08.719
Uh, on that note, uh, we've got one more podcast this month.
00:38:08.880 --> 00:38:16.000
Uh, we're gonna take a week break, and then Paul and I will be in Europe uh in early September.
00:38:16.159 --> 00:38:21.199
We're gonna be in uh Strasbourg for underground economy.
00:38:21.360 --> 00:38:23.199
So come say hi if you're going to UE.
00:38:23.599 --> 00:38:27.199
And then Paul, you're gonna be speaking at B sides which one?
00:38:27.599 --> 00:38:28.239
Frankfurt.
00:38:28.480 --> 00:38:29.039
Frankfurt.
00:38:29.280 --> 00:38:30.480
B Sides Frankfurt.
00:38:30.559 --> 00:38:33.280
So if you're gonna be at either of those events, come say hi.
00:38:33.440 --> 00:38:35.039
Let us know you're gonna be there, whatever.
00:38:35.119 --> 00:38:36.159
We'll give you a sticker.
00:38:37.119 --> 00:38:38.320
We'll talk about Paul and Rider.
00:38:38.480 --> 00:38:40.480
I think we're talking about Paul and Ryder at both, right?
00:38:40.559 --> 00:38:42.400
I assume that's what you're presenting in Frankfurt.
00:38:42.639 --> 00:38:43.679
Yeah, yeah, we are.
00:38:43.760 --> 00:38:44.000
Yeah.
00:38:44.159 --> 00:38:48.480
So uh uh UE is September 7th through 10th.
00:38:49.679 --> 00:38:52.079
And Frankfurt B size is September 11th.
00:38:52.239 --> 00:38:53.199
I can't forget that day.
00:38:53.280 --> 00:38:54.239
It's September 11th.
00:38:54.320 --> 00:39:00.719
So that's gonna be um that's gonna be an interesting thing to talk about, you know, in Frankfurt on September 11th.
00:39:00.960 --> 00:39:01.280
Yeah.
00:39:01.519 --> 00:39:03.280
All right, everyone, have a good one.
00:39:03.360 --> 00:39:07.280
This was a little bit longer than usual, but lots of interesting stuff to get into.
00:39:07.760 --> 00:39:08.000
Thanks.
00:39:08.079 --> 00:39:08.960
Thanks for listening, everybody.
00:39:09.119 --> 00:39:09.840
Appreciate it.