rtexit-method 0.1.13 → 0.1.15
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/package.json +55 -55
- package/packaged-assets/.agents/skills/rt-android-intent-exploitation/SKILL.md +251 -0
- package/packaged-assets/.agents/skills/rt-apk-repackaging/SKILL.md +270 -0
- package/packaged-assets/.agents/skills/rt-cross-platform-mobile/SKILL.md +290 -0
- package/packaged-assets/.agents/skills/rt-frida-advanced/SKILL.md +355 -0
- package/packaged-assets/.agents/skills/rt-mobile-malware-c2/SKILL.md +265 -0
- package/packaged-assets/.agents/skills/rt-mobile-ssl-pinning/SKILL.md +338 -0
- package/packaged-assets/.agents/skills/rt-mobile-static-deep/SKILL.md +262 -0
- package/tools/installer/commands/install.js +4 -2
- package/tools/installer/lib/asset-manifest.js +6 -1
- package/tools/installer/lib/copy-assets.js +8 -8
- package/tools/installer/lib/profiles.js +250 -0
- package/tools/installer/lib/prompts.js +18 -1
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-mobile-static-deep
|
|
3
|
+
description: "Deep static analysis of mobile apps — MobSF automated scanning, manual jadx source review, secret scanning (API keys, tokens, hardcoded creds), native library analysis (.so files with Ghidra/radare2), third-party SDK vulnerability hunting, obfuscation bypass, APK/IPA binary analysis. Foundation of every mobile pentest before dynamic testing."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
> 🐳 **Docker Environment (Recommended):** `docker exec -it rtexit-kali bash`
|
|
7
|
+
|
|
8
|
+
# rt-mobile-static-deep — Mobile App Static Analysis
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Static analysis reveals hardcoded secrets, insecure code patterns, weak cryptography, and attack surfaces before running a single line of code. Should be the FIRST step in any mobile pentest.
|
|
13
|
+
|
|
14
|
+
**What you find:**
|
|
15
|
+
- Hardcoded API keys, tokens, passwords
|
|
16
|
+
- Backend endpoints and internal hostnames
|
|
17
|
+
- Cryptographic weaknesses
|
|
18
|
+
- Exported components and deep links
|
|
19
|
+
- Third-party SDK vulnerabilities
|
|
20
|
+
- Native library vulnerabilities
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Phase 1: MobSF — Automated Full Scan
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
docker exec rtexit-kali bash -c "
|
|
28
|
+
# Run MobSF Docker (fastest setup)
|
|
29
|
+
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
|
|
30
|
+
|
|
31
|
+
# Upload APK/IPA via browser: http://localhost:8000
|
|
32
|
+
# Or via API:
|
|
33
|
+
curl -s 'http://localhost:8000/api/v1/upload' \
|
|
34
|
+
-H 'Authorization: YOUR_API_KEY' \
|
|
35
|
+
-F 'file=@target.apk' > /tmp/upload.json
|
|
36
|
+
|
|
37
|
+
SCAN_HASH=\$(cat /tmp/upload.json | python3 -c \"import json,sys; print(json.load(sys.stdin)['hash'])\")
|
|
38
|
+
|
|
39
|
+
# Run scan
|
|
40
|
+
curl -s 'http://localhost:8000/api/v1/scan' \
|
|
41
|
+
-H 'Authorization: YOUR_API_KEY' \
|
|
42
|
+
-d \"scan_type=apk&file_name=target.apk&hash=\${SCAN_HASH}\"
|
|
43
|
+
|
|
44
|
+
# Get JSON report
|
|
45
|
+
curl -s \"http://localhost:8000/api/v1/report_json\" \
|
|
46
|
+
-H 'Authorization: YOUR_API_KEY' \
|
|
47
|
+
-d \"hash=\${SCAN_HASH}\" > /tmp/mobsf_report.json
|
|
48
|
+
|
|
49
|
+
# Extract key findings
|
|
50
|
+
python3 -c \"
|
|
51
|
+
import json
|
|
52
|
+
r = json.load(open('/tmp/mobsf_report.json'))
|
|
53
|
+
print('=== Hardcoded Secrets ===')
|
|
54
|
+
for s in r.get('secrets', []): print(' -', s)
|
|
55
|
+
print('=== URLs ===')
|
|
56
|
+
for u in r.get('urls', []): print(' -', u['url'])
|
|
57
|
+
print('=== HIGH findings ===')
|
|
58
|
+
for k, v in r.get('code_analysis', {}).get('findings', {}).items():
|
|
59
|
+
if v.get('level') == 'high': print(' -', k, ':', v.get('cvss'))
|
|
60
|
+
\"
|
|
61
|
+
"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Phase 2: Secret Scanning
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
docker exec rtexit-kali bash -c "
|
|
70
|
+
# Decompile APK
|
|
71
|
+
apktool d target.apk -o /tmp/target_dc
|
|
72
|
+
jadx -d /tmp/target_java target.apk 2>/dev/null
|
|
73
|
+
|
|
74
|
+
# Comprehensive secret scan
|
|
75
|
+
# Tool: trufflehog
|
|
76
|
+
pip3 install trufflehog3 2>/dev/null
|
|
77
|
+
trufflehog filesystem /tmp/target_java/ --json > /tmp/secrets.json
|
|
78
|
+
cat /tmp/secrets.json | python3 -m json.tool | grep -A3 'reason\|stringsFound'
|
|
79
|
+
|
|
80
|
+
# Manual grep patterns
|
|
81
|
+
echo '=== API Keys ==='
|
|
82
|
+
grep -rE '(api[_-]?key|apikey)\s*[=:]\s*[\"'\'']\w{20,}' /tmp/target_java/ -i
|
|
83
|
+
echo '=== AWS Keys ==='
|
|
84
|
+
grep -rE 'AKIA[0-9A-Z]{16}' /tmp/target_java/
|
|
85
|
+
echo '=== JWT Tokens ==='
|
|
86
|
+
grep -rE 'eyJ[A-Za-z0-9+/=]{10,}\.[A-Za-z0-9+/=]{10,}' /tmp/target_java/
|
|
87
|
+
echo '=== Hardcoded passwords ==='
|
|
88
|
+
grep -rE '(password|passwd|pwd)\s*[=:]\s*[\"'\'']\w{4,}' /tmp/target_java/ -i
|
|
89
|
+
echo '=== Private keys ==='
|
|
90
|
+
grep -r 'BEGIN.*PRIVATE KEY\|BEGIN RSA\|BEGIN EC' /tmp/target_java/ -l
|
|
91
|
+
echo '=== Firebase URLs ==='
|
|
92
|
+
grep -rE 'firebaseio\.com|firebase\.google\.com' /tmp/target_java/
|
|
93
|
+
echo '=== Google Maps API Key ==='
|
|
94
|
+
grep -rE 'AIza[0-9A-Za-z-_]{35}' /tmp/target_java/
|
|
95
|
+
"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Phase 3: Endpoint Discovery
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
docker exec rtexit-kali bash -c "
|
|
104
|
+
# Extract all URLs and endpoints from source
|
|
105
|
+
echo '=== HTTPS Endpoints ==='
|
|
106
|
+
grep -rEoh 'https?://[^\"'\'')\s]{10,}' /tmp/target_java/ | sort -u | grep -v 'schema\|xmlns\|android\|google.com/design'
|
|
107
|
+
|
|
108
|
+
echo '=== API Base URLs ==='
|
|
109
|
+
grep -rEi 'base_?url|api_?url|endpoint|host_?url' /tmp/target_java/ | grep -oE '\"[^\"]*\"' | sort -u
|
|
110
|
+
|
|
111
|
+
echo '=== IP Addresses ==='
|
|
112
|
+
grep -rEoh '\b([0-9]{1,3}\.){3}[0-9]{1,3}(:[0-9]+)?\b' /tmp/target_java/ | grep -v '0\.0\.0\|127\.0\.0\|255\.255' | sort -u
|
|
113
|
+
|
|
114
|
+
echo '=== WebSocket URLs ==='
|
|
115
|
+
grep -rEoh 'wss?://[^\"'\'')\s]+' /tmp/target_java/ | sort -u
|
|
116
|
+
"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Phase 4: AndroidManifest Deep Analysis
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
docker exec rtexit-kali bash -c "
|
|
125
|
+
MANIFEST=/tmp/target_dc/AndroidManifest.xml
|
|
126
|
+
|
|
127
|
+
echo '=== Package + Permissions ==='
|
|
128
|
+
grep 'package\|uses-permission' \$MANIFEST | sort
|
|
129
|
+
|
|
130
|
+
echo '=== DANGEROUS permissions ==='
|
|
131
|
+
grep 'uses-permission' \$MANIFEST | grep -iE 'READ_SMS|READ_CONTACTS|READ_CALL_LOG|CAMERA|RECORD_AUDIO|ACCESS_FINE_LOCATION|PROCESS_OUTGOING_CALLS|BIND_ACCESSIBILITY'
|
|
132
|
+
|
|
133
|
+
echo '=== Exported components (attack surface) ==='
|
|
134
|
+
grep -E 'activity|service|receiver|provider' \$MANIFEST | grep 'exported=\"true\"'
|
|
135
|
+
|
|
136
|
+
echo '=== Deep links / intent filters ==='
|
|
137
|
+
grep -A5 'intent-filter' \$MANIFEST | grep -E 'scheme|host|path'
|
|
138
|
+
|
|
139
|
+
echo '=== Debuggable flag ==='
|
|
140
|
+
grep 'debuggable' \$MANIFEST
|
|
141
|
+
|
|
142
|
+
echo '=== Backup flag ==='
|
|
143
|
+
grep 'allowBackup' \$MANIFEST
|
|
144
|
+
|
|
145
|
+
echo '=== Network security config ==='
|
|
146
|
+
grep 'networkSecurityConfig' \$MANIFEST
|
|
147
|
+
"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Phase 5: Native Library Analysis
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
docker exec rtexit-kali bash -c "
|
|
156
|
+
# Extract and analyze .so files
|
|
157
|
+
unzip target.apk 'lib/arm64-v8a/*.so' -d /tmp/libs/
|
|
158
|
+
ls /tmp/libs/lib/arm64-v8a/
|
|
159
|
+
|
|
160
|
+
# Quick strings analysis on each .so
|
|
161
|
+
for lib in /tmp/libs/lib/arm64-v8a/*.so; do
|
|
162
|
+
echo \"=== \$lib ===\"
|
|
163
|
+
strings \"\$lib\" | grep -iE 'password|secret|api[_-]?key|token|http|base64|des|aes|rsa' | head -20
|
|
164
|
+
done
|
|
165
|
+
|
|
166
|
+
# Check for known vulnerable native libraries
|
|
167
|
+
strings /tmp/libs/lib/arm64-v8a/*.so | grep -E 'OpenSSL|libcurl' | head -5
|
|
168
|
+
# Look up CVEs for the versions found
|
|
169
|
+
|
|
170
|
+
# Deeper analysis with radare2
|
|
171
|
+
r2 /tmp/libs/lib/arm64-v8a/libapp.so
|
|
172
|
+
# In r2:
|
|
173
|
+
# aaa → analyze all
|
|
174
|
+
# afl → list all functions
|
|
175
|
+
# pdf @sym.verify_pin → disassemble specific function
|
|
176
|
+
"
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Phase 6: Cryptographic Analysis
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
docker exec rtexit-kali bash -c "
|
|
185
|
+
# Find cryptographic usage patterns in source
|
|
186
|
+
echo '=== Weak algorithms ==='
|
|
187
|
+
grep -rE 'DES[^3]|MD5|SHA1[^_]|RC4|ECB' /tmp/target_java/ -i | grep -v '//\|test\|Test'
|
|
188
|
+
|
|
189
|
+
echo '=== Hardcoded IV / Keys ==='
|
|
190
|
+
grep -rE 'IvParameterSpec|SecretKeySpec' /tmp/target_java/ -A2 | grep -E 'new byte\[\]|getBytes'
|
|
191
|
+
|
|
192
|
+
echo '=== Insecure random ==='
|
|
193
|
+
grep -rE 'new Random\(\)|Math\.random' /tmp/target_java/ | grep -v 'SecureRandom'
|
|
194
|
+
|
|
195
|
+
echo '=== Keystore usage (secure vs insecure) ==='
|
|
196
|
+
grep -rE 'KeyStore|AndroidKeyStore|KeyGenerator' /tmp/target_java/ -l
|
|
197
|
+
# If NOT using AndroidKeyStore → keys stored insecurely
|
|
198
|
+
"
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Phase 7: Third-Party SDK Vulnerability Check
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
docker exec rtexit-kali bash -c "
|
|
207
|
+
# Extract all third-party SDKs/libraries
|
|
208
|
+
grep -r 'implementation\|compile' /tmp/target_java/ 2>/dev/null | grep -oE \"'[^']+:[^']+:[^']+'\"|sort -u
|
|
209
|
+
|
|
210
|
+
# Check for known vulnerable SDKs from strings in APK
|
|
211
|
+
strings /tmp/target_apk/classes*.dex | grep -E 'com\.(facebook|google|firebase|amazonaws|stripe|braintree|okhttp|retrofit)' | sort -u | head -30
|
|
212
|
+
|
|
213
|
+
# Check OkHttp version (critical — many CVEs)
|
|
214
|
+
grep -r 'okhttp' /tmp/target_java/ | grep -oE 'okhttp:[0-9]+\.[0-9]+\.[0-9]+' | sort -u
|
|
215
|
+
"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## iOS Static Analysis
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
docker exec rtexit-kali bash -c "
|
|
224
|
+
# Extract IPA
|
|
225
|
+
unzip target.ipa -d /tmp/ipa_extracted/
|
|
226
|
+
APP_DIR=\$(find /tmp/ipa_extracted/Payload -name '*.app' -type d)
|
|
227
|
+
|
|
228
|
+
# Binary analysis
|
|
229
|
+
file \$APP_DIR/TargetApp
|
|
230
|
+
# Check: encryption, architecture
|
|
231
|
+
|
|
232
|
+
# Strings
|
|
233
|
+
strings \$APP_DIR/TargetApp | grep -iE 'api[_-]?key|secret|password|http|token' | head -50
|
|
234
|
+
|
|
235
|
+
# class-dump (get all Obj-C class declarations)
|
|
236
|
+
class-dump \$APP_DIR/TargetApp > /tmp/classes.h
|
|
237
|
+
grep -i 'password\|token\|pin\|secret\|auth' /tmp/classes.h | head -30
|
|
238
|
+
|
|
239
|
+
# Check Info.plist (often has API keys, URLs)
|
|
240
|
+
plutil -p \$APP_DIR/Info.plist 2>/dev/null || python3 -c \"
|
|
241
|
+
import plistlib
|
|
242
|
+
with open('\$APP_DIR/Info.plist', 'rb') as f:
|
|
243
|
+
plist = plistlib.load(f)
|
|
244
|
+
for k, v in plist.items():
|
|
245
|
+
if any(x in k.lower() for x in ['key', 'secret', 'token', 'url', 'api']):
|
|
246
|
+
print(k, '=', v)
|
|
247
|
+
\"
|
|
248
|
+
"
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Related Skills
|
|
254
|
+
- `rt-exploit-android` — dynamic testing following static findings
|
|
255
|
+
- `rt-exploit-ios` — iOS dynamic testing
|
|
256
|
+
- `rt-frida-advanced` — confirm static findings at runtime
|
|
257
|
+
- `rt-android-intent-exploitation` — exploit exported components found in manifest
|
|
258
|
+
|
|
259
|
+
## References
|
|
260
|
+
- https://github.com/MobSF/Mobile-Security-Framework-MobSF
|
|
261
|
+
- https://owasp.org/www-project-mobile-application-security-design-guide/
|
|
262
|
+
- https://attack.mitre.org/techniques/T1418/ — Software Discovery
|
|
@@ -3,6 +3,7 @@ const { resolveRepoRoot, resolveTargetRoot } = require('../lib/paths');
|
|
|
3
3
|
const { copyPackagedAssets } = require('../lib/copy-assets');
|
|
4
4
|
const { writeUserConfig } = require('../lib/write-config');
|
|
5
5
|
const { askInstallQuestions } = require('../lib/prompts');
|
|
6
|
+
const { resolveSkillSet } = require('../lib/profiles');
|
|
6
7
|
|
|
7
8
|
async function installCommand(options = {}) {
|
|
8
9
|
const repoRoot = options.repoRoot || resolveRepoRoot();
|
|
@@ -21,7 +22,8 @@ async function installCommand(options = {}) {
|
|
|
21
22
|
const targetRoot = resolveTargetRoot(answers.targetDirectory);
|
|
22
23
|
|
|
23
24
|
const ides = answers.ides && answers.ides.length ? answers.ides : ['agents'];
|
|
24
|
-
|
|
25
|
+
const allowedSkills = resolveSkillSet(answers.profiles || ['all']);
|
|
26
|
+
await copyPackagedAssets({ repoRoot, targetRoot, ides, allowedSkills });
|
|
25
27
|
await writeUserConfig({
|
|
26
28
|
targetRoot,
|
|
27
29
|
answers: {
|
|
@@ -36,7 +38,7 @@ async function installCommand(options = {}) {
|
|
|
36
38
|
});
|
|
37
39
|
|
|
38
40
|
io.log('RTExit installed successfully.');
|
|
39
|
-
io.log(`Skills installed into
|
|
41
|
+
io.log(`Skills installed: ${allowedSkills.size} skills into ${ideFolders.join(', ')}`);
|
|
40
42
|
io.log('Next steps:');
|
|
41
43
|
io.log('1. Open _rtexit/config.user.toml and complete client/project details');
|
|
42
44
|
io.log('2. Open your AI IDE in this project');
|
|
@@ -5,12 +5,17 @@ const IDE_SKILL_FOLDERS = {
|
|
|
5
5
|
codex: '.codex/skills',
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* @param {string[]} ides
|
|
10
|
+
* @param {Set<string>|null} allowedSkills — if null, install everything
|
|
11
|
+
*/
|
|
12
|
+
function getInstallEntries(ides = ['agents'], allowedSkills = null) {
|
|
9
13
|
const skillEntries = ides.map((ide) => ({
|
|
10
14
|
type: 'glob-dir-prefix',
|
|
11
15
|
base: 'packaged-assets/.agents/skills',
|
|
12
16
|
targetBase: IDE_SKILL_FOLDERS[ide] || `.${ide}/skills`,
|
|
13
17
|
prefix: 'rt-',
|
|
18
|
+
allowedSkills,
|
|
14
19
|
}));
|
|
15
20
|
|
|
16
21
|
return [
|
|
@@ -17,8 +17,8 @@ function copyRecursive(source, target) {
|
|
|
17
17
|
fs.copyFileSync(source, target);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
async function copyPackagedAssets({ repoRoot, targetRoot, ides }) {
|
|
21
|
-
for (const entry of getInstallEntries(ides)) {
|
|
20
|
+
async function copyPackagedAssets({ repoRoot, targetRoot, ides, allowedSkills = null }) {
|
|
21
|
+
for (const entry of getInstallEntries(ides, allowedSkills)) {
|
|
22
22
|
if (entry.type === 'path') {
|
|
23
23
|
const sourcePath = path.join(repoRoot, entry.value);
|
|
24
24
|
const targetPath = path.join(targetRoot, entry.target || entry.value);
|
|
@@ -29,12 +29,12 @@ async function copyPackagedAssets({ repoRoot, targetRoot, ides }) {
|
|
|
29
29
|
const skillsRoot = path.join(repoRoot, entry.base);
|
|
30
30
|
const targetBase = entry.targetBase || entry.base;
|
|
31
31
|
for (const name of fs.readdirSync(skillsRoot)) {
|
|
32
|
-
if (name.startsWith(entry.prefix))
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
)
|
|
37
|
-
|
|
32
|
+
if (!name.startsWith(entry.prefix)) continue;
|
|
33
|
+
if (entry.allowedSkills && !entry.allowedSkills.has(name)) continue;
|
|
34
|
+
copyRecursive(
|
|
35
|
+
path.join(skillsRoot, name),
|
|
36
|
+
path.join(targetRoot, targetBase, name)
|
|
37
|
+
);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Install profiles — each profile maps to a set of skill folder names.
|
|
3
|
+
* Skills in CORE are always installed regardless of profile selection.
|
|
4
|
+
* Users pick one or more profiles; they get CORE + selected profiles.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const CORE = [
|
|
8
|
+
// Agents
|
|
9
|
+
'rt-agent-breaker',
|
|
10
|
+
'rt-agent-commander',
|
|
11
|
+
'rt-agent-ghost',
|
|
12
|
+
'rt-agent-navigator',
|
|
13
|
+
'rt-agent-phantom',
|
|
14
|
+
'rt-agent-scout',
|
|
15
|
+
'rt-agent-scribe',
|
|
16
|
+
// Base methodology
|
|
17
|
+
'rt-help',
|
|
18
|
+
'rt-status',
|
|
19
|
+
'rt-party-mode',
|
|
20
|
+
'rt-scope-definition',
|
|
21
|
+
'rt-rules-of-engagement',
|
|
22
|
+
'rt-methodology-selector',
|
|
23
|
+
// Recon & mapping
|
|
24
|
+
'rt-active-recon',
|
|
25
|
+
'rt-osint',
|
|
26
|
+
'rt-shodan-recon',
|
|
27
|
+
'rt-attack-surface-map',
|
|
28
|
+
'rt-subdomain-enum',
|
|
29
|
+
'rt-subdomain-takeover',
|
|
30
|
+
'rt-wordlist-generation',
|
|
31
|
+
'rt-password-spray',
|
|
32
|
+
// Infrastructure
|
|
33
|
+
'rt-c2-operations',
|
|
34
|
+
'rt-redteam-infra',
|
|
35
|
+
// Core execution
|
|
36
|
+
'rt-defense-evasion',
|
|
37
|
+
'rt-lateral-movement',
|
|
38
|
+
'rt-persistence',
|
|
39
|
+
'rt-post-exploitation',
|
|
40
|
+
'rt-privilege-escalation',
|
|
41
|
+
'rt-credential-access',
|
|
42
|
+
'rt-credential-hunt',
|
|
43
|
+
'rt-lsass-dumping',
|
|
44
|
+
'rt-data-exfiltration',
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const PROFILES = {
|
|
48
|
+
web: {
|
|
49
|
+
label: 'Web & API',
|
|
50
|
+
description: 'Web apps, APIs, injection, auth, OWASP Top 10',
|
|
51
|
+
skills: [
|
|
52
|
+
'rt-exploit-web',
|
|
53
|
+
'rt-exploit-injection',
|
|
54
|
+
'rt-exploit-xss',
|
|
55
|
+
'rt-exploit-ssrf',
|
|
56
|
+
'rt-exploit-auth',
|
|
57
|
+
'rt-exploit-idor',
|
|
58
|
+
'rt-exploit-api',
|
|
59
|
+
'rt-exploit-jwt',
|
|
60
|
+
'rt-exploit-file-upload',
|
|
61
|
+
'rt-cors-csrf',
|
|
62
|
+
'rt-clickjacking',
|
|
63
|
+
'rt-dom-attacks',
|
|
64
|
+
'rt-cache-attacks',
|
|
65
|
+
'rt-business-logic',
|
|
66
|
+
'rt-race-conditions',
|
|
67
|
+
'rt-request-smuggling',
|
|
68
|
+
'rt-path-traversal',
|
|
69
|
+
'rt-deserialization',
|
|
70
|
+
'rt-prototype-pollution',
|
|
71
|
+
'rt-http-parameter-pollution',
|
|
72
|
+
'rt-ldap-xpath-injection',
|
|
73
|
+
'rt-xxe',
|
|
74
|
+
'rt-oauth-oidc',
|
|
75
|
+
'rt-websockets-grpc',
|
|
76
|
+
'rt-js-analysis',
|
|
77
|
+
'rt-browser-exploitation',
|
|
78
|
+
'rt-exploit-wordpress',
|
|
79
|
+
'rt-exploit-nodejs',
|
|
80
|
+
'rt-exploit-php',
|
|
81
|
+
'rt-exploit-python',
|
|
82
|
+
'rt-exploit-java',
|
|
83
|
+
'rt-exploit-dotnet',
|
|
84
|
+
'rt-exploit-ruby',
|
|
85
|
+
'rt-exploit-frameworks',
|
|
86
|
+
'rt-exploit-electron',
|
|
87
|
+
'rt-exploit-firebase',
|
|
88
|
+
'rt-supabase',
|
|
89
|
+
'rt-exploit-osticket',
|
|
90
|
+
'rt-exploit-bec',
|
|
91
|
+
'rt-serverless',
|
|
92
|
+
'rt-exploit-elasticsearch',
|
|
93
|
+
'rt-exploit-databases',
|
|
94
|
+
'rt-exploit-mongodb',
|
|
95
|
+
'rt-exploit-mssql',
|
|
96
|
+
'rt-exploit-mysql',
|
|
97
|
+
'rt-exploit-postgresql',
|
|
98
|
+
'rt-exploit-redis',
|
|
99
|
+
'rt-ai-llm-security',
|
|
100
|
+
'rt-crypto-attacks',
|
|
101
|
+
'rt-exploit-fuzzing',
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
mobile: {
|
|
106
|
+
label: 'Mobile',
|
|
107
|
+
description: 'Android, iOS, BLE, Frida, SSL bypass, cross-platform, C2',
|
|
108
|
+
skills: [
|
|
109
|
+
// Core mobile
|
|
110
|
+
'rt-exploit-android',
|
|
111
|
+
'rt-exploit-ios',
|
|
112
|
+
'rt-bluetooth-ble',
|
|
113
|
+
// Advanced mobile (new)
|
|
114
|
+
'rt-frida-advanced',
|
|
115
|
+
'rt-mobile-ssl-pinning',
|
|
116
|
+
'rt-apk-repackaging',
|
|
117
|
+
'rt-android-intent-exploitation',
|
|
118
|
+
'rt-cross-platform-mobile',
|
|
119
|
+
'rt-mobile-malware-c2',
|
|
120
|
+
'rt-mobile-static-deep',
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
cloud: {
|
|
125
|
+
label: 'Cloud',
|
|
126
|
+
description: 'AWS, Azure, GCP, Kubernetes, containers',
|
|
127
|
+
skills: [
|
|
128
|
+
'rt-exploit-cloud-aws',
|
|
129
|
+
'rt-exploit-cloud-azure',
|
|
130
|
+
'rt-exploit-cloud-gcp',
|
|
131
|
+
'rt-kubernetes',
|
|
132
|
+
'rt-exploit-containers',
|
|
133
|
+
'rt-serverless',
|
|
134
|
+
'rt-supply-chain',
|
|
135
|
+
'rt-exploit-firebase',
|
|
136
|
+
'rt-supabase',
|
|
137
|
+
'rt-exploit-elasticsearch',
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
ad: {
|
|
142
|
+
label: 'Active Directory & Windows',
|
|
143
|
+
description: 'AD, ADCS, Kerberos, lateral movement, EDR bypass, APT techniques',
|
|
144
|
+
skills: [
|
|
145
|
+
'rt-exploit-active-directory',
|
|
146
|
+
'rt-exploit-adcs',
|
|
147
|
+
'rt-adcs-esc9-13',
|
|
148
|
+
'rt-adfs',
|
|
149
|
+
'rt-azure-ad',
|
|
150
|
+
'rt-exchange-sharepoint',
|
|
151
|
+
'rt-exploit-desktop-win',
|
|
152
|
+
'rt-exploit-desktop-mac',
|
|
153
|
+
'rt-printer-attacks',
|
|
154
|
+
'rt-network-segmentation',
|
|
155
|
+
'rt-exploit-network',
|
|
156
|
+
'rt-ssl-mitm',
|
|
157
|
+
'rt-citrix-vdi',
|
|
158
|
+
// Nation-state / APT
|
|
159
|
+
'rt-kerberos-relay',
|
|
160
|
+
'rt-diamond-sapphire-tickets',
|
|
161
|
+
'rt-zerologon',
|
|
162
|
+
'rt-printnightmare-rce',
|
|
163
|
+
'rt-golden-saml',
|
|
164
|
+
'rt-skeleton-key',
|
|
165
|
+
'rt-syscall-bypass',
|
|
166
|
+
'rt-etw-bypass',
|
|
167
|
+
'rt-process-injection-advanced',
|
|
168
|
+
'rt-ppid-spoofing',
|
|
169
|
+
'rt-beacon-sleep-masking',
|
|
170
|
+
'rt-clm-jea-escape',
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
reporting: {
|
|
175
|
+
label: 'Reporting & Documentation',
|
|
176
|
+
description: 'Reports, findings, CVSS, MITRE, scenarios, compliance',
|
|
177
|
+
skills: [
|
|
178
|
+
'rt-technical-report',
|
|
179
|
+
'rt-executive-report',
|
|
180
|
+
'rt-finding-document',
|
|
181
|
+
'rt-finding-tracker',
|
|
182
|
+
'rt-autodoc',
|
|
183
|
+
'rt-create-sead',
|
|
184
|
+
'rt-evidence-chain',
|
|
185
|
+
'rt-compliance-mapper',
|
|
186
|
+
'rt-cvss-calculator',
|
|
187
|
+
'rt-poc-writer',
|
|
188
|
+
'rt-risk-matrix',
|
|
189
|
+
'rt-mitre-map',
|
|
190
|
+
'rt-kill-chain-map',
|
|
191
|
+
'rt-remediation-roadmap',
|
|
192
|
+
'rt-attack-chain-builder',
|
|
193
|
+
'rt-timeline',
|
|
194
|
+
'rt-threat-model',
|
|
195
|
+
'rt-scenario-library',
|
|
196
|
+
'rt-scenario-c001', 'rt-scenario-c002', 'rt-scenario-c003', 'rt-scenario-c004', 'rt-scenario-c005',
|
|
197
|
+
'rt-scenario-d001', 'rt-scenario-d002', 'rt-scenario-d003', 'rt-scenario-d004', 'rt-scenario-d005',
|
|
198
|
+
'rt-scenario-m001', 'rt-scenario-m002', 'rt-scenario-m003', 'rt-scenario-m004', 'rt-scenario-m005',
|
|
199
|
+
'rt-scenario-n001', 'rt-scenario-n002', 'rt-scenario-n003', 'rt-scenario-n004', 'rt-scenario-n005',
|
|
200
|
+
'rt-scenario-w001', 'rt-scenario-w002', 'rt-scenario-w003', 'rt-scenario-w004', 'rt-scenario-w005',
|
|
201
|
+
'rt-scenario-w006', 'rt-scenario-w007', 'rt-scenario-w008', 'rt-scenario-w009', 'rt-scenario-w010',
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
specialist: {
|
|
206
|
+
label: 'Specialist',
|
|
207
|
+
description: 'SCADA/ICS, IoT, hardware, physical, social engineering, wireless',
|
|
208
|
+
skills: [
|
|
209
|
+
'rt-exploit-scada',
|
|
210
|
+
'rt-exploit-iot',
|
|
211
|
+
'rt-hardware-hacking',
|
|
212
|
+
'rt-exploit-wireless',
|
|
213
|
+
'rt-wireless-rogue-ap',
|
|
214
|
+
'rt-exploit-physical',
|
|
215
|
+
'rt-exploit-phishing',
|
|
216
|
+
'rt-exploit-vishing',
|
|
217
|
+
'rt-social-engineering',
|
|
218
|
+
'rt-voip-sip',
|
|
219
|
+
'rt-traffic-analysis',
|
|
220
|
+
'rt-binary-reverse-engineering',
|
|
221
|
+
'rt-sap-exploitation',
|
|
222
|
+
'rt-steganography',
|
|
223
|
+
],
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Resolve the full set of skill folder names to install.
|
|
229
|
+
* @param {string[]|'all'} selectedProfiles — array of profile keys or 'all'
|
|
230
|
+
* @returns {Set<string>} — set of skill folder names
|
|
231
|
+
*/
|
|
232
|
+
function resolveSkillSet(selectedProfiles) {
|
|
233
|
+
if (selectedProfiles === 'all' || (Array.isArray(selectedProfiles) && selectedProfiles.includes('all'))) {
|
|
234
|
+
const all = new Set(CORE);
|
|
235
|
+
for (const profile of Object.values(PROFILES)) {
|
|
236
|
+
for (const s of profile.skills) all.add(s);
|
|
237
|
+
}
|
|
238
|
+
return all;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const result = new Set(CORE);
|
|
242
|
+
for (const key of selectedProfiles) {
|
|
243
|
+
if (PROFILES[key]) {
|
|
244
|
+
for (const s of PROFILES[key].skills) result.add(s);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
module.exports = { PROFILES, CORE, resolveSkillSet };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const prompts = require('@clack/prompts');
|
|
2
|
+
const { PROFILES } = require('./profiles');
|
|
2
3
|
|
|
3
4
|
async function askInstallQuestions({ cwd }) {
|
|
4
5
|
const targetDirectory = await prompts.text({
|
|
@@ -34,12 +35,28 @@ async function askInstallQuestions({ cwd }) {
|
|
|
34
35
|
required: true,
|
|
35
36
|
});
|
|
36
37
|
|
|
38
|
+
const profileOptions = [
|
|
39
|
+
{ value: 'all', label: 'All Skills (Full install — everything)', hint: 'recommended for full red team ops' },
|
|
40
|
+
...Object.entries(PROFILES).map(([key, p]) => ({
|
|
41
|
+
value: key,
|
|
42
|
+
label: `${p.label}`,
|
|
43
|
+
hint: p.description,
|
|
44
|
+
})),
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const profiles = await prompts.multiselect({
|
|
48
|
+
message: 'Which skill profiles do you need? (space to select, enter to confirm)',
|
|
49
|
+
options: profileOptions,
|
|
50
|
+
initialValues: ['all'],
|
|
51
|
+
required: true,
|
|
52
|
+
});
|
|
53
|
+
|
|
37
54
|
const confirmed = await prompts.confirm({
|
|
38
55
|
message: `Install RTExit into ${targetDirectory}?`,
|
|
39
56
|
initialValue: true,
|
|
40
57
|
});
|
|
41
58
|
|
|
42
|
-
return { targetDirectory, language, document_output_language, ides, confirmed };
|
|
59
|
+
return { targetDirectory, language, document_output_language, ides, profiles, confirmed };
|
|
43
60
|
}
|
|
44
61
|
|
|
45
62
|
module.exports = { askInstallQuestions };
|