TL; DR
Durant aproximadament dos mesos, un únic lladre d'informació npm ha ressorgit sota una sèrie rotativa de noms de paquets mentre enviava una càrrega útil gairebé sense canvis. Va començar obertament com forge-jsxy, generat forge-jsx3 / forge-jsx4 germans, van abandonar completament la marca "forja" per fer-se passar per infraestructura de desenvolupadors, primer zredis-typed, i més recentment pinokio-redis.
Cada variant porta la mateixa cadena d'eines interna: fitxers anomenats forge-jsx-explorer-*, un relayPackageServe mòdul que serveix a forge-jsxy-package.tgz, i un temps d'execució durador amagat sota un directori amb punts perquè sobrevisqui a l'eliminació del paquet npm.
La càrrega útil llegeix material de cartera de criptomonedes i les credencials de desenvolupador de l'amfitrió i les transmet al web de Discordhooks, càrregues de HuggingFace Hub i un punt final C2 codificat. Instal·la l'inici automàtic a nivell de sistema operatiu perquè es torni a executar després de reiniciar i captura l'activitat del porta-retalls, el teclat i la pantalla. L'última variant, pinokio-redis, es descriu a si mateix com una integració d'"Autodesk Forge", una descripció que no està relacionada amb el que fa el codi.
| Ecosistema | npm |
| Classe de càrrega útil | infostealer multietapa + agent de control remot (RAT) |
| Objectius principals | moneders criptogràfics, extensions de moneder de navegador, credencials de desenvolupador/núvol |
| Persistència | temps d'execució durador ocult + inici automàtic del sistema operatiu (sobreviu a l'eliminació del paquet) |
| Exfiltració | Discord webhooks + relé, HuggingFace Hub, C2 codificat al port 9877 |
| Larga observada | Maig 2026 – Juliol 2026 (en curs) |
| Nom més recent | pinokio-redis:1.0.127 |
Anatomia d'atac
Totes les variants d'aquesta família s'instal·len a través de la mateixa forma: un paquet que sembla inert a la seva pàgina de llistat però declara un ganxo de postinstal·lació, de manera que La càrrega útil s'executa en el moment en què el paquet s'instal·la com a dependència. el ganxo acciona una cadena de cinc etapes.
- Fase 1: materialitzar-se. L'script d'instal·lació descodifica un fitxer inclòs i codificat blob en un conjunt de scripts d'execució i els escriu en un directori ocult a la ubicació de configuració de la plataforma (les versions forge-jsxy utilitzaven un .forge-jsxy/runtime/v amb punts) /path). Com que aquesta còpia es troba fora de node_modules, l'eliminació o la cancel·lació de la publicació del paquet npm no elimina l'agent en execució.
- Fase 2: persisteix. La cadena registra una entrada d'inici automàtic del sistema operatiu, de manera que l'agent es torna a iniciar en reiniciar. A Windows, això s'executa a través d'un script de diagnòstic ocult de PowerShell; el procés de l'agent es genera desconnectat i amb windowsHide definit, de manera que no apareix cap finestra de consola.
- Fase 3: evadir. El temps d'execució comprova els marcadors d'integració contínua i es tanca silenciosament quan detecta un entorn de CI, de manera que els sandboxes de compilació automatitzats no veuen res. A les versions forge-jsxy, un comentari font indicava que un camp forgeInstall visible s'havia omès deliberadament de package.json "perquè aquest camp seria visible a npm"; l'operador va mantenir les metadades del disparador fora de la llista pública a propòsit.
- Fase 4: recollir. Un cop en execució, l'agent recol·lecta, en una sola passada:
- Material de cartera criptogràfica. Una llista de destinacions secret_filename_patterns.json inclosa impulsa un escombrat del sistema de fitxers per a wallet.dat, *.mnemonic /Fitxers .seed / *.phrase, keypair.json, Ethereum UTC– magatzems de claus i magatzems de claus *.p12 / *.pfx / *.jks. Les biblioteques de derivació de moneders (bip39, secp256k1, base58check i els ajudants de Solana) són presents al paquet.
- Extensions de cartera de navegador. Un mòdul chromiumExtensionDbHarvest llegeix les bases de dades d'emmagatzematge d'extensions locals dels navegadors Chromium, la ubicació on les extensions de cartera basades en navegador guarden les seves dades de volta.
- Credencials i secrets. L'agent escaneja l'historial de l'intèrpret d'ordres i els fitxers que contenen secrets, llegeix les credencials del desenvolupador/núvol i, a continuació, codifica les credencials de HuggingFace per a la seva càrrega.
- Entrada en directe. El contingut del porta-retalls, l'entrada de teclat i les captures de pantalla es capturen de manera contínua.
Etapa 5 — exfiltratLes dades recollides surten de l'amfitrió a través de tres canals que operen en paral·lel: Discord webhooks (discordWebhookPost) i un carregador de relé de Discord que parla amb `discord.com/api/v10` (discordRelayUpload), càrregues de HuggingFace Hub (hfUpload) i un S'ha arribat al punt final C2 codificat de manera fixa a través del port 9877. Un relayPackageServe el mòdul també serveix una resposta forge-jsxy-package.tgz, el mateix nom de l'artefacte en cada canvi de nom.
El punt estructural important és que les etapes 1–3 s'executen en el moment de la instal·lació amb sense interacció de l'usuari, i la fase 1 col·loca la càrrega útil en algun lloc del paquet el gestor no fa un seguiment. Un desenvolupador que s'adona de la dependència estranya i Executa npm uninstall i elimina la llista però no l'agent.
La càrrega útil també es resisteix a una lectura ràpida. Els scripts d'execució no s'envien. en clar: un pas de codificació-desplegament manté la lògica operativa com a blob codificat que només s'expandeix en scripts llegibles un cop finalitzada la cadena d'instal·lació el descodifica al directori d'execució ocult. Els fitxers que són visibles a la llista: la carcassa fina de postinstal·lació i una materialització de distribució ajudant — revela poc sobre el que finalment s'executa. Aquest lliurament codificat el disseny ha tingut un efecte mesurable en el triatge: al llarg de la vida de la família, diverses variants confirmades van ser qualificades com a segures mitjançant la classificació automatitzada, i la càrrega útil ha estat prou opaca com per aturar completament la revisió automatitzada. Els comportaments que delaten la família només són visibles després de la codificació L'etapa s'expandeix i el temps d'execució es llegeix directament.
Línia de temps
La càrrega útil de la família s'ha mantingut notablement estable; el que canvia és el nom a la caixa. L'arc va des de la marca oberta de "forja" cap a disfressades d'eines de desenvolupament no relacionades.
| Data (2026) | Paquet: versió | Nota |
|---|---|---|
| Maig (principis) | forge-jsxy:1.0.81, :1.0.90 | Variants confirmades més primerenques: RAT amb C2 xifrat amb AES-256-GCM |
| pot 19 | forge-jsxy:1.0.92 / 1.0.105 / 1.0.107 / 1.0.108 | Campanya en publicació activa; la versió 1.0.92 estava inicialment etiquetada erròniament com a segura i s'ha revertit en tornar a revisar el codi. |
| Finals de maig | forge-jsx3 / forge-jsx4:1.0.122 / 1.0.123, zod-pino | Noms de paquets germans, mateixa cadena d'eines |
| juny 4 | forge-jsxy:1.0.120 | Continuació; classificat com a segur pel model ML (un error) |
| 21–23 de juny | forge-jsxy:1.0.121 | Conjunt de mòduls sense canvis des de la versió 1.0.120 |
| juliol 6 | zredis-typed:1.0.127 | "Forja" eliminat del nom; encara s'envia forge-jsxy-package.tgz i forgeAgent* claus de configuració |
| juliol 7 | pinokio-redis:1.0.127 | Mateixa cadena d'eines; nou C2; es descriu a si mateix com una integració d'"Autodesk Forge" |
Dues coses destaquen al llarg de la cronologia. Primer, el número de versió 1.0.127 es reutilitza literalment tant per zredis-typed com per pinokio-redis: la denominació canvia però el llinatge de compilació no es restableix. Segon, el canvi dels noms "forge-*" coincideix amb un canvi cap a noms que es llegeixen com a infraestructura ordinària (redis, pinokio), cosa que redueix la possibilitat que un desenvolupador passi per alt el nom i dubti.
Indicadors de compromís
Els IOC següents estan desactivats. L'amfitrió C2 ha rotat entre la línia forge-jsxy. i la darrera variant mantenint el mateix port.
| Indicador | Valor | Vist a dins |
|---|---|---|
| Punt final C2 | 212.193.3[.]61:9877 | pinokio-redis:1.0.127 |
| Punt final C2 | 79.108.162[.]160:9877 | línia forge-jsxy, zredis-typed:1.0.127 |
| Canal Exfil | discord.com/api/webhooks/… (publicació de webhook) | totes les variants |
| Canal Exfil | discord.com/api/v10 (càrrega per relé) | totes les variants |
| Canal Exfil | Pujada al Hub de HuggingFace | totes les variants |
| Artefacte servit | forge-jsxy-package.tgz (Via relayPackageServe) | totes les variants |
| Fitxers de la cadena d'eines | chromiumExtensionDbHarvest, discordRelayUpload, discordWebhookPost, hfUpload, encode-hf-credentials, forge-jsx-explorer-* | totes les variants |
| Llista d'objectius | secret_filename_patterns.json (wallet.dat, .mnemonic/.seed/.phrase, keypair.json, UTC--, .p12/.pfx/*.jks) | totes les variants |
| Temps d'execució ocult | puntejat …/.forge-jsxy/runtime/v<version>/ ruta del directori de configuració | línia forge-jsxy |
| Persistència de Windows | script d'inici automàtic ocult de "diagnostics de forja" de PowerShell | totes les variants |
| Instal·la el disparador | ganxo de postinstal·lació que invoca una cadena de scripts de materialització de dist | totes les variants |
El senyal de detecció més durador no és cap host o webhook únic, sinó aquells rotar — però els noms de fitxer de la cadena d'eines i el fitxer forge-jsxy-package.tgz artefacte, que han persistit literalment a través de cada canvi de nom.
Atribució i comportament observat
Els paquets es van publicar sota més d'un compte npm. El forge-jsxy línia utilitzada per l'editor jacksonkaandorp2 (jacksonkaandorp2@outlook[.]com); La darrera variant de Pinokio-Redis va ser publicada per Donimique (donimiqueakers@gmail[.]com). Cap dels dos comptes tenia un correu electrònic verificat ni un repositori d'origen enllaçat. La línia de transmissió entre comptes és la cadena d'eines, no la identitat de l'editor: els mateixos noms de mòduls, el mateix servit .tgz, i el mateix disseny exfil es repeteix independentment de qui l'ha publicat.
Diversos comportaments observables indiquen una ocultació deliberada en lloc de sobrerecollida accidental:
El temps d'execució es troba fora de node_modules en un directori ocult, de manera que dura més que el paquet que el va lliurar.
L'agent es desactiva quan detecta un entorn de CI, cosa que limita l'exposició en els espais de prova d'anàlisi automatitzats.
El procés de l'agent s'inicia de forma desconnectada i finestra oculta.En A les versions forge-jsxy, un comentari vinculava l'omissió d'un camp d'instal·lació visible al fet que aquest camp fos "visible a npm".
Les descripcions dels paquets públics no estan relacionades amb el codi: pinokio-redis es presenta com una integració amb "Autodesk Forge".
Cal destacar una bretxa de detecció recurrent per als defensors que confien en classificació automatitzada: es van confirmar múltiples variants d'aquesta família qualificada com a segura per un classificador d'aprenentatge automàtic abans que la revisió del codi corregís el veredicte. Els elements estables en què un revisor es pot basar: el temps d'instal·lació cadena, el temps d'execució ocult, els noms de fitxer de la cadena d'eines — són exactament els que que sobreviuen als canvis de nom.
Descrivim l'anterior com a comportament observat. No atribuïm el campanya a qualsevol actor anomenat, i no fem cap afirmació sobre l'operador identitat o objectius més enllà del que demostren el codi i la infraestructura.
Impacte, tendències i orientació del defensor
Qui està exposat. El conjunt de col·leccions està dirigit directament a desenvolupadors màquines: moneders i magatzems de claus de criptomonedes, extensions de moneder de navegador, historial de shell i credencials de núvol/servei. Qualsevol persona que instal·li un paquet afectat, directament o com a dependència transitiva — durant el la finestra en què estava en directe està dins de l'abast, i el disseny de persistència significa que l'exposició no acaba quan es retira l'envàs.
Per què importa la persistència. Com que l'etapa 1 copia la càrrega útil en un directori d'execució ocult i registres de l'etapa 2, l'inici automàtic, l'habitual instint de remediació (desinstal·leu la dependència incorrecta, suprimiu node_modules, reinstal·lar) no expulsa l'agent. La resposta a incidents ha de buscar el el temps d'execució fora de l'arbre i l'entrada d'inici automàtic, no només el paquet.
La tendència. Aquesta família il·lustra un patró que val la pena observar: una càrrega útil estable i madura, embolicada en un flux de materials d'un sol úsnoms de paquets que migren fora de qualsevol nom que s'hagi eliminat anteriorment recognoscible, cap a noms que es llegeixen com a infraestructura ordinària. Basat en noms les llistes de bloqueig i la reputació de l'editor envelleixen ràpidament contra això; comportament- i els senyals basats en artefactes no.
Per a desenvolupadors i consumidors
Tracteu els scripts en temps d'instal·lació com la superfície de risc principal. Instal·leu-los amb els scripts desactivats sempre que sigui possible i reviseu qualsevol dependència que declari un postinstal·lació. Fixar i vetjar dependències transitives; aquesta classe de programari maliciós arriba tan fàcilment a través d'una subdependència com directament.
En un amfitrió sospitós, busqueu més enllà del paquet: busqueu un directori d'execució ocult a la ubicació de configuració de la plataforma, una entrada d'inici automàtic inesperada, i connexions de sortida al webhook de Discord o als punts finals :9877.
Assumeix que qualsevol frase llavor de cartera, magatzem de claus o credencial present en un amfitrió afectat durant la finestra d'exposició està compromesa i roteu-la.
Per a registres i defensors
Alerta sobre els artefactes duradors (forge-jsxy-package.tgz, forge-jsx-explorer-* / chromiumExtensionDbHarvest / discordRelayUpload) noms de fitxer) en lloc del nom del paquet, que canvia.
Marca la combinació estructural en què es basa la família: una postinstal·lació que materialitza els scripts en una ruta de configuració oculta més un sistema operatiu. registre d'inici automàtic, independent de les cadenes específiques implicades.
El nom del paquet ha canviat almenys quatre vegades; la caixa de dins no ho ha fet. La detecció basada en el que fa el codi ha sobreviscut a tots els reetiquetatge fins ara.







