mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-22 19:21:52 +08:00
feat: 优化日志颜色方案,区分漏洞和普通信息
- 新增 LogVuln 级别(红色),用于漏洞和重要发现 - 密码爆破成功、未授权访问、POC漏洞等改用红色显示 - 普通信息(扫描统计等)改为白色 - Web指纹保持绿色
This commit is contained in:
@@ -54,7 +54,7 @@ func (p *ActiveMQPlugin) Scan(ctx context.Context, info *common.HostInfo, config
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "activemq", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("activemq_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("activemq_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -52,7 +52,7 @@ func (p *CassandraPlugin) Scan(ctx context.Context, info *common.HostInfo, confi
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "cassandra", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("cassandra_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("cassandra_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -161,7 +161,7 @@ func (p *CassandraPlugin) tryNoAuthConnection(ctx context.Context, info *common.
|
||||
}
|
||||
|
||||
session.Close()
|
||||
common.LogSuccess(i18n.Tr("cassandra_unauth", target))
|
||||
common.LogVuln(i18n.Tr("cassandra_unauth", target))
|
||||
return &ScanResult{
|
||||
Type: plugins.ResultTypeService,
|
||||
Success: true,
|
||||
|
||||
@@ -34,7 +34,7 @@ func (p *ElasticsearchPlugin) Scan(ctx context.Context, info *common.HostInfo, c
|
||||
|
||||
// 首先检测未授权访问
|
||||
if p.testCredential(ctx, info, Credential{Username: "", Password: ""}, config, state) {
|
||||
common.LogSuccess(i18n.Tr("elasticsearch_unauth", target))
|
||||
common.LogVuln(i18n.Tr("elasticsearch_unauth", target))
|
||||
return &ScanResult{
|
||||
Success: true,
|
||||
Type: plugins.ResultTypeVuln,
|
||||
@@ -55,7 +55,7 @@ func (p *ElasticsearchPlugin) Scan(ctx context.Context, info *common.HostInfo, c
|
||||
|
||||
for _, cred := range credentials {
|
||||
if p.testCredential(ctx, info, cred, config, state) {
|
||||
common.LogSuccess(i18n.Tr("elasticsearch_credential", target, cred.Username, cred.Password))
|
||||
common.LogVuln(i18n.Tr("elasticsearch_credential", target, cred.Username, cred.Password))
|
||||
return &ScanResult{
|
||||
Success: true,
|
||||
Type: plugins.ResultTypeCredential,
|
||||
|
||||
@@ -61,7 +61,7 @@ func (p *FTPPlugin) Scan(ctx context.Context, info *common.HostInfo, config *com
|
||||
output.WriteString(fmt.Sprintf("\n [->] %s", file))
|
||||
}
|
||||
}
|
||||
common.LogSuccess(output.String())
|
||||
common.LogVuln(output.String())
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -202,7 +202,7 @@ func (p *FTPPlugin) testAnonymousAccess(ctx context.Context, info *common.HostIn
|
||||
output.WriteString(fmt.Sprintf("\n [->] %s", file))
|
||||
}
|
||||
}
|
||||
common.LogSuccess(output.String())
|
||||
common.LogVuln(output.String())
|
||||
|
||||
return &ScanResult{
|
||||
Type: plugins.ResultTypeCredential,
|
||||
|
||||
@@ -47,7 +47,7 @@ func (p *KafkaPlugin) Scan(ctx context.Context, info *common.HostInfo, config *c
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "kafka", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("kafka_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("kafka_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -46,7 +46,7 @@ func (p *LDAPPlugin) Scan(ctx context.Context, info *common.HostInfo, config *co
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "ldap", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("ldap_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("ldap_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -33,7 +33,7 @@ func (p *MemcachedPlugin) Scan(ctx context.Context, info *common.HostInfo, confi
|
||||
|
||||
// 检测未授权访问
|
||||
if result := p.testUnauthorizedAccess(ctx, info, config, state); result != nil && result.Success {
|
||||
common.LogSuccess(i18n.Tr("memcached_unauth", target))
|
||||
common.LogVuln(i18n.Tr("memcached_unauth", target))
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ func (p *MongoDBPlugin) Scan(ctx context.Context, info *common.HostInfo, config
|
||||
}
|
||||
|
||||
if isUnauth {
|
||||
common.LogSuccess(i18n.Tr("mongodb_unauth", target))
|
||||
common.LogVuln(i18n.Tr("mongodb_unauth", target))
|
||||
return &ScanResult{
|
||||
Type: plugins.ResultTypeVuln,
|
||||
Success: true,
|
||||
@@ -72,7 +72,7 @@ func (p *MongoDBPlugin) Scan(ctx context.Context, info *common.HostInfo, config
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "mongodb", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("mongodb_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("mongodb_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -195,7 +195,7 @@ func (p *MongoDBPlugin) identifyService(ctx context.Context, info *common.HostIn
|
||||
}
|
||||
|
||||
if isUnauth {
|
||||
common.LogSuccess(i18n.Tr("mongodb_unauth", target))
|
||||
common.LogVuln(i18n.Tr("mongodb_unauth", target))
|
||||
return &ScanResult{
|
||||
Type: plugins.ResultTypeVuln,
|
||||
Success: true,
|
||||
|
||||
@@ -70,7 +70,7 @@ func (p *MS17010Plugin) Scan(ctx context.Context, info *common.HostInfo, config
|
||||
if osVersion != "" {
|
||||
msg += fmt.Sprintf(" [%s]", osVersion)
|
||||
}
|
||||
common.LogSuccess(msg)
|
||||
common.LogVuln(msg)
|
||||
|
||||
return &ScanResult{
|
||||
Success: true,
|
||||
|
||||
@@ -48,7 +48,7 @@ func (p *MSSQLPlugin) Scan(ctx context.Context, info *common.HostInfo, config *c
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "mssql", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("mssql_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("mssql_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -59,7 +59,7 @@ func (p *MySQLPlugin) Scan(ctx context.Context, info *common.HostInfo, config *c
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "mysql", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("mysql_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("mysql_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -34,7 +34,7 @@ func (p *Neo4jPlugin) Scan(ctx context.Context, info *common.HostInfo, config *c
|
||||
|
||||
// 先测试未授权访问
|
||||
if result := p.testUnauthorizedAccess(ctx, info, config, state); result != nil && result.Success {
|
||||
common.LogSuccess(i18n.Tr("neo4j_unauth", target))
|
||||
common.LogVuln(i18n.Tr("neo4j_unauth", target))
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ func (p *Neo4jPlugin) Scan(ctx context.Context, info *common.HostInfo, config *c
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "neo4j", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("neo4j_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("neo4j_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -53,7 +53,7 @@ func (p *OraclePlugin) Scan(ctx context.Context, info *common.HostInfo, config *
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "oracle", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("oracle_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("oracle_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -172,7 +172,7 @@ func (p *OraclePlugin) testUnauthorizedAccess(ctx context.Context, info *common.
|
||||
if result.Conn != nil {
|
||||
_ = result.Conn.Close()
|
||||
}
|
||||
common.LogSuccess(i18n.Tr("oracle_default_account", target, cred.Username, cred.Password))
|
||||
common.LogVuln(i18n.Tr("oracle_default_account", target, cred.Username, cred.Password))
|
||||
return &ScanResult{
|
||||
Type: plugins.ResultTypeVuln,
|
||||
Success: true,
|
||||
|
||||
@@ -34,7 +34,7 @@ func (p *PostgreSQLPlugin) Scan(ctx context.Context, info *common.HostInfo, conf
|
||||
|
||||
// 先测试未授权访问
|
||||
if result := p.testUnauthorizedAccess(ctx, info, config, state); result != nil && result.Success {
|
||||
common.LogSuccess(i18n.Tr("postgresql_vuln", target, result.VulInfo))
|
||||
common.LogVuln(i18n.Tr("postgresql_vuln", target, result.VulInfo))
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ func (p *PostgreSQLPlugin) Scan(ctx context.Context, info *common.HostInfo, conf
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "postgresql", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("postgresql_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("postgresql_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -55,7 +55,7 @@ func (p *RabbitMQPlugin) Scan(ctx context.Context, info *common.HostInfo, config
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "rabbitmq", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("rabbitmq_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("rabbitmq_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -124,7 +124,7 @@ func (p *RDPPlugin) Scan(ctx context.Context, info *common.HostInfo, config *com
|
||||
}
|
||||
|
||||
result := fmt.Sprintf("RDP %s %s\\%s %s", target, displayDomain, cred.Username, cred.Password)
|
||||
common.LogSuccess(result)
|
||||
common.LogVuln(result)
|
||||
|
||||
return &ScanResult{
|
||||
Success: true,
|
||||
|
||||
@@ -41,7 +41,7 @@ func (p *RedisPlugin) Scan(ctx context.Context, info *common.HostInfo, config *c
|
||||
|
||||
// 首先检查未授权访问
|
||||
if result := p.testUnauthorizedAccess(ctx, info, config, state); result != nil && result.Success {
|
||||
common.LogSuccess(i18n.Tr("redis_unauth_success", target)) //nolint:govet
|
||||
common.LogVuln(i18n.Tr("redis_unauth_success", target)) //nolint:govet
|
||||
|
||||
// 如果需要利用,重新建立连接执行
|
||||
if p.shouldExploit(config) {
|
||||
@@ -62,7 +62,7 @@ func (p *RedisPlugin) Scan(ctx context.Context, info *common.HostInfo, config *c
|
||||
|
||||
// 如果成功,记录并执行利用
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("redis_scan_success", target, result.Password)) //nolint:govet
|
||||
common.LogVuln(i18n.Tr("redis_scan_success", target, result.Password)) //nolint:govet
|
||||
|
||||
// 如果需要利用,重新建立连接执行
|
||||
if p.shouldExploit(config) {
|
||||
@@ -352,7 +352,7 @@ func (p *RedisPlugin) exploit(ctx context.Context, info *common.HostInfo, conn n
|
||||
if success, _, writeErr := p.writeCustomFile(conn, dirPath, fileName, config.Redis.WriteContent); writeErr != nil {
|
||||
common.LogError(i18n.Tr("redis_write_failed", writeErr))
|
||||
} else if success {
|
||||
common.LogSuccess(i18n.Tr("redis_write_success", config.Redis.WritePath))
|
||||
common.LogVuln(i18n.Tr("redis_write_success", config.Redis.WritePath))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,7 +368,7 @@ func (p *RedisPlugin) exploit(ctx context.Context, info *common.HostInfo, conn n
|
||||
if success, _, writeErr := p.writeCustomFile(conn, dirPath, fileName, string(fileContent)); writeErr != nil {
|
||||
common.LogError(i18n.Tr("redis_write_failed", writeErr))
|
||||
} else if success {
|
||||
common.LogSuccess(i18n.Tr("redis_file_write_success", config.Redis.WriteFile, config.Redis.WritePath))
|
||||
common.LogVuln(i18n.Tr("redis_file_write_success", config.Redis.WriteFile, config.Redis.WritePath))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -378,7 +378,7 @@ func (p *RedisPlugin) exploit(ctx context.Context, info *common.HostInfo, conn n
|
||||
if success, _, keyErr := p.writeKey(conn, config.Redis.File); keyErr != nil {
|
||||
common.LogError(i18n.Tr("redis_ssh_key_failed", keyErr))
|
||||
} else if success {
|
||||
common.LogSuccess(i18n.GetText("redis_ssh_key_success"))
|
||||
common.LogVuln(i18n.GetText("redis_ssh_key_success"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ func (p *RedisPlugin) exploit(ctx context.Context, info *common.HostInfo, conn n
|
||||
if success, _, cronErr := p.writeCron(conn, config.Redis.Shell); cronErr != nil {
|
||||
common.LogError(i18n.Tr("redis_cron_failed", cronErr))
|
||||
} else if success {
|
||||
common.LogSuccess(i18n.GetText("redis_cron_success"))
|
||||
common.LogVuln(i18n.GetText("redis_cron_success"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ func (p *RsyncPlugin) Scan(ctx context.Context, info *common.HostInfo, config *c
|
||||
result := TestCredentialsConcurrently(ctx, creds, authFn, "rsync", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("rsync_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("rsync_credential", target, result.Username, result.Password))
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ func (p *SmbPlugin) Scan(ctx context.Context, info *common.HostInfo, config *com
|
||||
if smbTarget.Protocol == SMBProtocol2 && info.Port == 445 {
|
||||
if checkSMBGhost(info.Host, config.Timeout) {
|
||||
smbTarget.Vulnerable = &SMBVuln{CVE20200796: true}
|
||||
common.LogSuccess(i18n.Tr("smbghost_vuln", target))
|
||||
common.LogVuln(i18n.Tr("smbghost_vuln", target))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func (p *SmbPlugin) Scan(ctx context.Context, info *common.HostInfo, config *com
|
||||
} else {
|
||||
successMsg = fmt.Sprintf("SMB %s 未授权访问 - %s:%s", target, result.Username, result.Password)
|
||||
}
|
||||
common.LogSuccess(successMsg)
|
||||
common.LogVuln(successMsg)
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ func (p *SmbPlugin) Scan(ctx context.Context, info *common.HostInfo, config *com
|
||||
} else {
|
||||
successMsg = fmt.Sprintf("SMB %s %s:%s", target, result.Username, result.Password)
|
||||
}
|
||||
common.LogSuccess(successMsg)
|
||||
common.LogVuln(successMsg)
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -61,7 +61,7 @@ func (p *SMTPPlugin) Scan(ctx context.Context, info *common.HostInfo, config *co
|
||||
result := TestCredentialsConcurrently(ctx, creds, authFn, "smtp", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("smtp_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("smtp_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -40,7 +40,7 @@ func (p *SSHPlugin) Scan(ctx context.Context, info *common.HostInfo, config *com
|
||||
// 如果指定了SSH密钥,优先使用密钥认证
|
||||
if config.Credentials.SSHKeyPath != "" {
|
||||
if result := p.scanWithKey(ctx, info, config, state); result != nil && result.Success {
|
||||
common.LogSuccess(i18n.Tr("ssh_key_auth_success", target, result.Username)) //nolint:govet
|
||||
common.LogVuln(i18n.Tr("ssh_key_auth_success", target, result.Username)) //nolint:govet
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ func (p *SSHPlugin) Scan(ctx context.Context, info *common.HostInfo, config *com
|
||||
|
||||
// 记录成功
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("ssh_pwd_auth_success", target, result.Username, result.Password)) //nolint:govet
|
||||
common.LogVuln(i18n.Tr("ssh_pwd_auth_success", target, result.Username, result.Password)) //nolint:govet
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -71,7 +71,7 @@ func (p *TelnetPlugin) Scan(ctx context.Context, info *common.HostInfo, config *
|
||||
result := TestCredentialsConcurrently(ctx, creds, authFn, "telnet", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("telnet_credential", target, result.Username, result.Password))
|
||||
common.LogVuln(i18n.Tr("telnet_credential", target, result.Username, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -29,7 +29,7 @@ func (p *VNCPlugin) Scan(ctx context.Context, info *common.HostInfo, config *com
|
||||
|
||||
// 检查未授权访问
|
||||
if result := p.testUnauthAccess(ctx, info, config, state); result != nil && result.Success {
|
||||
common.LogSuccess(i18n.Tr("vnc_unauth", target))
|
||||
common.LogVuln(i18n.Tr("vnc_unauth", target))
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (p *VNCPlugin) Scan(ctx context.Context, info *common.HostInfo, config *com
|
||||
result := TestCredentialsConcurrently(ctx, credentials, authFn, "vnc", testConfig)
|
||||
|
||||
if result.Success {
|
||||
common.LogSuccess(i18n.Tr("vnc_credential", target, result.Password))
|
||||
common.LogVuln(i18n.Tr("vnc_credential", target, result.Password))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user