WEBVTT
00:00:00.320 --> 00:00:04.240
Hello, it is Thursday, October 8th.
00:00:04.480 --> 00:00:11.599
Um we have a couple topics on the agenda, but before we dive in, what's up, Paul?
00:00:11.679 --> 00:00:12.720
What's new?
00:00:13.519 --> 00:00:14.160
Good question.
00:00:14.320 --> 00:00:15.199
What is new?
00:00:15.519 --> 00:00:20.879
Um just, you know, enjoying being home for a few months.
00:00:20.960 --> 00:00:22.640
I think that's um nice.
00:00:22.800 --> 00:00:25.600
You're you're taking one for the team and you're going to the Sands thing.
00:00:25.679 --> 00:00:27.519
So thank you for doing that.
00:00:27.679 --> 00:00:29.600
Although I really, really, really wanted to go to the show.
00:00:34.240 --> 00:00:35.600
Why am I doing this again?
00:00:35.840 --> 00:00:39.439
But I'm excited for the the things that I have coming up.
00:00:40.240 --> 00:00:43.039
Yeah, you got a couple really, really cool things coming up.
00:00:43.119 --> 00:00:44.399
And I forgot you were going to Lascon.
00:00:44.799 --> 00:00:46.240
So that's that's super dope.
00:00:46.479 --> 00:00:46.719
Yeah.
00:00:46.880 --> 00:00:55.520
So uh for anybody who's going to the Sands uh summit next week in Virginia slash Washington, DC, come say hi.
00:00:55.600 --> 00:00:59.679
I'm going to be giving a talk on um Pollenwriter.
00:00:59.920 --> 00:01:07.840
And then uh at the end of the month, I'll be in Austin at Lascon giving a talk on malicious AI skills.
00:01:07.920 --> 00:01:09.359
Uh, I really like LasCon.
00:01:09.680 --> 00:01:17.359
I was um looking at their webpage, website, uh, you know, kind of writing up my post to say, hey, you know, I'm gonna be there.
00:01:17.599 --> 00:01:20.560
And their website says they get about 400 people a year.
00:01:20.640 --> 00:01:26.239
And honestly, it's one of those conferences that, like, if you had told me 400, I wouldn't have believed it.
00:01:26.400 --> 00:01:31.599
It either would be more or less, but like it's just, I don't know, they have a ton of cracks.
00:01:31.920 --> 00:01:34.719
Um, people from all over the country travel to it.
00:01:34.799 --> 00:01:38.079
Like it's just a really unique conference.
00:01:38.319 --> 00:01:42.000
So uh if you haven't gotten your ticket yet, they are still available.
00:01:42.079 --> 00:01:52.159
They're a little pricey if um you're paying out of pocket last minute, but if you can get your employer to pay for it, you should because the content's great, the networking's great.
00:01:52.319 --> 00:01:54.719
Uh, they put on a really nice conference.
00:01:55.120 --> 00:01:58.640
The show from uh I'm sorry, the shirt, the swag.
00:01:59.040 --> 00:02:03.840
The shirt from the 20, I guess it would have been 2024 when they did the upside down.
00:02:04.159 --> 00:02:04.879
Um yeah.
00:02:05.200 --> 00:02:08.080
The strange I didn't get that shirt, but I know which one you're talking about.
00:02:08.319 --> 00:02:09.759
I I wore it a couple days ago.
00:02:09.840 --> 00:02:11.680
It's just such a great shirt.
00:02:12.080 --> 00:02:12.639
Great swag.
00:02:12.960 --> 00:02:14.879
Oh, I have the challenge coin right here.
00:02:15.759 --> 00:02:17.680
There you go, there you go, there you go, there you go.
00:02:17.840 --> 00:02:23.919
Uh oh, very nice, and then the upside down bowl because they always have the bull.
00:02:24.080 --> 00:02:25.520
And I did ride the bull.
00:02:26.000 --> 00:02:30.159
Yeah, uh, I enjoy going and watching who does ride the bull.
00:02:30.400 --> 00:02:35.919
That's the best part about the happy hours to see who who decides to bull ride.
00:02:36.479 --> 00:02:40.960
I definitely bull rode and watching the video back, I'm just so embarrassed.
00:02:41.039 --> 00:02:42.960
It's like painful to watch it.
00:02:43.039 --> 00:02:49.599
Like it's so slow, and at one point my tummy pops out because you're you're like this.
00:02:50.159 --> 00:02:52.639
I just the whole thing is so cringe.
00:02:53.039 --> 00:02:53.919
Pretty cringe.
00:02:54.719 --> 00:02:55.280
I don't know.
00:02:55.360 --> 00:02:58.560
I feel like uh that might be part of growing up.
00:02:58.719 --> 00:03:02.319
Somebody, you know, you gotta at some point if you have an opportunity to ride the bull.
00:03:02.479 --> 00:03:04.479
I probably did it in my 20s at some point.
00:03:04.560 --> 00:03:07.439
Uh I'm not gonna do it now because I will hurt myself.
00:03:07.680 --> 00:03:08.560
Okay, anyway.
00:03:08.960 --> 00:03:16.080
So yesterday so many jokes, so many jokes in there that we're just not gonna like we're not gonna we're we're we're gonna roll on.
00:03:16.240 --> 00:03:18.080
We're gonna talk about Tensor Lake.
00:03:18.400 --> 00:03:26.800
Um, yeah, as I was uh winding down last night, um, we saw Tensor Lake get compromised.
00:03:27.120 --> 00:03:31.280
Tensorlake uh it's is their SDK, is what was compromised.
00:03:31.520 --> 00:03:36.960
So it is uh used for building and operating AI agents.
00:03:37.360 --> 00:03:40.479
And um there's a couple things to know about this.
00:03:40.639 --> 00:03:43.360
Uh first, it is a pretty widely used package.
00:03:43.439 --> 00:03:52.639
So if you're a TensorLake user, um definitely uh, you know, make sure you're not using the compromise version.
00:03:52.879 --> 00:03:59.039
It was taken down relatively quickly within a couple of hours, I think.
00:03:59.280 --> 00:04:15.280
Uh, but this was uh the second time, I think second or third time we've seen an attack that leveraged the open sourced mini Shy Hulued worm from earlier this year.
00:04:15.520 --> 00:04:22.000
Um it's very similar to the attack that happened in August that targeted Jared Ray's projects.
00:04:22.160 --> 00:04:24.560
So that was um a pretty substantial one.
00:04:24.639 --> 00:04:33.279
It you know, hit 400 or so packages because he maintains a lot of things and it had a little bit of success on the worm-like behavior.
00:04:33.600 --> 00:04:39.120
Uh, I'm not seeing any success on this iterations worm.
00:04:39.279 --> 00:04:41.279
Have you seen heard anything?
00:04:41.839 --> 00:04:43.839
No, I mean, I've seen it described.
00:04:44.240 --> 00:04:48.399
The only thing I've seen really is I've seen it described as not having any real impact.
00:04:48.480 --> 00:04:50.560
So um yeah.
00:04:51.759 --> 00:04:53.120
So that's good news.
00:04:53.360 --> 00:04:58.160
Um I'm gonna go ahead and drop our threat report on it in the chat.
00:04:58.399 --> 00:04:59.120
Then sorry.
00:05:03.680 --> 00:05:04.639
Sorry to continue.
00:05:05.279 --> 00:05:17.439
I was just gonna say, uh, you know, I was just going through the list of stuff that it exfils, the specific um it's real similar to what we've seen from the previous iterations.
00:05:17.600 --> 00:05:30.319
Um, I'm sharing our blog that we published in August about the cacheable kev um compromise that was the bigger version of this because it's it's not identical, but it's very similar.
00:05:31.839 --> 00:05:41.360
I don't know if the um I'm looking at it's also it also specifically looked for the bitrise underscore IO variable, which um I don't know if that was anything.
00:05:41.680 --> 00:05:42.319
That might be new.
00:05:42.639 --> 00:05:43.199
That might be new.
00:05:43.279 --> 00:05:47.040
There's always, yeah, I mean, whenever you look at these, there's always one or two things that are added.
00:05:47.680 --> 00:05:55.040
But I mean, I think what we're driving at here at some level, Jen, is the fact that this, you know, this is kind of I don't want to say it's a nothing burger because it's not.
00:05:55.120 --> 00:06:02.399
I mean, it's it's real, but uh it looks and feels like the last several versions of this, right?
00:06:02.560 --> 00:06:17.600
And I think that people have, you know, over the course of the Namiasma and the many Shy Halud iterations, you know, have worked on some form of excuse me, um, you know, way to deal with this.
00:06:17.680 --> 00:06:19.279
And so I think shields are up.
00:06:19.360 --> 00:06:20.959
I I guess that's what I'm trying to say.
00:06:21.360 --> 00:06:23.600
Bringing back a term from 2024.
00:06:23.839 --> 00:06:30.079
Shields are up, and um, and it appears those shields were, you know, I think mostly successful.
00:06:30.399 --> 00:06:44.720
Yeah, I think it's probably a combination of better defense, and um, I'm gonna go out on a limb and make some uh uh I would say assumptions here, not proven.
00:06:44.800 --> 00:06:48.480
Um, I don't think we're dealing with a very sophisticated threat actor.
00:06:48.639 --> 00:07:08.000
Uh, this reads like they used the open sourced form as a template, probably had access to some LLMs and some automation, and uh somehow managed to get access to the GitHub repository for this uh TensorLake project.
00:07:08.240 --> 00:07:21.600
Um, I think it took them a little bit of time to detect it, but it's not clear how they got uh in, much in the way that it's not clear how the attackers got in uh back in August.
00:07:21.759 --> 00:07:49.279
So there's probably some combination going on here of using AI to find a reasonably popular open source project that has a vulnerability in it somewhere, um combined with you know a little DIY malware template, but I think just based on the you know lack of panic, which is a good thing.
00:07:49.360 --> 00:07:52.639
I don't think we're dealing with somebody very sophisticated here.
00:07:53.920 --> 00:08:00.480
Yeah, I think all signs point to low sophistication for this one.
00:08:00.800 --> 00:08:09.040
Um and uh you know they did use a custom um you know domain.
00:08:09.519 --> 00:08:17.360
So uh it's following the form and function of some of those, you know, April to June um patterns.
00:08:17.680 --> 00:08:19.680
Uh but I want to take this opportunity.
00:08:20.000 --> 00:08:23.759
Wait, I want to look right down the hey GitHub, npm.
00:08:24.399 --> 00:08:26.959
I thought you guys are scanning npm packages.
00:08:27.839 --> 00:08:29.199
What's going on, homies?
00:08:29.680 --> 00:08:35.679
Yeah, I guess what I'll say there is this is definitely following a really clear playbook.
00:08:35.840 --> 00:08:46.000
Um, the malicious version contained two files uh in addition to the regular uh content that you would expect in the package.
00:08:46.240 --> 00:08:50.799
That included a setup.mjs, which fires through a pre-install hook.
00:08:50.960 --> 00:08:54.240
Oh, isn't that one of the things we all know to look for at this point?
00:08:54.480 --> 00:08:58.000
That's what any scanning, proactive scanning should have caught.
00:08:58.240 --> 00:09:09.679
And then uh so that pre-install hook uh launches the payload using bun again, fairly um well-known pattern at this stage.
00:09:10.000 --> 00:09:21.919
And then we have a math underscore symbol.js file, which again, similar to what we saw in August, slightly different names, uh, that contains a credential stealer and self-propagating worm.
00:09:22.000 --> 00:09:28.639
So yeah, there's some pretty clear signals with this that proactive scanning likely should have caught.
00:09:28.960 --> 00:09:34.399
Yeah, I'm I I will go a step further and proactive scanning likely doesn't exist.
00:09:35.360 --> 00:09:36.000
Yes.
00:09:37.440 --> 00:09:38.480
That would be what follows.
00:09:39.039 --> 00:09:43.440
As a functioning thing, as a functioning function.
00:09:43.759 --> 00:09:50.080
You know, it's interesting because oh sorry, I was gonna I was gonna go off topic today because we're YOLOing it right a bit.
00:09:50.159 --> 00:09:50.879
Is that okay?
00:09:51.200 --> 00:09:51.519
Sure.
00:09:51.600 --> 00:09:57.360
I was gonna move on to the Ruby Gem topic, but if you have something that's uh worth talking about now, let's start there.
00:09:57.679 --> 00:10:06.559
I want to do both, obviously, but um I think in anticipation of the NPM V12 you know changes, we we saw bad guys even before that came out.
00:10:06.639 --> 00:10:14.000
We saw bad guys like you know pivoting and and coming up with really unique ways, and and that continues, that trend continues.
00:10:14.159 --> 00:10:16.720
I'm seeing every day, I'm seeing kind of unique attempts.
00:10:16.799 --> 00:10:29.200
So something that I saw yesterday, I haven't even had a chance to write this up, but yesterday, excuse me, what we saw is we saw a contagious interview style attack, which is a combination of a GitHub repo and an NPM package.
00:10:29.279 --> 00:10:32.559
Um, and if I'm not mistaken, the GitHub repo required the npm package.
00:10:32.720 --> 00:10:47.200
But here's what happened is if you looked at, and this wasn't a public npm package, if you looked in its package.json manifest, it called out to this package that wasn't in the public uh uh registry.
00:10:47.679 --> 00:10:55.200
And so here's what happened the GitHub repo that you downloaded and you cloned beforehand is part of this interview process.
00:10:55.360 --> 00:11:03.360
And there's no yet I've seen Jen, just to be clear, I have yet to see data saying this is genuinely a DPRK contagious interview thing.
00:11:03.759 --> 00:11:07.039
It just it looks and feels like a like an interview process.
00:11:07.200 --> 00:11:09.360
Well, it is, it's following the kind of GitHub.
00:11:09.840 --> 00:11:13.360
It's following the playbook, whether it's DPRK or not, is not attributed.
00:11:13.519 --> 00:11:13.679
Yeah.
00:11:13.840 --> 00:11:16.799
I'll I'll do more and I'll circle back next week and I'll have an answer there.
00:11:16.879 --> 00:11:29.919
But in the meantime, what happened is because you cloned the GitHub repo earlier, what it did is it did this really sneaky thing where it dropped an NPMRC, a custom npmrc, into the to the repository.
00:11:30.159 --> 00:11:43.039
And then when you when later on it did the npm install and it got to that line, which if you don't have the npmrc, if you're just talking to registry.npmjs.com, that file doesn't exist.
00:11:43.200 --> 00:11:47.360
You think, oh, it must be an internal, you know, a private um package.
00:11:47.679 --> 00:11:55.840
Turns out that npmrc token they dropped in there, then points you at a different registry where it does resolve, right?
00:11:55.919 --> 00:12:06.000
And it was one of the Chinese, by the way, like all this work that I did last year on the Chinese mirrors is still coming to fruition because that's exactly what this was.
00:12:06.159 --> 00:12:15.919
This is pointing at one of the Chinese NPM mirrors, npm mirror.com, and very subtly named, um, does what it says on the tin.
00:12:16.399 --> 00:12:18.799
But I just thought it was a really unique way of doing it, right?
00:12:18.879 --> 00:12:21.679
Like, especially if you know that you're gonna own the whole workflow.
00:12:21.759 --> 00:12:34.559
And I think that's the important thing here is that a lot of people, when they look at an npm package, they think about it, and like all the security scanning companies do this, they kind of oversimplify what's happening behind the scenes.
00:12:34.639 --> 00:12:36.799
They think somebody going there, what's gonna happen?
00:12:36.960 --> 00:12:44.559
The problem is a lot of these npm installs, or the equivalent in in Pip and other places, happen as part of a constructed workflow.
00:12:44.799 --> 00:12:48.320
Contagious interview is a really good example of that, but there's others versions of this.
00:12:48.480 --> 00:12:55.600
So other things happen beforehand that are the dependencies and the foundation that then that can and we're seeing this in other places too.
00:12:55.759 --> 00:12:59.919
A really good example, and Akito and all the other scanners will see this too as well.
00:13:00.000 --> 00:13:14.799
We're seeing a lot of packages right now that don't have a malicious payload, and we talked about this a little bit in last week's episode, where you have to combine two or three npm packages that and they all call each other in dependency structure, and then the three of those will combine to give you that payload.
00:13:14.879 --> 00:13:17.440
Um, and those are just some really kind of simplistic ways.
00:13:17.759 --> 00:13:34.960
So, first, npm GitHub, you're not doing a very good job scanning based on the really simple pattern matching that we already know about, like these, you know, these existing mini shy halud patterns, and you don't even have anything for this other stuff, which is actually much more you know productive.
00:13:35.120 --> 00:13:45.279
And scanners aren't finding these things, like the software supply chain firewall scanners aren't finding these, and um a lot of times the scanning companies aren't labeling these things as malicious because guess what?
00:13:45.360 --> 00:13:47.840
There's no malicious by itself, it's not malicious.
00:13:48.000 --> 00:13:49.759
Yeah, you gotta combine it.
00:13:49.840 --> 00:13:52.320
It's like the the the Voltron, right?
00:13:52.480 --> 00:13:55.759
I know I'm envisioning like Power Rangers or something.
00:13:56.320 --> 00:14:01.120
I almost said that and I said I cannot say that word, those two words together.
00:14:01.360 --> 00:14:08.480
Um, I've always been wanting to give Ken shit because he's got a bunch of Power Rangers um helmets behind him in his in his office.
00:14:08.720 --> 00:14:10.240
Want to find out the story there.
00:14:10.480 --> 00:14:12.240
Yeah, okay, let's talk about Ruby.
00:14:12.399 --> 00:14:14.080
Um love you, mate.
00:14:15.360 --> 00:14:27.200
You discovered, well, not you, but kind of you, our automatic uh watchers that take a look at Ruby Gems, flagged some concerning behavior a couple days ago.
00:14:27.440 --> 00:14:38.639
Um, 40-something, I think 42 malicious packages uh were published in a burst to RubyGems, all from one user by the name of Ghost Dev.
00:14:39.120 --> 00:14:39.519
Very clever.
00:14:39.919 --> 00:14:40.559
Ghost Dev.
00:14:40.720 --> 00:14:43.279
I don't know, you had to think real hard on that one.
00:14:43.519 --> 00:14:56.960
Um and they are targeting crypto and web 3 developers through a combination of typosquatting, brand jacking, plausible utility names.
00:14:57.279 --> 00:15:04.480
Um with uh essentially it's a cryptocurrency theft kit included in it.
00:15:04.639 --> 00:15:08.399
Um, I think it also has an info stealer, remind me.
00:15:08.480 --> 00:15:10.559
I know there's a couple versions of this.
00:15:11.120 --> 00:15:12.480
Yeah, there, yeah.
00:15:12.639 --> 00:15:21.279
So it definitely has the the crypto stealer, and um uh I don't know if there's like a kind of generic info stealer component.
00:15:21.360 --> 00:15:22.480
I'm looking right now.
00:15:22.639 --> 00:15:25.759
Um I don't think they're I don't think there is yeah, sorry, I don't remember.
00:15:25.840 --> 00:15:29.440
It's been a couple days since I uh soaked in this one.
00:15:29.679 --> 00:15:38.720
But basically the attack flow here is um like what we saw with the Gemstuffer campaign a month ago or so.
00:15:38.879 --> 00:15:45.519
Uh gem install runs uh a file called extconf.rb x.
00:15:46.159 --> 00:15:50.000
Um and so that's a native extension build script.
00:15:50.480 --> 00:15:54.559
Kind of works in the same way as a pre-install script.
00:15:54.639 --> 00:15:59.919
Uh it checks the environment for the little bits and bobs that it needs to run.
00:16:00.159 --> 00:16:02.960
And then I like how you said, and then it takes a nap.
00:16:03.519 --> 00:16:08.240
So it takes a nap for somewhere from 20 to 40 minutes.
00:16:08.399 --> 00:16:19.039
Uh, presumably, this is uh an evasion, you know, detection evasion technique of like, you know, it doesn't look scary if it's asleep.
00:16:19.360 --> 00:16:21.919
And uh then from there it has two variants.
00:16:22.080 --> 00:16:26.480
Uh variant one opens a reverse shell, gives the attacker remote control.
00:16:26.559 --> 00:16:27.440
That's what I was thinking of.
00:16:27.519 --> 00:16:28.559
I knew there was something else.
00:16:28.639 --> 00:16:31.200
So there's a rat component essentially.
00:16:31.360 --> 00:16:31.679
Yeah.
00:16:31.840 --> 00:16:38.879
And then variant two is the theft kit, which um is posing as a tool called wallet guard.
00:16:38.960 --> 00:16:49.600
Uh again, gotta love the threat actor that pretends something is a good thing when in fact it is doing the opposite of the thing that it's telling you that it's doing.
00:16:49.919 --> 00:16:51.440
There is so much of this right now.
00:16:51.600 --> 00:16:58.799
If you download an AI skill npm or pipie package that ostensibly is about security, be careful.
00:16:58.960 --> 00:17:03.039
There's a pretty good chance it's the the antithesis of security.
00:17:03.279 --> 00:17:05.359
It's it's actually malware.
00:17:05.759 --> 00:17:07.200
Oh womp.
00:17:07.519 --> 00:17:09.440
Um let's see.
00:17:09.680 --> 00:17:12.720
What else is interesting to share about this one?
00:17:12.960 --> 00:17:14.799
I mean, this thing had everything, right?
00:17:14.880 --> 00:17:16.319
I really, really enjoyed this.
00:17:16.400 --> 00:17:20.000
Um, one of my favorite things about it was that you know it was it was Ruby, right?
00:17:20.079 --> 00:17:26.160
It was uh Ruby code, but the um the C2 uh once it downloaded the second stage.
00:17:26.240 --> 00:17:28.240
So, like Jen said, there was like two versions of it.
00:17:28.319 --> 00:17:34.480
There was the reverse shell version of it, which was pretty simplistic, and then there was the other version of it that had the rat component.
00:17:34.559 --> 00:17:36.000
Um, and rat-ish.
00:17:36.319 --> 00:17:37.359
It really wasn't a rat.
00:17:37.599 --> 00:17:42.480
Yeah, I had a whole I had a whole conversation back and forth with Codex about does this qualify as a rat?
00:17:42.640 --> 00:17:46.160
And in Codex and I were kind of like debating each other back and forth.
00:17:46.400 --> 00:17:49.519
Well, anyhow, um, it's not really a rat.
00:17:49.680 --> 00:17:52.160
Uh it we we landed on the language gen.
00:17:53.200 --> 00:17:55.839
Uh a backdoor, what do we say?
00:17:55.920 --> 00:17:59.279
Uh uh a malicious backdoor or something like that.
00:17:59.519 --> 00:18:03.680
But um uh it and the code was actually in Python.
00:18:03.759 --> 00:18:06.799
So the Ruby, the second stage of the Ruby was Python.
00:18:06.880 --> 00:18:07.680
And we're seeing this a lot.
00:18:08.160 --> 00:18:09.680
Something that we've been seeing, right?
00:18:09.839 --> 00:18:17.759
You know, the 100% front door, so to speak, is Ruby, and then it includes code in there that's not Ruby related.
00:18:18.319 --> 00:18:33.680
Because you have to think about these attack chains, and this is another thing that people do is that they only look at what the first they look at the npm package and look at what it does, and they just they don't realize that there's like five other stages after that that you got to pull and deconstruct and uh sorry, deobfuscate and reconstruct and whatnot.
00:18:33.759 --> 00:18:39.519
But in this case, that that Python payload was probably probably came from something else, right?
00:18:39.599 --> 00:18:43.519
And they're just using it like a portable second stage, third stage.
00:18:43.599 --> 00:18:59.839
So um, let me ask, because I'm certainly not a Ruby expert, would this be one of those things that should be tipping you off that there's a problem if you download a Ruby package that's written in Python, or would that be like uh could happen benignly?
00:19:00.799 --> 00:19:09.359
I mean, I think there are a lot of like NPM, like a lot of NPM packages pull all kinds of other stuff, you know, so binaries and other code.
00:19:09.519 --> 00:19:10.720
I think it's a signal.
00:19:10.799 --> 00:19:13.519
I wouldn't say it's a high quality signal.
00:19:13.599 --> 00:19:15.680
I think it's a signal you're gonna look at with other things.
00:19:15.839 --> 00:19:28.640
But in this particular case, there's a lot more high-quality signals that you saw before that, in the sense that you know, that first stage, that second stage, when it's calling out to these additional things and it's pulling files, that is a very, very clear signal.
00:19:28.720 --> 00:19:36.480
You know, yar, even simplistic yar rules will be able to find this stuff for you really quickly, looking for these fetches and the axios calls and what have you, or the equivalent.
00:19:36.559 --> 00:19:37.200
Sorry, the equivalent.
00:19:37.279 --> 00:19:38.720
This is Ruby, so the equivalent.
00:19:38.960 --> 00:19:50.720
Um, so you know, then you combine that high-quality signal with then the fact that it is in another language, you know, those things together they start to add up.
00:19:50.960 --> 00:19:55.599
Well, in addition to what we've talked about, it does uh clipboard hijacking.
00:19:55.839 --> 00:20:08.319
So, you know, of concern when a cryptocurrency address is detected on the clipboard, they exfiltrate it and they actually replace it with a corresponding operator wallet.
00:20:08.720 --> 00:20:18.160
Um it also is uh wallet vault and secret harvesting, so reading off the uh ecosystems it's looking for here.
00:20:18.480 --> 00:20:26.880
Uh Tron Link, MetaMask, Phantom, Binance, Coinbase, Trust Wallis, Wallet, uh, Exodus, Electrum.
00:20:26.960 --> 00:20:35.359
So pretty broad range of um uh crypto ecosystems that could get hit by this.
00:20:36.319 --> 00:20:44.640
Yeah, I mean, it was hitting all the big ones, um, you know, BitGet among them, who is you know having a hard couple of weeks, but um yeah, it's it's it's pretty typical.
00:20:44.880 --> 00:20:56.000
When we um when we were tracking the DPR case stuff, you know, they initially were looking at something like I don't know, six or seven um uh different companies and exchange.
00:20:56.240 --> 00:21:01.119
They were looking for the Chrome extensions, and there's all this kind of like infrastructure that you could tell that they're looking for this stuff.
00:21:01.279 --> 00:21:23.279
And it went from like seven to like 16 to 28 to 35, and you know, so they just kept looking for more and more and more and more is more of these uh extensions and and um you know the way that people interact with their with their crypto assets as more of those became popular, you know, DPRK and other threat reactors just kept swallowing them up, swallowing them up.
00:21:24.000 --> 00:21:24.400
Yep.
00:21:24.559 --> 00:21:24.960
Yeah.
00:21:25.200 --> 00:21:37.759
Yeah, and just looking at the uh malicious gems here, the typos squats definitely are not sophisticated and remind me a lot of some of the other Ruby attacks we've seen over the summer.
00:21:37.920 --> 00:21:57.039
However, the brand jacking generic utility names, these resonate a little bit more as efforts to uh, you know, name something in a smart way that somebody might actually choose on purpose rather than relying on the you know keyboard fat finger.
00:21:57.119 --> 00:21:59.519
You know, we've got things for Ethereum.
00:22:00.480 --> 00:22:09.119
Uh Bitcoin, and you know, we've got a crypto key utils, like there's there's these look more legitimate.
00:22:09.279 --> 00:22:15.279
So I see a bit more maturity with the way this threat actor decided to approach this campaign.
00:22:15.519 --> 00:22:22.400
Um something I haven't dug into yet in our data, and maybe I'll do that after we're uh done today.
00:22:22.720 --> 00:22:25.680
But I know it's not my imagination.
00:22:26.000 --> 00:22:37.680
I think Ruby is seeing perhaps the highest um velocity compared to previous months and years of malware.
00:22:37.759 --> 00:22:51.119
Uh, it does seem like attackers are starting to not necessarily shift focus because we certainly still see it in NPM, but uh nobody was talking about Ruby malware before the summer.
00:22:51.440 --> 00:22:51.920
Right.
00:22:53.039 --> 00:22:53.519
Yeah.
00:22:53.680 --> 00:23:00.559
And you know, I you and I have quite the relationship now with the RubyGems people because we keep disclosing things.
00:23:00.640 --> 00:23:02.559
I mean, like I like I the speed dial.
00:23:02.720 --> 00:23:04.079
Hey guys, you got another one.
00:23:04.240 --> 00:23:14.960
Um but um you're right, and it's not like there's a corresponding drop in npm or pipy volume, it's just now there's an increased volume in RubyGems, and we're seeing that everywhere.
00:23:15.119 --> 00:23:18.799
Same thing with VS Code and all these other places, as but bad guys realized.
00:23:18.960 --> 00:23:21.039
I mean, part of it is what we're talking about, the portability.
00:23:21.119 --> 00:23:29.599
They're like, oh shit, you know, I've got this, I've got this stager over here and this this rat uh in Python, I'll just load it in npm.
00:23:29.680 --> 00:23:30.240
Oh, you know what?
00:23:30.319 --> 00:23:32.559
Actually, I'll do the same thing in RubyGems, why not?
00:23:32.799 --> 00:23:45.599
And these dependency confusion attacks like are again, if we just look at it like nobody's gonna be stupid enough to take, you know, uh gems install, you know, bitcoin spelled with O in the I backwards.
00:23:45.759 --> 00:23:52.880
No, it's like you know, you grab something, you cut and paste something from somewhere else, or it's in some automation, or the AI misspells it, or whatever.
00:23:53.039 --> 00:23:57.200
You know, a lot of it is AI, you can blame it on AI ultimately, right?
00:23:57.519 --> 00:24:10.000
Um, one thing I noticed though is that red actors don't know how to use linters because like they just always leave their comments in there, and the comments are so they're all always in English, or almost always in English.
00:24:10.160 --> 00:24:21.519
Occasionally you'll see Chinese comments, or you know, I've seen Vietnamese and Chinese and Thai and stuff, but other than that, they're almost always in English, and they just explicitly say, here's the payload right here.
00:24:21.680 --> 00:24:27.680
Make sure that you know it's just like so the signposts are very clear.
00:24:28.079 --> 00:24:36.240
We're gonna start seeing like linters and tools coming out from people, um uh you know, like bad guys, right?
00:24:36.400 --> 00:24:40.079
Which I think is great because we can then we can use those things as watering holes.
00:24:40.160 --> 00:24:45.440
But um well, you said something that I think is worth bringing up with this particular campaign.
00:24:45.599 --> 00:24:51.200
So the previous uh Ruby campaign we talked about with Gemstuffer, we found it in Ruby first.
00:24:51.440 --> 00:24:55.200
It turned out it also hit NPM at the same time.
00:24:55.599 --> 00:25:16.799
Uh, haven't necessarily seen evidence that this one made an effort to be cross-ecosystem, but to your point that I don't know if you were explicitly making or not, it's possible that they've tried this previously in a different ecosystem, like PiPi, perhaps had mixed results, decided to give it a go over in Ruby.
00:25:17.680 --> 00:25:18.559
Yeah, exactly.
00:25:18.640 --> 00:25:19.440
I wouldn't be surprised.
00:25:19.920 --> 00:25:21.519
I don't actually know that.
00:25:21.839 --> 00:25:28.079
No, but that's this is a pure hypothesis here, but given the behavior we've seen, wouldn't surprise me.
00:25:28.400 --> 00:25:33.119
Yeah, and and looking at the fact that they're two different languages and they're totally distinct things, right?
00:25:33.200 --> 00:25:41.279
Like it's not, it doesn't take a genius to say, you know, that PyPy stuff is probably pre-existing, they probably used it over in PyPy, you know.
00:25:41.920 --> 00:25:57.279
Well, and you know, I saw something interesting the other day, and I can't even remember the source, so I'm sorry, maybe you will recognize this, but that there is uh an increase in AI tools getting confused about which ecosystem something exists in.
00:25:57.359 --> 00:26:00.240
And this kind of relates to the sloping stuff.
00:26:00.480 --> 00:26:07.279
You know, there's a legitimate npm package, it makes an assumption that it's available over in Ruby.
00:26:07.680 --> 00:26:08.319
Who knows?
00:26:08.480 --> 00:26:15.759
Maybe all these package names exist legitimately in another ecosystem, and this is uh an effort at slop squatting.
00:26:16.160 --> 00:26:19.119
Yeah, that was the podcast with Josh Pressers and uh that's right.
00:26:19.279 --> 00:26:20.160
That was open source security.
00:26:20.799 --> 00:26:21.920
I wasn't making it up.
00:26:22.400 --> 00:26:23.519
No, you were not.
00:26:23.759 --> 00:26:30.559
Um I can't remember what I had for dinner last night, but I can remember every podcast that I've ever freaking listened to and all the content they're in.
00:26:30.720 --> 00:26:40.400
Um, but yeah, I mean, I think that um uh oh my gosh, what was the what was the point that he was trying to make that you brought up there?
00:26:40.480 --> 00:26:54.880
I'm oh it was the either slop squatting is perhaps getting more uh effective as a strategy because AI tools are making assumptions about things existing in other ecosystems.
00:26:54.960 --> 00:26:59.279
And that's that's uh like it makes total sense when you say it out loud.
00:26:59.359 --> 00:27:04.720
It's not something I've given a lot of thought to when we talk about slopping, but uh I I buy it.
00:27:05.119 --> 00:27:09.279
Yeah, in particular, he mentioned um he mentioned the the requests, right?
00:27:09.359 --> 00:27:11.519
Which is the famous Python library.
00:27:12.160 --> 00:27:20.319
Um and the fact that you're seeing, you know, instead of Axios, you're seeing rat you know, requests over in the JavaScript world and you're seeing fetch.
00:27:20.720 --> 00:27:30.000
So basically, slop squatting absolutely is encouraging this kind of cross-ecosystem naming kind of confusion that we're seeing.
00:27:30.240 --> 00:27:42.240
Um which is which is very I mean, the thing is that the people generating code now don't really know the code like they did five years ago or 10 years ago because it's being vibe coded for us, right?
00:27:42.319 --> 00:27:47.920
And so because of that, a lot of this stuff is lost to the person that's actually sitting in front of the keyboard.
00:27:48.000 --> 00:27:50.559
Uh, the distinction there is lost on the human.
00:27:50.720 --> 00:27:52.559
Um, so the AI doesn't know.
00:27:52.640 --> 00:27:53.759
It's like, let me just go and look for it.
00:27:53.839 --> 00:27:54.960
Oh, hey, look, it exists.
00:27:55.039 --> 00:27:57.680
Oh, look, it looks like it does right what I want it to do.
00:27:57.839 --> 00:28:00.400
Sweet as happy days, let's install it.
00:28:01.119 --> 00:28:01.759
Yep.
00:28:02.000 --> 00:28:04.960
Bad times bad times all around.
00:28:05.519 --> 00:28:06.000
All right.
00:28:06.160 --> 00:28:09.119
Well, I think that reaches the end of our list.
00:28:09.359 --> 00:28:12.160
Um, anything you want to add before we wrap up?
00:28:12.319 --> 00:28:15.279
I think next week we may be recording at a different time.
00:28:15.440 --> 00:28:22.480
Uh, we'll see you and I have to work that out with my travel schedule, but uh we'll be around the next couple of weeks for sure.
00:28:22.799 --> 00:28:23.519
Yeah, cool.
00:28:23.759 --> 00:28:30.079
Yeah, I mean, I'm I'm chilling until RuCon, which I'm looking forward to in um Google RuCon in November.
00:28:30.160 --> 00:28:33.119
So I'm just chilling here and uh you're gonna be busy.
00:28:33.200 --> 00:28:34.160
So happy days.
00:28:34.400 --> 00:28:37.680
Well, I mean, I would love an excuse to get down to Australia.
00:28:38.079 --> 00:28:41.680
Google, if you want to buy me a ticket, happy to have to come.
00:28:42.480 --> 00:28:44.319
I feel like they can probably afford it.
00:28:44.640 --> 00:28:45.680
I think they could.
00:28:45.920 --> 00:28:48.160
Um, we have a Google Workspace account, right?
00:28:48.240 --> 00:28:49.039
That seems like it should be.
00:28:49.359 --> 00:28:49.680
We do.
00:28:49.839 --> 00:28:51.119
I've got a bunch.
00:28:52.799 --> 00:28:54.000
I got a collection.
00:28:54.400 --> 00:28:54.880
On that note.
00:28:55.359 --> 00:28:55.680
On that note.
00:28:56.079 --> 00:28:57.039
Not looking for handouts.
00:28:57.279 --> 00:28:57.599
Thank you.
00:28:57.759 --> 00:28:58.319
Have a good luck.
00:28:58.559 --> 00:28:58.960
See everybody.
00:28:59.039 --> 00:29:00.000
Hey, we'll take handouts.
00:29:00.160 --> 00:29:00.799
We'll take handouts.
00:29:01.200 --> 00:29:01.839
Yeah, yeah, yeah.
00:29:02.000 --> 00:29:03.839
Let's not let's not be crazy here.
00:29:03.920 --> 00:29:04.960
We'll totally take them.
00:29:05.119 --> 00:29:05.920
All right, bye.
00:29:06.079 --> 00:29:06.720
Bye, everybody.
00:29:06.799 --> 00:29:07.359
See ya.
00:00:00.320 --> 00:00:04.240
Hello, it is Thursday, October 8th.
00:00:04.480 --> 00:00:11.599
Um we have a couple topics on the agenda, but before we dive in, what's up, Paul?
00:00:11.679 --> 00:00:12.720
What's new?
00:00:13.519 --> 00:00:14.160
Good question.
00:00:14.320 --> 00:00:15.199
What is new?
00:00:15.519 --> 00:00:20.879
Um just, you know, enjoying being home for a few months.
00:00:20.960 --> 00:00:22.640
I think that's um nice.
00:00:22.800 --> 00:00:25.600
You're you're taking one for the team and you're going to the Sands thing.
00:00:25.679 --> 00:00:27.519
So thank you for doing that.
00:00:27.679 --> 00:00:29.600
Although I really, really, really wanted to go to the show.
00:00:34.240 --> 00:00:35.600
Why am I doing this again?
00:00:35.840 --> 00:00:39.439
But I'm excited for the the things that I have coming up.
00:00:40.240 --> 00:00:43.039
Yeah, you got a couple really, really cool things coming up.
00:00:43.119 --> 00:00:44.399
And I forgot you were going to Lascon.
00:00:44.799 --> 00:00:46.240
So that's that's super dope.
00:00:46.479 --> 00:00:46.719
Yeah.
00:00:46.880 --> 00:00:55.520
So uh for anybody who's going to the Sands uh summit next week in Virginia slash Washington, DC, come say hi.
00:00:55.600 --> 00:00:59.679
I'm going to be giving a talk on um Pollenwriter.
00:00:59.920 --> 00:01:07.840
And then uh at the end of the month, I'll be in Austin at Lascon giving a talk on malicious AI skills.
00:01:07.920 --> 00:01:09.359
Uh, I really like LasCon.
00:01:09.680 --> 00:01:17.359
I was um looking at their webpage, website, uh, you know, kind of writing up my post to say, hey, you know, I'm gonna be there.
00:01:17.599 --> 00:01:20.560
And their website says they get about 400 people a year.
00:01:20.640 --> 00:01:26.239
And honestly, it's one of those conferences that, like, if you had told me 400, I wouldn't have believed it.
00:01:26.400 --> 00:01:31.599
It either would be more or less, but like it's just, I don't know, they have a ton of cracks.
00:01:31.920 --> 00:01:34.719
Um, people from all over the country travel to it.
00:01:34.799 --> 00:01:38.079
Like it's just a really unique conference.
00:01:38.319 --> 00:01:42.000
So uh if you haven't gotten your ticket yet, they are still available.
00:01:42.079 --> 00:01:52.159
They're a little pricey if um you're paying out of pocket last minute, but if you can get your employer to pay for it, you should because the content's great, the networking's great.
00:01:52.319 --> 00:01:54.719
Uh, they put on a really nice conference.
00:01:55.120 --> 00:01:58.640
The show from uh I'm sorry, the shirt, the swag.
00:01:59.040 --> 00:02:03.840
The shirt from the 20, I guess it would have been 2024 when they did the upside down.
00:02:04.159 --> 00:02:04.879
Um yeah.
00:02:05.200 --> 00:02:08.080
The strange I didn't get that shirt, but I know which one you're talking about.
00:02:08.319 --> 00:02:09.759
I I wore it a couple days ago.
00:02:09.840 --> 00:02:11.680
It's just such a great shirt.
00:02:12.080 --> 00:02:12.639
Great swag.
00:02:12.960 --> 00:02:14.879
Oh, I have the challenge coin right here.
00:02:15.759 --> 00:02:17.680
There you go, there you go, there you go, there you go.
00:02:17.840 --> 00:02:23.919
Uh oh, very nice, and then the upside down bowl because they always have the bull.
00:02:24.080 --> 00:02:25.520
And I did ride the bull.
00:02:26.000 --> 00:02:30.159
Yeah, uh, I enjoy going and watching who does ride the bull.
00:02:30.400 --> 00:02:35.919
That's the best part about the happy hours to see who who decides to bull ride.
00:02:36.479 --> 00:02:40.960
I definitely bull rode and watching the video back, I'm just so embarrassed.
00:02:41.039 --> 00:02:42.960
It's like painful to watch it.
00:02:43.039 --> 00:02:49.599
Like it's so slow, and at one point my tummy pops out because you're you're like this.
00:02:50.159 --> 00:02:52.639
I just the whole thing is so cringe.
00:02:53.039 --> 00:02:53.919
Pretty cringe.
00:02:54.719 --> 00:02:55.280
I don't know.
00:02:55.360 --> 00:02:58.560
I feel like uh that might be part of growing up.
00:02:58.719 --> 00:03:02.319
Somebody, you know, you gotta at some point if you have an opportunity to ride the bull.
00:03:02.479 --> 00:03:04.479
I probably did it in my 20s at some point.
00:03:04.560 --> 00:03:07.439
Uh I'm not gonna do it now because I will hurt myself.
00:03:07.680 --> 00:03:08.560
Okay, anyway.
00:03:08.960 --> 00:03:16.080
So yesterday so many jokes, so many jokes in there that we're just not gonna like we're not gonna we're we're we're gonna roll on.
00:03:16.240 --> 00:03:18.080
We're gonna talk about Tensor Lake.
00:03:18.400 --> 00:03:26.800
Um, yeah, as I was uh winding down last night, um, we saw Tensor Lake get compromised.
00:03:27.120 --> 00:03:31.280
Tensorlake uh it's is their SDK, is what was compromised.
00:03:31.520 --> 00:03:36.960
So it is uh used for building and operating AI agents.
00:03:37.360 --> 00:03:40.479
And um there's a couple things to know about this.
00:03:40.639 --> 00:03:43.360
Uh first, it is a pretty widely used package.
00:03:43.439 --> 00:03:52.639
So if you're a TensorLake user, um definitely uh, you know, make sure you're not using the compromise version.
00:03:52.879 --> 00:03:59.039
It was taken down relatively quickly within a couple of hours, I think.
00:03:59.280 --> 00:04:15.280
Uh, but this was uh the second time, I think second or third time we've seen an attack that leveraged the open sourced mini Shy Hulued worm from earlier this year.
00:04:15.520 --> 00:04:22.000
Um it's very similar to the attack that happened in August that targeted Jared Ray's projects.
00:04:22.160 --> 00:04:24.560
So that was um a pretty substantial one.
00:04:24.639 --> 00:04:33.279
It you know, hit 400 or so packages because he maintains a lot of things and it had a little bit of success on the worm-like behavior.
00:04:33.600 --> 00:04:39.120
Uh, I'm not seeing any success on this iterations worm.
00:04:39.279 --> 00:04:41.279
Have you seen heard anything?
00:04:41.839 --> 00:04:43.839
No, I mean, I've seen it described.
00:04:44.240 --> 00:04:48.399
The only thing I've seen really is I've seen it described as not having any real impact.
00:04:48.480 --> 00:04:50.560
So um yeah.
00:04:51.759 --> 00:04:53.120
So that's good news.
00:04:53.360 --> 00:04:58.160
Um I'm gonna go ahead and drop our threat report on it in the chat.
00:04:58.399 --> 00:04:59.120
Then sorry.
00:05:03.680 --> 00:05:04.639
Sorry to continue.
00:05:05.279 --> 00:05:17.439
I was just gonna say, uh, you know, I was just going through the list of stuff that it exfils, the specific um it's real similar to what we've seen from the previous iterations.
00:05:17.600 --> 00:05:30.319
Um, I'm sharing our blog that we published in August about the cacheable kev um compromise that was the bigger version of this because it's it's not identical, but it's very similar.
00:05:31.839 --> 00:05:41.360
I don't know if the um I'm looking at it's also it also specifically looked for the bitrise underscore IO variable, which um I don't know if that was anything.
00:05:41.680 --> 00:05:42.319
That might be new.
00:05:42.639 --> 00:05:43.199
That might be new.
00:05:43.279 --> 00:05:47.040
There's always, yeah, I mean, whenever you look at these, there's always one or two things that are added.
00:05:47.680 --> 00:05:55.040
But I mean, I think what we're driving at here at some level, Jen, is the fact that this, you know, this is kind of I don't want to say it's a nothing burger because it's not.
00:05:55.120 --> 00:06:02.399
I mean, it's it's real, but uh it looks and feels like the last several versions of this, right?
00:06:02.560 --> 00:06:17.600
And I think that people have, you know, over the course of the Namiasma and the many Shy Halud iterations, you know, have worked on some form of excuse me, um, you know, way to deal with this.
00:06:17.680 --> 00:06:19.279
And so I think shields are up.
00:06:19.360 --> 00:06:20.959
I I guess that's what I'm trying to say.
00:06:21.360 --> 00:06:23.600
Bringing back a term from 2024.
00:06:23.839 --> 00:06:30.079
Shields are up, and um, and it appears those shields were, you know, I think mostly successful.
00:06:30.399 --> 00:06:44.720
Yeah, I think it's probably a combination of better defense, and um, I'm gonna go out on a limb and make some uh uh I would say assumptions here, not proven.
00:06:44.800 --> 00:06:48.480
Um, I don't think we're dealing with a very sophisticated threat actor.
00:06:48.639 --> 00:07:08.000
Uh, this reads like they used the open sourced form as a template, probably had access to some LLMs and some automation, and uh somehow managed to get access to the GitHub repository for this uh TensorLake project.
00:07:08.240 --> 00:07:21.600
Um, I think it took them a little bit of time to detect it, but it's not clear how they got uh in, much in the way that it's not clear how the attackers got in uh back in August.
00:07:21.759 --> 00:07:49.279
So there's probably some combination going on here of using AI to find a reasonably popular open source project that has a vulnerability in it somewhere, um combined with you know a little DIY malware template, but I think just based on the you know lack of panic, which is a good thing.
00:07:49.360 --> 00:07:52.639
I don't think we're dealing with somebody very sophisticated here.
00:07:53.920 --> 00:08:00.480
Yeah, I think all signs point to low sophistication for this one.
00:08:00.800 --> 00:08:09.040
Um and uh you know they did use a custom um you know domain.
00:08:09.519 --> 00:08:17.360
So uh it's following the form and function of some of those, you know, April to June um patterns.
00:08:17.680 --> 00:08:19.680
Uh but I want to take this opportunity.
00:08:20.000 --> 00:08:23.759
Wait, I want to look right down the hey GitHub, npm.
00:08:24.399 --> 00:08:26.959
I thought you guys are scanning npm packages.
00:08:27.839 --> 00:08:29.199
What's going on, homies?
00:08:29.680 --> 00:08:35.679
Yeah, I guess what I'll say there is this is definitely following a really clear playbook.
00:08:35.840 --> 00:08:46.000
Um, the malicious version contained two files uh in addition to the regular uh content that you would expect in the package.
00:08:46.240 --> 00:08:50.799
That included a setup.mjs, which fires through a pre-install hook.
00:08:50.960 --> 00:08:54.240
Oh, isn't that one of the things we all know to look for at this point?
00:08:54.480 --> 00:08:58.000
That's what any scanning, proactive scanning should have caught.
00:08:58.240 --> 00:09:09.679
And then uh so that pre-install hook uh launches the payload using bun again, fairly um well-known pattern at this stage.
00:09:10.000 --> 00:09:21.919
And then we have a math underscore symbol.js file, which again, similar to what we saw in August, slightly different names, uh, that contains a credential stealer and self-propagating worm.
00:09:22.000 --> 00:09:28.639
So yeah, there's some pretty clear signals with this that proactive scanning likely should have caught.
00:09:28.960 --> 00:09:34.399
Yeah, I'm I I will go a step further and proactive scanning likely doesn't exist.
00:09:35.360 --> 00:09:36.000
Yes.
00:09:37.440 --> 00:09:38.480
That would be what follows.
00:09:39.039 --> 00:09:43.440
As a functioning thing, as a functioning function.
00:09:43.759 --> 00:09:50.080
You know, it's interesting because oh sorry, I was gonna I was gonna go off topic today because we're YOLOing it right a bit.
00:09:50.159 --> 00:09:50.879
Is that okay?
00:09:51.200 --> 00:09:51.519
Sure.
00:09:51.600 --> 00:09:57.360
I was gonna move on to the Ruby Gem topic, but if you have something that's uh worth talking about now, let's start there.
00:09:57.679 --> 00:10:06.559
I want to do both, obviously, but um I think in anticipation of the NPM V12 you know changes, we we saw bad guys even before that came out.
00:10:06.639 --> 00:10:14.000
We saw bad guys like you know pivoting and and coming up with really unique ways, and and that continues, that trend continues.
00:10:14.159 --> 00:10:16.720
I'm seeing every day, I'm seeing kind of unique attempts.
00:10:16.799 --> 00:10:29.200
So something that I saw yesterday, I haven't even had a chance to write this up, but yesterday, excuse me, what we saw is we saw a contagious interview style attack, which is a combination of a GitHub repo and an NPM package.
00:10:29.279 --> 00:10:32.559
Um, and if I'm not mistaken, the GitHub repo required the npm package.
00:10:32.720 --> 00:10:47.200
But here's what happened is if you looked at, and this wasn't a public npm package, if you looked in its package.json manifest, it called out to this package that wasn't in the public uh uh registry.
00:10:47.679 --> 00:10:55.200
And so here's what happened the GitHub repo that you downloaded and you cloned beforehand is part of this interview process.
00:10:55.360 --> 00:11:03.360
And there's no yet I've seen Jen, just to be clear, I have yet to see data saying this is genuinely a DPRK contagious interview thing.
00:11:03.759 --> 00:11:07.039
It just it looks and feels like a like an interview process.
00:11:07.200 --> 00:11:09.360
Well, it is, it's following the kind of GitHub.
00:11:09.840 --> 00:11:13.360
It's following the playbook, whether it's DPRK or not, is not attributed.
00:11:13.519 --> 00:11:13.679
Yeah.
00:11:13.840 --> 00:11:16.799
I'll I'll do more and I'll circle back next week and I'll have an answer there.
00:11:16.879 --> 00:11:29.919
But in the meantime, what happened is because you cloned the GitHub repo earlier, what it did is it did this really sneaky thing where it dropped an NPMRC, a custom npmrc, into the to the repository.
00:11:30.159 --> 00:11:43.039
And then when you when later on it did the npm install and it got to that line, which if you don't have the npmrc, if you're just talking to registry.npmjs.com, that file doesn't exist.
00:11:43.200 --> 00:11:47.360
You think, oh, it must be an internal, you know, a private um package.
00:11:47.679 --> 00:11:55.840
Turns out that npmrc token they dropped in there, then points you at a different registry where it does resolve, right?
00:11:55.919 --> 00:12:06.000
And it was one of the Chinese, by the way, like all this work that I did last year on the Chinese mirrors is still coming to fruition because that's exactly what this was.
00:12:06.159 --> 00:12:15.919
This is pointing at one of the Chinese NPM mirrors, npm mirror.com, and very subtly named, um, does what it says on the tin.
00:12:16.399 --> 00:12:18.799
But I just thought it was a really unique way of doing it, right?
00:12:18.879 --> 00:12:21.679
Like, especially if you know that you're gonna own the whole workflow.
00:12:21.759 --> 00:12:34.559
And I think that's the important thing here is that a lot of people, when they look at an npm package, they think about it, and like all the security scanning companies do this, they kind of oversimplify what's happening behind the scenes.
00:12:34.639 --> 00:12:36.799
They think somebody going there, what's gonna happen?
00:12:36.960 --> 00:12:44.559
The problem is a lot of these npm installs, or the equivalent in in Pip and other places, happen as part of a constructed workflow.
00:12:44.799 --> 00:12:48.320
Contagious interview is a really good example of that, but there's others versions of this.
00:12:48.480 --> 00:12:55.600
So other things happen beforehand that are the dependencies and the foundation that then that can and we're seeing this in other places too.
00:12:55.759 --> 00:12:59.919
A really good example, and Akito and all the other scanners will see this too as well.
00:13:00.000 --> 00:13:14.799
We're seeing a lot of packages right now that don't have a malicious payload, and we talked about this a little bit in last week's episode, where you have to combine two or three npm packages that and they all call each other in dependency structure, and then the three of those will combine to give you that payload.
00:13:14.879 --> 00:13:17.440
Um, and those are just some really kind of simplistic ways.
00:13:17.759 --> 00:13:34.960
So, first, npm GitHub, you're not doing a very good job scanning based on the really simple pattern matching that we already know about, like these, you know, these existing mini shy halud patterns, and you don't even have anything for this other stuff, which is actually much more you know productive.
00:13:35.120 --> 00:13:45.279
And scanners aren't finding these things, like the software supply chain firewall scanners aren't finding these, and um a lot of times the scanning companies aren't labeling these things as malicious because guess what?
00:13:45.360 --> 00:13:47.840
There's no malicious by itself, it's not malicious.
00:13:48.000 --> 00:13:49.759
Yeah, you gotta combine it.
00:13:49.840 --> 00:13:52.320
It's like the the the Voltron, right?
00:13:52.480 --> 00:13:55.759
I know I'm envisioning like Power Rangers or something.
00:13:56.320 --> 00:14:01.120
I almost said that and I said I cannot say that word, those two words together.
00:14:01.360 --> 00:14:08.480
Um, I've always been wanting to give Ken shit because he's got a bunch of Power Rangers um helmets behind him in his in his office.
00:14:08.720 --> 00:14:10.240
Want to find out the story there.
00:14:10.480 --> 00:14:12.240
Yeah, okay, let's talk about Ruby.
00:14:12.399 --> 00:14:14.080
Um love you, mate.
00:14:15.360 --> 00:14:27.200
You discovered, well, not you, but kind of you, our automatic uh watchers that take a look at Ruby Gems, flagged some concerning behavior a couple days ago.
00:14:27.440 --> 00:14:38.639
Um, 40-something, I think 42 malicious packages uh were published in a burst to RubyGems, all from one user by the name of Ghost Dev.
00:14:39.120 --> 00:14:39.519
Very clever.
00:14:39.919 --> 00:14:40.559
Ghost Dev.
00:14:40.720 --> 00:14:43.279
I don't know, you had to think real hard on that one.
00:14:43.519 --> 00:14:56.960
Um and they are targeting crypto and web 3 developers through a combination of typosquatting, brand jacking, plausible utility names.
00:14:57.279 --> 00:15:04.480
Um with uh essentially it's a cryptocurrency theft kit included in it.
00:15:04.639 --> 00:15:08.399
Um, I think it also has an info stealer, remind me.
00:15:08.480 --> 00:15:10.559
I know there's a couple versions of this.
00:15:11.120 --> 00:15:12.480
Yeah, there, yeah.
00:15:12.639 --> 00:15:21.279
So it definitely has the the crypto stealer, and um uh I don't know if there's like a kind of generic info stealer component.
00:15:21.360 --> 00:15:22.480
I'm looking right now.
00:15:22.639 --> 00:15:25.759
Um I don't think they're I don't think there is yeah, sorry, I don't remember.
00:15:25.840 --> 00:15:29.440
It's been a couple days since I uh soaked in this one.
00:15:29.679 --> 00:15:38.720
But basically the attack flow here is um like what we saw with the Gemstuffer campaign a month ago or so.
00:15:38.879 --> 00:15:45.519
Uh gem install runs uh a file called extconf.rb x.
00:15:46.159 --> 00:15:50.000
Um and so that's a native extension build script.
00:15:50.480 --> 00:15:54.559
Kind of works in the same way as a pre-install script.
00:15:54.639 --> 00:15:59.919
Uh it checks the environment for the little bits and bobs that it needs to run.
00:16:00.159 --> 00:16:02.960
And then I like how you said, and then it takes a nap.
00:16:03.519 --> 00:16:08.240
So it takes a nap for somewhere from 20 to 40 minutes.
00:16:08.399 --> 00:16:19.039
Uh, presumably, this is uh an evasion, you know, detection evasion technique of like, you know, it doesn't look scary if it's asleep.
00:16:19.360 --> 00:16:21.919
And uh then from there it has two variants.
00:16:22.080 --> 00:16:26.480
Uh variant one opens a reverse shell, gives the attacker remote control.
00:16:26.559 --> 00:16:27.440
That's what I was thinking of.
00:16:27.519 --> 00:16:28.559
I knew there was something else.
00:16:28.639 --> 00:16:31.200
So there's a rat component essentially.
00:16:31.360 --> 00:16:31.679
Yeah.
00:16:31.840 --> 00:16:38.879
And then variant two is the theft kit, which um is posing as a tool called wallet guard.
00:16:38.960 --> 00:16:49.600
Uh again, gotta love the threat actor that pretends something is a good thing when in fact it is doing the opposite of the thing that it's telling you that it's doing.
00:16:49.919 --> 00:16:51.440
There is so much of this right now.
00:16:51.600 --> 00:16:58.799
If you download an AI skill npm or pipie package that ostensibly is about security, be careful.
00:16:58.960 --> 00:17:03.039
There's a pretty good chance it's the the antithesis of security.
00:17:03.279 --> 00:17:05.359
It's it's actually malware.
00:17:05.759 --> 00:17:07.200
Oh womp.
00:17:07.519 --> 00:17:09.440
Um let's see.
00:17:09.680 --> 00:17:12.720
What else is interesting to share about this one?
00:17:12.960 --> 00:17:14.799
I mean, this thing had everything, right?
00:17:14.880 --> 00:17:16.319
I really, really enjoyed this.
00:17:16.400 --> 00:17:20.000
Um, one of my favorite things about it was that you know it was it was Ruby, right?
00:17:20.079 --> 00:17:26.160
It was uh Ruby code, but the um the C2 uh once it downloaded the second stage.
00:17:26.240 --> 00:17:28.240
So, like Jen said, there was like two versions of it.
00:17:28.319 --> 00:17:34.480
There was the reverse shell version of it, which was pretty simplistic, and then there was the other version of it that had the rat component.
00:17:34.559 --> 00:17:36.000
Um, and rat-ish.
00:17:36.319 --> 00:17:37.359
It really wasn't a rat.
00:17:37.599 --> 00:17:42.480
Yeah, I had a whole I had a whole conversation back and forth with Codex about does this qualify as a rat?
00:17:42.640 --> 00:17:46.160
And in Codex and I were kind of like debating each other back and forth.
00:17:46.400 --> 00:17:49.519
Well, anyhow, um, it's not really a rat.
00:17:49.680 --> 00:17:52.160
Uh it we we landed on the language gen.
00:17:53.200 --> 00:17:55.839
Uh a backdoor, what do we say?
00:17:55.920 --> 00:17:59.279
Uh uh a malicious backdoor or something like that.
00:17:59.519 --> 00:18:03.680
But um uh it and the code was actually in Python.
00:18:03.759 --> 00:18:06.799
So the Ruby, the second stage of the Ruby was Python.
00:18:06.880 --> 00:18:07.680
And we're seeing this a lot.
00:18:08.160 --> 00:18:09.680
Something that we've been seeing, right?
00:18:09.839 --> 00:18:17.759
You know, the 100% front door, so to speak, is Ruby, and then it includes code in there that's not Ruby related.
00:18:18.319 --> 00:18:33.680
Because you have to think about these attack chains, and this is another thing that people do is that they only look at what the first they look at the npm package and look at what it does, and they just they don't realize that there's like five other stages after that that you got to pull and deconstruct and uh sorry, deobfuscate and reconstruct and whatnot.
00:18:33.759 --> 00:18:39.519
But in this case, that that Python payload was probably probably came from something else, right?
00:18:39.599 --> 00:18:43.519
And they're just using it like a portable second stage, third stage.
00:18:43.599 --> 00:18:59.839
So um, let me ask, because I'm certainly not a Ruby expert, would this be one of those things that should be tipping you off that there's a problem if you download a Ruby package that's written in Python, or would that be like uh could happen benignly?
00:19:00.799 --> 00:19:09.359
I mean, I think there are a lot of like NPM, like a lot of NPM packages pull all kinds of other stuff, you know, so binaries and other code.
00:19:09.519 --> 00:19:10.720
I think it's a signal.
00:19:10.799 --> 00:19:13.519
I wouldn't say it's a high quality signal.
00:19:13.599 --> 00:19:15.680
I think it's a signal you're gonna look at with other things.
00:19:15.839 --> 00:19:28.640
But in this particular case, there's a lot more high-quality signals that you saw before that, in the sense that you know, that first stage, that second stage, when it's calling out to these additional things and it's pulling files, that is a very, very clear signal.
00:19:28.720 --> 00:19:36.480
You know, yar, even simplistic yar rules will be able to find this stuff for you really quickly, looking for these fetches and the axios calls and what have you, or the equivalent.
00:19:36.559 --> 00:19:37.200
Sorry, the equivalent.
00:19:37.279 --> 00:19:38.720
This is Ruby, so the equivalent.
00:19:38.960 --> 00:19:50.720
Um, so you know, then you combine that high-quality signal with then the fact that it is in another language, you know, those things together they start to add up.
00:19:50.960 --> 00:19:55.599
Well, in addition to what we've talked about, it does uh clipboard hijacking.
00:19:55.839 --> 00:20:08.319
So, you know, of concern when a cryptocurrency address is detected on the clipboard, they exfiltrate it and they actually replace it with a corresponding operator wallet.
00:20:08.720 --> 00:20:18.160
Um it also is uh wallet vault and secret harvesting, so reading off the uh ecosystems it's looking for here.
00:20:18.480 --> 00:20:26.880
Uh Tron Link, MetaMask, Phantom, Binance, Coinbase, Trust Wallis, Wallet, uh, Exodus, Electrum.
00:20:26.960 --> 00:20:35.359
So pretty broad range of um uh crypto ecosystems that could get hit by this.
00:20:36.319 --> 00:20:44.640
Yeah, I mean, it was hitting all the big ones, um, you know, BitGet among them, who is you know having a hard couple of weeks, but um yeah, it's it's it's pretty typical.
00:20:44.880 --> 00:20:56.000
When we um when we were tracking the DPR case stuff, you know, they initially were looking at something like I don't know, six or seven um uh different companies and exchange.
00:20:56.240 --> 00:21:01.119
They were looking for the Chrome extensions, and there's all this kind of like infrastructure that you could tell that they're looking for this stuff.
00:21:01.279 --> 00:21:23.279
And it went from like seven to like 16 to 28 to 35, and you know, so they just kept looking for more and more and more and more is more of these uh extensions and and um you know the way that people interact with their with their crypto assets as more of those became popular, you know, DPRK and other threat reactors just kept swallowing them up, swallowing them up.
00:21:24.000 --> 00:21:24.400
Yep.
00:21:24.559 --> 00:21:24.960
Yeah.
00:21:25.200 --> 00:21:37.759
Yeah, and just looking at the uh malicious gems here, the typos squats definitely are not sophisticated and remind me a lot of some of the other Ruby attacks we've seen over the summer.
00:21:37.920 --> 00:21:57.039
However, the brand jacking generic utility names, these resonate a little bit more as efforts to uh, you know, name something in a smart way that somebody might actually choose on purpose rather than relying on the you know keyboard fat finger.
00:21:57.119 --> 00:21:59.519
You know, we've got things for Ethereum.
00:22:00.480 --> 00:22:09.119
Uh Bitcoin, and you know, we've got a crypto key utils, like there's there's these look more legitimate.
00:22:09.279 --> 00:22:15.279
So I see a bit more maturity with the way this threat actor decided to approach this campaign.
00:22:15.519 --> 00:22:22.400
Um something I haven't dug into yet in our data, and maybe I'll do that after we're uh done today.
00:22:22.720 --> 00:22:25.680
But I know it's not my imagination.
00:22:26.000 --> 00:22:37.680
I think Ruby is seeing perhaps the highest um velocity compared to previous months and years of malware.
00:22:37.759 --> 00:22:51.119
Uh, it does seem like attackers are starting to not necessarily shift focus because we certainly still see it in NPM, but uh nobody was talking about Ruby malware before the summer.
00:22:51.440 --> 00:22:51.920
Right.
00:22:53.039 --> 00:22:53.519
Yeah.
00:22:53.680 --> 00:23:00.559
And you know, I you and I have quite the relationship now with the RubyGems people because we keep disclosing things.
00:23:00.640 --> 00:23:02.559
I mean, like I like I the speed dial.
00:23:02.720 --> 00:23:04.079
Hey guys, you got another one.
00:23:04.240 --> 00:23:14.960
Um but um you're right, and it's not like there's a corresponding drop in npm or pipy volume, it's just now there's an increased volume in RubyGems, and we're seeing that everywhere.
00:23:15.119 --> 00:23:18.799
Same thing with VS Code and all these other places, as but bad guys realized.
00:23:18.960 --> 00:23:21.039
I mean, part of it is what we're talking about, the portability.
00:23:21.119 --> 00:23:29.599
They're like, oh shit, you know, I've got this, I've got this stager over here and this this rat uh in Python, I'll just load it in npm.
00:23:29.680 --> 00:23:30.240
Oh, you know what?
00:23:30.319 --> 00:23:32.559
Actually, I'll do the same thing in RubyGems, why not?
00:23:32.799 --> 00:23:45.599
And these dependency confusion attacks like are again, if we just look at it like nobody's gonna be stupid enough to take, you know, uh gems install, you know, bitcoin spelled with O in the I backwards.
00:23:45.759 --> 00:23:52.880
No, it's like you know, you grab something, you cut and paste something from somewhere else, or it's in some automation, or the AI misspells it, or whatever.
00:23:53.039 --> 00:23:57.200
You know, a lot of it is AI, you can blame it on AI ultimately, right?
00:23:57.519 --> 00:24:10.000
Um, one thing I noticed though is that red actors don't know how to use linters because like they just always leave their comments in there, and the comments are so they're all always in English, or almost always in English.
00:24:10.160 --> 00:24:21.519
Occasionally you'll see Chinese comments, or you know, I've seen Vietnamese and Chinese and Thai and stuff, but other than that, they're almost always in English, and they just explicitly say, here's the payload right here.
00:24:21.680 --> 00:24:27.680
Make sure that you know it's just like so the signposts are very clear.
00:24:28.079 --> 00:24:36.240
We're gonna start seeing like linters and tools coming out from people, um uh you know, like bad guys, right?
00:24:36.400 --> 00:24:40.079
Which I think is great because we can then we can use those things as watering holes.
00:24:40.160 --> 00:24:45.440
But um well, you said something that I think is worth bringing up with this particular campaign.
00:24:45.599 --> 00:24:51.200
So the previous uh Ruby campaign we talked about with Gemstuffer, we found it in Ruby first.
00:24:51.440 --> 00:24:55.200
It turned out it also hit NPM at the same time.
00:24:55.599 --> 00:25:16.799
Uh, haven't necessarily seen evidence that this one made an effort to be cross-ecosystem, but to your point that I don't know if you were explicitly making or not, it's possible that they've tried this previously in a different ecosystem, like PiPi, perhaps had mixed results, decided to give it a go over in Ruby.
00:25:17.680 --> 00:25:18.559
Yeah, exactly.
00:25:18.640 --> 00:25:19.440
I wouldn't be surprised.
00:25:19.920 --> 00:25:21.519
I don't actually know that.
00:25:21.839 --> 00:25:28.079
No, but that's this is a pure hypothesis here, but given the behavior we've seen, wouldn't surprise me.
00:25:28.400 --> 00:25:33.119
Yeah, and and looking at the fact that they're two different languages and they're totally distinct things, right?
00:25:33.200 --> 00:25:41.279
Like it's not, it doesn't take a genius to say, you know, that PyPy stuff is probably pre-existing, they probably used it over in PyPy, you know.
00:25:41.920 --> 00:25:57.279
Well, and you know, I saw something interesting the other day, and I can't even remember the source, so I'm sorry, maybe you will recognize this, but that there is uh an increase in AI tools getting confused about which ecosystem something exists in.
00:25:57.359 --> 00:26:00.240
And this kind of relates to the sloping stuff.
00:26:00.480 --> 00:26:07.279
You know, there's a legitimate npm package, it makes an assumption that it's available over in Ruby.
00:26:07.680 --> 00:26:08.319
Who knows?
00:26:08.480 --> 00:26:15.759
Maybe all these package names exist legitimately in another ecosystem, and this is uh an effort at slop squatting.
00:26:16.160 --> 00:26:19.119
Yeah, that was the podcast with Josh Pressers and uh that's right.
00:26:19.279 --> 00:26:20.160
That was open source security.
00:26:20.799 --> 00:26:21.920
I wasn't making it up.
00:26:22.400 --> 00:26:23.519
No, you were not.
00:26:23.759 --> 00:26:30.559
Um I can't remember what I had for dinner last night, but I can remember every podcast that I've ever freaking listened to and all the content they're in.
00:26:30.720 --> 00:26:40.400
Um, but yeah, I mean, I think that um uh oh my gosh, what was the what was the point that he was trying to make that you brought up there?
00:26:40.480 --> 00:26:54.880
I'm oh it was the either slop squatting is perhaps getting more uh effective as a strategy because AI tools are making assumptions about things existing in other ecosystems.
00:26:54.960 --> 00:26:59.279
And that's that's uh like it makes total sense when you say it out loud.
00:26:59.359 --> 00:27:04.720
It's not something I've given a lot of thought to when we talk about slopping, but uh I I buy it.
00:27:05.119 --> 00:27:09.279
Yeah, in particular, he mentioned um he mentioned the the requests, right?
00:27:09.359 --> 00:27:11.519
Which is the famous Python library.
00:27:12.160 --> 00:27:20.319
Um and the fact that you're seeing, you know, instead of Axios, you're seeing rat you know, requests over in the JavaScript world and you're seeing fetch.
00:27:20.720 --> 00:27:30.000
So basically, slop squatting absolutely is encouraging this kind of cross-ecosystem naming kind of confusion that we're seeing.
00:27:30.240 --> 00:27:42.240
Um which is which is very I mean, the thing is that the people generating code now don't really know the code like they did five years ago or 10 years ago because it's being vibe coded for us, right?
00:27:42.319 --> 00:27:47.920
And so because of that, a lot of this stuff is lost to the person that's actually sitting in front of the keyboard.
00:27:48.000 --> 00:27:50.559
Uh, the distinction there is lost on the human.
00:27:50.720 --> 00:27:52.559
Um, so the AI doesn't know.
00:27:52.640 --> 00:27:53.759
It's like, let me just go and look for it.
00:27:53.839 --> 00:27:54.960
Oh, hey, look, it exists.
00:27:55.039 --> 00:27:57.680
Oh, look, it looks like it does right what I want it to do.
00:27:57.839 --> 00:28:00.400
Sweet as happy days, let's install it.
00:28:01.119 --> 00:28:01.759
Yep.
00:28:02.000 --> 00:28:04.960
Bad times bad times all around.
00:28:05.519 --> 00:28:06.000
All right.
00:28:06.160 --> 00:28:09.119
Well, I think that reaches the end of our list.
00:28:09.359 --> 00:28:12.160
Um, anything you want to add before we wrap up?
00:28:12.319 --> 00:28:15.279
I think next week we may be recording at a different time.
00:28:15.440 --> 00:28:22.480
Uh, we'll see you and I have to work that out with my travel schedule, but uh we'll be around the next couple of weeks for sure.
00:28:22.799 --> 00:28:23.519
Yeah, cool.
00:28:23.759 --> 00:28:30.079
Yeah, I mean, I'm I'm chilling until RuCon, which I'm looking forward to in um Google RuCon in November.
00:28:30.160 --> 00:28:33.119
So I'm just chilling here and uh you're gonna be busy.
00:28:33.200 --> 00:28:34.160
So happy days.
00:28:34.400 --> 00:28:37.680
Well, I mean, I would love an excuse to get down to Australia.
00:28:38.079 --> 00:28:41.680
Google, if you want to buy me a ticket, happy to have to come.
00:28:42.480 --> 00:28:44.319
I feel like they can probably afford it.
00:28:44.640 --> 00:28:45.680
I think they could.
00:28:45.920 --> 00:28:48.160
Um, we have a Google Workspace account, right?
00:28:48.240 --> 00:28:49.039
That seems like it should be.
00:28:49.359 --> 00:28:49.680
We do.
00:28:49.839 --> 00:28:51.119
I've got a bunch.
00:28:52.799 --> 00:28:54.000
I got a collection.
00:28:54.400 --> 00:28:54.880
On that note.
00:28:55.359 --> 00:28:55.680
On that note.
00:28:56.079 --> 00:28:57.039
Not looking for handouts.
00:28:57.279 --> 00:28:57.599
Thank you.
00:28:57.759 --> 00:28:58.319
Have a good luck.
00:28:58.559 --> 00:28:58.960
See everybody.
00:28:59.039 --> 00:29:00.000
Hey, we'll take handouts.
00:29:00.160 --> 00:29:00.799
We'll take handouts.
00:29:01.200 --> 00:29:01.839
Yeah, yeah, yeah.
00:29:02.000 --> 00:29:03.839
Let's not let's not be crazy here.
00:29:03.920 --> 00:29:04.960
We'll totally take them.
00:29:05.119 --> 00:29:05.920
All right, bye.
00:29:06.079 --> 00:29:06.720
Bye, everybody.
00:29:06.799 --> 00:29:07.359
See ya.