@panguard-ai/core 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/adapters/adapter-registry.d.ts +150 -0
- package/dist/adapters/adapter-registry.d.ts.map +1 -0
- package/dist/adapters/adapter-registry.js +271 -0
- package/dist/adapters/adapter-registry.js.map +1 -0
- package/dist/adapters/base-adapter.d.ts +101 -0
- package/dist/adapters/base-adapter.d.ts.map +1 -0
- package/dist/adapters/base-adapter.js +160 -0
- package/dist/adapters/base-adapter.js.map +1 -0
- package/dist/adapters/defender-adapter.d.ts +90 -0
- package/dist/adapters/defender-adapter.d.ts.map +1 -0
- package/dist/adapters/defender-adapter.js +227 -0
- package/dist/adapters/defender-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +22 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +23 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/syslog-adapter.d.ts +207 -0
- package/dist/adapters/syslog-adapter.d.ts.map +1 -0
- package/dist/adapters/syslog-adapter.js +432 -0
- package/dist/adapters/syslog-adapter.js.map +1 -0
- package/dist/adapters/types.d.ts +135 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +13 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/adapters/wazuh-adapter.d.ts +120 -0
- package/dist/adapters/wazuh-adapter.d.ts.map +1 -0
- package/dist/adapters/wazuh-adapter.js +266 -0
- package/dist/adapters/wazuh-adapter.js.map +1 -0
- package/dist/ai/claude-provider.d.ts +66 -0
- package/dist/ai/claude-provider.d.ts.map +1 -0
- package/dist/ai/claude-provider.js +166 -0
- package/dist/ai/claude-provider.js.map +1 -0
- package/dist/ai/funnel-router.d.ts +75 -0
- package/dist/ai/funnel-router.d.ts.map +1 -0
- package/dist/ai/funnel-router.js +173 -0
- package/dist/ai/funnel-router.js.map +1 -0
- package/dist/ai/index.d.ts +77 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +95 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/ollama-provider.d.ts +73 -0
- package/dist/ai/ollama-provider.d.ts.map +1 -0
- package/dist/ai/ollama-provider.js +200 -0
- package/dist/ai/ollama-provider.js.map +1 -0
- package/dist/ai/openai-provider.d.ts +70 -0
- package/dist/ai/openai-provider.d.ts.map +1 -0
- package/dist/ai/openai-provider.js +175 -0
- package/dist/ai/openai-provider.js.map +1 -0
- package/dist/ai/prompts/event-classifier.d.ts +25 -0
- package/dist/ai/prompts/event-classifier.d.ts.map +1 -0
- package/dist/ai/prompts/event-classifier.js +94 -0
- package/dist/ai/prompts/event-classifier.js.map +1 -0
- package/dist/ai/prompts/index.d.ts +13 -0
- package/dist/ai/prompts/index.d.ts.map +1 -0
- package/dist/ai/prompts/index.js +13 -0
- package/dist/ai/prompts/index.js.map +1 -0
- package/dist/ai/prompts/report-generator.d.ts +25 -0
- package/dist/ai/prompts/report-generator.d.ts.map +1 -0
- package/dist/ai/prompts/report-generator.js +131 -0
- package/dist/ai/prompts/report-generator.js.map +1 -0
- package/dist/ai/prompts/threat-analyzer.d.ts +26 -0
- package/dist/ai/prompts/threat-analyzer.d.ts.map +1 -0
- package/dist/ai/prompts/threat-analyzer.js +75 -0
- package/dist/ai/prompts/threat-analyzer.js.map +1 -0
- package/dist/ai/provider-base.d.ts +100 -0
- package/dist/ai/provider-base.d.ts.map +1 -0
- package/dist/ai/provider-base.js +166 -0
- package/dist/ai/provider-base.js.map +1 -0
- package/dist/ai/response-parser.d.ts +36 -0
- package/dist/ai/response-parser.d.ts.map +1 -0
- package/dist/ai/response-parser.js +195 -0
- package/dist/ai/response-parser.js.map +1 -0
- package/dist/ai/token-tracker.d.ts +72 -0
- package/dist/ai/token-tracker.d.ts.map +1 -0
- package/dist/ai/token-tracker.js +145 -0
- package/dist/ai/token-tracker.js.map +1 -0
- package/dist/ai/types.d.ts +138 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +12 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/cli/index.d.ts +146 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +515 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompts.d.ts +58 -0
- package/dist/cli/prompts.d.ts.map +1 -0
- package/dist/cli/prompts.js +327 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/cli/wizard.d.ts +58 -0
- package/dist/cli/wizard.d.ts.map +1 -0
- package/dist/cli/wizard.js +200 -0
- package/dist/cli/wizard.js.map +1 -0
- package/dist/discovery/firewall-checker.d.ts +28 -0
- package/dist/discovery/firewall-checker.d.ts.map +1 -0
- package/dist/discovery/firewall-checker.js +379 -0
- package/dist/discovery/firewall-checker.js.map +1 -0
- package/dist/discovery/index.d.ts +23 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +29 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/network-scanner.d.ts +60 -0
- package/dist/discovery/network-scanner.d.ts.map +1 -0
- package/dist/discovery/network-scanner.js +640 -0
- package/dist/discovery/network-scanner.js.map +1 -0
- package/dist/discovery/os-detector.d.ts +24 -0
- package/dist/discovery/os-detector.d.ts.map +1 -0
- package/dist/discovery/os-detector.js +253 -0
- package/dist/discovery/os-detector.js.map +1 -0
- package/dist/discovery/osquery-provider.d.ts +127 -0
- package/dist/discovery/osquery-provider.d.ts.map +1 -0
- package/dist/discovery/osquery-provider.js +214 -0
- package/dist/discovery/osquery-provider.js.map +1 -0
- package/dist/discovery/risk-scorer.d.ts +66 -0
- package/dist/discovery/risk-scorer.d.ts.map +1 -0
- package/dist/discovery/risk-scorer.js +294 -0
- package/dist/discovery/risk-scorer.js.map +1 -0
- package/dist/discovery/security-tools.d.ts +31 -0
- package/dist/discovery/security-tools.d.ts.map +1 -0
- package/dist/discovery/security-tools.js +346 -0
- package/dist/discovery/security-tools.js.map +1 -0
- package/dist/discovery/service-detector.d.ts +28 -0
- package/dist/discovery/service-detector.d.ts.map +1 -0
- package/dist/discovery/service-detector.js +300 -0
- package/dist/discovery/service-detector.js.map +1 -0
- package/dist/discovery/types.d.ts +502 -0
- package/dist/discovery/types.d.ts.map +1 -0
- package/dist/discovery/types.js +12 -0
- package/dist/discovery/types.js.map +1 -0
- package/dist/discovery/user-auditor.d.ts +28 -0
- package/dist/discovery/user-auditor.d.ts.map +1 -0
- package/dist/discovery/user-auditor.js +385 -0
- package/dist/discovery/user-auditor.js.map +1 -0
- package/dist/i18n/config.d.ts +45 -0
- package/dist/i18n/config.d.ts.map +1 -0
- package/dist/i18n/config.js +135 -0
- package/dist/i18n/config.js.map +1 -0
- package/dist/i18n/index.d.ts +8 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +8 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/monitor/event-normalizer.d.ts +102 -0
- package/dist/monitor/event-normalizer.d.ts.map +1 -0
- package/dist/monitor/event-normalizer.js +195 -0
- package/dist/monitor/event-normalizer.js.map +1 -0
- package/dist/monitor/file-monitor.d.ts +90 -0
- package/dist/monitor/file-monitor.d.ts.map +1 -0
- package/dist/monitor/file-monitor.js +222 -0
- package/dist/monitor/file-monitor.js.map +1 -0
- package/dist/monitor/index.d.ts +147 -0
- package/dist/monitor/index.d.ts.map +1 -0
- package/dist/monitor/index.js +293 -0
- package/dist/monitor/index.js.map +1 -0
- package/dist/monitor/log-monitor.d.ts +102 -0
- package/dist/monitor/log-monitor.d.ts.map +1 -0
- package/dist/monitor/log-monitor.js +245 -0
- package/dist/monitor/log-monitor.js.map +1 -0
- package/dist/monitor/network-monitor.d.ts +103 -0
- package/dist/monitor/network-monitor.d.ts.map +1 -0
- package/dist/monitor/network-monitor.js +336 -0
- package/dist/monitor/network-monitor.js.map +1 -0
- package/dist/monitor/process-monitor.d.ts +108 -0
- package/dist/monitor/process-monitor.d.ts.map +1 -0
- package/dist/monitor/process-monitor.js +245 -0
- package/dist/monitor/process-monitor.js.map +1 -0
- package/dist/monitor/threat-intel-feeds.d.ts +141 -0
- package/dist/monitor/threat-intel-feeds.d.ts.map +1 -0
- package/dist/monitor/threat-intel-feeds.js +430 -0
- package/dist/monitor/threat-intel-feeds.js.map +1 -0
- package/dist/monitor/threat-intel.d.ts +83 -0
- package/dist/monitor/threat-intel.d.ts.map +1 -0
- package/dist/monitor/threat-intel.js +215 -0
- package/dist/monitor/threat-intel.js.map +1 -0
- package/dist/monitor/types.d.ts +65 -0
- package/dist/monitor/types.d.ts.map +1 -0
- package/dist/monitor/types.js +20 -0
- package/dist/monitor/types.js.map +1 -0
- package/dist/rules/index.d.ts +115 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +244 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/rule-loader.d.ts +54 -0
- package/dist/rules/rule-loader.d.ts.map +1 -0
- package/dist/rules/rule-loader.js +167 -0
- package/dist/rules/rule-loader.js.map +1 -0
- package/dist/rules/sigma-matcher.d.ts +40 -0
- package/dist/rules/sigma-matcher.d.ts.map +1 -0
- package/dist/rules/sigma-matcher.js +447 -0
- package/dist/rules/sigma-matcher.js.map +1 -0
- package/dist/rules/sigma-parser.d.ts +36 -0
- package/dist/rules/sigma-parser.d.ts.map +1 -0
- package/dist/rules/sigma-parser.js +180 -0
- package/dist/rules/sigma-parser.js.map +1 -0
- package/dist/rules/types.d.ts +112 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +11 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/rules/yara-scanner.d.ts +103 -0
- package/dist/rules/yara-scanner.d.ts.map +1 -0
- package/dist/rules/yara-scanner.js +421 -0
- package/dist/rules/yara-scanner.js.map +1 -0
- package/dist/scoring/achievements.d.ts +76 -0
- package/dist/scoring/achievements.d.ts.map +1 -0
- package/dist/scoring/achievements.js +211 -0
- package/dist/scoring/achievements.js.map +1 -0
- package/dist/scoring/index.d.ts +3 -0
- package/dist/scoring/index.d.ts.map +1 -0
- package/dist/scoring/index.js +3 -0
- package/dist/scoring/index.js.map +1 -0
- package/dist/scoring/security-score.d.ts +60 -0
- package/dist/scoring/security-score.d.ts.map +1 -0
- package/dist/scoring/security-score.js +211 -0
- package/dist/scoring/security-score.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +38 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +71 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validation.d.ts +35 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +56 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network information scanner
|
|
3
|
+
* 網路資訊掃描器
|
|
4
|
+
*
|
|
5
|
+
* Scans network interfaces, open ports, active connections,
|
|
6
|
+
* gateway, and DNS configuration across macOS, Linux, and Windows.
|
|
7
|
+
* 掃描跨 macOS、Linux 和 Windows 的網路介面、開放埠、活躍連線、閘道和 DNS 配置。
|
|
8
|
+
*
|
|
9
|
+
* @module @panguard-ai/core/discovery/network-scanner
|
|
10
|
+
*/
|
|
11
|
+
import { execFile } from 'child_process';
|
|
12
|
+
import { promisify } from 'util';
|
|
13
|
+
import dns from 'dns';
|
|
14
|
+
import { networkInterfaces as osNetworkInterfaces, platform as osPlatform } from 'os';
|
|
15
|
+
import { readFile } from 'fs/promises';
|
|
16
|
+
import { createLogger } from '../utils/logger.js';
|
|
17
|
+
const execFileAsync = promisify(execFile);
|
|
18
|
+
const logger = createLogger('discovery:network');
|
|
19
|
+
/**
|
|
20
|
+
* Safely execute a command and return stdout, or empty string on failure
|
|
21
|
+
* 安全地執行命令並回傳 stdout,失敗時回傳空字串
|
|
22
|
+
*
|
|
23
|
+
* @param cmd - Command to execute / 要執行的命令
|
|
24
|
+
* @param args - Command arguments / 命令參數
|
|
25
|
+
* @returns stdout output trimmed / 修剪後的 stdout 輸出
|
|
26
|
+
*/
|
|
27
|
+
async function safeExec(cmd, args) {
|
|
28
|
+
try {
|
|
29
|
+
const { stdout } = await execFileAsync(cmd, args, { timeout: 15_000 });
|
|
30
|
+
return stdout.trim();
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
logger.debug(`Command failed: ${cmd} ${args.join(' ')}`, {
|
|
34
|
+
error: err instanceof Error ? err.message : String(err),
|
|
35
|
+
});
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get all network interfaces from the operating system
|
|
41
|
+
* 從作業系統取得所有網路介面
|
|
42
|
+
*
|
|
43
|
+
* Uses Node.js os.networkInterfaces() for cross-platform compatibility.
|
|
44
|
+
* 使用 Node.js os.networkInterfaces() 實現跨平台相容性。
|
|
45
|
+
*
|
|
46
|
+
* @returns Array of detected network interfaces / 偵測到的網路介面陣列
|
|
47
|
+
*/
|
|
48
|
+
export function getNetworkInterfaces() {
|
|
49
|
+
const interfaces = [];
|
|
50
|
+
try {
|
|
51
|
+
const nets = osNetworkInterfaces();
|
|
52
|
+
for (const [name, addrs] of Object.entries(nets)) {
|
|
53
|
+
if (!addrs)
|
|
54
|
+
continue;
|
|
55
|
+
for (const addr of addrs) {
|
|
56
|
+
if (addr.family === 'IPv4') {
|
|
57
|
+
interfaces.push({
|
|
58
|
+
name,
|
|
59
|
+
ip: addr.address,
|
|
60
|
+
mac: addr.mac,
|
|
61
|
+
netmask: addr.netmask,
|
|
62
|
+
internal: addr.internal,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
logger.info(`Detected ${interfaces.length} network interfaces`);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
logger.error('Failed to enumerate network interfaces', {
|
|
71
|
+
error: err instanceof Error ? err.message : String(err),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return interfaces;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Map a well-known port number to its service name
|
|
78
|
+
* 將常見埠號映射到其服務名稱
|
|
79
|
+
*
|
|
80
|
+
* @param port - Port number / 埠號
|
|
81
|
+
* @returns Service name or 'unknown' / 服務名稱或 'unknown'
|
|
82
|
+
*/
|
|
83
|
+
function mapPortToService(port) {
|
|
84
|
+
const wellKnownPorts = {
|
|
85
|
+
20: 'ftp-data',
|
|
86
|
+
21: 'ftp',
|
|
87
|
+
22: 'ssh',
|
|
88
|
+
23: 'telnet',
|
|
89
|
+
25: 'smtp',
|
|
90
|
+
53: 'dns',
|
|
91
|
+
67: 'dhcp',
|
|
92
|
+
68: 'dhcp',
|
|
93
|
+
80: 'http',
|
|
94
|
+
110: 'pop3',
|
|
95
|
+
119: 'nntp',
|
|
96
|
+
123: 'ntp',
|
|
97
|
+
135: 'msrpc',
|
|
98
|
+
137: 'netbios-ns',
|
|
99
|
+
138: 'netbios-dgm',
|
|
100
|
+
139: 'netbios-ssn',
|
|
101
|
+
143: 'imap',
|
|
102
|
+
161: 'snmp',
|
|
103
|
+
162: 'snmp-trap',
|
|
104
|
+
389: 'ldap',
|
|
105
|
+
443: 'https',
|
|
106
|
+
445: 'microsoft-ds',
|
|
107
|
+
465: 'smtps',
|
|
108
|
+
514: 'syslog',
|
|
109
|
+
587: 'submission',
|
|
110
|
+
636: 'ldaps',
|
|
111
|
+
993: 'imaps',
|
|
112
|
+
995: 'pop3s',
|
|
113
|
+
1433: 'mssql',
|
|
114
|
+
1434: 'mssql-monitor',
|
|
115
|
+
1521: 'oracle',
|
|
116
|
+
3306: 'mysql',
|
|
117
|
+
3389: 'rdp',
|
|
118
|
+
5432: 'postgresql',
|
|
119
|
+
5900: 'vnc',
|
|
120
|
+
6379: 'redis',
|
|
121
|
+
8080: 'http-proxy',
|
|
122
|
+
8443: 'https-alt',
|
|
123
|
+
9200: 'elasticsearch',
|
|
124
|
+
27017: 'mongodb',
|
|
125
|
+
};
|
|
126
|
+
return wellKnownPorts[port] ?? 'unknown';
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Parse macOS lsof output for open/listening ports
|
|
130
|
+
* 解析 macOS lsof 輸出以取得開放/監聽埠
|
|
131
|
+
*
|
|
132
|
+
* @param output - Raw lsof -i -P -n output / 原始 lsof -i -P -n 輸出
|
|
133
|
+
* @returns Parsed port info array / 解析後的埠資訊陣列
|
|
134
|
+
*/
|
|
135
|
+
function parseLsofOutput(output) {
|
|
136
|
+
const ports = [];
|
|
137
|
+
const seen = new Set();
|
|
138
|
+
const lines = output.split('\n').slice(1);
|
|
139
|
+
for (const line of lines) {
|
|
140
|
+
const parts = line.trim().split(/\s+/);
|
|
141
|
+
if (parts.length < 9)
|
|
142
|
+
continue;
|
|
143
|
+
const processName = parts[0] ?? '';
|
|
144
|
+
const pidStr = parts[1] ?? '';
|
|
145
|
+
const pid = parseInt(pidStr, 10);
|
|
146
|
+
const nameField = parts[8] ?? '';
|
|
147
|
+
if (!nameField)
|
|
148
|
+
continue;
|
|
149
|
+
const portMatch = nameField.match(/:(\d+)$/);
|
|
150
|
+
if (!portMatch)
|
|
151
|
+
continue;
|
|
152
|
+
const portStr = portMatch[1];
|
|
153
|
+
if (!portStr)
|
|
154
|
+
continue;
|
|
155
|
+
const port = parseInt(portStr, 10);
|
|
156
|
+
if (isNaN(port))
|
|
157
|
+
continue;
|
|
158
|
+
const state = (parts[9] ?? 'LISTEN').replace(/[()]/g, '');
|
|
159
|
+
const protoField = parts[7] ?? '';
|
|
160
|
+
const protocol = protoField.toLowerCase().includes('udp') ? 'udp' : 'tcp';
|
|
161
|
+
const key = `${port}:${protocol}:${state}`;
|
|
162
|
+
if (seen.has(key))
|
|
163
|
+
continue;
|
|
164
|
+
seen.add(key);
|
|
165
|
+
ports.push({
|
|
166
|
+
port,
|
|
167
|
+
protocol,
|
|
168
|
+
state,
|
|
169
|
+
pid: isNaN(pid) ? undefined : pid,
|
|
170
|
+
process: processName,
|
|
171
|
+
service: mapPortToService(port),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return ports;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Parse Linux ss output for open/listening ports
|
|
178
|
+
* 解析 Linux ss 輸出以取得開放/監聯埠
|
|
179
|
+
*
|
|
180
|
+
* @param output - Raw ss -tlnp output / 原始 ss -tlnp 輸出
|
|
181
|
+
* @returns Parsed port info array / 解析後的埠資訊陣列
|
|
182
|
+
*/
|
|
183
|
+
function parseSsOutput(output) {
|
|
184
|
+
const ports = [];
|
|
185
|
+
const lines = output.split('\n').slice(1);
|
|
186
|
+
for (const line of lines) {
|
|
187
|
+
const parts = line.trim().split(/\s+/);
|
|
188
|
+
if (parts.length < 4)
|
|
189
|
+
continue;
|
|
190
|
+
const state = parts[0] ?? 'LISTEN';
|
|
191
|
+
const localAddr = parts[3] ?? '';
|
|
192
|
+
if (!localAddr)
|
|
193
|
+
continue;
|
|
194
|
+
const portMatch = localAddr.match(/:(\d+)$/);
|
|
195
|
+
if (!portMatch)
|
|
196
|
+
continue;
|
|
197
|
+
const portStr = portMatch[1];
|
|
198
|
+
if (!portStr)
|
|
199
|
+
continue;
|
|
200
|
+
const port = parseInt(portStr, 10);
|
|
201
|
+
if (isNaN(port))
|
|
202
|
+
continue;
|
|
203
|
+
let processName = '';
|
|
204
|
+
let pid;
|
|
205
|
+
const processField = parts.find((p) => p.startsWith('users:'));
|
|
206
|
+
if (processField) {
|
|
207
|
+
const pidMatch = processField.match(/pid=(\d+)/);
|
|
208
|
+
const nameMatch = processField.match(/\("([^"]+)"/);
|
|
209
|
+
if (pidMatch?.[1])
|
|
210
|
+
pid = parseInt(pidMatch[1], 10);
|
|
211
|
+
if (nameMatch?.[1])
|
|
212
|
+
processName = nameMatch[1];
|
|
213
|
+
}
|
|
214
|
+
ports.push({
|
|
215
|
+
port,
|
|
216
|
+
protocol: 'tcp',
|
|
217
|
+
state,
|
|
218
|
+
pid,
|
|
219
|
+
process: processName,
|
|
220
|
+
service: mapPortToService(port),
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return ports;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Parse Windows netstat output for open/listening ports
|
|
227
|
+
* 解析 Windows netstat 輸出以取得開放/監聽埠
|
|
228
|
+
*
|
|
229
|
+
* @param output - Raw netstat -an output / 原始 netstat -an 輸出
|
|
230
|
+
* @returns Parsed port info array / 解析後的埠資訊陣列
|
|
231
|
+
*/
|
|
232
|
+
function parseNetstatPortsOutput(output) {
|
|
233
|
+
const ports = [];
|
|
234
|
+
const seen = new Set();
|
|
235
|
+
const lines = output.split('\n');
|
|
236
|
+
for (const line of lines) {
|
|
237
|
+
const parts = line.trim().split(/\s+/);
|
|
238
|
+
if (parts.length < 4)
|
|
239
|
+
continue;
|
|
240
|
+
const protocol = (parts[0] ?? '').toLowerCase();
|
|
241
|
+
if (protocol !== 'tcp' && protocol !== 'udp')
|
|
242
|
+
continue;
|
|
243
|
+
const localAddr = parts[1] ?? '';
|
|
244
|
+
const state = parts[3] ?? 'LISTENING';
|
|
245
|
+
if (protocol === 'tcp' && !state.includes('LISTEN'))
|
|
246
|
+
continue;
|
|
247
|
+
const portMatch = localAddr.match(/:(\d+)$/);
|
|
248
|
+
if (!portMatch)
|
|
249
|
+
continue;
|
|
250
|
+
const portStr = portMatch[1];
|
|
251
|
+
if (!portStr)
|
|
252
|
+
continue;
|
|
253
|
+
const port = parseInt(portStr, 10);
|
|
254
|
+
if (isNaN(port))
|
|
255
|
+
continue;
|
|
256
|
+
const key = `${port}:${protocol}`;
|
|
257
|
+
if (seen.has(key))
|
|
258
|
+
continue;
|
|
259
|
+
seen.add(key);
|
|
260
|
+
ports.push({
|
|
261
|
+
port,
|
|
262
|
+
protocol,
|
|
263
|
+
state,
|
|
264
|
+
pid: undefined,
|
|
265
|
+
process: '',
|
|
266
|
+
service: mapPortToService(port),
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return ports;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Scan for open/listening ports on the system
|
|
273
|
+
* 掃描系統上的開放/監聽埠
|
|
274
|
+
*
|
|
275
|
+
* @returns Array of detected open ports / 偵測到的開放埠陣列
|
|
276
|
+
*/
|
|
277
|
+
export async function scanOpenPorts() {
|
|
278
|
+
const currentPlatform = osPlatform();
|
|
279
|
+
logger.info(`Scanning open ports on ${currentPlatform}`);
|
|
280
|
+
try {
|
|
281
|
+
switch (currentPlatform) {
|
|
282
|
+
case 'darwin': {
|
|
283
|
+
const output = await safeExec('lsof', ['-i', '-P', '-n']);
|
|
284
|
+
if (!output)
|
|
285
|
+
return [];
|
|
286
|
+
const ports = parseLsofOutput(output);
|
|
287
|
+
logger.info(`Found ${ports.length} open ports via lsof`);
|
|
288
|
+
return ports;
|
|
289
|
+
}
|
|
290
|
+
case 'linux': {
|
|
291
|
+
const output = await safeExec('ss', ['-tlnp']);
|
|
292
|
+
if (!output)
|
|
293
|
+
return [];
|
|
294
|
+
const ports = parseSsOutput(output);
|
|
295
|
+
logger.info(`Found ${ports.length} open ports via ss`);
|
|
296
|
+
return ports;
|
|
297
|
+
}
|
|
298
|
+
case 'win32': {
|
|
299
|
+
const output = await safeExec('netstat', ['-an']);
|
|
300
|
+
if (!output)
|
|
301
|
+
return [];
|
|
302
|
+
const ports = parseNetstatPortsOutput(output);
|
|
303
|
+
logger.info(`Found ${ports.length} open ports via netstat`);
|
|
304
|
+
return ports;
|
|
305
|
+
}
|
|
306
|
+
default:
|
|
307
|
+
logger.warn(`Unsupported platform for port scanning: ${currentPlatform}`);
|
|
308
|
+
return [];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
catch (err) {
|
|
312
|
+
logger.error('Port scanning failed', {
|
|
313
|
+
error: err instanceof Error ? err.message : String(err),
|
|
314
|
+
});
|
|
315
|
+
return [];
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Parse an address:port pair from a regex match result
|
|
320
|
+
* 從正規表達式匹配結果解析 address:port 對
|
|
321
|
+
*
|
|
322
|
+
* @param match - Regex match result / 正規表達式匹配結果
|
|
323
|
+
* @returns Parsed address and port, or null / 解析後的位址和埠,或 null
|
|
324
|
+
*/
|
|
325
|
+
function parseAddrPort(match) {
|
|
326
|
+
if (!match)
|
|
327
|
+
return null;
|
|
328
|
+
const addr = match[1];
|
|
329
|
+
const portStr = match[2];
|
|
330
|
+
if (!addr || !portStr)
|
|
331
|
+
return null;
|
|
332
|
+
const port = parseInt(portStr, 10);
|
|
333
|
+
if (isNaN(port))
|
|
334
|
+
return null;
|
|
335
|
+
return { address: addr, port };
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Get active network connections
|
|
339
|
+
* 取得活躍網路連線
|
|
340
|
+
*
|
|
341
|
+
* Parses netstat or ss output to enumerate established connections.
|
|
342
|
+
* 解析 netstat 或 ss 輸出以列舉已建立的連線。
|
|
343
|
+
*
|
|
344
|
+
* @returns Array of active connections / 活躍連線陣列
|
|
345
|
+
*/
|
|
346
|
+
export async function getActiveConnections() {
|
|
347
|
+
const currentPlatform = osPlatform();
|
|
348
|
+
const connections = [];
|
|
349
|
+
logger.info(`Getting active connections on ${currentPlatform}`);
|
|
350
|
+
try {
|
|
351
|
+
let output = '';
|
|
352
|
+
switch (currentPlatform) {
|
|
353
|
+
case 'darwin':
|
|
354
|
+
output = await safeExec('netstat', ['-an', '-p', 'tcp']);
|
|
355
|
+
break;
|
|
356
|
+
case 'linux':
|
|
357
|
+
output = await safeExec('ss', ['-tnp']);
|
|
358
|
+
break;
|
|
359
|
+
case 'win32':
|
|
360
|
+
output = await safeExec('netstat', ['-an']);
|
|
361
|
+
break;
|
|
362
|
+
default:
|
|
363
|
+
logger.warn(`Unsupported platform for connection scanning: ${currentPlatform}`);
|
|
364
|
+
return [];
|
|
365
|
+
}
|
|
366
|
+
if (!output)
|
|
367
|
+
return [];
|
|
368
|
+
const lines = output.split('\n');
|
|
369
|
+
const validStates = new Set([
|
|
370
|
+
'ESTABLISHED',
|
|
371
|
+
'TIME_WAIT',
|
|
372
|
+
'CLOSE_WAIT',
|
|
373
|
+
'ESTAB',
|
|
374
|
+
'TIME-WAIT',
|
|
375
|
+
'CLOSE-WAIT',
|
|
376
|
+
]);
|
|
377
|
+
for (const line of lines) {
|
|
378
|
+
const parts = line.trim().split(/\s+/);
|
|
379
|
+
if (currentPlatform === 'darwin') {
|
|
380
|
+
if (parts.length < 6)
|
|
381
|
+
continue;
|
|
382
|
+
const proto = parts[0] ?? '';
|
|
383
|
+
if (!proto.startsWith('tcp'))
|
|
384
|
+
continue;
|
|
385
|
+
const state = parts[5] ?? '';
|
|
386
|
+
if (!validStates.has(state))
|
|
387
|
+
continue;
|
|
388
|
+
const localStr = parts[3] ?? '';
|
|
389
|
+
const remoteStr = parts[4] ?? '';
|
|
390
|
+
const localParsed = parseAddrPort(localStr.match(/^(.+)\.(\d+)$/));
|
|
391
|
+
const remoteParsed = parseAddrPort(remoteStr.match(/^(.+)\.(\d+)$/));
|
|
392
|
+
if (localParsed && remoteParsed) {
|
|
393
|
+
connections.push({
|
|
394
|
+
localAddress: localParsed.address,
|
|
395
|
+
localPort: localParsed.port,
|
|
396
|
+
remoteAddress: remoteParsed.address,
|
|
397
|
+
remotePort: remoteParsed.port,
|
|
398
|
+
state,
|
|
399
|
+
pid: undefined,
|
|
400
|
+
process: '',
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
else if (currentPlatform === 'linux') {
|
|
405
|
+
if (parts.length < 5)
|
|
406
|
+
continue;
|
|
407
|
+
const state = parts[0] ?? '';
|
|
408
|
+
if (!validStates.has(state))
|
|
409
|
+
continue;
|
|
410
|
+
const localStr = parts[3] ?? '';
|
|
411
|
+
const remoteStr = parts[4] ?? '';
|
|
412
|
+
const localParsed = parseAddrPort(localStr.match(/^(.+):(\d+)$/));
|
|
413
|
+
const remoteParsed = parseAddrPort(remoteStr.match(/^(.+):(\d+)$/));
|
|
414
|
+
let pid;
|
|
415
|
+
let processName = '';
|
|
416
|
+
const processField = parts.find((p) => p.startsWith('users:'));
|
|
417
|
+
if (processField) {
|
|
418
|
+
const pidMatch = processField.match(/pid=(\d+)/);
|
|
419
|
+
const nameMatch = processField.match(/\("([^"]+)"/);
|
|
420
|
+
if (pidMatch?.[1])
|
|
421
|
+
pid = parseInt(pidMatch[1], 10);
|
|
422
|
+
if (nameMatch?.[1])
|
|
423
|
+
processName = nameMatch[1];
|
|
424
|
+
}
|
|
425
|
+
if (localParsed && remoteParsed) {
|
|
426
|
+
connections.push({
|
|
427
|
+
localAddress: localParsed.address,
|
|
428
|
+
localPort: localParsed.port,
|
|
429
|
+
remoteAddress: remoteParsed.address,
|
|
430
|
+
remotePort: remoteParsed.port,
|
|
431
|
+
state: state === 'ESTAB' ? 'ESTABLISHED' : state,
|
|
432
|
+
pid,
|
|
433
|
+
process: processName,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
else if (currentPlatform === 'win32') {
|
|
438
|
+
if (parts.length < 4)
|
|
439
|
+
continue;
|
|
440
|
+
const proto = (parts[0] ?? '').toLowerCase();
|
|
441
|
+
if (!proto.startsWith('tcp'))
|
|
442
|
+
continue;
|
|
443
|
+
const state = parts[3] ?? '';
|
|
444
|
+
if (!validStates.has(state))
|
|
445
|
+
continue;
|
|
446
|
+
const localStr = parts[1] ?? '';
|
|
447
|
+
const remoteStr = parts[2] ?? '';
|
|
448
|
+
const localParsed = parseAddrPort(localStr.match(/^(.+):(\d+)$/));
|
|
449
|
+
const remoteParsed = parseAddrPort(remoteStr.match(/^(.+):(\d+)$/));
|
|
450
|
+
if (localParsed && remoteParsed) {
|
|
451
|
+
connections.push({
|
|
452
|
+
localAddress: localParsed.address,
|
|
453
|
+
localPort: localParsed.port,
|
|
454
|
+
remoteAddress: remoteParsed.address,
|
|
455
|
+
remotePort: remoteParsed.port,
|
|
456
|
+
state,
|
|
457
|
+
pid: undefined,
|
|
458
|
+
process: '',
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
logger.info(`Found ${connections.length} active connections`);
|
|
464
|
+
}
|
|
465
|
+
catch (err) {
|
|
466
|
+
logger.error('Active connection scanning failed', {
|
|
467
|
+
error: err instanceof Error ? err.message : String(err),
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
return connections;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Get the default gateway IP address
|
|
474
|
+
* 取得預設閘道 IP 位址
|
|
475
|
+
*
|
|
476
|
+
* @returns Gateway IP address, or 'unknown' / 閘道 IP 位址,或 'unknown'
|
|
477
|
+
*/
|
|
478
|
+
export async function getGateway() {
|
|
479
|
+
const currentPlatform = osPlatform();
|
|
480
|
+
try {
|
|
481
|
+
switch (currentPlatform) {
|
|
482
|
+
case 'darwin': {
|
|
483
|
+
const output = await safeExec('netstat', ['-rn']);
|
|
484
|
+
if (output) {
|
|
485
|
+
for (const line of output.split('\n')) {
|
|
486
|
+
const parts = line.trim().split(/\s+/);
|
|
487
|
+
const dest = parts[0];
|
|
488
|
+
const gw = parts[1];
|
|
489
|
+
if (dest === 'default' && gw) {
|
|
490
|
+
logger.info(`Default gateway: ${gw}`);
|
|
491
|
+
return gw;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
const routeOutput = await safeExec('route', ['-n', 'get', 'default']);
|
|
496
|
+
if (routeOutput) {
|
|
497
|
+
const gwMatch = routeOutput.match(/gateway:\s*(\S+)/);
|
|
498
|
+
const gw = gwMatch?.[1];
|
|
499
|
+
if (gw) {
|
|
500
|
+
logger.info(`Default gateway (via route): ${gw}`);
|
|
501
|
+
return gw;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
case 'linux': {
|
|
507
|
+
const output = await safeExec('ip', ['route', 'show', 'default']);
|
|
508
|
+
if (output) {
|
|
509
|
+
const match = output.match(/default via (\S+)/);
|
|
510
|
+
const gw = match?.[1];
|
|
511
|
+
if (gw) {
|
|
512
|
+
logger.info(`Default gateway: ${gw}`);
|
|
513
|
+
return gw;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
break;
|
|
517
|
+
}
|
|
518
|
+
case 'win32': {
|
|
519
|
+
const output = await safeExec('netstat', ['-rn']);
|
|
520
|
+
if (output) {
|
|
521
|
+
for (const line of output.split('\n')) {
|
|
522
|
+
const parts = line.trim().split(/\s+/);
|
|
523
|
+
const dest = parts[0];
|
|
524
|
+
const gw = parts[2];
|
|
525
|
+
if (dest === '0.0.0.0' && gw) {
|
|
526
|
+
logger.info(`Default gateway: ${gw}`);
|
|
527
|
+
return gw;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
catch (err) {
|
|
536
|
+
logger.error('Gateway detection failed', {
|
|
537
|
+
error: err instanceof Error ? err.message : String(err),
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
logger.warn('Could not determine default gateway');
|
|
541
|
+
return 'unknown';
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Get configured DNS server addresses (synchronous, via Node.js dns module)
|
|
545
|
+
* 取得已配置的 DNS 伺服器位址(同步,透過 Node.js dns 模組)
|
|
546
|
+
*
|
|
547
|
+
* @returns Array of DNS server IP addresses / DNS 伺服器 IP 位址陣列
|
|
548
|
+
*/
|
|
549
|
+
export function getDnsServers() {
|
|
550
|
+
try {
|
|
551
|
+
const servers = dns.getServers();
|
|
552
|
+
if (servers.length > 0) {
|
|
553
|
+
logger.info(`DNS servers: ${servers.join(', ')}`);
|
|
554
|
+
return servers;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
catch {
|
|
558
|
+
// Fallback: empty / 備用:空陣列
|
|
559
|
+
}
|
|
560
|
+
logger.warn('Could not determine DNS servers via Node.js dns module');
|
|
561
|
+
return [];
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Get configured DNS server addresses with platform-specific fallbacks
|
|
565
|
+
* 取得已配置的 DNS 伺服器位址(含平台特定備用方案)
|
|
566
|
+
*
|
|
567
|
+
* @returns Array of DNS server IP addresses / DNS 伺服器 IP 位址陣列
|
|
568
|
+
*/
|
|
569
|
+
export async function getDnsServersAsync() {
|
|
570
|
+
const syncServers = getDnsServers();
|
|
571
|
+
if (syncServers.length > 0)
|
|
572
|
+
return syncServers;
|
|
573
|
+
const currentPlatform = osPlatform();
|
|
574
|
+
try {
|
|
575
|
+
switch (currentPlatform) {
|
|
576
|
+
case 'darwin': {
|
|
577
|
+
const output = await safeExec('scutil', ['--dns']);
|
|
578
|
+
if (output) {
|
|
579
|
+
const servers = [];
|
|
580
|
+
const matches = output.matchAll(/nameserver\[\d+\]\s*:\s*(\S+)/g);
|
|
581
|
+
for (const m of matches) {
|
|
582
|
+
const addr = m[1];
|
|
583
|
+
if (addr && !servers.includes(addr))
|
|
584
|
+
servers.push(addr);
|
|
585
|
+
}
|
|
586
|
+
if (servers.length > 0) {
|
|
587
|
+
logger.info(`DNS servers (scutil): ${servers.join(', ')}`);
|
|
588
|
+
return servers;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
case 'linux': {
|
|
594
|
+
try {
|
|
595
|
+
const content = await readFile('/etc/resolv.conf', 'utf-8');
|
|
596
|
+
const servers = [];
|
|
597
|
+
for (const line of content.split('\n')) {
|
|
598
|
+
const m = line.match(/^nameserver\s+(\S+)/);
|
|
599
|
+
const addr = m?.[1];
|
|
600
|
+
if (addr && !servers.includes(addr))
|
|
601
|
+
servers.push(addr);
|
|
602
|
+
}
|
|
603
|
+
if (servers.length > 0) {
|
|
604
|
+
logger.info(`DNS servers (resolv.conf): ${servers.join(', ')}`);
|
|
605
|
+
return servers;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
catch {
|
|
609
|
+
logger.debug('Could not read /etc/resolv.conf');
|
|
610
|
+
}
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
613
|
+
case 'win32': {
|
|
614
|
+
const output = await safeExec('netsh', ['interface', 'ip', 'show', 'dns']);
|
|
615
|
+
if (output) {
|
|
616
|
+
const servers = [];
|
|
617
|
+
const matches = output.matchAll(/(\d+\.\d+\.\d+\.\d+)/g);
|
|
618
|
+
for (const m of matches) {
|
|
619
|
+
const addr = m[1];
|
|
620
|
+
if (addr && !servers.includes(addr))
|
|
621
|
+
servers.push(addr);
|
|
622
|
+
}
|
|
623
|
+
if (servers.length > 0) {
|
|
624
|
+
logger.info(`DNS servers (netsh): ${servers.join(', ')}`);
|
|
625
|
+
return servers;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
catch (err) {
|
|
633
|
+
logger.error('DNS server detection failed', {
|
|
634
|
+
error: err instanceof Error ? err.message : String(err),
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
logger.warn('Could not determine DNS servers');
|
|
638
|
+
return [];
|
|
639
|
+
}
|
|
640
|
+
//# sourceMappingURL=network-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-scanner.js","sourceRoot":"","sources":["../../src/discovery/network-scanner.ts"],"names":[],"mappings":"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"}
|