fix(documentation): Improve documentation formatting and code consistency across project files
This commit is contained in:
@@ -24,11 +24,11 @@ export class Detector {
|
||||
parseInt(parsedUrl.port, 10),
|
||||
);
|
||||
const portAvailable = !portUnused;
|
||||
|
||||
|
||||
const result: IDetectorResult = {
|
||||
isActive: portAvailable
|
||||
isActive: portAvailable,
|
||||
};
|
||||
|
||||
|
||||
if (options?.detectServiceType) {
|
||||
if (portAvailable) {
|
||||
const serviceType = await this.detectType(urlArg);
|
||||
@@ -37,7 +37,7 @@ export class Detector {
|
||||
result.serviceType = ServiceType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
} else {
|
||||
console.log(`detector target is remote domain ${parsedUrl.host} on port ${parsedUrl.port}`);
|
||||
@@ -45,11 +45,11 @@ export class Detector {
|
||||
parsedUrl.host,
|
||||
parseInt(parsedUrl.port, 10),
|
||||
);
|
||||
|
||||
|
||||
const result: IDetectorResult = {
|
||||
isActive: portAvailable
|
||||
isActive: portAvailable,
|
||||
};
|
||||
|
||||
|
||||
if (options?.detectServiceType) {
|
||||
if (portAvailable) {
|
||||
const serviceType = await this.detectType(urlArg);
|
||||
@@ -58,36 +58,36 @@ export class Detector {
|
||||
result.serviceType = ServiceType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public async detectType(urlArg: string): Promise<ServiceType> {
|
||||
const parsedUrl = plugins.smarturl.Smarturl.createFromUrl(urlArg);
|
||||
|
||||
|
||||
// Handle different URL schemes and default ports
|
||||
let port = parseInt(parsedUrl.port, 10);
|
||||
if (isNaN(port)) {
|
||||
// Set default ports based on scheme
|
||||
const defaultPorts: { [key: string]: number } = {
|
||||
'http': 80,
|
||||
'https': 443,
|
||||
'ssh': 22,
|
||||
'ftp': 21,
|
||||
'smtp': 25,
|
||||
'mysql': 3306,
|
||||
'postgresql': 5432,
|
||||
'mongodb': 27017,
|
||||
'redis': 6379
|
||||
http: 80,
|
||||
https: 443,
|
||||
ssh: 22,
|
||||
ftp: 21,
|
||||
smtp: 25,
|
||||
mysql: 3306,
|
||||
postgresql: 5432,
|
||||
mongodb: 27017,
|
||||
redis: 6379,
|
||||
};
|
||||
|
||||
|
||||
const scheme = parsedUrl.protocol.replace(':', '').toLowerCase();
|
||||
port = defaultPorts[scheme] || 80;
|
||||
}
|
||||
|
||||
|
||||
const hostname = parsedUrl.hostname;
|
||||
|
||||
|
||||
// Check common ports first
|
||||
const commonPorts: { [key: number]: ServiceType } = {
|
||||
80: ServiceType.HTTP,
|
||||
@@ -100,9 +100,9 @@ export class Detector {
|
||||
3306: ServiceType.MYSQL,
|
||||
5432: ServiceType.POSTGRESQL,
|
||||
27017: ServiceType.MONGODB,
|
||||
6379: ServiceType.REDIS
|
||||
6379: ServiceType.REDIS,
|
||||
};
|
||||
|
||||
|
||||
if (commonPorts[port]) {
|
||||
// Verify the service is actually what we expect
|
||||
const verified = await this.verifyServiceType(hostname, port, commonPorts[port]);
|
||||
@@ -110,12 +110,16 @@ export class Detector {
|
||||
return commonPorts[port];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Try to detect service by banner/protocol
|
||||
return await this.detectServiceByProtocol(hostname, port);
|
||||
}
|
||||
|
||||
private async verifyServiceType(hostname: string, port: number, expectedType: ServiceType): Promise<boolean> {
|
||||
|
||||
private async verifyServiceType(
|
||||
hostname: string,
|
||||
port: number,
|
||||
expectedType: ServiceType,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
switch (expectedType) {
|
||||
case ServiceType.HTTP:
|
||||
@@ -130,33 +134,37 @@ export class Detector {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async detectServiceByProtocol(hostname: string, port: number): Promise<ServiceType> {
|
||||
// Try HTTPS first
|
||||
if (await this.checkHttpService(hostname, port, true)) {
|
||||
return ServiceType.HTTPS;
|
||||
}
|
||||
|
||||
|
||||
// Try HTTP
|
||||
if (await this.checkHttpService(hostname, port, false)) {
|
||||
return ServiceType.HTTP;
|
||||
}
|
||||
|
||||
|
||||
// Try SSH
|
||||
if (await this.checkSshService(hostname, port)) {
|
||||
return ServiceType.SSH;
|
||||
}
|
||||
|
||||
|
||||
// Try to get banner for other services
|
||||
const banner = await this.getBanner(hostname, port);
|
||||
if (banner) {
|
||||
return this.identifyServiceByBanner(banner);
|
||||
}
|
||||
|
||||
|
||||
return ServiceType.UNKNOWN;
|
||||
}
|
||||
|
||||
private async checkHttpService(hostname: string, port: number, isHttps: boolean): Promise<boolean> {
|
||||
|
||||
private async checkHttpService(
|
||||
hostname: string,
|
||||
port: number,
|
||||
isHttps: boolean,
|
||||
): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
const protocol = isHttps ? plugins.https : plugins.http;
|
||||
const options = {
|
||||
@@ -164,81 +172,81 @@ export class Detector {
|
||||
port,
|
||||
method: 'HEAD',
|
||||
timeout: 5000,
|
||||
rejectUnauthorized: false // Accept self-signed certificates
|
||||
rejectUnauthorized: false, // Accept self-signed certificates
|
||||
};
|
||||
|
||||
|
||||
const req = protocol.request(options, () => {
|
||||
resolve(true);
|
||||
});
|
||||
|
||||
|
||||
req.on('error', () => {
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
|
||||
req.on('timeout', () => {
|
||||
req.destroy();
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private async checkSshService(hostname: string, port: number): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
const socket = new plugins.net.Socket();
|
||||
|
||||
|
||||
socket.setTimeout(5000);
|
||||
|
||||
|
||||
socket.on('data', (data) => {
|
||||
const banner = data.toString();
|
||||
socket.destroy();
|
||||
// SSH banners typically start with "SSH-"
|
||||
resolve(banner.startsWith('SSH-'));
|
||||
});
|
||||
|
||||
|
||||
socket.on('error', () => {
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
|
||||
socket.on('timeout', () => {
|
||||
socket.destroy();
|
||||
resolve(false);
|
||||
});
|
||||
|
||||
|
||||
socket.connect(port, hostname);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private async getBanner(hostname: string, port: number): Promise<string | null> {
|
||||
return new Promise((resolve) => {
|
||||
const socket = new plugins.net.Socket();
|
||||
let banner = '';
|
||||
|
||||
|
||||
socket.setTimeout(5000);
|
||||
|
||||
|
||||
socket.on('data', (data) => {
|
||||
banner += data.toString();
|
||||
socket.destroy();
|
||||
resolve(banner);
|
||||
});
|
||||
|
||||
|
||||
socket.on('error', () => {
|
||||
resolve(null);
|
||||
});
|
||||
|
||||
|
||||
socket.on('timeout', () => {
|
||||
socket.destroy();
|
||||
resolve(banner || null);
|
||||
});
|
||||
|
||||
|
||||
socket.connect(port, hostname);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private identifyServiceByBanner(banner: string): ServiceType {
|
||||
const bannerLower = banner.toLowerCase();
|
||||
|
||||
|
||||
if (bannerLower.includes('ssh')) return ServiceType.SSH;
|
||||
if (bannerLower.includes('ftp')) return ServiceType.FTP;
|
||||
if (bannerLower.includes('smtp')) return ServiceType.SMTP;
|
||||
@@ -248,7 +256,7 @@ export class Detector {
|
||||
if (bannerLower.includes('postgresql')) return ServiceType.POSTGRESQL;
|
||||
if (bannerLower.includes('mongodb')) return ServiceType.MONGODB;
|
||||
if (bannerLower.includes('redis')) return ServiceType.REDIS;
|
||||
|
||||
|
||||
return ServiceType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user