@panguard-ai/panguard-scan 0.1.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/dist/cli/commands.d.ts +13 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +132 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +138 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/report/compliance-map.d.ts +91 -0
- package/dist/report/compliance-map.d.ts.map +1 -0
- package/dist/report/compliance-map.js +156 -0
- package/dist/report/compliance-map.js.map +1 -0
- package/dist/report/index.d.ts +14 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +13 -0
- package/dist/report/index.js.map +1 -0
- package/dist/report/pdf-generator.d.ts +41 -0
- package/dist/report/pdf-generator.d.ts.map +1 -0
- package/dist/report/pdf-generator.js +238 -0
- package/dist/report/pdf-generator.js.map +1 -0
- package/dist/report/sections/compliance.d.ts +28 -0
- package/dist/report/sections/compliance.d.ts.map +1 -0
- package/dist/report/sections/compliance.js +227 -0
- package/dist/report/sections/compliance.js.map +1 -0
- package/dist/report/sections/cover.d.ts +22 -0
- package/dist/report/sections/cover.d.ts.map +1 -0
- package/dist/report/sections/cover.js +190 -0
- package/dist/report/sections/cover.js.map +1 -0
- package/dist/report/sections/executive-summary.d.ts +22 -0
- package/dist/report/sections/executive-summary.d.ts.map +1 -0
- package/dist/report/sections/executive-summary.js +206 -0
- package/dist/report/sections/executive-summary.js.map +1 -0
- package/dist/report/sections/findings-table.d.ts +28 -0
- package/dist/report/sections/findings-table.d.ts.map +1 -0
- package/dist/report/sections/findings-table.js +189 -0
- package/dist/report/sections/findings-table.js.map +1 -0
- package/dist/report/sections/remediation.d.ts +28 -0
- package/dist/report/sections/remediation.d.ts.map +1 -0
- package/dist/report/sections/remediation.js +157 -0
- package/dist/report/sections/remediation.js.map +1 -0
- package/dist/report/styles.d.ts +65 -0
- package/dist/report/styles.d.ts.map +1 -0
- package/dist/report/styles.js +80 -0
- package/dist/report/styles.js.map +1 -0
- package/dist/scanners/cve-checker.d.ts +21 -0
- package/dist/scanners/cve-checker.d.ts.map +1 -0
- package/dist/scanners/cve-checker.js +198 -0
- package/dist/scanners/cve-checker.js.map +1 -0
- package/dist/scanners/discovery-scanner.d.ts +24 -0
- package/dist/scanners/discovery-scanner.d.ts.map +1 -0
- package/dist/scanners/discovery-scanner.js +208 -0
- package/dist/scanners/discovery-scanner.js.map +1 -0
- package/dist/scanners/index.d.ts +54 -0
- package/dist/scanners/index.d.ts.map +1 -0
- package/dist/scanners/index.js +328 -0
- package/dist/scanners/index.js.map +1 -0
- package/dist/scanners/open-ports.d.ts +25 -0
- package/dist/scanners/open-ports.d.ts.map +1 -0
- package/dist/scanners/open-ports.js +198 -0
- package/dist/scanners/open-ports.js.map +1 -0
- package/dist/scanners/password-policy.d.ts +23 -0
- package/dist/scanners/password-policy.d.ts.map +1 -0
- package/dist/scanners/password-policy.js +324 -0
- package/dist/scanners/password-policy.js.map +1 -0
- package/dist/scanners/remote/dns-checker.d.ts +21 -0
- package/dist/scanners/remote/dns-checker.d.ts.map +1 -0
- package/dist/scanners/remote/dns-checker.js +103 -0
- package/dist/scanners/remote/dns-checker.js.map +1 -0
- package/dist/scanners/remote/http-headers.d.ts +19 -0
- package/dist/scanners/remote/http-headers.d.ts.map +1 -0
- package/dist/scanners/remote/http-headers.js +65 -0
- package/dist/scanners/remote/http-headers.js.map +1 -0
- package/dist/scanners/remote/index.d.ts +22 -0
- package/dist/scanners/remote/index.d.ts.map +1 -0
- package/dist/scanners/remote/index.js +120 -0
- package/dist/scanners/remote/index.js.map +1 -0
- package/dist/scanners/remote/port-scanner.d.ts +20 -0
- package/dist/scanners/remote/port-scanner.d.ts.map +1 -0
- package/dist/scanners/remote/port-scanner.js +65 -0
- package/dist/scanners/remote/port-scanner.js.map +1 -0
- package/dist/scanners/remote/ssl-checker.d.ts +24 -0
- package/dist/scanners/remote/ssl-checker.d.ts.map +1 -0
- package/dist/scanners/remote/ssl-checker.js +109 -0
- package/dist/scanners/remote/ssl-checker.js.map +1 -0
- package/dist/scanners/scheduled-tasks.d.ts +26 -0
- package/dist/scanners/scheduled-tasks.d.ts.map +1 -0
- package/dist/scanners/scheduled-tasks.js +299 -0
- package/dist/scanners/scheduled-tasks.js.map +1 -0
- package/dist/scanners/shared-folders.d.ts +25 -0
- package/dist/scanners/shared-folders.d.ts.map +1 -0
- package/dist/scanners/shared-folders.js +310 -0
- package/dist/scanners/shared-folders.js.map +1 -0
- package/dist/scanners/ssl-checker.d.ts +27 -0
- package/dist/scanners/ssl-checker.d.ts.map +1 -0
- package/dist/scanners/ssl-checker.js +197 -0
- package/dist/scanners/ssl-checker.js.map +1 -0
- package/dist/scanners/types.d.ts +140 -0
- package/dist/scanners/types.d.ts.map +1 -0
- package/dist/scanners/types.js +31 -0
- package/dist/scanners/types.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unnecessary open ports checker
|
|
3
|
+
* 不必要的開放埠檢查器
|
|
4
|
+
*
|
|
5
|
+
* Analyzes a list of open ports against a known set of risky or unnecessary
|
|
6
|
+
* ports and generates findings for each match.
|
|
7
|
+
* 將開放埠列表與已知的風險或不必要埠集合進行比對,並為每個匹配產生發現。
|
|
8
|
+
*
|
|
9
|
+
* @module @panguard-ai/panguard-scan/scanners/open-ports
|
|
10
|
+
*/
|
|
11
|
+
import { createLogger } from '@panguard-ai/core';
|
|
12
|
+
const logger = createLogger('panguard-scan:open-ports');
|
|
13
|
+
/**
|
|
14
|
+
* Map of unnecessary or risky port numbers to their descriptions
|
|
15
|
+
* 不必要或有風險的埠號與其描述的對應表
|
|
16
|
+
*
|
|
17
|
+
* Each entry contains the service name, risk description, and recommended remediation.
|
|
18
|
+
* 每個條目包含服務名稱、風險描述和建議的修復措施。
|
|
19
|
+
*/
|
|
20
|
+
const UNNECESSARY_PORTS = new Map([
|
|
21
|
+
[
|
|
22
|
+
21,
|
|
23
|
+
{
|
|
24
|
+
name: 'FTP',
|
|
25
|
+
risk: 'Unencrypted file transfer',
|
|
26
|
+
remediation: 'Use SFTP instead',
|
|
27
|
+
manualFix: ['sudo ufw deny 21', 'sudo systemctl disable vsftpd'],
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
[
|
|
31
|
+
23,
|
|
32
|
+
{
|
|
33
|
+
name: 'Telnet',
|
|
34
|
+
risk: 'Unencrypted remote access',
|
|
35
|
+
remediation: 'Use SSH instead',
|
|
36
|
+
manualFix: ['sudo ufw deny 23', 'sudo systemctl disable telnetd'],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
135,
|
|
41
|
+
{
|
|
42
|
+
name: 'MSRPC',
|
|
43
|
+
risk: 'Windows RPC exploitation',
|
|
44
|
+
remediation: 'Block with firewall',
|
|
45
|
+
manualFix: ['sudo ufw deny 135'],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
[
|
|
49
|
+
139,
|
|
50
|
+
{
|
|
51
|
+
name: 'NetBIOS',
|
|
52
|
+
risk: 'SMB relay attacks',
|
|
53
|
+
remediation: 'Disable NetBIOS over TCP/IP',
|
|
54
|
+
manualFix: ['sudo ufw deny 139'],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
[
|
|
58
|
+
445,
|
|
59
|
+
{
|
|
60
|
+
name: 'SMB',
|
|
61
|
+
risk: 'EternalBlue and SMB attacks',
|
|
62
|
+
remediation: 'Restrict SMB access',
|
|
63
|
+
manualFix: ['sudo ufw deny 445'],
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
[
|
|
67
|
+
1433,
|
|
68
|
+
{
|
|
69
|
+
name: 'MSSQL',
|
|
70
|
+
risk: 'Database exposure',
|
|
71
|
+
remediation: 'Bind to localhost only',
|
|
72
|
+
manualFix: ['sudo ufw deny 1433'],
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
[
|
|
76
|
+
3306,
|
|
77
|
+
{
|
|
78
|
+
name: 'MySQL',
|
|
79
|
+
risk: 'Database exposure',
|
|
80
|
+
remediation: 'Bind to localhost only',
|
|
81
|
+
manualFix: [
|
|
82
|
+
"sudo sed -i 's/bind-address.*/bind-address = 127.0.0.1/' /etc/mysql/mysql.conf.d/mysqld.cnf",
|
|
83
|
+
'sudo systemctl restart mysql',
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
[
|
|
88
|
+
3389,
|
|
89
|
+
{
|
|
90
|
+
name: 'RDP',
|
|
91
|
+
risk: 'Brute force and BlueKeep',
|
|
92
|
+
remediation: 'Use VPN for remote access',
|
|
93
|
+
manualFix: ['sudo ufw deny 3389'],
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
[
|
|
97
|
+
5432,
|
|
98
|
+
{
|
|
99
|
+
name: 'PostgreSQL',
|
|
100
|
+
risk: 'Database exposure',
|
|
101
|
+
remediation: 'Bind to localhost only',
|
|
102
|
+
manualFix: [
|
|
103
|
+
"sudo sed -i \"s/#listen_addresses = 'localhost'/listen_addresses = 'localhost'/\" /etc/postgresql/*/main/postgresql.conf",
|
|
104
|
+
'sudo systemctl restart postgresql',
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
[
|
|
109
|
+
5900,
|
|
110
|
+
{
|
|
111
|
+
name: 'VNC',
|
|
112
|
+
risk: 'Unencrypted remote desktop',
|
|
113
|
+
remediation: 'Use SSH tunnel',
|
|
114
|
+
manualFix: ['sudo ufw deny 5900'],
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
[
|
|
118
|
+
6379,
|
|
119
|
+
{
|
|
120
|
+
name: 'Redis',
|
|
121
|
+
risk: 'Unauthenticated access',
|
|
122
|
+
remediation: 'Enable AUTH and bind to localhost',
|
|
123
|
+
manualFix: [
|
|
124
|
+
"sudo sed -i 's/# requirepass.*/requirepass YOUR_STRONG_PASSWORD/' /etc/redis/redis.conf",
|
|
125
|
+
"sudo sed -i 's/bind .*/bind 127.0.0.1/' /etc/redis/redis.conf",
|
|
126
|
+
'sudo systemctl restart redis',
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
[
|
|
131
|
+
27017,
|
|
132
|
+
{
|
|
133
|
+
name: 'MongoDB',
|
|
134
|
+
risk: 'Unauthenticated access',
|
|
135
|
+
remediation: 'Enable auth and bind to localhost',
|
|
136
|
+
manualFix: [
|
|
137
|
+
"sudo sed -i 's/bindIp:.*/bindIp: 127.0.0.1/' /etc/mongod.conf",
|
|
138
|
+
'sudo systemctl restart mongod',
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
]);
|
|
143
|
+
/**
|
|
144
|
+
* Ports that warrant critical severity due to unencrypted protocols
|
|
145
|
+
* 因未加密協定而需要嚴重等級的埠
|
|
146
|
+
*/
|
|
147
|
+
const CRITICAL_PORTS = new Set([21, 23]);
|
|
148
|
+
/**
|
|
149
|
+
* Check a list of open ports for unnecessary or risky services
|
|
150
|
+
* 檢查開放埠列表中是否有不必要或有風險的服務
|
|
151
|
+
*
|
|
152
|
+
* This is a synchronous function that analyzes existing port data without
|
|
153
|
+
* performing any additional system calls.
|
|
154
|
+
* 這是一個同步函式,分析現有的埠資料而不執行任何額外的系統呼叫。
|
|
155
|
+
*
|
|
156
|
+
* @param ports - Array of open port info from discovery / 來自偵察的開放埠資訊陣列
|
|
157
|
+
* @returns Array of findings for unnecessary ports / 不必要埠的發現陣列
|
|
158
|
+
*/
|
|
159
|
+
export function checkUnnecessaryPorts(ports) {
|
|
160
|
+
const findings = [];
|
|
161
|
+
logger.info(`Checking ${ports.length} open ports against unnecessary ports list`);
|
|
162
|
+
for (const portInfo of ports) {
|
|
163
|
+
const unnecessary = UNNECESSARY_PORTS.get(portInfo.port);
|
|
164
|
+
if (!unnecessary)
|
|
165
|
+
continue;
|
|
166
|
+
const severity = CRITICAL_PORTS.has(portInfo.port) ? 'critical' : 'high';
|
|
167
|
+
const finding = {
|
|
168
|
+
id: `SCAN-PORT-${portInfo.port}`,
|
|
169
|
+
title: `Unnecessary port open: ${portInfo.port}/${portInfo.protocol} (${unnecessary.name}) / ` +
|
|
170
|
+
`不必要的開放埠:${portInfo.port}/${portInfo.protocol} (${unnecessary.name})`,
|
|
171
|
+
description: `Port ${portInfo.port} (${unnecessary.name}) is open. ` +
|
|
172
|
+
`Risk: ${unnecessary.risk}. ` +
|
|
173
|
+
`Process: ${portInfo.process || 'unknown'}. / ` +
|
|
174
|
+
`埠 ${portInfo.port} (${unnecessary.name}) 已開放。` +
|
|
175
|
+
`風險:${unnecessary.risk}。` +
|
|
176
|
+
`行程:${portInfo.process || 'unknown'}。`,
|
|
177
|
+
severity,
|
|
178
|
+
category: 'network',
|
|
179
|
+
remediation: `${unnecessary.remediation}. ` +
|
|
180
|
+
`If this service is not needed, close port ${portInfo.port} or stop the associated process. / ` +
|
|
181
|
+
`${unnecessary.remediation}。` +
|
|
182
|
+
`如果不需要此服務,請關閉埠 ${portInfo.port} 或停止相關行程。`,
|
|
183
|
+
complianceRef: '4.3',
|
|
184
|
+
details: `Port: ${portInfo.port}, Protocol: ${portInfo.protocol}, ` +
|
|
185
|
+
`State: ${portInfo.state}, PID: ${portInfo.pid ?? 'N/A'}, ` +
|
|
186
|
+
`Process: ${portInfo.process || 'N/A'}, Service: ${portInfo.service || 'N/A'}`,
|
|
187
|
+
manualFix: unnecessary.manualFix,
|
|
188
|
+
};
|
|
189
|
+
logger.info(`Found unnecessary port: ${portInfo.port} (${unnecessary.name})`, {
|
|
190
|
+
port: portInfo.port,
|
|
191
|
+
severity,
|
|
192
|
+
});
|
|
193
|
+
findings.push(finding);
|
|
194
|
+
}
|
|
195
|
+
logger.info(`Unnecessary ports check complete: ${findings.length} finding(s)`);
|
|
196
|
+
return findings;
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=open-ports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-ports.js","sourceRoot":"","sources":["../../src/scanners/open-ports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Password policy checker
|
|
3
|
+
* 密碼策略檢查器
|
|
4
|
+
*
|
|
5
|
+
* Checks the system's password policy configuration to identify weak or
|
|
6
|
+
* missing policies. Supports macOS, Linux, and Windows.
|
|
7
|
+
* 檢查系統的密碼策略配置以識別弱或缺失的策略。支援 macOS、Linux 和 Windows。
|
|
8
|
+
*
|
|
9
|
+
* @module @panguard-ai/panguard-scan/scanners/password-policy
|
|
10
|
+
*/
|
|
11
|
+
import type { Finding } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Check password policy strength on the current platform
|
|
14
|
+
* 檢查目前平台上的密碼策略強度
|
|
15
|
+
*
|
|
16
|
+
* Cross-platform password policy checker that dispatches to the appropriate
|
|
17
|
+
* platform-specific implementation.
|
|
18
|
+
* 跨平台密碼策略檢查器,分派到適當的平台特定實作。
|
|
19
|
+
*
|
|
20
|
+
* @returns Array of password policy findings / 密碼策略發現陣列
|
|
21
|
+
*/
|
|
22
|
+
export declare function checkPasswordPolicy(): Promise<Finding[]>;
|
|
23
|
+
//# sourceMappingURL=password-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password-policy.d.ts","sourceRoot":"","sources":["../../src/scanners/password-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAgU1C;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CA+B9D"}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Password policy checker
|
|
3
|
+
* 密碼策略檢查器
|
|
4
|
+
*
|
|
5
|
+
* Checks the system's password policy configuration to identify weak or
|
|
6
|
+
* missing policies. Supports macOS, Linux, and Windows.
|
|
7
|
+
* 檢查系統的密碼策略配置以識別弱或缺失的策略。支援 macOS、Linux 和 Windows。
|
|
8
|
+
*
|
|
9
|
+
* @module @panguard-ai/panguard-scan/scanners/password-policy
|
|
10
|
+
*/
|
|
11
|
+
import { execFile } from 'child_process';
|
|
12
|
+
import { promisify } from 'util';
|
|
13
|
+
import { readFile } from 'fs/promises';
|
|
14
|
+
import { platform as osPlatform } from 'os';
|
|
15
|
+
import { createLogger } from '@panguard-ai/core';
|
|
16
|
+
const execFileAsync = promisify(execFile);
|
|
17
|
+
const logger = createLogger('panguard-scan:password-policy');
|
|
18
|
+
/**
|
|
19
|
+
* Safely execute a command and return stdout, or empty string on failure
|
|
20
|
+
* 安全地執行命令並回傳 stdout,失敗時回傳空字串
|
|
21
|
+
*
|
|
22
|
+
* @param cmd - Command to execute / 要執行的命令
|
|
23
|
+
* @param args - Command arguments / 命令參數
|
|
24
|
+
* @returns stdout output trimmed / 修剪後的 stdout 輸出
|
|
25
|
+
*/
|
|
26
|
+
async function safeExecFile(cmd, args) {
|
|
27
|
+
try {
|
|
28
|
+
const { stdout } = await execFileAsync(cmd, args, { timeout: 15_000 });
|
|
29
|
+
return stdout.trim();
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
logger.debug(`Command failed: ${cmd} ${args.join(' ')}`, {
|
|
33
|
+
error: err instanceof Error ? err.message : String(err),
|
|
34
|
+
});
|
|
35
|
+
return '';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check password policy on macOS
|
|
40
|
+
* 檢查 macOS 上的密碼策略
|
|
41
|
+
*
|
|
42
|
+
* Uses pwpolicy getaccountpolicies to retrieve and parse the current policy.
|
|
43
|
+
* 使用 pwpolicy getaccountpolicies 來擷取並解析目前的策略。
|
|
44
|
+
*
|
|
45
|
+
* @returns Array of findings related to macOS password policy / 與 macOS 密碼策略相關的發現陣列
|
|
46
|
+
*/
|
|
47
|
+
async function checkMacOSPolicy() {
|
|
48
|
+
const findings = [];
|
|
49
|
+
const output = await safeExecFile('pwpolicy', ['getaccountpolicies']);
|
|
50
|
+
if (!output) {
|
|
51
|
+
// No password policy configured at all
|
|
52
|
+
// 完全未配置密碼策略
|
|
53
|
+
findings.push({
|
|
54
|
+
id: 'SCAN-PWD-001',
|
|
55
|
+
title: 'No password policy configured / 未配置密碼策略',
|
|
56
|
+
description: 'No account password policy was found on this macOS system. ' +
|
|
57
|
+
'Without a password policy, users can set weak or empty passwords. / ' +
|
|
58
|
+
'在此 macOS 系統上未找到帳號密碼策略。' +
|
|
59
|
+
'沒有密碼策略,使用者可以設定弱或空密碼。',
|
|
60
|
+
severity: 'high',
|
|
61
|
+
category: 'password',
|
|
62
|
+
remediation: 'Configure a password policy using pwpolicy or an MDM profile ' +
|
|
63
|
+
'that enforces minimum length, complexity, and expiration. / ' +
|
|
64
|
+
'使用 pwpolicy 或 MDM 設定檔配置密碼策略,' +
|
|
65
|
+
'強制最小長度、複雜度和到期時間。',
|
|
66
|
+
complianceRef: '4.5',
|
|
67
|
+
});
|
|
68
|
+
return findings;
|
|
69
|
+
}
|
|
70
|
+
// Check for weak policy indicators
|
|
71
|
+
// 檢查弱策略指標
|
|
72
|
+
const hasMinLength = output.includes('minLength') || output.includes('policyAttributeMinimumLength');
|
|
73
|
+
const hasComplexity = output.includes('requiresAlpha') ||
|
|
74
|
+
output.includes('requiresNumeric') ||
|
|
75
|
+
output.includes('policyAttributeMinimumNumericCharacters');
|
|
76
|
+
const hasExpiration = output.includes('maxPINAgeInDays') || output.includes('policyAttributeExpiresEveryNDays');
|
|
77
|
+
if (!hasMinLength && !hasComplexity) {
|
|
78
|
+
findings.push({
|
|
79
|
+
id: 'SCAN-PWD-001',
|
|
80
|
+
title: 'Weak password policy detected / 偵測到弱密碼策略',
|
|
81
|
+
description: 'The macOS password policy does not enforce minimum length or complexity requirements. / ' +
|
|
82
|
+
'macOS 密碼策略未強制最小長度或複雜度要求。',
|
|
83
|
+
severity: 'medium',
|
|
84
|
+
category: 'password',
|
|
85
|
+
remediation: 'Update the password policy to require a minimum length of at least 8 characters ' +
|
|
86
|
+
'and include alphanumeric complexity requirements. / ' +
|
|
87
|
+
'更新密碼策略以要求至少 8 個字元的最小長度,' +
|
|
88
|
+
'並包含英數複雜度要求。',
|
|
89
|
+
complianceRef: '4.5',
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (!hasExpiration) {
|
|
93
|
+
findings.push({
|
|
94
|
+
id: 'SCAN-PWD-001',
|
|
95
|
+
title: 'No password expiration policy / 無密碼到期策略',
|
|
96
|
+
description: 'The macOS password policy does not enforce password expiration. ' +
|
|
97
|
+
'Passwords that never expire increase the risk of credential compromise. / ' +
|
|
98
|
+
'macOS 密碼策略未強制密碼到期。' +
|
|
99
|
+
'永不過期的密碼增加了憑證被破解的風險。',
|
|
100
|
+
severity: 'medium',
|
|
101
|
+
category: 'password',
|
|
102
|
+
remediation: 'Configure password expiration to require password changes at least every 90 days. / ' +
|
|
103
|
+
'配置密碼到期以要求至少每 90 天更改密碼。',
|
|
104
|
+
complianceRef: '4.5',
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return findings;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check password policy on Linux
|
|
111
|
+
* 檢查 Linux 上的密碼策略
|
|
112
|
+
*
|
|
113
|
+
* Reads /etc/pam.d/common-password and /etc/security/pwquality.conf to
|
|
114
|
+
* determine if a password quality policy is configured.
|
|
115
|
+
* 讀取 /etc/pam.d/common-password 和 /etc/security/pwquality.conf 以
|
|
116
|
+
* 判斷是否已配置密碼品質策略。
|
|
117
|
+
*
|
|
118
|
+
* @returns Array of findings related to Linux password policy / 與 Linux 密碼策略相關的發現陣列
|
|
119
|
+
*/
|
|
120
|
+
async function checkLinuxPolicy() {
|
|
121
|
+
const findings = [];
|
|
122
|
+
let policyFound = false;
|
|
123
|
+
// Try /etc/pam.d/common-password
|
|
124
|
+
// 嘗試 /etc/pam.d/common-password
|
|
125
|
+
try {
|
|
126
|
+
const pamContent = await readFile('/etc/pam.d/common-password', 'utf-8');
|
|
127
|
+
policyFound = true;
|
|
128
|
+
const hasMinLen = pamContent.includes('minlen') || pamContent.includes('min=');
|
|
129
|
+
const hasComplexity = pamContent.includes('ucredit') ||
|
|
130
|
+
pamContent.includes('lcredit') ||
|
|
131
|
+
pamContent.includes('dcredit') ||
|
|
132
|
+
pamContent.includes('ocredit') ||
|
|
133
|
+
pamContent.includes('pam_pwquality') ||
|
|
134
|
+
pamContent.includes('pam_cracklib');
|
|
135
|
+
if (!hasMinLen && !hasComplexity) {
|
|
136
|
+
findings.push({
|
|
137
|
+
id: 'SCAN-PWD-001',
|
|
138
|
+
title: 'Weak PAM password policy / 弱 PAM 密碼策略',
|
|
139
|
+
description: 'The PAM password configuration (/etc/pam.d/common-password) does not enforce ' +
|
|
140
|
+
'minimum length or complexity requirements. / ' +
|
|
141
|
+
'PAM 密碼配置 (/etc/pam.d/common-password) 未強制最小長度或複雜度要求。',
|
|
142
|
+
severity: 'medium',
|
|
143
|
+
category: 'password',
|
|
144
|
+
remediation: 'Install and configure pam_pwquality or pam_cracklib with minlen >= 8, ' +
|
|
145
|
+
'and enforce uppercase, lowercase, digit, and special character requirements. / ' +
|
|
146
|
+
'安裝並配置 pam_pwquality 或 pam_cracklib,設定 minlen >= 8,' +
|
|
147
|
+
'並強制大寫、小寫、數字和特殊字元要求。',
|
|
148
|
+
complianceRef: '4.5',
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
logger.debug('Could not read /etc/pam.d/common-password');
|
|
154
|
+
}
|
|
155
|
+
// Try /etc/security/pwquality.conf
|
|
156
|
+
// 嘗試 /etc/security/pwquality.conf
|
|
157
|
+
try {
|
|
158
|
+
const pwqContent = await readFile('/etc/security/pwquality.conf', 'utf-8');
|
|
159
|
+
policyFound = true;
|
|
160
|
+
// Parse minlen value
|
|
161
|
+
// 解析 minlen 值
|
|
162
|
+
const minlenMatch = pwqContent.match(/^\s*minlen\s*=\s*(\d+)/m);
|
|
163
|
+
const minlen = minlenMatch ? parseInt(minlenMatch[1] ?? '0', 10) : 0;
|
|
164
|
+
if (minlen > 0 && minlen < 8) {
|
|
165
|
+
findings.push({
|
|
166
|
+
id: 'SCAN-PWD-001',
|
|
167
|
+
title: 'Insufficient minimum password length / 最小密碼長度不足',
|
|
168
|
+
description: `Password minimum length is set to ${minlen} in pwquality.conf. ` +
|
|
169
|
+
'A minimum of 8 characters is recommended. / ' +
|
|
170
|
+
`pwquality.conf 中密碼最小長度設定為 ${minlen}。建議至少 8 個字元。`,
|
|
171
|
+
severity: 'medium',
|
|
172
|
+
category: 'password',
|
|
173
|
+
remediation: 'Set minlen = 8 or higher in /etc/security/pwquality.conf. / ' +
|
|
174
|
+
'在 /etc/security/pwquality.conf 中設定 minlen = 8 或更高。',
|
|
175
|
+
complianceRef: '4.5',
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
logger.debug('Could not read /etc/security/pwquality.conf');
|
|
181
|
+
}
|
|
182
|
+
if (!policyFound) {
|
|
183
|
+
findings.push({
|
|
184
|
+
id: 'SCAN-PWD-001',
|
|
185
|
+
title: 'No password policy configured / 未配置密碼策略',
|
|
186
|
+
description: 'No password quality policy files were found on this Linux system. ' +
|
|
187
|
+
'Neither /etc/pam.d/common-password nor /etc/security/pwquality.conf exist. / ' +
|
|
188
|
+
'在此 Linux 系統上未找到密碼品質策略檔案。' +
|
|
189
|
+
'/etc/pam.d/common-password 和 /etc/security/pwquality.conf 均不存在。',
|
|
190
|
+
severity: 'high',
|
|
191
|
+
category: 'password',
|
|
192
|
+
remediation: 'Install libpam-pwquality and configure /etc/security/pwquality.conf ' +
|
|
193
|
+
'with appropriate password complexity and length requirements. / ' +
|
|
194
|
+
'安裝 libpam-pwquality 並配置 /etc/security/pwquality.conf,' +
|
|
195
|
+
'設定適當的密碼複雜度和長度要求。',
|
|
196
|
+
complianceRef: '4.5',
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
return findings;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Check password policy on Windows
|
|
203
|
+
* 檢查 Windows 上的密碼策略
|
|
204
|
+
*
|
|
205
|
+
* Uses 'net accounts' to retrieve the current password policy settings.
|
|
206
|
+
* 使用 'net accounts' 來擷取目前的密碼策略設定。
|
|
207
|
+
*
|
|
208
|
+
* @returns Array of findings related to Windows password policy / 與 Windows 密碼策略相關的發現陣列
|
|
209
|
+
*/
|
|
210
|
+
async function checkWindowsPolicy() {
|
|
211
|
+
const findings = [];
|
|
212
|
+
const output = await safeExecFile('net', ['accounts']);
|
|
213
|
+
if (!output) {
|
|
214
|
+
findings.push({
|
|
215
|
+
id: 'SCAN-PWD-001',
|
|
216
|
+
title: 'Unable to retrieve password policy / 無法擷取密碼策略',
|
|
217
|
+
description: 'Could not run "net accounts" to retrieve the Windows password policy. / ' +
|
|
218
|
+
'無法執行 "net accounts" 來擷取 Windows 密碼策略。',
|
|
219
|
+
severity: 'medium',
|
|
220
|
+
category: 'password',
|
|
221
|
+
remediation: 'Run this scan with administrator privileges to read the password policy. / ' +
|
|
222
|
+
'以管理員權限執行此掃描以讀取密碼策略。',
|
|
223
|
+
complianceRef: '4.5',
|
|
224
|
+
});
|
|
225
|
+
return findings;
|
|
226
|
+
}
|
|
227
|
+
// Parse minimum password length
|
|
228
|
+
// 解析最小密碼長度
|
|
229
|
+
const minLengthMatch = output.match(/Minimum password length\s*:\s*(\d+)/i);
|
|
230
|
+
const minLength = minLengthMatch ? parseInt(minLengthMatch[1] ?? '0', 10) : 0;
|
|
231
|
+
if (minLength < 8) {
|
|
232
|
+
findings.push({
|
|
233
|
+
id: 'SCAN-PWD-001',
|
|
234
|
+
title: 'Insufficient minimum password length / 最小密碼長度不足',
|
|
235
|
+
description: `Windows minimum password length is set to ${minLength}. ` +
|
|
236
|
+
'A minimum of 8 characters is recommended. / ' +
|
|
237
|
+
`Windows 最小密碼長度設定為 ${minLength}。建議至少 8 個字元。`,
|
|
238
|
+
severity: minLength === 0 ? 'high' : 'medium',
|
|
239
|
+
category: 'password',
|
|
240
|
+
remediation: 'Use Group Policy (secpol.msc) to set the minimum password length to at least 8 characters. / ' +
|
|
241
|
+
'使用群組原則 (secpol.msc) 將最小密碼長度設定為至少 8 個字元。',
|
|
242
|
+
complianceRef: '4.5',
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
// Parse maximum password age
|
|
246
|
+
// 解析最大密碼使用天數
|
|
247
|
+
const maxAgeMatch = output.match(/Maximum password age\s*\(days\)\s*:\s*(\w+)/i);
|
|
248
|
+
const maxAgeStr = maxAgeMatch?.[1] ?? '';
|
|
249
|
+
if (maxAgeStr.toLowerCase() === 'unlimited' || maxAgeStr === '0') {
|
|
250
|
+
findings.push({
|
|
251
|
+
id: 'SCAN-PWD-001',
|
|
252
|
+
title: 'No password expiration policy / 無密碼到期策略',
|
|
253
|
+
description: 'Windows password policy has no maximum password age. ' +
|
|
254
|
+
'Passwords that never expire increase the risk of credential compromise. / ' +
|
|
255
|
+
'Windows 密碼策略未設定最大密碼使用天數。' +
|
|
256
|
+
'永不過期的密碼增加了憑證被破解的風險。',
|
|
257
|
+
severity: 'medium',
|
|
258
|
+
category: 'password',
|
|
259
|
+
remediation: 'Set a maximum password age of 90 days or less via Group Policy. / ' +
|
|
260
|
+
'透過群組原則設定最大密碼使用天數為 90 天或更短。',
|
|
261
|
+
complianceRef: '4.5',
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
// Parse lockout threshold
|
|
265
|
+
// 解析鎖定閾值
|
|
266
|
+
const lockoutMatch = output.match(/Lockout threshold\s*:\s*(\w+)/i);
|
|
267
|
+
const lockoutStr = lockoutMatch?.[1] ?? '';
|
|
268
|
+
if (lockoutStr.toLowerCase() === 'never' || lockoutStr === '0') {
|
|
269
|
+
findings.push({
|
|
270
|
+
id: 'SCAN-PWD-001',
|
|
271
|
+
title: 'No account lockout policy / 無帳號鎖定策略',
|
|
272
|
+
description: 'No account lockout threshold is configured. ' +
|
|
273
|
+
'This allows unlimited password guessing attempts. / ' +
|
|
274
|
+
'未配置帳號鎖定閾值。這允許無限次密碼猜測嘗試。',
|
|
275
|
+
severity: 'high',
|
|
276
|
+
category: 'password',
|
|
277
|
+
remediation: 'Configure an account lockout threshold of 5 or fewer failed attempts ' +
|
|
278
|
+
'via Group Policy. / ' +
|
|
279
|
+
'透過群組原則配置帳號鎖定閾值為 5 次或更少的失敗嘗試。',
|
|
280
|
+
complianceRef: '4.5',
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
return findings;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Check password policy strength on the current platform
|
|
287
|
+
* 檢查目前平台上的密碼策略強度
|
|
288
|
+
*
|
|
289
|
+
* Cross-platform password policy checker that dispatches to the appropriate
|
|
290
|
+
* platform-specific implementation.
|
|
291
|
+
* 跨平台密碼策略檢查器,分派到適當的平台特定實作。
|
|
292
|
+
*
|
|
293
|
+
* @returns Array of password policy findings / 密碼策略發現陣列
|
|
294
|
+
*/
|
|
295
|
+
export async function checkPasswordPolicy() {
|
|
296
|
+
const currentPlatform = osPlatform();
|
|
297
|
+
logger.info(`Checking password policy on ${currentPlatform}`);
|
|
298
|
+
try {
|
|
299
|
+
let findings = [];
|
|
300
|
+
switch (currentPlatform) {
|
|
301
|
+
case 'darwin':
|
|
302
|
+
findings = await checkMacOSPolicy();
|
|
303
|
+
break;
|
|
304
|
+
case 'linux':
|
|
305
|
+
findings = await checkLinuxPolicy();
|
|
306
|
+
break;
|
|
307
|
+
case 'win32':
|
|
308
|
+
findings = await checkWindowsPolicy();
|
|
309
|
+
break;
|
|
310
|
+
default:
|
|
311
|
+
logger.warn(`Unsupported platform for password policy check: ${currentPlatform}`);
|
|
312
|
+
return [];
|
|
313
|
+
}
|
|
314
|
+
logger.info(`Password policy check complete: ${findings.length} finding(s)`);
|
|
315
|
+
return findings;
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
logger.error('Password policy check failed', {
|
|
319
|
+
error: err instanceof Error ? err.message : String(err),
|
|
320
|
+
});
|
|
321
|
+
return [];
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=password-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password-policy.js","sourceRoot":"","sources":["../../src/scanners/password-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote DNS security record checker (SPF, DMARC, DKIM).
|
|
3
|
+
* @module @panguard-ai/panguard-scan/scanners/remote/dns-checker
|
|
4
|
+
*/
|
|
5
|
+
import type { Finding } from '../types.js';
|
|
6
|
+
import type { Language } from '@panguard-ai/core';
|
|
7
|
+
export interface DNSCheckResult {
|
|
8
|
+
hasSPF: boolean;
|
|
9
|
+
hasDMARC: boolean;
|
|
10
|
+
hasDKIM: boolean;
|
|
11
|
+
spfRecord?: string;
|
|
12
|
+
dmarcRecord?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Check DNS security records for a domain.
|
|
16
|
+
*/
|
|
17
|
+
export declare function checkDNS(host: string, lang: Language): Promise<{
|
|
18
|
+
findings: Finding[];
|
|
19
|
+
result: DNSCheckResult;
|
|
20
|
+
}>;
|
|
21
|
+
//# sourceMappingURL=dns-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dns-checker.d.ts","sourceRoot":"","sources":["../../../src/scanners/remote/dns-checker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC,CAyG1D"}
|