@voidagency/web-scanner 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +198 -0
  2. package/dist/aggregator.d.ts +65 -0
  3. package/dist/aggregator.d.ts.map +1 -0
  4. package/dist/aggregator.js +546 -0
  5. package/dist/aggregator.js.map +1 -0
  6. package/dist/categories.d.ts +59 -0
  7. package/dist/categories.d.ts.map +1 -0
  8. package/dist/categories.js +278 -0
  9. package/dist/categories.js.map +1 -0
  10. package/dist/cli.d.ts +12 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +457 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/config.d.ts +19 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +121 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/coverage.d.ts +49 -0
  19. package/dist/coverage.d.ts.map +1 -0
  20. package/dist/coverage.js +165 -0
  21. package/dist/coverage.js.map +1 -0
  22. package/dist/enrichers/nvd.d.ts +55 -0
  23. package/dist/enrichers/nvd.d.ts.map +1 -0
  24. package/dist/enrichers/nvd.js +326 -0
  25. package/dist/enrichers/nvd.js.map +1 -0
  26. package/dist/report.d.ts +12 -0
  27. package/dist/report.d.ts.map +1 -0
  28. package/dist/report.js +460 -0
  29. package/dist/report.js.map +1 -0
  30. package/dist/runners/nuclei.d.ts +59 -0
  31. package/dist/runners/nuclei.d.ts.map +1 -0
  32. package/dist/runners/nuclei.js +531 -0
  33. package/dist/runners/nuclei.js.map +1 -0
  34. package/dist/runners/testssl.d.ts +16 -0
  35. package/dist/runners/testssl.d.ts.map +1 -0
  36. package/dist/runners/testssl.js +179 -0
  37. package/dist/runners/testssl.js.map +1 -0
  38. package/dist/runners/zap.d.ts +30 -0
  39. package/dist/runners/zap.d.ts.map +1 -0
  40. package/dist/runners/zap.js +389 -0
  41. package/dist/runners/zap.js.map +1 -0
  42. package/dist/types.d.ts +172 -0
  43. package/dist/types.d.ts.map +1 -0
  44. package/dist/types.js +6 -0
  45. package/dist/types.js.map +1 -0
  46. package/package.json +54 -0
  47. package/templates/drupal-api-index-exposed.yaml +81 -0
  48. package/templates/drupal-api-user-detail.yaml +76 -0
  49. package/templates/drupal-api-user-listing.yaml +59 -0
  50. package/templates/drupal-dev-files-exposed.yaml +73 -0
  51. package/templates/drupal-file-path-disclosure.yaml +59 -0
  52. package/templates/drupal-files-listing.yaml +63 -0
  53. package/templates/drupal-install-error-disclosure.yaml +62 -0
  54. package/templates/drupal-theme-lockfiles.yaml +79 -0
  55. package/templates/drupal-version-detect.yaml +89 -0
  56. package/templates/http-options-enabled.yaml +56 -0
  57. package/templates/nextjs-version-detect.yaml +35 -0
  58. package/templates/php-version-detect.yaml +37 -0
  59. package/zap.yaml +33 -0
@@ -0,0 +1,172 @@
1
+ /**
2
+ * VoidSec Scanner - Core Types
3
+ * Based on actual tool output fields
4
+ */
5
+ export type Severity = 'critical' | 'high' | 'medium' | 'low' | 'info';
6
+ export type ToolSource = 'nuclei' | 'testssl' | 'trivy' | 'katana' | 'nvd' | 'zap';
7
+ /**
8
+ * Unified finding from any scanning tool
9
+ */
10
+ export interface Finding {
11
+ id: string;
12
+ title: string;
13
+ description: string;
14
+ severity: Severity;
15
+ source: ToolSource;
16
+ target: string;
17
+ affectedUrls?: string[];
18
+ cveTable?: CveTableEntry[];
19
+ cve?: string;
20
+ cwe?: string;
21
+ cvss?: string;
22
+ templateId?: string;
23
+ tags?: string[];
24
+ matcher?: string;
25
+ extracted?: string[];
26
+ request?: string;
27
+ response?: string;
28
+ curl?: string;
29
+ packageName?: string;
30
+ installedVersion?: string;
31
+ fixedVersion?: string;
32
+ references?: string[];
33
+ }
34
+ /**
35
+ * Technology detection entry
36
+ */
37
+ export interface TechDetection {
38
+ host: string;
39
+ technologies: string[];
40
+ }
41
+ /**
42
+ * Severity counts for summary
43
+ */
44
+ export interface SeverityCounts {
45
+ critical: number;
46
+ high: number;
47
+ medium: number;
48
+ low: number;
49
+ info: number;
50
+ }
51
+ /**
52
+ * Scan profile configuration
53
+ */
54
+ export type ScanProfile = 'quick' | 'standard' | 'deep';
55
+ /**
56
+ * Test coverage result for a category
57
+ */
58
+ export interface TestCoverageItem {
59
+ name: string;
60
+ description: string;
61
+ tested: boolean;
62
+ status: 'pass' | 'fail' | 'info' | 'untested';
63
+ count: number;
64
+ }
65
+ /**
66
+ * Passed security check item
67
+ */
68
+ export interface PassedCheckItem {
69
+ name: string;
70
+ description: string;
71
+ }
72
+ /**
73
+ * CVE table entry for consolidated version-based findings
74
+ */
75
+ export interface CveTableEntry {
76
+ cve: string;
77
+ cvss?: string;
78
+ severity: Severity;
79
+ summary: string;
80
+ references?: string[];
81
+ }
82
+ /**
83
+ * Complete scan report
84
+ */
85
+ export interface Report {
86
+ target: string;
87
+ scanDate: string;
88
+ duration: string;
89
+ profile: ScanProfile;
90
+ summary: SeverityCounts;
91
+ totalFindings: number;
92
+ technologies: TechDetection[];
93
+ findings: Finding[];
94
+ coverage?: TestCoverageItem[];
95
+ passedChecks?: PassedCheckItem[];
96
+ }
97
+ /**
98
+ * Nuclei JSONL output structure
99
+ */
100
+ export interface NucleiOutput {
101
+ 'template-id': string;
102
+ 'template-path'?: string;
103
+ info: {
104
+ name: string;
105
+ description?: string;
106
+ severity: string;
107
+ tags?: string[];
108
+ reference?: string[];
109
+ classification?: {
110
+ 'cve-id'?: string[];
111
+ 'cwe-id'?: string[];
112
+ 'cvss-metrics'?: string;
113
+ 'cvss-score'?: number;
114
+ };
115
+ };
116
+ 'matcher-name'?: string;
117
+ 'matched-at': string;
118
+ 'extracted-results'?: string[];
119
+ host?: string;
120
+ request?: string;
121
+ response?: string;
122
+ 'curl-command'?: string;
123
+ timestamp?: string;
124
+ }
125
+ /**
126
+ * testssl.sh JSON output structure
127
+ */
128
+ export interface TestsslOutput {
129
+ id: string;
130
+ ip: string;
131
+ port: string;
132
+ severity: string;
133
+ cve?: string;
134
+ cwe?: string;
135
+ finding: string;
136
+ }
137
+ /**
138
+ * Trivy JSON output structure (simplified)
139
+ */
140
+ export interface TrivyVulnerability {
141
+ VulnerabilityID: string;
142
+ PkgName: string;
143
+ InstalledVersion: string;
144
+ FixedVersion?: string;
145
+ Severity: string;
146
+ Title?: string;
147
+ Description?: string;
148
+ References?: string[];
149
+ CVSS?: {
150
+ nvd?: {
151
+ V3Score?: number;
152
+ V3Vector?: string;
153
+ };
154
+ };
155
+ }
156
+ export interface TrivyOutput {
157
+ Results?: Array<{
158
+ Target: string;
159
+ Vulnerabilities?: TrivyVulnerability[];
160
+ }>;
161
+ }
162
+ /**
163
+ * Scan options passed to runners
164
+ */
165
+ export interface ScanOptions {
166
+ target: string;
167
+ profile: ScanProfile;
168
+ outputDir?: string;
169
+ rateLimit?: number;
170
+ timeout?: number;
171
+ }
172
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * VoidSec Scanner - Core Types
3
+ * Based on actual tool output fields
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@voidagency/web-scanner",
3
+ "version": "0.0.1",
4
+ "description": "Security scanning CLI orchestrating ZAP, Nuclei, and testssl.sh",
5
+ "type": "module",
6
+ "main": "./dist/cli.js",
7
+ "bin": {
8
+ "voidsec": "./dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "templates",
13
+ "zap.yaml",
14
+ "README.md"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "dev": "tsx src/cli.ts",
19
+ "start": "node dist/cli.js",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "security",
24
+ "scanner",
25
+ "vulnerability",
26
+ "pentest",
27
+ "zap",
28
+ "nuclei",
29
+ "testssl",
30
+ "cve",
31
+ "security-audit"
32
+ ],
33
+ "author": "",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": ""
38
+ },
39
+ "dependencies": {
40
+ "commander": "^12.1.0",
41
+ "execa": "^9.3.0",
42
+ "handlebars": "^4.7.8",
43
+ "glob": "^11.0.0"
44
+ },
45
+ "devDependencies": {
46
+ "typescript": "^5.5.0",
47
+ "@types/node": "^22.0.0",
48
+ "tsx": "^4.16.0"
49
+ },
50
+ "engines": {
51
+ "node": ">=20.0.0"
52
+ }
53
+ }
54
+
@@ -0,0 +1,81 @@
1
+ id: drupal-api-index-exposed
2
+
3
+ info:
4
+ name: Drupal JSON:API Index Exposed
5
+ author: voidsec
6
+ severity: high
7
+ description: |
8
+ The Drupal JSON:API index is publicly accessible without authentication.
9
+ This exposes the entire API structure including endpoints for users, nodes,
10
+ files, webform submissions, and other sensitive resources.
11
+ Attackers can use this to map the application and access sensitive data.
12
+ remediation: |
13
+ Restrict JSON:API access using authentication or disable public access.
14
+ In settings.php or via contrib module like 'jsonapi_extras'.
15
+ reference:
16
+ - https://www.drupal.org/project/drupal/issues/3240913
17
+ - https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module/security-considerations
18
+ classification:
19
+ cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
20
+ cvss-score: 7.5
21
+ cwe-id: CWE-200
22
+ metadata:
23
+ verified: true
24
+ max-request: 4
25
+ vendor: drupal
26
+ product: drupal
27
+ tags: drupal,exposure,api,jsonapi,misconfig,high
28
+
29
+ http:
30
+ - method: GET
31
+ path:
32
+ # With language prefix
33
+ - "{{BaseURL}}/fr/api"
34
+ - "{{BaseURL}}/en/api"
35
+ - "{{BaseURL}}/ar/api"
36
+ # Without language prefix
37
+ - "{{BaseURL}}/api"
38
+ # Standard jsonapi prefix
39
+ - "{{BaseURL}}/jsonapi"
40
+ - "{{BaseURL}}/fr/jsonapi"
41
+
42
+ stop-at-first-match: true
43
+
44
+ matchers-condition: and
45
+ matchers:
46
+ # Must be JSON:API response with links (index)
47
+ - type: word
48
+ part: body
49
+ words:
50
+ - '"jsonapi"'
51
+ - '"links"'
52
+ condition: and
53
+
54
+ # Must expose sensitive endpoints (not just 403)
55
+ - type: word
56
+ part: body
57
+ words:
58
+ - 'user--user'
59
+ - 'node--'
60
+ - 'file--'
61
+ condition: or
62
+
63
+ # Must NOT be an error response
64
+ - type: word
65
+ part: body
66
+ words:
67
+ - '"errors"'
68
+ negative: true
69
+
70
+ - type: status
71
+ status:
72
+ - 200
73
+
74
+ extractors:
75
+ # Extract exposed resource types
76
+ - type: regex
77
+ name: exposed_endpoints
78
+ group: 1
79
+ regex:
80
+ - '"([a-z_]+--[a-z_]+)":\{"href"'
81
+
@@ -0,0 +1,76 @@
1
+ id: drupal-api-user-detail-exposure
2
+
3
+ info:
4
+ name: Drupal JSON:API User Details Exposed
5
+ author: voidsec
6
+ severity: medium
7
+ description: |
8
+ Individual Drupal user records expose sensitive attributes via JSON:API.
9
+ This can leak usernames, email patterns, and account information.
10
+ remediation: |
11
+ Configure JSON:API permissions to restrict user field access.
12
+ Use jsonapi_extras module to hide sensitive fields.
13
+ reference:
14
+ - https://www.drupal.org/project/drupal/issues/3240913
15
+ - https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module/security-considerations
16
+ classification:
17
+ cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
18
+ cvss-score: 5.3
19
+ cwe-id: CWE-200
20
+ metadata:
21
+ verified: true
22
+ max-request: 1
23
+ vendor: drupal
24
+ product: drupal
25
+ tags: drupal,exposure,api,jsonapi,user,pii
26
+
27
+ # Usage: nuclei -t drupal-api-user-detail.yaml -u URL -var user_url=<full_user_url>
28
+ # The 'user_url' variable should be passed from the scanner after extracting from API response
29
+
30
+ http:
31
+ - method: GET
32
+ path:
33
+ - "{{user_url}}"
34
+
35
+ matchers-condition: and
36
+ matchers:
37
+ - type: status
38
+ status:
39
+ - 200
40
+
41
+ - type: word
42
+ part: body
43
+ words:
44
+ - '"jsonapi"'
45
+ - '"attributes"'
46
+ condition: and
47
+
48
+ # Check for sensitive attributes being exposed
49
+ - type: word
50
+ part: body
51
+ words:
52
+ - '"display_name"'
53
+ - '"mail"'
54
+ - '"name"'
55
+ - '"created"'
56
+ - '"changed"'
57
+ - '"access"'
58
+ - '"login"'
59
+ condition: or
60
+
61
+ extractors:
62
+ - type: json
63
+ name: display_name
64
+ json:
65
+ - '.data.attributes.display_name'
66
+
67
+ - type: json
68
+ name: username
69
+ json:
70
+ - '.data.attributes.name'
71
+
72
+ - type: json
73
+ name: email
74
+ json:
75
+ - '.data.attributes.mail'
76
+
@@ -0,0 +1,59 @@
1
+ id: drupal-api-user-listing
2
+
3
+ info:
4
+ name: Drupal API Username Listing - Detect
5
+ author: voidsec,lixts
6
+ severity: medium
7
+ description: |
8
+ Drupal API username listing was detected. This exposes user display names
9
+ which could be used for targeted attacks or enumeration.
10
+ reference:
11
+ - https://www.drupal.org/project/drupal/issues/3240913
12
+ - https://raw.githubusercontent.com/projectdiscovery/nuclei-templates/refs/heads/main/http/exposures/apis/drupal-jsonapi-user-listing.yaml
13
+ classification:
14
+ cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
15
+ cvss-score: 5.3
16
+ cwe-id: CWE-200
17
+ metadata:
18
+ verified: true
19
+ max-request: 2
20
+ vendor: drupal
21
+ product: drupal
22
+ tags: drupal,exposure,discovery,api,user-enum
23
+
24
+ http:
25
+ - method: GET
26
+ path:
27
+ # Custom /api/ prefix (common in decoupled Drupal)
28
+ - "{{BaseURL}}/api/user/user"
29
+ # Standard JSON:API prefix
30
+ - "{{BaseURL}}/jsonapi/user/user"
31
+
32
+ stop-at-first-match: true
33
+
34
+ matchers-condition: and
35
+ matchers:
36
+ - type: regex
37
+ regex:
38
+ - '"display_name"\s*:\s*"[^"]+"'
39
+ - '"name"\s*:\s*"[^"]+"'
40
+ condition: or
41
+
42
+ - type: status
43
+ status:
44
+ - 200
45
+
46
+ - type: word
47
+ part: header
48
+ words:
49
+ - "application/json"
50
+ - "application/vnd.api+json"
51
+ condition: or
52
+
53
+ extractors:
54
+ - type: json
55
+ name: usernames
56
+ json:
57
+ - '.data[].attributes.display_name'
58
+ - '.data[].attributes.name'
59
+
@@ -0,0 +1,73 @@
1
+ id: drupal-dev-files-exposed
2
+
3
+ info:
4
+ name: Drupal Development Files Exposed
5
+ author: voidsec
6
+ severity: low
7
+ description: |
8
+ Development and configuration files are publicly accessible.
9
+ These files can reveal project structure, dependencies, and
10
+ configuration that aids attackers in reconnaissance.
11
+ remediation: |
12
+ Block access to development files in web server configuration.
13
+ Add to nginx: location ~* \.(lock|properties)$ { deny all; }
14
+ reference:
15
+ - https://www.drupal.org/docs/security-in-drupal
16
+ classification:
17
+ cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
18
+ cvss-score: 5.3
19
+ cwe-id: CWE-538
20
+ metadata:
21
+ verified: true
22
+ max-request: 8
23
+ vendor: drupal
24
+ product: drupal
25
+ tags: drupal,exposure,config,devfiles,misconfig
26
+
27
+ http:
28
+ - method: GET
29
+ path:
30
+ - "{{BaseURL}}/cghooks.lock"
31
+ - "{{BaseURL}}/sonar-project.properties"
32
+ - "{{BaseURL}}/core/yarn.lock"
33
+ - "{{BaseURL}}/yarn.lock"
34
+ - "{{BaseURL}}/package-lock.json"
35
+ - "{{BaseURL}}/composer.lock"
36
+ - "{{BaseURL}}/.gitlab-ci.yml"
37
+ - "{{BaseURL}}/.github/workflows/main.yml"
38
+
39
+ stop-at-first-match: false
40
+
41
+ matchers-condition: and
42
+ matchers:
43
+ - type: status
44
+ status:
45
+ - 200
46
+
47
+ # Content indicators for each file type
48
+ - type: word
49
+ part: body
50
+ words:
51
+ - '"pre-commit"' # cghooks.lock
52
+ - 'sonar.projectKey' # sonar-project.properties
53
+ - '# yarn lockfile' # yarn.lock
54
+ - '"lockfileVersion"' # package-lock.json
55
+ - '"_readme"' # composer.lock
56
+ - 'stages:' # gitlab-ci
57
+ - 'runs-on:' # github actions
58
+ condition: or
59
+
60
+ extractors:
61
+ # Extract project identifiers (NOT all package names)
62
+ - type: regex
63
+ name: sonar_project
64
+ regex:
65
+ - 'sonar\.projectKey=([^\s]+)'
66
+ - 'sonar\.projectName=([^\s]+)'
67
+
68
+ # For composer.lock - just confirm it's a Drupal project
69
+ - type: regex
70
+ name: drupal_version
71
+ regex:
72
+ - '"drupal/core":\s*\{\s*"version":\s*"([^"]+)"'
73
+
@@ -0,0 +1,59 @@
1
+ id: drupal-file-path-disclosure
2
+
3
+ info:
4
+ name: Drupal File Path Disclosure in 403 Response
5
+ author: voidsec
6
+ severity: medium
7
+ description: |
8
+ The /file/{id}/download endpoint returns 403 Access Denied but leaks
9
+ the actual filename in the error message (e.g., "Access to file
10
+ public://2023-02/document.pdf denied"). An attacker can use this to
11
+ discover file paths and access them directly via /sites/default/files/.
12
+ remediation: |
13
+ Customize error messages to not include file paths.
14
+ Use hook_file_download() to return generic access denied messages.
15
+ reference:
16
+ - https://www.drupal.org/docs/security-in-drupal/writing-secure-code-for-drupal
17
+ classification:
18
+ cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
19
+ cvss-score: 5.3
20
+ cwe-id: CWE-200
21
+ metadata:
22
+ verified: true
23
+ max-request: 6
24
+ vendor: drupal
25
+ product: drupal
26
+ tags: drupal,exposure,file,path-disclosure,info-leak
27
+
28
+ http:
29
+ - method: GET
30
+ path:
31
+ - "{{BaseURL}}/file/1/download"
32
+ - "{{BaseURL}}/fr/file/1/download"
33
+ - "{{BaseURL}}/en/file/1/download"
34
+ - "{{BaseURL}}/ar/file/1/download"
35
+ - "{{BaseURL}}/file/2/download"
36
+ - "{{BaseURL}}/fr/file/2/download"
37
+
38
+ stop-at-first-match: true
39
+
40
+ matchers-condition: and
41
+ matchers:
42
+ - type: status
43
+ status:
44
+ - 403
45
+
46
+ - type: word
47
+ part: body
48
+ words:
49
+ - "public://"
50
+ - "Access to file"
51
+ condition: and
52
+
53
+ extractors:
54
+ - type: regex
55
+ name: disclosed_path
56
+ group: 1
57
+ regex:
58
+ - 'public://([^\s"<>]+)'
59
+
@@ -0,0 +1,63 @@
1
+ id: drupal-files-listing
2
+
3
+ info:
4
+ name: Drupal Files Directory Listing
5
+ author: voidsec
6
+ severity: medium
7
+ description: |
8
+ The Drupal /sites/default/files/ directory has listing enabled or is
9
+ directly accessible. This can expose uploaded files, private documents,
10
+ and potentially sensitive information.
11
+ remediation: |
12
+ Disable directory listing in web server configuration.
13
+ For Nginx: autoindex off;
14
+ For Apache: Options -Indexes
15
+ reference:
16
+ - https://www.drupal.org/docs/security-in-drupal/writing-secure-code-for-drupal
17
+ classification:
18
+ cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
19
+ cvss-score: 5.3
20
+ cwe-id: CWE-548
21
+ metadata:
22
+ verified: true
23
+ max-request: 6
24
+ vendor: drupal
25
+ product: drupal
26
+ tags: drupal,exposure,listing,files,misconfig
27
+
28
+ http:
29
+ - method: GET
30
+ path:
31
+ # Standard Drupal files path
32
+ - "{{BaseURL}}/sites/default/files/"
33
+ # With language prefix
34
+ - "{{BaseURL}}/fr/sites/default/files/"
35
+ - "{{BaseURL}}/en/sites/default/files/"
36
+ # Alternative paths
37
+ - "{{BaseURL}}/files/"
38
+ - "{{BaseURL}}/sites/files/"
39
+
40
+ stop-at-first-match: true
41
+
42
+ matchers-condition: and
43
+ matchers:
44
+ # Directory listing indicators
45
+ - type: word
46
+ part: body
47
+ words:
48
+ - "Index of"
49
+ - "Directory listing"
50
+ - "<title>Index of"
51
+ - "Parent Directory"
52
+ condition: or
53
+
54
+ - type: status
55
+ status:
56
+ - 200
57
+
58
+ extractors:
59
+ - type: regex
60
+ name: files_found
61
+ regex:
62
+ - 'href="([^"]+\.(pdf|doc|docx|xls|xlsx|zip|sql|bak|txt|log))"'
63
+