diff --git a/commands/scan.go b/commands/scan.go index a0b426dc..6786be0d 100644 --- a/commands/scan.go +++ b/commands/scan.go @@ -211,6 +211,8 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) util.Log.Info("Detecting Platforms... ") scan.DetectPlatforms(p.timeoutSec) + util.Log.Info("Detecting IPS identifiers... ") + scan.DetectIPSs(p.timeoutSec) util.Log.Info("Scanning vulnerabilities... ") if err := scan.Scan(p.scanTimeoutSec); err != nil { diff --git a/config/config.go b/config/config.go index 7c3566b4..668580df 100644 --- a/config/config.go +++ b/config/config.go @@ -1072,8 +1072,9 @@ type ServerInfo struct { WordPress WordPressConf `toml:"wordpress,omitempty" json:"wordpress,omitempty"` // used internal - IPv4Addrs []string `toml:"-" json:"ipv4Addrs,omitempty"` - IPv6Addrs []string `toml:"-" json:"ipv6Addrs,omitempty"` + IPv4Addrs []string `toml:"-" json:"ipv4Addrs,omitempty"` + IPv6Addrs []string `toml:"-" json:"ipv6Addrs,omitempty"` + IPSIdentifiers map[IPS]string `toml:"-" json:"ipsIdentifiers,omitempty"` LogMsgAnsiColor string `toml:"-" json:"-"` // DebugLog Color Container Container `toml:"-" json:"-"` diff --git a/config/ips.go b/config/ips.go new file mode 100644 index 00000000..0483e7b4 --- /dev/null +++ b/config/ips.go @@ -0,0 +1,9 @@ +package config + +// IPS is +type IPS string + +const ( + // DeepSecurity is + DeepSecurity IPS = "deepsecurity" +) diff --git a/models/scanresults.go b/models/scanresults.go index 1231296e..86baf77f 100644 --- a/models/scanresults.go +++ b/models/scanresults.go @@ -36,31 +36,32 @@ type ScanResults []ScanResult // ScanResult has the result of scanned CVE information. type ScanResult struct { - JSONVersion int `json:"jsonVersion"` - Lang string `json:"lang"` - ServerUUID string `json:"serverUUID"` - ServerName string `json:"serverName"` // TOML Section key - Family string `json:"family"` - Release string `json:"release"` - Container Container `json:"container"` - Image Image `json:"image"` - Platform Platform `json:"platform"` - IPv4Addrs []string `json:"ipv4Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast) - IPv6Addrs []string `json:"ipv6Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast) - ScannedAt time.Time `json:"scannedAt"` - ScanMode string `json:"scanMode"` - ScannedVersion string `json:"scannedVersion"` - ScannedRevision string `json:"scannedRevision"` - ScannedBy string `json:"scannedBy"` - ScannedVia string `json:"scannedVia"` - ScannedIPv4Addrs []string `json:"scannedIpv4Addrs,omitempty"` - ScannedIPv6Addrs []string `json:"scannedIpv6Addrs,omitempty"` - ReportedAt time.Time `json:"reportedAt"` - ReportedVersion string `json:"reportedVersion"` - ReportedRevision string `json:"reportedRevision"` - ReportedBy string `json:"reportedBy"` - Errors []string `json:"errors"` - Warnings []string `json:"warnings"` + JSONVersion int `json:"jsonVersion"` + Lang string `json:"lang"` + ServerUUID string `json:"serverUUID"` + ServerName string `json:"serverName"` // TOML Section key + Family string `json:"family"` + Release string `json:"release"` + Container Container `json:"container"` + Image Image `json:"image"` + Platform Platform `json:"platform"` + IPv4Addrs []string `json:"ipv4Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast) + IPv6Addrs []string `json:"ipv6Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast) + IPSIdentifiers map[config.IPS]string `json:"ipsIdentifiers,omitempty"` + ScannedAt time.Time `json:"scannedAt"` + ScanMode string `json:"scanMode"` + ScannedVersion string `json:"scannedVersion"` + ScannedRevision string `json:"scannedRevision"` + ScannedBy string `json:"scannedBy"` + ScannedVia string `json:"scannedVia"` + ScannedIPv4Addrs []string `json:"scannedIpv4Addrs,omitempty"` + ScannedIPv6Addrs []string `json:"scannedIpv6Addrs,omitempty"` + ReportedAt time.Time `json:"reportedAt"` + ReportedVersion string `json:"reportedVersion"` + ReportedRevision string `json:"reportedRevision"` + ReportedBy string `json:"reportedBy"` + Errors []string `json:"errors"` + Warnings []string `json:"warnings"` ScannedCves VulnInfos `json:"scannedCves"` RunningKernel Kernel `json:"runningKernel"` diff --git a/scan/base.go b/scan/base.go index cd32dd68..87575177 100644 --- a/scan/base.go +++ b/scan/base.go @@ -336,6 +336,35 @@ func (l *base) detectPlatform() { return } +var dsFingerPrintPrefix = "AgentStatus.agentCertHash: " + +func (l *base) detectDeepSecurity() (fingerprint string, err error) { + // only work root user + if l.getServerInfo().Mode.IsFastRoot() { + if r := l.exec("test -f /opt/ds_agent/dsa_query", sudo); r.isSuccess() { + cmd := fmt.Sprintf(`/opt/ds_agent/dsa_query -c "GetAgentStatus" | grep %q`, dsFingerPrintPrefix) + r := l.exec(cmd, sudo) + if r.isSuccess() { + line := strings.TrimSpace(r.Stdout) + return line[len(dsFingerPrintPrefix):], nil + } + l.warns = append(l.warns, xerrors.New("Fail to retrieve deepsecurity fingerprint")) + } + } + return "", xerrors.Errorf("Failed to detect deepsecurity %s", l.ServerInfo.ServerName) +} + +func (l *base) detectIPSs() { + ips := map[config.IPS]string{} + + fingerprint, err := l.detectDeepSecurity() + if err != nil { + return + } + ips[config.DeepSecurity] = fingerprint + l.ServerInfo.IPSIdentifiers = ips +} + func (l *base) detectRunningOnAws() (ok bool, instanceID string, err error) { if r := l.exec("type curl", noSudo); r.isSuccess() { cmd := "curl --max-time 1 --noproxy 169.254.169.254 http://169.254.169.254/latest/meta-data/instance-id" @@ -432,6 +461,7 @@ func (l *base) convertToModel() models.ScanResult { Platform: l.Platform, IPv4Addrs: l.ServerInfo.IPv4Addrs, IPv6Addrs: l.ServerInfo.IPv6Addrs, + IPSIdentifiers: l.ServerInfo.IPSIdentifiers, ScannedCves: l.VulnInfos, ScannedVia: scannedVia, RunningKernel: l.Kernel, diff --git a/scan/serverapi.go b/scan/serverapi.go index 3f05477a..42d6a508 100644 --- a/scan/serverapi.go +++ b/scan/serverapi.go @@ -54,6 +54,7 @@ type osTypeInterface interface { setDistro(string, string) getDistro() config.Distro detectPlatform() + detectIPSs() getPlatform() models.Platform checkScanMode() error @@ -584,6 +585,28 @@ func detectPlatforms(timeoutSec int) { return } +// DetectIPSs detects the IPS of each servers. +func DetectIPSs(timeoutSec int) { + detectIPSs(timeoutSec) + for i, s := range servers { + if !s.getServerInfo().IsContainer() { + util.Log.Infof("(%d/%d) %s has %d IPS integration", + i+1, len(servers), + s.getServerInfo().ServerName, + len(s.getServerInfo().IPSIdentifiers), + ) + } + } +} + +func detectIPSs(timeoutSec int) { + parallelExec(func(o osTypeInterface) error { + o.detectIPSs() + // Logging only if IPS can not be specified + return nil + }, timeoutSec) +} + // Scan scan func Scan(timeoutSec int) error { if len(servers) == 0 {