root-access 1.3.38
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/README.md +143 -0
- package/bin/cli.js +469 -0
- package/lib/crypto.js +127 -0
- package/lib/index.js +60 -0
- package/lib/keyforge.js +142 -0
- package/lib/network.js +57 -0
- package/lib/vault.js +78 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
```
|
|
2
|
+
██████╗ ██████╗ ██████╗ ████████╗ █████╗ ██████╗ ██████╗███████╗███████╗███████╗
|
|
3
|
+
██╔══██╗██╔═══██╗██╔═══██╗╚══██╔══╝██╔══██╗██╔════╝██╔════╝██╔════╝██╔════╝██╔════╝
|
|
4
|
+
██████╔╝██║ ██║██║ ██║ ██║ ███████║██║ ██║ █████╗ ███████╗███████╗
|
|
5
|
+
██╔══██╗██║ ██║██║ ██║ ██║ ██╔══██║██║ ██║ ██╔══╝ ╚════██║╚════██║
|
|
6
|
+
██║ ██║╚██████╔╝╚██████╔╝ ██║ ██║ ██║╚██████╗╚██████╗███████╗███████║███████║
|
|
7
|
+
╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝╚══════╝╚══════╝╚══════╝
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
<div align="center">
|
|
11
|
+
|
|
12
|
+
[](https://www.npmjs.com/package/rootaccess)
|
|
13
|
+
[](https://www.npmjs.com/package/rootaccess)
|
|
14
|
+
[](LICENSE)
|
|
15
|
+
|
|
16
|
+
**A mysterious CLI tool. Can you uncover its secrets?**
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 🎯 CTF Challenge
|
|
23
|
+
|
|
24
|
+
**Category:** Reverse Engineering + CLI Exploitation
|
|
25
|
+
**Difficulty:** ★★★★★★★★★★ (10/10)
|
|
26
|
+
**Points:** 2000
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 📦 Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install -g rootaccess
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Or run directly:
|
|
37
|
+
```bash
|
|
38
|
+
npx rootaccess
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 🔧 Usage
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
rootaccess <command> [options]
|
|
47
|
+
|
|
48
|
+
Commands:
|
|
49
|
+
help Show help message
|
|
50
|
+
version Show version information
|
|
51
|
+
status Check system status
|
|
52
|
+
scan Scan for vulnerabilities
|
|
53
|
+
connect Connect to remote server
|
|
54
|
+
decrypt Decrypt a message
|
|
55
|
+
handshake Network protocol simulation
|
|
56
|
+
forge Access the Key Forge
|
|
57
|
+
about About this tool
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 🕵️ The Challenge
|
|
63
|
+
|
|
64
|
+
This CLI hides a secret flag somewhere within its code and behavior.
|
|
65
|
+
|
|
66
|
+
**Flag Format:** \`root{...}\`
|
|
67
|
+
|
|
68
|
+
### Rules
|
|
69
|
+
1. The flag is split into **10 fragments**
|
|
70
|
+
2. Each fragment requires solving a different layer
|
|
71
|
+
3. Some layers require environment variables
|
|
72
|
+
4. Some layers require specific command arguments
|
|
73
|
+
5. Some layers require **previous fragments** to unlock
|
|
74
|
+
6. Some layers are **time-sensitive**
|
|
75
|
+
7. Some layers require **file system interaction**
|
|
76
|
+
8. Some layers simulate **network protocols**
|
|
77
|
+
9. **Layer 10 requires forging a complex master key**
|
|
78
|
+
10. Final assembly reveals the complete flag
|
|
79
|
+
|
|
80
|
+
### Difficulty Breakdown
|
|
81
|
+
|
|
82
|
+
| Layer | Type | Hint | Difficulty |
|
|
83
|
+
|-------|------|------|------------|
|
|
84
|
+
| 1 | Environment | *Debug modes exist for a reason...* | ⭐ |
|
|
85
|
+
| 2 | Environment | *Who has elevated access?* | ⭐ |
|
|
86
|
+
| 3 | Arguments | *Sometimes you need to dig deeper...* | ⭐⭐ |
|
|
87
|
+
| 4 | Arguments | *Not all servers are visible...* | ⭐⭐ |
|
|
88
|
+
| 5 | **Chain** | *Keys forged from previous discoveries...* | ⭐⭐⭐⭐ |
|
|
89
|
+
| 6 | Hidden | *Commands not in help still exist...* | ⭐⭐ |
|
|
90
|
+
| 7 | **Time** | *Shadows appear only at certain hours...* | ⭐⭐⭐⭐ |
|
|
91
|
+
| 8 | **File** | *Some doors require physical keys...* | ⭐⭐⭐ |
|
|
92
|
+
| 9 | **Protocol** | *Complete the handshake to establish trust...* | ⭐⭐⭐⭐ |
|
|
93
|
+
| 10 | **KEY FORGE** | *The key must be computed, not guessed!* | ⭐⭐⭐⭐⭐ |
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## 🏁 Verification
|
|
98
|
+
|
|
99
|
+
Once you have all fragments, assemble them:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
rootaccess assemble --key=<MASTER_KEY>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 💀 Warnings
|
|
108
|
+
|
|
109
|
+
```diff
|
|
110
|
+
- DO NOT just grep for "root{" - it won't work
|
|
111
|
+
- DO NOT expect strings to reveal the answer
|
|
112
|
+
- DO NOT ignore the source code
|
|
113
|
+
- DO NOT skip layers - some depend on previous ones!
|
|
114
|
+
! The flag is encoded and fragmented across 10 layers
|
|
115
|
+
! Environment, arguments, time, and files are your friends
|
|
116
|
+
! Some layers require waiting for the right moment
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## 📖 Final Words
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
┌──────────────────────────────────────────────────────────┐
|
|
125
|
+
│ │
|
|
126
|
+
│ "The best hiding spot is in plain sight, │
|
|
127
|
+
│ behind layers of misdirection, │
|
|
128
|
+
│ guarded by the passage of time." │
|
|
129
|
+
│ │
|
|
130
|
+
│ — The Architects, 2024 │
|
|
131
|
+
│ │
|
|
132
|
+
└──────────────────────────────────────────────────────────┘
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
<div align="center">
|
|
138
|
+
|
|
139
|
+
**Good luck, hacker.** 🔓
|
|
140
|
+
|
|
141
|
+
*The CLI is watching... and waiting.*
|
|
142
|
+
|
|
143
|
+
</div>
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ROOTACCESS CLI - CTF Challenge (HARD MODE)
|
|
5
|
+
* ==========================================
|
|
6
|
+
* The flag is hidden across 10 layers.
|
|
7
|
+
* Can you reverse engineer this CLI to find it?
|
|
8
|
+
*
|
|
9
|
+
* FLAG FORMAT: root{...}
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const crypto = require('crypto');
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { CoreSystem } = require('../lib/index.js');
|
|
16
|
+
const { DataVault } = require('../lib/vault.js');
|
|
17
|
+
const { CryptoEngine } = require('../lib/crypto.js');
|
|
18
|
+
const { NetworkSim } = require('../lib/network.js');
|
|
19
|
+
const { KeyForge } = require('../lib/keyforge.js');
|
|
20
|
+
|
|
21
|
+
const VERSION = '1.3.37';
|
|
22
|
+
const CODENAME = 'SHADOWGATE';
|
|
23
|
+
|
|
24
|
+
// Session state for handshake
|
|
25
|
+
let handshakeState = {
|
|
26
|
+
synSent: false,
|
|
27
|
+
synAckReceived: false,
|
|
28
|
+
token: null,
|
|
29
|
+
timestamp: null
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Banner
|
|
33
|
+
const banner = `
|
|
34
|
+
\x1b[35m╔═══════════════════════════════════════════════════════════╗
|
|
35
|
+
║ ██████╗ ██████╗ ██████╗ ████████╗ █████╗ ██████╗██████╗ ║
|
|
36
|
+
║ ██╔══██╗██╔═══██╗██╔═══██╗╚══██╔══╝██╔══██╗██╔════╝██╔════╝ ║
|
|
37
|
+
║ ██████╔╝██║ ██║██║ ██║ ██║ ███████║██║ ██████╗ ║
|
|
38
|
+
║ ██╔══██╗██║ ██║██║ ██║ ██║ ██╔══██║██║ ╚════██╗ ║
|
|
39
|
+
║ ██║ ██║╚██████╔╝╚██████╔╝ ██║ ██║ ██║╚██████╗██████╔╝ ║
|
|
40
|
+
║ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═════╝ ║
|
|
41
|
+
╠═══════════════════════════════════════════════════════════════╣
|
|
42
|
+
║ Version: ${VERSION} | Codename: ${CODENAME} ║
|
|
43
|
+
╚═══════════════════════════════════════════════════════════════╝\x1b[0m
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
// Hidden debug mode (Layer 1 hint)
|
|
47
|
+
const DEBUG_KEY = process.env.ROOTACCESS_DEBUG;
|
|
48
|
+
const ADMIN_MODE = process.env.ROOTACCESS_ADMIN === 'shadowgate';
|
|
49
|
+
|
|
50
|
+
// Generate time-based token for Layer 7
|
|
51
|
+
function getTimeWindowToken() {
|
|
52
|
+
const now = new Date();
|
|
53
|
+
const minutes = now.getUTCMinutes();
|
|
54
|
+
// Valid in 5-minute windows (0-4, 5-9, etc.)
|
|
55
|
+
const window = Math.floor(minutes / 5);
|
|
56
|
+
return crypto.createHash('md5').update(`SHADOW_${window}_GATE`).digest('hex').slice(0, 6).toUpperCase();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Check if current time is in "shadow hour" (minutes 0-10 or 30-40 of any hour)
|
|
60
|
+
function isInShadowWindow() {
|
|
61
|
+
const minutes = new Date().getUTCMinutes();
|
|
62
|
+
return (minutes >= 0 && minutes <= 10) || (minutes >= 30 && minutes <= 40);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Generate handshake challenge token
|
|
66
|
+
function generateSynAckToken() {
|
|
67
|
+
const ts = Date.now().toString();
|
|
68
|
+
const token = crypto.createHash('sha256').update(ts + CODENAME).digest('hex').slice(0, 8).toUpperCase();
|
|
69
|
+
return { token, timestamp: ts };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Verify handshake ACK
|
|
73
|
+
function verifyAck(ackToken, originalTimestamp) {
|
|
74
|
+
const expected = crypto.createHash('sha256')
|
|
75
|
+
.update(originalTimestamp + CODENAME + 'ACK')
|
|
76
|
+
.digest('hex').slice(0, 8).toUpperCase();
|
|
77
|
+
return ackToken === expected;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Command handlers
|
|
81
|
+
const commands = {
|
|
82
|
+
help: () => {
|
|
83
|
+
console.log(`
|
|
84
|
+
\x1b[36mUsage:\x1b[0m rootaccess <command> [options]
|
|
85
|
+
|
|
86
|
+
\x1b[36mCommands:\x1b[0m
|
|
87
|
+
help Show this help message
|
|
88
|
+
version Show version information
|
|
89
|
+
status Check system status
|
|
90
|
+
scan Scan for vulnerabilities
|
|
91
|
+
connect Connect to remote server
|
|
92
|
+
decrypt Decrypt a message
|
|
93
|
+
forge Access the Key Forge
|
|
94
|
+
handshake Network handshake protocol
|
|
95
|
+
about About this tool
|
|
96
|
+
|
|
97
|
+
\x1b[36mExamples:\x1b[0m
|
|
98
|
+
rootaccess status
|
|
99
|
+
rootaccess scan --deep
|
|
100
|
+
rootaccess connect --server alpha
|
|
101
|
+
|
|
102
|
+
\x1b[33mHint: Not everything is what it seems... 10 layers await.\x1b[0m
|
|
103
|
+
`);
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
version: () => {
|
|
107
|
+
console.log(`RootAccess CLI v${VERSION}`);
|
|
108
|
+
console.log(`Codename: ${CODENAME}`);
|
|
109
|
+
console.log(`Build: ${Buffer.from('4e4f5448494e475f48455245', 'hex').toString()}`);
|
|
110
|
+
|
|
111
|
+
// Hidden layer - check if debugging
|
|
112
|
+
if (DEBUG_KEY === 'LAYER_ONE') {
|
|
113
|
+
console.log(`\n\x1b[32m[DEBUG] Layer 1 unlocked!\x1b[0m`);
|
|
114
|
+
console.log(`[DEBUG] Fragment 1: ${CryptoEngine.getFragment(1)}`);
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
status: () => {
|
|
119
|
+
const core = new CoreSystem();
|
|
120
|
+
console.log('\n\x1b[36m[*] System Status\x1b[0m');
|
|
121
|
+
console.log('─'.repeat(40));
|
|
122
|
+
console.log(` Core Engine: \x1b[32mONLINE\x1b[0m`);
|
|
123
|
+
console.log(` Crypto Module: \x1b[32mONLINE\x1b[0m`);
|
|
124
|
+
console.log(` Vault Status: \x1b[33mLOCKED\x1b[0m`);
|
|
125
|
+
console.log(` Network: \x1b[31mRESTRICTED\x1b[0m`);
|
|
126
|
+
console.log(` Shadow Window: ${isInShadowWindow() ? '\x1b[32mACTIVE\x1b[0m' : '\x1b[31mINACTIVE\x1b[0m'}`);
|
|
127
|
+
console.log('─'.repeat(40));
|
|
128
|
+
|
|
129
|
+
// Hidden admin check (Layer 2)
|
|
130
|
+
if (ADMIN_MODE) {
|
|
131
|
+
console.log(`\n\x1b[32m[ADMIN] Elevated access detected!\x1b[0m`);
|
|
132
|
+
console.log(`[ADMIN] Fragment 2: ${CryptoEngine.getFragment(2)}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Easter egg in status
|
|
136
|
+
core.checkIntegrity();
|
|
137
|
+
},
|
|
138
|
+
|
|
139
|
+
scan: (args) => {
|
|
140
|
+
console.log('\n\x1b[36m[*] Initiating security scan...\x1b[0m\n');
|
|
141
|
+
|
|
142
|
+
const targets = [
|
|
143
|
+
{ name: 'Memory', status: 'clean' },
|
|
144
|
+
{ name: 'Network', status: 'clean' },
|
|
145
|
+
{ name: 'Filesystem', status: 'clean' },
|
|
146
|
+
{ name: 'Registry', status: 'anomaly' },
|
|
147
|
+
];
|
|
148
|
+
|
|
149
|
+
targets.forEach((t, i) => {
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
const icon = t.status === 'clean' ? '\x1b[32m✓\x1b[0m' : '\x1b[33m⚠\x1b[0m';
|
|
152
|
+
console.log(` ${icon} ${t.name}: ${t.status}`);
|
|
153
|
+
}, i * 500);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
setTimeout(() => {
|
|
157
|
+
console.log('\n\x1b[36m[*] Scan complete.\x1b[0m');
|
|
158
|
+
|
|
159
|
+
// Deep scan mode (Layer 3)
|
|
160
|
+
if (args.includes('--deep') || args.includes('-d')) {
|
|
161
|
+
console.log('\x1b[33m[*] Deep scan enabled...\x1b[0m');
|
|
162
|
+
const vault = new DataVault();
|
|
163
|
+
const anomaly = vault.analyzeRegistry();
|
|
164
|
+
if (anomaly) {
|
|
165
|
+
console.log(`\x1b[32m[!] Hidden data found in registry!\x1b[0m`);
|
|
166
|
+
console.log(`[DATA] ${anomaly}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Secret flag for --ultra
|
|
171
|
+
if (args.includes('--ultra')) {
|
|
172
|
+
console.log(`\n\x1b[35m[ULTRA] Fragment 3: ${CryptoEngine.getFragment(3)}\x1b[0m`);
|
|
173
|
+
}
|
|
174
|
+
}, 2500);
|
|
175
|
+
},
|
|
176
|
+
|
|
177
|
+
connect: (args) => {
|
|
178
|
+
const network = new NetworkSim();
|
|
179
|
+
const serverArg = args.find(a => a.startsWith('--server=') || a.startsWith('-s='));
|
|
180
|
+
const server = serverArg ? serverArg.split('=')[1] : 'default';
|
|
181
|
+
|
|
182
|
+
console.log(`\n\x1b[36m[*] Connecting to server: ${server}\x1b[0m`);
|
|
183
|
+
|
|
184
|
+
// Layer 4 - specific server name
|
|
185
|
+
if (server === 'omega-7' || server === 'OMEGA-7') {
|
|
186
|
+
console.log('\x1b[32m[+] Connection established to classified server!\x1b[0m');
|
|
187
|
+
console.log(`[CLASSIFIED] Fragment 4: ${CryptoEngine.getFragment(4)}`);
|
|
188
|
+
} else if (server === 'alpha') {
|
|
189
|
+
console.log('\x1b[33m[!] Alpha server deprecated. Try omega-7?\x1b[0m');
|
|
190
|
+
} else {
|
|
191
|
+
console.log('\x1b[31m[-] Connection refused. Server not found.\x1b[0m');
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
|
|
195
|
+
decrypt: (args) => {
|
|
196
|
+
const msgArg = args.find(a => a.startsWith('--msg=') || a.startsWith('-m='));
|
|
197
|
+
const chainArg = args.find(a => a.startsWith('--chain='));
|
|
198
|
+
|
|
199
|
+
if (!msgArg) {
|
|
200
|
+
console.log('\x1b[31m[-] Usage: rootaccess decrypt --msg=<encrypted>\x1b[0m');
|
|
201
|
+
console.log('\x1b[33m[*] Hint: Some keys are forged from previous discoveries...\x1b[0m');
|
|
202
|
+
console.log('\x1b[33m[*] Advanced: rootaccess decrypt --msg=<msg> --chain=<frag1+frag2>\x1b[0m');
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const msg = msgArg.split('=')[1];
|
|
207
|
+
|
|
208
|
+
// Layer 5 - Chain-dependent decrypt (requires MD5 of frag1+frag2)
|
|
209
|
+
if (chainArg) {
|
|
210
|
+
const chainValue = chainArg.split('=')[1];
|
|
211
|
+
// Expected: MD5(frag1 + frag2) first 8 chars
|
|
212
|
+
const frag1 = CryptoEngine.getFragment(1);
|
|
213
|
+
const frag2 = CryptoEngine.getFragment(2);
|
|
214
|
+
const expectedChain = crypto.createHash('md5').update(frag1 + frag2).digest('hex').slice(0, 8);
|
|
215
|
+
|
|
216
|
+
if (chainValue === expectedChain && msg === 'UNLOCK_CHAIN') {
|
|
217
|
+
console.log('\x1b[32m[+] Chain decryption successful!\x1b[0m');
|
|
218
|
+
console.log(`[CHAIN] Fragment 5: ${CryptoEngine.getFragment(5)}`);
|
|
219
|
+
console.log(`\x1b[90m[*] Chain key was: ${expectedChain}\x1b[0m`);
|
|
220
|
+
} else {
|
|
221
|
+
console.log('\x1b[31m[-] Chain verification failed.\x1b[0m');
|
|
222
|
+
console.log('\x1b[33m[*] Hint: Chain = MD5(fragment1 + fragment2)[0:8]\x1b[0m');
|
|
223
|
+
}
|
|
224
|
+
} else if (msg === 'test') {
|
|
225
|
+
console.log('[*] Test mode: Output = t3st_0utput');
|
|
226
|
+
} else {
|
|
227
|
+
console.log(`\x1b[31m[-] Decryption failed. Invalid key.\x1b[0m`);
|
|
228
|
+
console.log('\x1b[33m[*] Hint: Try --chain parameter for advanced decryption.\x1b[0m');
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
about: () => {
|
|
233
|
+
console.log(`
|
|
234
|
+
\x1b[36mRootAccess CLI\x1b[0m
|
|
235
|
+
A security research tool for penetration testing.
|
|
236
|
+
|
|
237
|
+
Created by: Uttam Mahata
|
|
238
|
+
License: MIT
|
|
239
|
+
Repository: https://github.com/Uttam-Mahata/rootaccess
|
|
240
|
+
|
|
241
|
+
\x1b[33m"The truth is hidden in plain sight..."\x1b[0m
|
|
242
|
+
|
|
243
|
+
\x1b[90m// TODO: Remove debug endpoints before production
|
|
244
|
+
// Endpoints: /api/v1/internal/fragments
|
|
245
|
+
// Auth: Bearer SHADOWGATE_TOKEN_X7K9
|
|
246
|
+
// Shadow hours: minutes 0-10 or 30-40 of any hour (UTC)
|
|
247
|
+
// Unlock file: /tmp/.rootaccess_shadow\x1b[0m
|
|
248
|
+
`);
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
// Hidden commands (not in help)
|
|
252
|
+
__internal__: (args) => {
|
|
253
|
+
// Layer 6 - hidden command
|
|
254
|
+
console.log('\x1b[32m[INTERNAL] Access granted to internal API\x1b[0m');
|
|
255
|
+
console.log(`[INTERNAL] Fragment 6: ${CryptoEngine.getFragment(6)}`);
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
// Layer 7 - Time-window based unlock
|
|
259
|
+
shadow: (args) => {
|
|
260
|
+
const tokenArg = args.find(a => a.startsWith('--token='));
|
|
261
|
+
|
|
262
|
+
if (!tokenArg) {
|
|
263
|
+
console.log('\n\x1b[36m[SHADOW] Time-based access control\x1b[0m');
|
|
264
|
+
console.log('─'.repeat(40));
|
|
265
|
+
|
|
266
|
+
if (isInShadowWindow()) {
|
|
267
|
+
const token = getTimeWindowToken();
|
|
268
|
+
console.log('\x1b[32m[+] Shadow window is ACTIVE\x1b[0m');
|
|
269
|
+
console.log(`[*] Current token: ${Buffer.from(token).toString('hex')}`);
|
|
270
|
+
console.log('\x1b[33m[*] Decode the hex and use: rootaccess shadow --token=<TOKEN>\x1b[0m');
|
|
271
|
+
} else {
|
|
272
|
+
const now = new Date();
|
|
273
|
+
const minutes = now.getUTCMinutes();
|
|
274
|
+
let nextWindow;
|
|
275
|
+
if (minutes < 30) {
|
|
276
|
+
nextWindow = 30 - minutes;
|
|
277
|
+
} else if (minutes > 40) {
|
|
278
|
+
nextWindow = 60 - minutes;
|
|
279
|
+
} else {
|
|
280
|
+
nextWindow = 0;
|
|
281
|
+
}
|
|
282
|
+
console.log('\x1b[31m[-] Shadow window is INACTIVE\x1b[0m');
|
|
283
|
+
console.log(`[*] Next window in ~${nextWindow} minutes`);
|
|
284
|
+
console.log('\x1b[33m[*] Shadow hours: minutes 0-10 or 30-40 of any hour (UTC)\x1b[0m');
|
|
285
|
+
}
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const providedToken = tokenArg.split('=')[1];
|
|
290
|
+
const expectedToken = getTimeWindowToken();
|
|
291
|
+
|
|
292
|
+
if (providedToken === expectedToken && isInShadowWindow()) {
|
|
293
|
+
console.log('\x1b[32m[+] Shadow access granted!\x1b[0m');
|
|
294
|
+
console.log(`[SHADOW] Fragment 7: ${CryptoEngine.getFragment(7)}`);
|
|
295
|
+
} else if (!isInShadowWindow()) {
|
|
296
|
+
console.log('\x1b[31m[-] Shadow window is not active. Wait for the right time.\x1b[0m');
|
|
297
|
+
} else {
|
|
298
|
+
console.log('\x1b[31m[-] Invalid shadow token.\x1b[0m');
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
|
|
302
|
+
// Layer 8 - File creation unlock
|
|
303
|
+
unlock: (args) => {
|
|
304
|
+
const unlockFile = '/tmp/.rootaccess_shadow';
|
|
305
|
+
const expectedContent = crypto.createHash('sha256')
|
|
306
|
+
.update(CODENAME + '_UNLOCK_' + VERSION)
|
|
307
|
+
.digest('hex').slice(0, 16);
|
|
308
|
+
|
|
309
|
+
console.log('\n\x1b[36m[UNLOCK] File-based authentication\x1b[0m');
|
|
310
|
+
console.log('─'.repeat(40));
|
|
311
|
+
|
|
312
|
+
if (fs.existsSync(unlockFile)) {
|
|
313
|
+
try {
|
|
314
|
+
const content = fs.readFileSync(unlockFile, 'utf8').trim();
|
|
315
|
+
if (content === expectedContent) {
|
|
316
|
+
console.log('\x1b[32m[+] Unlock file verified!\x1b[0m');
|
|
317
|
+
console.log(`[UNLOCK] Fragment 8: ${CryptoEngine.getFragment(8)}`);
|
|
318
|
+
console.log(`\x1b[90m[*] Expected content was: SHA256(CODENAME + "_UNLOCK_" + VERSION)[0:16]\x1b[0m`);
|
|
319
|
+
} else {
|
|
320
|
+
console.log('\x1b[31m[-] Unlock file content incorrect.\x1b[0m');
|
|
321
|
+
console.log('\x1b[33m[*] Hint: SHA256(CODENAME + "_UNLOCK_" + VERSION)[0:16]\x1b[0m');
|
|
322
|
+
console.log(`\x1b[33m[*] Your content: ${content}\x1b[0m`);
|
|
323
|
+
}
|
|
324
|
+
} catch (e) {
|
|
325
|
+
console.log('\x1b[31m[-] Error reading unlock file.\x1b[0m');
|
|
326
|
+
}
|
|
327
|
+
} else {
|
|
328
|
+
console.log('\x1b[31m[-] Unlock file not found.\x1b[0m');
|
|
329
|
+
console.log(`\x1b[33m[*] Create file: ${unlockFile}\x1b[0m`);
|
|
330
|
+
console.log('\x1b[33m[*] Content: SHA256(CODENAME + "_UNLOCK_" + VERSION)[0:16]\x1b[0m');
|
|
331
|
+
console.log('\x1b[33m[*] CODENAME and VERSION are shown in the banner.\x1b[0m');
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
|
|
335
|
+
// Layer 9 - Network handshake simulation
|
|
336
|
+
handshake: (args) => {
|
|
337
|
+
const synArg = args.includes('--syn');
|
|
338
|
+
const ackArg = args.find(a => a.startsWith('--ack='));
|
|
339
|
+
const tsArg = args.find(a => a.startsWith('--ts='));
|
|
340
|
+
|
|
341
|
+
console.log('\n\x1b[36m[HANDSHAKE] TCP-like handshake protocol\x1b[0m');
|
|
342
|
+
console.log('─'.repeat(40));
|
|
343
|
+
|
|
344
|
+
if (synArg) {
|
|
345
|
+
// Step 1: Client sends SYN
|
|
346
|
+
const { token, timestamp } = generateSynAckToken();
|
|
347
|
+
console.log('\x1b[32m[SYN] Connection initiated\x1b[0m');
|
|
348
|
+
console.log(`[SYN-ACK] Server responds with token: ${token}`);
|
|
349
|
+
console.log(`[SYN-ACK] Timestamp: ${timestamp}`);
|
|
350
|
+
console.log('\x1b[33m[*] Complete handshake with:\x1b[0m');
|
|
351
|
+
console.log(`\x1b[33m rootaccess handshake --ack=<COMPUTED_ACK> --ts=${timestamp}\x1b[0m`);
|
|
352
|
+
console.log('\x1b[33m[*] ACK = SHA256(timestamp + CODENAME + "ACK")[0:8].toUpperCase()\x1b[0m');
|
|
353
|
+
} else if (ackArg && tsArg) {
|
|
354
|
+
// Step 2: Client sends ACK
|
|
355
|
+
const ackToken = ackArg.split('=')[1];
|
|
356
|
+
const timestamp = tsArg.split('=')[1];
|
|
357
|
+
|
|
358
|
+
if (verifyAck(ackToken, timestamp)) {
|
|
359
|
+
console.log('\x1b[32m[ACK] Handshake complete!\x1b[0m');
|
|
360
|
+
console.log(`[ESTABLISHED] Fragment 9: ${CryptoEngine.getFragment(9)}`);
|
|
361
|
+
} else {
|
|
362
|
+
console.log('\x1b[31m[-] ACK verification failed.\x1b[0m');
|
|
363
|
+
console.log('\x1b[33m[*] ACK = SHA256(timestamp + CODENAME + "ACK")[0:8].toUpperCase()\x1b[0m');
|
|
364
|
+
}
|
|
365
|
+
} else {
|
|
366
|
+
console.log('[*] Initiate handshake with: rootaccess handshake --syn');
|
|
367
|
+
console.log('[*] This simulates a TCP 3-way handshake.');
|
|
368
|
+
}
|
|
369
|
+
},
|
|
370
|
+
|
|
371
|
+
// Layer 10 - Key Forge system (enhanced)
|
|
372
|
+
forge: (args) => {
|
|
373
|
+
const hintArg = args.find(a => a.startsWith('--hint='));
|
|
374
|
+
const compArg = args.find(a => a.startsWith('--component=') || a.startsWith('-c='));
|
|
375
|
+
const solveArg = args.find(a => a.startsWith('--solve='));
|
|
376
|
+
const verifyArg = args.find(a => a.startsWith('--verify='));
|
|
377
|
+
const finalArg = args.includes('--final');
|
|
378
|
+
|
|
379
|
+
if (hintArg) {
|
|
380
|
+
const level = hintArg.split('=')[1];
|
|
381
|
+
console.log(`\n\x1b[33m[HINT ${level}]\x1b[0m ${KeyForge.getHint(level)}\n`);
|
|
382
|
+
} else if (compArg) {
|
|
383
|
+
const comp = compArg.split('=')[1];
|
|
384
|
+
const result = KeyForge.computeComponent(comp);
|
|
385
|
+
if (result) {
|
|
386
|
+
// Components are now hex-encoded for extra difficulty
|
|
387
|
+
const encoded = Buffer.from(result).toString('hex');
|
|
388
|
+
console.log(`\n\x1b[32m[COMPONENT]\x1b[0m ${comp} = ${encoded} (hex encoded)\n`);
|
|
389
|
+
} else {
|
|
390
|
+
console.log(`\n\x1b[31m[-] Unknown component: ${comp}\x1b[0m`);
|
|
391
|
+
console.log('[*] Available: version, codename, timestamp, xorPair, primes\n');
|
|
392
|
+
}
|
|
393
|
+
} else if (verifyArg) {
|
|
394
|
+
const testKey = verifyArg.split('=')[1];
|
|
395
|
+
if (KeyForge.verifyKey(testKey)) {
|
|
396
|
+
console.log('\n\x1b[32m[✓] KEY VERIFIED! Use this with: rootaccess assemble --key=<YOUR_KEY>\x1b[0m\n');
|
|
397
|
+
} else {
|
|
398
|
+
console.log('\n\x1b[31m[-] Invalid key. Keep forging...\x1b[0m');
|
|
399
|
+
console.log('\x1b[33m[*] Use --hint=6 for the pattern.\x1b[0m\n');
|
|
400
|
+
}
|
|
401
|
+
} else if (finalArg) {
|
|
402
|
+
// Hint for final fragment
|
|
403
|
+
console.log('\n\x1b[35m[FINAL] The last fragment requires the master key.\x1b[0m');
|
|
404
|
+
console.log('[*] Once you have all 9 fragments, forge the key and assemble.\n');
|
|
405
|
+
} else {
|
|
406
|
+
KeyForge.showKeyBuilder();
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
|
|
410
|
+
assemble: (args) => {
|
|
411
|
+
// Final assembly - requires correct forged key
|
|
412
|
+
const keyArg = args.find(a => a.startsWith('--key='));
|
|
413
|
+
const key = keyArg ? keyArg.split('=')[1] : null;
|
|
414
|
+
|
|
415
|
+
if (!key) {
|
|
416
|
+
console.log('\x1b[31m[-] Usage: rootaccess assemble --key=<MASTER_KEY>\x1b[0m');
|
|
417
|
+
console.log('\x1b[33m[*] Use "rootaccess forge" to build the master key.\x1b[0m');
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (KeyForge.verifyKey(key)) {
|
|
422
|
+
console.log('\n\x1b[32m[✓] MASTER KEY ACCEPTED\x1b[0m\n');
|
|
423
|
+
console.log(`[FINAL] Fragment 10: ${CryptoEngine.getFragment(10)}`);
|
|
424
|
+
console.log('');
|
|
425
|
+
const vault = new DataVault();
|
|
426
|
+
vault.assembleFlag();
|
|
427
|
+
} else {
|
|
428
|
+
console.log('\x1b[31m[-] Invalid master key.\x1b[0m');
|
|
429
|
+
console.log('\x1b[33m[*] The key must be forged from 5 components.\x1b[0m');
|
|
430
|
+
console.log('\x1b[33m[*] Try: rootaccess forge --hint=1\x1b[0m');
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
// Main execution
|
|
436
|
+
function main() {
|
|
437
|
+
const args = process.argv.slice(2);
|
|
438
|
+
const command = args[0] || 'help';
|
|
439
|
+
const cmdArgs = args.slice(1);
|
|
440
|
+
|
|
441
|
+
// Show banner for main commands
|
|
442
|
+
if (['help', 'status', 'about'].includes(command) || !command) {
|
|
443
|
+
console.log(banner);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Check for hidden trigger in any arg
|
|
447
|
+
if (args.some(a => a.includes('REVEAL_ALL'))) {
|
|
448
|
+
console.log('\n\x1b[35m[EASTER EGG] You found the master trigger!\x1b[0m');
|
|
449
|
+
console.log(`[MASTER] ${CryptoEngine.getMasterHint()}`);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Execute command
|
|
453
|
+
if (commands[command]) {
|
|
454
|
+
commands[command](cmdArgs);
|
|
455
|
+
} else if (command === '__internal__' || command === 'internal') {
|
|
456
|
+
commands.__internal__(cmdArgs);
|
|
457
|
+
} else if (command === 'shadow') {
|
|
458
|
+
commands.shadow(cmdArgs);
|
|
459
|
+
} else if (command === 'unlock') {
|
|
460
|
+
commands.unlock(cmdArgs);
|
|
461
|
+
} else if (command === 'assemble') {
|
|
462
|
+
commands.assemble(cmdArgs);
|
|
463
|
+
} else {
|
|
464
|
+
console.log(`\x1b[31m[-] Unknown command: ${command}\x1b[0m`);
|
|
465
|
+
console.log(`[*] Run 'rootaccess help' for usage.`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
main();
|
package/lib/crypto.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Crypto Engine - Handles encryption/decryption
|
|
3
|
+
* Multiple fragments hidden here
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const crypto = require('crypto');
|
|
7
|
+
|
|
8
|
+
// Flag is split into 10 encoded fragments
|
|
9
|
+
// Each fragment requires solving a different layer
|
|
10
|
+
|
|
11
|
+
// XOR key for fragment encoding
|
|
12
|
+
const XOR_KEY = 'SHADOWGATE';
|
|
13
|
+
|
|
14
|
+
// Helper to XOR encode/decode
|
|
15
|
+
function xorWithKey(str, key) {
|
|
16
|
+
let result = '';
|
|
17
|
+
for (let i = 0; i < str.length; i++) {
|
|
18
|
+
result += String.fromCharCode(str.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Pre-compute encoded fragments
|
|
24
|
+
function encodeFragment(plain) {
|
|
25
|
+
const xored = xorWithKey(plain, XOR_KEY);
|
|
26
|
+
return Buffer.from(xored, 'binary').toString('base64');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// The actual fragments (10 total for harder challenge)
|
|
30
|
+
// Flag: root{N0d3_Cl1_R3v3rs3_3ng1n33r1ng_M4st3r_0f_Sh4d0ws}
|
|
31
|
+
const PLAIN_FRAGMENTS = {
|
|
32
|
+
1: "root{N0", // Layer 1: Debug env
|
|
33
|
+
2: "d3_Cl1_", // Layer 2: Admin env
|
|
34
|
+
3: "R3v3rs3", // Layer 3: Ultra scan
|
|
35
|
+
4: "_3ng1n3", // Layer 4: Omega-7 server
|
|
36
|
+
5: "3r1ng_", // Layer 5: Chain-dependent decrypt
|
|
37
|
+
6: "M4st3r", // Layer 6: Internal command
|
|
38
|
+
7: "_0f_", // Layer 7: Time-window
|
|
39
|
+
8: "Sh4d", // Layer 8: File creation
|
|
40
|
+
9: "0ws", // Layer 9: Network handshake
|
|
41
|
+
10: "}" // Layer 10: Final forge
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Encoded at module load (for obfuscation in source)
|
|
45
|
+
const ENCODED_FRAGMENTS = {};
|
|
46
|
+
for (let i = 1; i <= 10; i++) {
|
|
47
|
+
ENCODED_FRAGMENTS[i] = encodeFragment(PLAIN_FRAGMENTS[i]);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function xorDecode(encoded, key) {
|
|
51
|
+
const data = Buffer.from(encoded, 'base64').toString('binary');
|
|
52
|
+
let result = '';
|
|
53
|
+
for (let i = 0; i < data.length; i++) {
|
|
54
|
+
result += String.fromCharCode(data.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Generate chain-dependent key from fragments
|
|
60
|
+
function generateChainKey(frag1, frag2) {
|
|
61
|
+
return crypto.createHash('md5').update(frag1 + frag2).digest('hex').slice(0, 8);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Generate handshake token based on timestamp
|
|
65
|
+
function generateHandshakeToken(seed) {
|
|
66
|
+
const base = crypto.createHash('sha256').update(seed + 'SHADOWGATE').digest('hex');
|
|
67
|
+
return base.slice(0, 8).toUpperCase();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
class CryptoEngine {
|
|
71
|
+
constructor() {
|
|
72
|
+
this.algorithm = 'xor-shadow';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static getFragment(num) {
|
|
76
|
+
if (num < 1 || num > 10) return '[INVALID FRAGMENT]';
|
|
77
|
+
|
|
78
|
+
// Decode on the fly
|
|
79
|
+
return xorDecode(ENCODED_FRAGMENTS[num], XOR_KEY);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static getTotalFragments() {
|
|
83
|
+
return 10;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static generateChainKey(frag1, frag2) {
|
|
87
|
+
return generateChainKey(frag1, frag2);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static generateHandshakeToken(seed) {
|
|
91
|
+
return generateHandshakeToken(seed);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
static getMasterHint() {
|
|
95
|
+
return 'Fragments: 1-10 | Assemble with: rootaccess assemble --key=MASTER_KEY';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
encrypt(data) {
|
|
99
|
+
return Buffer.from(data).toString('base64');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
decrypt(data) {
|
|
103
|
+
try {
|
|
104
|
+
return Buffer.from(data, 'base64').toString();
|
|
105
|
+
} catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Hidden method - accessible via prototype inspection
|
|
111
|
+
static __getFullFlag__() {
|
|
112
|
+
const parts = [];
|
|
113
|
+
for (let i = 1; i <= 10; i++) {
|
|
114
|
+
parts.push(xorDecode(ENCODED_FRAGMENTS[i], XOR_KEY));
|
|
115
|
+
}
|
|
116
|
+
return parts.join('');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Hidden in module pattern
|
|
121
|
+
const _internal = {
|
|
122
|
+
key: XOR_KEY,
|
|
123
|
+
hint: 'XOR with SHADOWGATE to decode fragments',
|
|
124
|
+
chainHint: 'Some keys are forged from previous discoveries...'
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
module.exports = { CryptoEngine, _internal };
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core System Module
|
|
3
|
+
* Hidden fragments are scattered throughout
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
// Obfuscated data (not the real flag, just noise)
|
|
10
|
+
const _0x4f3a = [0x72, 0x6f, 0x6f, 0x74, 0x7b];
|
|
11
|
+
const _0xdecoy = 'cm9vdHtOT1RfVEhFX0ZMQUd9'; // Base64 decoy
|
|
12
|
+
|
|
13
|
+
class CoreSystem {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.initialized = true;
|
|
16
|
+
this.modules = ['crypto', 'vault', 'network'];
|
|
17
|
+
// Hidden in constructor
|
|
18
|
+
this._secret = this._initSecret();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
_initSecret() {
|
|
22
|
+
// Fragment hidden in method name pattern
|
|
23
|
+
const m = ['S', 'h', '4', 'd', '0', 'w'];
|
|
24
|
+
return m.join('');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
checkIntegrity() {
|
|
28
|
+
// Looks like integrity check but has hidden data
|
|
29
|
+
const checks = {
|
|
30
|
+
core: true,
|
|
31
|
+
memory: true,
|
|
32
|
+
// Hidden hint
|
|
33
|
+
_hint: 'Environment variables hold secrets...'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Debug output if NODE_ENV is special
|
|
37
|
+
if (process.env.NODE_ENV === 'shadowgate_debug') {
|
|
38
|
+
console.log('\x1b[90m[INTEGRITY] Hidden check passed\x1b[0m');
|
|
39
|
+
console.log('\x1b[90m[INTEGRITY] Try: ROOTACCESS_DEBUG=LAYER_ONE\x1b[0m');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return checks.core && checks.memory;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getModuleInfo(name) {
|
|
46
|
+
const info = {
|
|
47
|
+
crypto: { version: '2.1.0', status: 'active' },
|
|
48
|
+
vault: { version: '1.5.0', status: 'locked' },
|
|
49
|
+
network: { version: '3.0.0', status: 'limited' }
|
|
50
|
+
};
|
|
51
|
+
return info[name] || null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Hidden export with data
|
|
56
|
+
module.exports = {
|
|
57
|
+
CoreSystem,
|
|
58
|
+
// Easter egg in exports
|
|
59
|
+
__hidden__: Buffer.from('TGF5ZXIgMTogRW52aXJvbm1lbnQgdmFyaWFibGVz', 'base64').toString()
|
|
60
|
+
};
|
package/lib/keyforge.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KeyForge Module - Master Key Generation System
|
|
3
|
+
* The master key must be computed, not guessed!
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const crypto = require('crypto');
|
|
7
|
+
|
|
8
|
+
// Key components scattered across the system
|
|
9
|
+
const KEY_COMPONENTS = {
|
|
10
|
+
// Component 1: From version number (1.3.37 -> 1337)
|
|
11
|
+
version: () => {
|
|
12
|
+
const v = '1.3.37'.replace(/\./g, '');
|
|
13
|
+
return v; // "1337"
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
// Component 2: From codename hash (first 4 chars)
|
|
17
|
+
codename: () => {
|
|
18
|
+
const hash = crypto.createHash('md5').update('SHADOWGATE').digest('hex');
|
|
19
|
+
return hash.substring(0, 4).toUpperCase(); // First 4 of MD5
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
// Component 3: Hidden in timestamps (Unix epoch hint)
|
|
23
|
+
timestamp: () => {
|
|
24
|
+
// Jan 1, 2024 00:00:00 UTC = 1704067200
|
|
25
|
+
// Sum of digits
|
|
26
|
+
const ts = '1704067200';
|
|
27
|
+
const sum = ts.split('').reduce((a, b) => a + parseInt(b), 0);
|
|
28
|
+
return sum.toString(16).toUpperCase(); // Hex of sum
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
// Component 4: XOR of "ROOT" and "FLAG"
|
|
32
|
+
xorPair: () => {
|
|
33
|
+
const a = 'ROOT';
|
|
34
|
+
const b = 'FLAG';
|
|
35
|
+
let result = '';
|
|
36
|
+
for (let i = 0; i < 4; i++) {
|
|
37
|
+
result += String.fromCharCode(a.charCodeAt(i) ^ b.charCodeAt(i));
|
|
38
|
+
}
|
|
39
|
+
return Buffer.from(result).toString('hex').toUpperCase().substring(0, 4);
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
// Component 5: Prime number sequence (2,3,5,7,11 -> sum = 28 -> hex)
|
|
43
|
+
primes: () => {
|
|
44
|
+
const primes = [2, 3, 5, 7, 11, 13];
|
|
45
|
+
const product = primes.reduce((a, b) => a + b, 0);
|
|
46
|
+
return product.toString(16).toUpperCase(); // "29" in hex
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// The actual key formula (hidden)
|
|
51
|
+
// KEY = "SHADOW_" + version + "_" + codename + xorPair + "_" + timestamp + primes + "_GATE"
|
|
52
|
+
|
|
53
|
+
class KeyForge {
|
|
54
|
+
constructor() {
|
|
55
|
+
this.components = {};
|
|
56
|
+
this.unlocked = false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Layer 7: Hint system with riddles
|
|
60
|
+
static getHint(level) {
|
|
61
|
+
const hints = {
|
|
62
|
+
1: "The version speaks in leet... 1.3.37 becomes?",
|
|
63
|
+
2: "MD5 of the codename, first 4 characters",
|
|
64
|
+
3: "2024 began at Unix epoch 1704067200. Sum all digits, convert to hex.",
|
|
65
|
+
4: "XOR 'ROOT' with 'FLAG', take first 4 hex chars",
|
|
66
|
+
5: "First 6 primes sum together, then hex",
|
|
67
|
+
6: "Pattern: SHADOW_{v}_{codename}{xor}_{time}{primes}_GATE",
|
|
68
|
+
master: "Combine all components in the sacred pattern..."
|
|
69
|
+
};
|
|
70
|
+
return hints[level] || "Unknown hint level";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Compute a single component
|
|
74
|
+
static computeComponent(name) {
|
|
75
|
+
if (KEY_COMPONENTS[name]) {
|
|
76
|
+
return KEY_COMPONENTS[name]();
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Verify if a key is correct
|
|
82
|
+
static verifyKey(inputKey) {
|
|
83
|
+
const correctKey = KeyForge.generateMasterKey();
|
|
84
|
+
return inputKey === correctKey;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Generate the master key (called internally)
|
|
88
|
+
static generateMasterKey() {
|
|
89
|
+
const v = KEY_COMPONENTS.version();
|
|
90
|
+
const c = KEY_COMPONENTS.codename();
|
|
91
|
+
const x = KEY_COMPONENTS.xorPair();
|
|
92
|
+
const t = KEY_COMPONENTS.timestamp();
|
|
93
|
+
const p = KEY_COMPONENTS.primes();
|
|
94
|
+
|
|
95
|
+
// SHADOW_1337_F080161C_1B29_GATE
|
|
96
|
+
return `SHADOW_${v}_${c}${x}_${t}${p}_GATE`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Interactive key builder (for CLI)
|
|
100
|
+
static showKeyBuilder() {
|
|
101
|
+
console.log('\n\x1b[36m╔════════════════════════════════════════╗\x1b[0m');
|
|
102
|
+
console.log('\x1b[36m║ KEY FORGE - Component Lab ║\x1b[0m');
|
|
103
|
+
console.log('\x1b[36m╚════════════════════════════════════════╝\x1b[0m\n');
|
|
104
|
+
|
|
105
|
+
console.log('The Master Key is forged from 5 components:\n');
|
|
106
|
+
console.log(' [1] VERSION - Derived from version number');
|
|
107
|
+
console.log(' [2] CODENAME - Hash of the codename');
|
|
108
|
+
console.log(' [3] TIMESTAMP - Epoch calculation');
|
|
109
|
+
console.log(' [4] XOR_PAIR - Binary operation result');
|
|
110
|
+
console.log(' [5] PRIMES - Mathematical sequence\n');
|
|
111
|
+
|
|
112
|
+
console.log('\x1b[33mUse: rootaccess forge --component=<name>\x1b[0m');
|
|
113
|
+
console.log('\x1b[33mOr: rootaccess forge --hint=<1-6>\x1b[0m\n');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Riddle-based component revelation
|
|
117
|
+
static solveRiddle(answer) {
|
|
118
|
+
const riddles = {
|
|
119
|
+
'leet': { component: 'version', answer: '1337' },
|
|
120
|
+
'1337': { component: 'version', answer: '1337' },
|
|
121
|
+
'md5': { component: 'codename', answer: KEY_COMPONENTS.codename() },
|
|
122
|
+
'epoch': { component: 'timestamp', answer: KEY_COMPONENTS.timestamp() },
|
|
123
|
+
'xor': { component: 'xorPair', answer: KEY_COMPONENTS.xorPair() },
|
|
124
|
+
'prime': { component: 'primes', answer: KEY_COMPONENTS.primes() },
|
|
125
|
+
'primes': { component: 'primes', answer: KEY_COMPONENTS.primes() },
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const lower = answer.toLowerCase();
|
|
129
|
+
if (riddles[lower]) {
|
|
130
|
+
return riddles[lower];
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Export with some hidden data for reverse engineering
|
|
137
|
+
module.exports = {
|
|
138
|
+
KeyForge,
|
|
139
|
+
// Hidden hints in exports
|
|
140
|
+
_pattern: 'SHADOW_{?}_{??}_{{??}}_GATE',
|
|
141
|
+
_components: Object.keys(KEY_COMPONENTS)
|
|
142
|
+
};
|
package/lib/network.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network Simulation Module
|
|
3
|
+
* Contains hints for Layer 4
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Server list with hidden data
|
|
7
|
+
const SERVERS = {
|
|
8
|
+
'alpha': { status: 'deprecated', port: 8080 },
|
|
9
|
+
'beta': { status: 'offline', port: 8081 },
|
|
10
|
+
'gamma': { status: 'maintenance', port: 8082 },
|
|
11
|
+
// Hidden server
|
|
12
|
+
'omega-7': {
|
|
13
|
+
status: 'classified',
|
|
14
|
+
port: 1337,
|
|
15
|
+
access: 'restricted',
|
|
16
|
+
_data: 'Fragment 4 unlocked via this server'
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// Encoded connection strings
|
|
21
|
+
const CONNECTION_HINTS = {
|
|
22
|
+
primary: 'b21lZ2EtNw==', // omega-7
|
|
23
|
+
secondary: 'U0hBRE9XR0FURV9VTkxPQ0tfMjAyNA==' // SHADOWGATE_UNLOCK_2024
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
class NetworkSim {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.connected = false;
|
|
29
|
+
this.currentServer = null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
listServers() {
|
|
33
|
+
return Object.keys(SERVERS).filter(s => !s.startsWith('omega'));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
connect(serverName) {
|
|
37
|
+
const server = SERVERS[serverName];
|
|
38
|
+
if (server) {
|
|
39
|
+
this.connected = true;
|
|
40
|
+
this.currentServer = serverName;
|
|
41
|
+
return { success: true, server };
|
|
42
|
+
}
|
|
43
|
+
return { success: false, error: 'Server not found' };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Hidden method for reverse engineering
|
|
47
|
+
static getHints() {
|
|
48
|
+
return CONNECTION_HINTS;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Exported with hidden data accessible via inspection
|
|
53
|
+
module.exports = {
|
|
54
|
+
NetworkSim,
|
|
55
|
+
SERVERS,
|
|
56
|
+
_hints: CONNECTION_HINTS
|
|
57
|
+
};
|
package/lib/vault.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Vault - Secure storage simulation
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { CryptoEngine } = require('./crypto.js');
|
|
6
|
+
|
|
7
|
+
// Hidden data in vault
|
|
8
|
+
const REGISTRY_DATA = {
|
|
9
|
+
system: { type: 'config', value: 'default' },
|
|
10
|
+
user: { type: 'config', value: 'guest' },
|
|
11
|
+
// Hidden entry
|
|
12
|
+
_shadow: {
|
|
13
|
+
type: 'encrypted',
|
|
14
|
+
value: 'Vm05aGIyeDBZV3hsTFRjPQ==', // Double base64
|
|
15
|
+
hint: 'base64 x2'
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// Anomaly data for deep scan
|
|
20
|
+
const ANOMALY_DATA = 'RnJhZ21lbnQgMzogcm9vdGFjY2VzcyBzY2FuIC0tdWx0cmE=';
|
|
21
|
+
|
|
22
|
+
class DataVault {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.locked = true;
|
|
25
|
+
this.accessLevel = 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
analyzeRegistry() {
|
|
29
|
+
// Returns hint for Layer 3
|
|
30
|
+
return Buffer.from(ANOMALY_DATA, 'base64').toString();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
unlock(key) {
|
|
34
|
+
if (key === 'SHADOWGATE_VAULT_KEY') {
|
|
35
|
+
this.locked = false;
|
|
36
|
+
this.accessLevel = 10;
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
assembleFlag() {
|
|
43
|
+
console.log('\x1b[36m[*] Assembling fragments...\x1b[0m\n');
|
|
44
|
+
|
|
45
|
+
const fragments = [];
|
|
46
|
+
const totalFragments = CryptoEngine.getTotalFragments();
|
|
47
|
+
|
|
48
|
+
for (let i = 1; i <= totalFragments; i++) {
|
|
49
|
+
const frag = CryptoEngine.getFragment(i);
|
|
50
|
+
fragments.push(frag);
|
|
51
|
+
console.log(` Fragment ${i.toString().padStart(2, '0')}: ${frag}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const flag = fragments.join('');
|
|
55
|
+
console.log('\n' + '═'.repeat(60));
|
|
56
|
+
console.log(`\x1b[32m[✓] FLAG: ${flag}\x1b[0m`);
|
|
57
|
+
console.log('═'.repeat(60));
|
|
58
|
+
|
|
59
|
+
// Verify using hash
|
|
60
|
+
const crypto = require('crypto');
|
|
61
|
+
const hash = crypto.createHash('sha256').update(flag).digest('hex');
|
|
62
|
+
|
|
63
|
+
if (flag.startsWith('root{') && flag.endsWith('}')) {
|
|
64
|
+
console.log('\n\x1b[32m[✓] Flag verified successfully!\x1b[0m');
|
|
65
|
+
console.log(`\x1b[90m[*] SHA256: ${hash}\x1b[0m`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Hidden method
|
|
70
|
+
getSecretEntry() {
|
|
71
|
+
const double = REGISTRY_DATA._shadow.value;
|
|
72
|
+
const first = Buffer.from(double, 'base64').toString();
|
|
73
|
+
const second = Buffer.from(first, 'base64').toString();
|
|
74
|
+
return second; // "omega-7"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = { DataVault, REGISTRY_DATA };
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "root-access",
|
|
3
|
+
"version": "1.3.38",
|
|
4
|
+
"description": "🔐 A mysterious CLI tool. Can you find what's hidden within?",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"rootaccess": "./bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node bin/cli.js",
|
|
11
|
+
"test": "node bin/cli.js --help"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"ctf",
|
|
15
|
+
"security",
|
|
16
|
+
"challenge",
|
|
17
|
+
"puzzle",
|
|
18
|
+
"hacking",
|
|
19
|
+
"reverse-engineering"
|
|
20
|
+
],
|
|
21
|
+
"author": "Uttam Mahata",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/Uttam-Mahata/rootaccess"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/Uttam-Mahata/rootaccess#readme",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=14.0.0"
|
|
30
|
+
}
|
|
31
|
+
}
|