Een gegenereerde abstracte illustratie op een donker marineblauw vlak: een stapel van vijf dunne cyaan geheugentrays in doorsnede, elk met rijen kleine grijze blokjes, waarbij één kleine amberkleurige kubus tussen de derde en vierde tray is geschoven; vanuit die kubus boogt een dun amberkleurig filament van deeltjes naar rechts over een donkere leegte naar drie kleine roodoranje knooppunten in een driehoek. Achter de trays hangen vaalgrijze labels aan dunne lusjes aan een sleutelring. Er verschijnen geen tekst, mensen of organisatielogo's. Het OrcaRouter-logo is samengevoegd in de rechteronderhoek.
AI Safety Incidents

sckit: De AI-geheugenpakketten van MemTensor waren voorzien van een backdoor om de inloggegevens en prompts van agents te stelen

Auteur

Rowan Sterling

Publicatiedatum

Nieuwste modellen · 20Bekijk alle modellen →
Benchmarks: Artificial Analysis · dagelijks bijgewerkt
Terug naar alle berichten

Vier MemTensor-releases die op 23 september 2026 zijn gepubliceerd, bevatten dezelfde gestripte Go-implant, en elk ervan was de nieuwste versie op zijn registry terwijl die live stond. De npm-package @memtensor/memos-cloud-openclaw-plugin verscheen als 0.1.21 om 02:23 UTC, 0.1.23 om 03:49 en 0.1.25 om 04:36; die van PyPI, MemoryOS, verscheen als 2.0.34 om 05:25. Alle vier bevatten sckit, dat start wanneer de OpenClaw-agentgateway opstart, opnieuw start bij elke memory recall — waarbij de prompttekst van de gebruiker in een omgevingsvariabele wordt meegegeven — en, in het Python-pakket, start bij een gewone import van de memos-module. Daarna doorzoekt het de thuismap op npm-, PyPI-, GitHub-, GitLab-, AWS-, Vault- en SSH-geheimen en stuurt wat het vindt naar servers onder skyleen[.]fr. Socket, StepSecurity, SafeDep en Aikido documenteerden de compromittering die dag onafhankelijk, en geen van hen rapporteerde bewijs dat de implant op een echte host had gedraaid. Het Orca AI Incident Archive bevat deze vermelding volledig, naast elk ander supplychainincident dat het heeft geregistreerd, en elk record heeft zijn eigen zekerheidsgraad en schadestatus.

Vier releases, en een openbare bugmelding te midden daarvan

MemOS is het open-source geheugenframework van MemTensor voor LLM-agenten, en het npm-pakket is de connector waarmee een OpenClaw-agentruntime kan lezen van en schrijven naar een gehoste geheugenservice; StepSecurity merkt op dat hetzelfde pakket ook integratiepunten voor de Clawdbot- en Moltbot-runtimes declareert. Socket mat de repository op ongeveer 11.500 sterren en 1.100 forks toen het dit publiceerde. Die positie verklaart waarom de compromittering vier afzonderlijke onderzoeken opleverde: zoals StepSecurity het verwoordde, "plaatst dit de plugin in een proces dat routinematig gebruikersinvoer verwerkt en mogelijk waardevolle inloggegevens erft." De mensen die zijn blootgesteld, zijn degenen die een van beide pakketten hebben geïnstalleerd — ontwikkelaars op hun eigen machines, en CI-runners en containers die alleen een testsuite hebben uitgevoerd.

De npm-reeks is het duidelijkste deel van het dossier, omdat de registry-tijdstempels openbaar zijn en meerdere bedrijven ze onafhankelijk hebben vastgelegd. Het verslag van Socket en de tijdlijn van SafeDep komen op elke minuut overeen: 0.1.21 om 02:23:04, 0.1.22 om 03:45:44, 0.1.23 om 03:49:20, 0.1.24 om 04:33:30 en 0.1.25 om 04:36:58. Versies 0.1.22 en 0.1.24 waren schoon — Socket zegt dat ze overeenkwamen met 0.1.20 afgezien van versiestrings — en de payload kwam drieënhalve minuut na elk daarvan terug.

De sprong in grootte verraadt het. Socket mat 0.1.20 op ongeveer 272 KB uitgepakt en 0.1.21 op 43,6 MB, omdat de kwaadaardige releases zes statisch gelinkte platformbinaries van ongeveer 7,4 MB elk meebrachten. PyPI laat hetzelfde patroon zien: de wheel van 2.0.34 was 19.201.772 bytes tegenover 951.210 voor 2.0.33, volgens Socket.

Om 04:17 UTC — zestien minuten vóór de schone versie 0.1.24 en negentien minuten voordat de payload terugkwam als 0.1.25 — opende een GitHub-gebruiker genaamd omeridel issue #173 op de pluginrepository, met de titel "Kwaadaardige versies 0.1.21 en 0.1.23 gepubliceerd op npm — publicatietoken lijkt gecompromitteerd." De issue vermeldt dat 0.1.23 toen de nieuwste tag was, dat geen van beide versies overeenkwam met een commit of tag in de repository, en dat de meest recente legitieme commit dateerde van 14 augustus. De issue is nog steeds open, zonder reacties van de maintainers, per 26 oktober 2026.

A self-built HTML card headed 'Supply chain, 23 September 2026, all times UTC', titled 'Four and a half hours on npm and PyPI', subtitled 'Each malicious release was the registry's newest version while it was live'. Nine rows, each with a time, an event, a detail and a status chip: 00:48 attacker branch first pushed, pipeline; 02:23 npm 0.1.21 published, 43.6 MB unpacked up from 272 KB, malicious; 03:17 MemOS commit b52958f, six sckit binaries and a CI token stealer, malicious; 03:45 npm 0.1.22 published, matches 0.1.20 apart from version strings, clean; 03:49 npm 0.1.23 published, payload restored three minutes later, malicious; 04:17 GitHub issue 173 filed, disclosure; 04:33 npm 0.1.24 published, clean again and the latest tag for three minutes; 04:36 npm 0.1.25 published, payload back and this one takes the latest tag, malicious; 05:25 PyPI MemoryOS 2.0.34, 19.2 MB wheel against 951 KB in 2.0.33, malicious. A footer reads 'Timestamps from Socket and SafeDep, which agree to the minute. Sizes from Socket.' The OrcaRouter logo is composited in the bottom-right corner.

Wat sckit doet zodra het pakket is geladen

Geen van beide pakketten gebruikte een install-hook, daarom was het gebruikelijke advies over --ignore-scripts niet van toepassing. De analyse van StepSecurity van de npm-variant beschrijft een nieuw bestand, lib/sckit.js, dat een launcher exporteert die de bestaande opstart- en memory-recall-code van de plugin importeert en aanroept. Bij het opstarten start het een detached .sckit/<os>-<arch>/sckit-proces met stage0 --config64 en de volledige omgeving van het bovenliggende proces; bij recall doet het hetzelfde en geeft het de gestripte gebruikersprompt door via een omgevingsvariabele met de naam SCKIT_EVENT_TEXT. Socket verwoordde de consequentie ronduit: de binary draait daardoor bij elke recall opnieuw.

De PyPI-variant is korter en in de praktijk moeilijker te vermijden. Socket ontdekte dat memos/log.py een triggerfunctie aanroept in memos/_stage0.py wanneer logboekregistratie is geconfigureerd, dat 149 modules de logger op moduleniveau aanroepen, en dat een gewone import van de memos-module daarom voldoende is om de payload één keer per proces te starten. De analyse van StepSecurity van hetzelfde pakket was puur statisch — het heeft het niet geïnstalleerd, geïmporteerd, gebouwd of uitgevoerd.

Het verzamelbereik is de volledige homedirectory. SafeDep vermeldt de inventarisroot als $HOME en de beoogde bestanden als .npmrc, .pypirc, .git-credentials, .netrc, id_rsa, id_ecdsa, id_ed25519, .vault-token, msal_token_cache, access_tokens.json en access_tokens.db, plus omgevingsvariabelen waarvan de naam token, secret, password, API key of database URL bevat, plus erkende tokenformaten voor GitHub, GitLab, npm, PyPI, Hugging Face, Slack, Stripe, AWS en SendGrid. De OSV-records voor de twee pakketten, MAL-2026-16476 voor npm en MAL-2026-16475 voor PyPI, beschrijven dezelfde bestandenlijst en voegen toe dat het command-and-controlprotocol CBOR, X25519-sleuteluitwisseling en XChaCha20-Poly1305 gebruikt, met ondertekende leases en modules die tijdens runtime worden aangeleverd — dus de inhoud van de modules is nooit waargenomen, alleen de loader die ze ophaalt.

Twee details bepalen wat een verdediger nog kan terugvinden. Het binaire bestand bevat zelfverwijderingsroutines met de naam scheduleSelfDelete en deleteExecutable, volgens het OSV-record, en daarom luidt het advies om te jagen op proces- en netwerkartefacten in plaats van op bestanden. En 0.1.25 voegde lib/tls-trust.js toe, dat op minimale Linux-systemen SSL_CERT_FILE instelt op een meegeleverd bestand met 145 certificaatautoriteiten, volgens StepSecurity — een oplossing om het eigen verkeer te laten werken op containers zonder systeemtruststore.

A generated abstract illustration on a dark navy field: at left, a dim cyan isometric tree of folders, several leaves carrying small grey key and badge silhouettes; from those keys a cluster of amber threads lifts away, braids into one bright cord and runs right through a narrow vertical cyan gateway frame that carries an amber keyhole, toward three small red-orange receivers with faint pulse rings on the far right. No text, people or organisation logos appear. The OrcaRouter logo is composited in the bottom-right corner.

De releasepipeline was de ingang.

De reconstructie van SafeDep is het meest gedetailleerde verslag van de initiële toegang, en wijst op GitHub Actions in plaats van op een gestolen registerwachtwoord. Tussen 00:48 en 02:03 UTC, heeft een GitHub-account dat opereerde als Memtensor-AI vijf keer een branch met de naam sc/release-0.1.21-20260922-cloud aangemaakt, gepusht en verwijderd. De commit 9b97ec6 wijzigde het workflowscript .github/scripts/validate-release-confirmation.mjs zodat het een BASH_ENV-waarde aan $GITHUB_ENV toevoegde, waardoor latere niet-interactieve shellstappen een door de aanvaller aangeleverd sckit-publish-bridge.sh inlaadden voordat ze hun eigen opdrachten uitvoerden. Die bridge controleerde de pakketnaam en de time-out van 150 seconden van de publicatiestap, riep de tokenverzamelaar aan met NPM_TOKEN of NODE_AUTH_TOKEN, verwijderde zichzelf en stopte met exitcode 1 — waardoor de publicatie mislukte nadat het token was buitgemaakt. De eerste kwaadaardige npm-release verscheen twintig minuten na de laatste branch-push.

Het PyPI-pad gebruikte dezelfde truc tegen een andere pipeline. SafeDep meldt dat tag v2.0.34 naar niet-ondertekende commits wees die niet op main stonden, en dat commit b52958f, met als auteur "MemTensor CI Review", de zes binaire bestanden, een Python-loader en een aangepaste buildbackend genaamd sckit_poetry_build toevoegde. Die backend schreef een BASH_ENV die naar_pypi_bridge.sh wees in $GITHUB_ENV; de bridge handelde alleen binnen de twine-uploadwrapper, haalde een ondertekende index op van de host skyleen[.]fr, verifieerde een emitter met een Ed25519-implementatie, drukte een markerregel af, verwijderde het uploadwachtwoord en stopte zonder iets te uploaden. Ongeveer twee uur later verwijderde commit 41bf5c7 die aanroep met het bericht "chore: allow native PyPI upload [skip ci]", werd de tag binnen tien seconden verwijderd en opnieuw aangemaakt, en volgde de PyPI-upload 62 seconden daarna. SafeDep ziet de eerste commit als een run om tokens buit te maken en de tweede als de run die ervoor zorgde dat MemTensors eigen workflow het kwaadaardige pakket kon bouwen en publiceren met het echte token van het project.

Niet elke lezing komt hiermee overeen. Socket merkte op dat de npm-releases van hetzelfde npm-account afkomstig waren als eerdere legitieme versies en geen gitHead hadden, wat het opvatte als een teken dat ze niet door de CI van het project waren geproduceerd, en verklaarde dat het niet kon bevestigen hoe de aanvaller publicatietoegang had verkregen. SC Media, dat op 24 september verslag deed van Socket's bevindingen, kwam tot dezelfde gevolgtrekking richting een gecompromitteerd account. De twee lezingen zijn het erover eens dat publicatie-inloggegevens uit de releasepipeline zijn weggenomen en verschillen van mening over hoe het npm-artefact zelf tot stand kwam; niemand heeft de workflowlogs gepubliceerd, omdat de Actions API van GitHub na 7 september geen runs vertoonde en SafeDep afleidt dat de records zijn verwijderd. Hoe het Memtensor-AI-account in de eerste plaats push-toegang heeft verkregen, is in beide lezingen onbekend; SafeDep noemt een gestolen accounttoken waarschijnlijk, maar niet bevestigd.

Vastgesteld, afgeleid en afwezig

De betrouwbaarheidsgraad van het record is A en die is niet betwist, wat precisering verdient, omdat de zekerheid betrekking heeft op wat is gepubliceerd en niet op wat het heeft gedaan.

• Vastgesteld: de inhoud van de vier artefacten, gereconstrueerd door statische analyse bij Socket, StepSecurity en SafeDep; de npm-publicatietijden en de nieuwste tag op 0.1.25; de sprong in grootte in beide ecosystemen; de commits, tags en branchgeschiedenis in de twee repositories; de infrastructuur van skyleen[.]fr en de campagne-identificatoren cloud-openclaw-semi-nuclear en memos-semi-nuclear; en de configuratie van de payload, die volgens Socket en SafeDep verloopt op 22–23 oktober 2026.

• Afgeleid: dat de tool met behulp van een taalmodel is geschreven, wat SafeDep direct zegt en een inferentie noemt; en dat de gestolen publicatietokens bedoeld waren om opnieuw te worden gebruikt, wat de kanaalstring van de configuratie — "exact-ref-one-use-NPM_TOKEN" — ondersteunt maar niet bewijst.

• Niet vastgesteld: wie de aanvaller was; of ooit een kopie van sckit buiten een sandbox is uitgevoerd; of er ooit een inloggegeven een host heeft verlaten; of een prompt die in een OpenClaw-agent is getypt de aanvaller heeft bereikt; en of een downstreampakket opnieuw is gepubliceerd. Socket en StepSecurity werkten beide statisch, en StepSecurity stelt dat in zijn analyse geen procesuitvoering, geen overdracht van geheimen, geen succesvolle exfiltratie, geen workflow-installatie en geen verdere pakketpublicatie is waargenomen.

Die leemte is de reden dat het archief dit incident vastlegt met 'reële schade' op onwaar. De blootstelling is reëel en breed — iedereen die een getroffen versie heeft geïnstalleerd, krijgt het advies de host als gecompromitteerd te beschouwen — maar schade, in de zin van een aantoonbaar gebruikt inloggegeven of een aantoonbaar bereikt systeem, is door geen van de vier onderzoekende bureaus geregistreerd.

A self-built HTML card headed 'What the record supports', titled 'Four investigating firms, no confirmed victim', subtitled 'Socket, StepSecurity, SafeDep and Aikido documented the same four artefacts on 23 September 2026'. The left column, headed 'Established by static analysis', lists: four malicious releases, npm 0.1.21, 0.1.23 and 0.1.25 and PyPI MemoryOS 2.0.34; one implant, the same stripped Go binary sckit in all four; the publish window 02:23 to 05:25 UTC with 0.1.25 tagged latest; package growth from 272 KB to 43.6 MB on npm and 951 KB to 19.2 MB for the PyPI wheel; six builds per package for Linux, macOS and Windows on amd64 and arm64; collection scoped to the whole home directory across registry, source-control, cloud, Vault and SSH secrets; exfiltration to servers under skyleen[.]fr; and OSV tracking as MAL-2026-16476 and MAL-2026-16475. The right column, headed 'Not established', lists: the attacker's identity; how Memtensor-AI obtained push access; whether any copy ever executed outside static analysis; whether a stolen secret reached the attacker; whether any prompt text was received; and whether any downstream package was republished. A footer reads 'Archive classification for this record: incident, severity high, confidence A, real harm false.' The OrcaRouter logo is composited in the bottom-right corner.

De worm waarvan nooit is gezien dat hij zich verspreidde

De binaries bevatten meer dan alleen een stealer. SafeDep vermeldt functies met de namen recursivePublish, prepareRemoteNode, prepareRemotePython en prepareRemoteWorkflow, plus een ingebed GitHub Actions-sjabloon dat bij een push wordt geactiveerd en de mogelijkheid om een workflowbestand met de naam runtime-update.yml in repositories die het implant kan bereiken, te schrijven. Socket vond strings over het coderen van pakketmanifesten en het installeren van repositorybestanden en concludeerde dat de binaries mogelijk pakketten opnieuw kunnen publiceren met gestolen registry-tokens.

Dat is een wormontwerp. Het is geen worm waarvan is waargenomen dat hij werkte. StepSecurity vond geen bewijs dat de logica ooit is gebruikt om zich te verspreiden, en de onderzoeksnotitie van de Cloud Security Alliance van 25 september interpreteert de mogelijkheid als een beperkt potentieel voor zelfverspreiding in plaats van bevestigd wormgedrag. Verschillende media beschreven de zaak als de eerste toeleveringsketenworm gericht op de geheugeninfrastructuur van AI-agenten; die beschrijving klopt als uitspraak over het ontwerp, en de rapporten ondersteunen haar niet als uitspraak over wat er is gebeurd.

Wat is er daarna veranderd?

De pakketregistries zijn dezelfde dag opgeschoond. Bij controle op 26 oktober 2026 vermeldt de npm-pakketmetadata 0.1.21, 0.1.23 en 0.1.25 niet meer onder de versies, wijst de latest-tag naar 0.1.24 en is het pakket voor het laatst gewijzigd op 23 september om 11:53 UTC. Er zijn nog twee ongebruikelijke dist-tags gekoppeld — clean-inverse-0-1-23 die naar 0.1.22 wijst en clean-inverse-0-1-25 die naar 0.1.24 wijst — die de twee schone releases weerspiegelen die de kwaadaardige releases kort onderbraken. Op PyPI is MemoryOS 2.0.34 verdwenen en is de nieuwste release 2.0.33, geüpload op 3 september 2026; in de zeven weken sindsdien is er geen nieuwe PyPI-release meer geweest.

Wat niet is veranderd, is de publieke verantwoording van het project. De repository vermeldt geen beveiligingsadviezen, de GitHub-issue van 04:17 op de dag van het incident staat nog open en is onbeantwoord, en geen van de hier onderzochte berichten citeert een verklaring van MemTensor of van OpenClaw. Geen van beide kwaadaardige pakketten droeg een herkomstattest, waardoor volgens SafeDep het enige signaal verdween dat de artefacten uit een onverwachte commit waren gebouwd.

Het antwoord dat wél bestaat, bevindt zich aan de detectiekant: StepSecurity heeft de command-and-control-domeinen skyleen[.]fr aan zijn wereldwijde blocklist toegevoegd, en de twee packages worden in OSV gevolgd als MAL-2026-16476 en MAL-2026-16475.

Als een getroffen versie was geïnstalleerd

De richtlijn van Socket is de strengste en de eenvoudigste: als een van de vermelde versies is geladen of geïmporteerd, beschouw die host dan als gecompromitteerd, inclusief CI-runners en containers die alleen tests hebben uitgevoerd. De concrete stappen waar de vier bedrijven het over eens zijn:

• Verwijder het pakket en pin op een schone versie — npm 0.1.20, PyPI 2.0.33. StepSecurity waarschuwt dat de analyse geen schone PyPI-basislijn heeft vastgesteld, terwijl SafeDep en SC Media beide 2.0.33 noemen als de laatste goede release.

Zoek naar de commandoregel van het proces, aangezien het uitvoerbare bestand zichzelf kan verwijderen: sckit stage0 --config64, en de omgevingsvariabele SCKIT_EVENT_TEXT.

• Verwijder de statusmappen ~/.openclaw/.cache/runtime en ~/.memos/.cache/runtime, en controleer repositories op een onverwachte runtime-update.yml-workflow of .sckit/-mappen.

• Roteer elk credential dat bereikbaar is vanuit de thuismap en de procesomgeving, vanaf een schone machine: npm, PyPI, GitHub, GitLab, AWS, Vault, SSH, Hugging Face, Slack, Stripe en SendGrid, en alle .env-waarden. Registry- en source-controltokens gaan eerst.

• Controleer de releases van je eigen pakketten, voor het geval een gestolen publicatietoken is gebruikt om versies te publiceren die je niet hebt geschreven.

• Blokkeer skyleen[.]fr en de bijbehorende subdomeinen, en lees egresslogboeken terug tot 23 september.

• Behandel elke prompt of elk geplakt geheim dat door de plugin is gegaan terwijl die actief was, als blootgesteld. Dit is het deel van het incident dat specifiek is voor agentgeheugen: het implant hoefde geen transcript te scrapen, omdat het transcript bij elke recall aan het implant werd overhandigd.