// PrintResults() is an *optional* method that returns results in a human-readable format. // if matchOnly is set, only results that have at least one match are returned. // If matchOnly is not set, all results are returned, along with errors and statistics. func (r Runner) PrintResults(result modules.Result, matchOnly bool) (prints []string, err error) { var ( el elements stats statistics ) err = result.GetElements(&el) if err != nil { panic(err) } if el.Hostname != "" { prints = append(prints, fmt.Sprintf("hostname is %s", el.Hostname)) } for _, addr := range el.Addresses { prints = append(prints, fmt.Sprintf("address is %s", addr)) } for host, addrs := range el.LookedUpHost { for _, addr := range addrs { prints = append(prints, fmt.Sprintf("lookedup host %s has IP %s", host, addr)) } } if matchOnly { return } for _, e := range result.Errors { prints = append(prints, fmt.Sprintf("error: %v", e)) } err = result.GetStatistics(&stats) if err != nil { panic(err) } prints = append(prints, fmt.Sprintf("stat: %d stuff found", stats.StuffFound)) return }
// PrintResults() returns results in a human-readable format. if foundOnly is set, // only results that have at least one match are returned. // If foundOnly is not set, all results are returned, along with errors and // statistics. func (r Runner) PrintResults(result modules.Result, foundOnly bool) (prints []string, err error) { var ( el searchResults stats statistics ) err = result.GetElements(&el) if err != nil { panic(err) } err = result.GetStatistics(&stats) if err != nil { panic(err) } for label, sr := range el { for _, mps := range sr { var out string if mps.Process.Name == "" { if foundOnly { continue } out = fmt.Sprintf("0 match found in search '%s'", label) } else { out = fmt.Sprintf("%s [pid:%.0f] in search '%s'", mps.Process.Name, mps.Process.Pid, label) } if mps.Search.Options.MatchAll { prints = append(prints, out) continue } out += " on checks" // if matchany, print the detail of the checks that matched with the filename for _, v := range mps.Search.Names { out += fmt.Sprintf(" name='%s'", v) } for _, v := range mps.Search.Libraries { out += fmt.Sprintf(" library='%s'", v) } for _, v := range mps.Search.Contents { out += fmt.Sprintf(" content='%s'", v) } for _, v := range mps.Search.Bytes { out += fmt.Sprintf(" byte='%s'", v) } prints = append(prints, out) } } if !foundOnly { for _, e := range stats.Failures { prints = append(prints, fmt.Sprintf("Failure: %v", e)) } for _, e := range result.Errors { prints = append(prints, e) } stat := fmt.Sprintf("Statistics: %.0f processes checked, %.0f matched, %d failures, ran in %s.", stats.ProcessCount, stats.TotalHits, len(stats.Failures), stats.Exectime) prints = append(prints, stat) } return }
func (r *run) PrintResults(result modules.Result, foundOnly bool) (prints []string, err error) { var ( elem elements stats Statistics ) err = result.GetElements(&elem) if err != nil { panic(err) } err = result.GetStatistics(&stats) if err != nil { panic(err) } for _, x := range elem.Matches { resStr := fmt.Sprintf("pkgmatch name=%v version=%v type=%v", x.PkgName, x.PkgVersion, x.PkgType) prints = append(prints, resStr) } for _, x := range elem.OvalResults { resStr := fmt.Sprintf("ovalresult id=%v title=\"%v\" outcome=%v", x.ID, x.Title, x.Status) prints = append(prints, resStr) } if !foundOnly { for _, we := range result.Errors { prints = append(prints, we) } stats := fmt.Sprintf("Statistics: runtime %v, parsetime %v, defsize %v", stats.ExecRuntime, stats.Parsetime, stats.InDefSize) prints = append(prints, stats) } return }
func (r *run) PrintResults(result modules.Result, foundOnly bool) (prints []string, err error) { var ( elem elements stats Statistics ) err = result.GetElements(&elem) if err != nil { panic(err) } err = result.GetStatistics(&stats) if err != nil { panic(err) } for _, x := range elem.Packages { resStr := fmt.Sprintf("pkgmatch name=%v version=%v type=%v", x.Name, x.Version, x.Type) prints = append(prints, resStr) } if !foundOnly { for _, we := range result.Errors { prints = append(prints, we) } stats := fmt.Sprintf("Statistics: runtime %v", stats.ExecRuntime) prints = append(prints, stats) } return }
func buildResults(e elements, r *modules.Result, matches int) (buf []byte, err error) { r.Success = true if matches > 0 { r.FoundAnything = true } r.Elements = e endCounters() r.Statistics = stats buf, err = json.Marshal(r) return }
func buildResults(e elements, r *modules.Result) (buf []byte, err error) { r.Success = true r.Elements = e if len(e.Packages) > 0 { r.FoundAnything = true } endCounters() r.Statistics = stats buf, err = json.Marshal(r) return }
func (r Runner) PrintResults(result modules.Result, foundOnly bool) (prints []string, err error) { var el elements defer func() { if e := recover(); e != nil { err = fmt.Errorf("Print Error: %v", e) } }() err = result.GetElements(&el) if err != nil { panic(err) } if result.FoundAnything { prints = append(prints, fmt.Sprintf("%s ping of %s succeeded. Target is reachable.", el.Protocol, el.ResolvedHost, ), ) } // if we don't care about results where the target was not reachable, stop here if foundOnly { return } if !result.FoundAnything { prints = append(prints, fmt.Sprintf("%s ping of %s failed. Target is no reachable.", el.Protocol, el.ResolvedHost, ), ) } for i, lat := range el.Latencies { switch lat { case -1: prints = append(prints, fmt.Sprintf("ping #%d failed, target was unreachable", i+1)) case 0: prints = append(prints, fmt.Sprintf("ping #%d failed, reason unknown", i+1)) case 9999999: if el.Protocol == "udp" { prints = append(prints, fmt.Sprintf("ping #%d may have succeeded (no udp response)", i+1)) } else { prints = append(prints, fmt.Sprintf("ping #%d failed, connection timed out", i+1)) } default: prints = append(prints, fmt.Sprintf("ping #%d succeeded in %.0fms", i+1, lat)) } } return }
func (r Runner) PrintResults(result modules.Result, foundOnly bool) (prints []string, err error) { var ( el elements stats statistics ) err = result.GetElements(&el) if err != nil { return } prints = append(prints, "local time is "+el.LocalTime) if el.HasCheckedDrift { if el.IsWithinDrift { prints = append(prints, "local time is within acceptable drift from NTP servers") } else { prints = append(prints, "local time is out of sync from NTP servers") for _, drift := range el.Drifts { prints = append(prints, drift) } } } // stop here if foundOnly is set, we don't want to see errors and stats if foundOnly { return } for _, e := range result.Errors { prints = append(prints, "error:", e) } err = result.GetStatistics(&stats) if err != nil { panic(err) } prints = append(prints, "stat: execution time was "+stats.ExecTime) for _, ntpstat := range stats.NtpStats { if ntpstat.Reachable { prints = append(prints, "stat: "+ntpstat.Host+" responded in "+ntpstat.Latency+" with time "+ntpstat.Time.UTC().String()+". local time drifts by "+ntpstat.Drift) } else { prints = append(prints, "stat: "+ntpstat.Host+" was unreachable") } } if result.Success { prints = append(prints, fmt.Sprintf("timedrift module has succeeded")) } else { prints = append(prints, fmt.Sprintf("timedrift module has failed")) } return }
func (r *run) PrintResults(result modules.Result, foundOnly bool) (prints []string, err error) { var statusMsg string err = result.GetElements(&statusMsg) if err != nil { prints = append(prints, "[error] failed to retrieve status message from results") } if statusMsg != "" { prints = append(prints, statusMsg) } if foundOnly { return } for _, e := range result.Errors { prints = append(prints, "[error] "+e) } if result.Success { prints = append(prints, fmt.Sprintf("agentdestroy module has succeeded")) } else { prints = append(prints, fmt.Sprintf("agentdestroy module has failed")) } return }
func makeComplianceItem(cmd mig.Command, conf Config) (items []gozdef.ComplianceItem, err error) { var ci gozdef.ComplianceItem ci.Utctimestamp = time.Now().UTC().Format(time.RFC3339Nano) ci.Target = cmd.Agent.Name ci.Policy.Name = cmd.Action.Threat.Type ci.Policy.URL = cmd.Action.Description.URL ci.Policy.Level = cmd.Action.Threat.Level ci.Check.Ref = cmd.Action.Threat.Ref ci.Check.Description = cmd.Action.Name ci.Link = fmt.Sprintf("%s/command?commandid=%.0f", conf.API.Host, cmd.ID) if cmd.Agent.Tags != nil { operator := "" if _, ok := cmd.Agent.Tags.(map[string]interface{})["operator"]; ok { operator = cmd.Agent.Tags.(map[string]interface{})["operator"].(string) } team := getTeam(cmd.Agent, conf) ci.Tags = struct { Operator string `json:"operator"` Team string `json:"team"` }{ Operator: operator, Team: team, } } for i, result := range cmd.Results { buf, err := json.Marshal(result) if err != nil { return items, err } if i > (len(cmd.Action.Operations) - 1) { // skip this entry if the lookup fails continue } switch cmd.Action.Operations[i].Module { case "file": var r modules.Result var el file.SearchResults err = json.Unmarshal(buf, &r) if err != nil { return items, err } err = r.GetElements(&el) if err != nil { return items, err } for label, sr := range el { for _, mf := range sr { ci.Check.Location = mf.File ci.Check.Name = label ci.Check.Test.Type = "file" ci.Check.Test.Value = "" for _, v := range mf.Search.Names { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("name='%s'", v) } for _, v := range mf.Search.Sizes { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("size='%s'", v) } for _, v := range mf.Search.Modes { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("mode='%s'", v) } for _, v := range mf.Search.Mtimes { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("mtime='%s'", v) } for _, v := range mf.Search.Contents { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("content='%s'", v) } for _, v := range mf.Search.MD5 { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("md5='%s'", v) } for _, v := range mf.Search.SHA1 { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("sha1='%s'", v) } for _, v := range mf.Search.SHA256 { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("sha256='%s'", v) } for _, v := range mf.Search.SHA384 { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("sha384='%s'", v) } for _, v := range mf.Search.SHA512 { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("sha512='%s'", v) } for _, v := range mf.Search.SHA3_224 { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("sha3_224='%s'", v) } for _, v := range mf.Search.SHA3_256 { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("sha3_256='%s'", v) } for _, v := range mf.Search.SHA3_384 { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("sha3_384='%s'", v) } for _, v := range mf.Search.SHA3_512 { if len(ci.Check.Test.Value) > 0 { ci.Check.Test.Value += " and " } ci.Check.Test.Value += fmt.Sprintf("sha3_512='%s'", v) } if mf.File == "" { for i, p := range mf.Search.Paths { if i > 0 { ci.Check.Location += ", " } ci.Check.Location += p } ci.Compliance = false } else { ci.Compliance = true } items = append(items, ci) } } } } return }
func (r *run) PrintResults(result modules.Result, matchOnly bool) (prints []string, err error) { var ( el elements stats statistics ) defer func() { if e := recover(); e != nil { err = fmt.Errorf("PrintResults() -> %v", e) } }() el = *newElements() err = result.GetElements(&el) if err != nil { panic(err) } for val, res := range el.LocalMAC { if matchOnly && len(res) < 1 { continue } for _, el := range res { resStr := fmt.Sprintf("found local mac %s for netstat localmac:'%s'", el.LocalMACAddr, val) prints = append(prints, resStr) } } for val, res := range el.NeighborMAC { if matchOnly && len(res) < 1 { continue } for _, el := range res { resStr := fmt.Sprintf("found neighbor mac %s %s for netstat neighbormac:'%s'", el.RemoteMACAddr, el.RemoteAddr, val) prints = append(prints, resStr) } if len(res) == 0 { resStr := fmt.Sprintf("did not find anything for netstat neighbormac:'%s'", val) prints = append(prints, resStr) } } for val, res := range el.LocalIP { if matchOnly && len(res) < 1 { continue } for _, el := range res { resStr := fmt.Sprintf("found local ip %s for netstat localip:'%s'", el.LocalAddr, val) prints = append(prints, resStr) } if len(res) == 0 { resStr := fmt.Sprintf("did not find anything for netstat localip:'%s'", val) prints = append(prints, resStr) } } for val, res := range el.ConnectedIP { if matchOnly && len(res) < 1 { continue } for _, el := range res { resStr := fmt.Sprintf("found connected tuple %s:%.0f with local tuple %s:%.0f for netstat connectedip:'%s'", el.RemoteAddr, el.RemotePort, el.LocalAddr, el.LocalPort, val) prints = append(prints, resStr) } if len(res) == 0 { resStr := fmt.Sprintf("did not find anything for netstat connectedip:'%s'", val) prints = append(prints, resStr) } } for val, res := range el.ListeningPort { if matchOnly && len(res) < 1 { continue } for _, el := range res { resStr := fmt.Sprintf("found listening port %.0f for netstat listeningport:'%s'", el.LocalPort, val) prints = append(prints, resStr) } if len(res) == 0 { resStr := fmt.Sprintf("did not find anything for netstat listeningport:'%s'", val) prints = append(prints, resStr) } } if matchOnly { return } for _, e := range result.Errors { prints = append(prints, fmt.Sprintf("error: %v", e)) } err = result.GetStatistics(&stats) if err != nil { panic(err) } resStr := fmt.Sprintf("Statistics: total hits %.0f examined %.0f items exectime %s", stats.Totalhits, stats.Examined, stats.Exectime) prints = append(prints, resStr) return }
func commandsToComplianceItems(commands []mig.Command) (items []ComplianceItem, err error) { for _, cmd := range commands { var bitem ComplianceItem bitem.Utctimestamp = cmd.FinishTime.UTC().Format(time.RFC3339Nano) bitem.Target = cmd.Agent.Name bitem.Policy.Name = cmd.Action.Threat.Type bitem.Policy.URL = cmd.Action.Description.URL bitem.Policy.Level = cmd.Action.Threat.Level bitem.Check.Ref = cmd.Action.Threat.Ref bitem.Check.Description = cmd.Action.Name bitem.Link = fmt.Sprintf("%s/command?commandid=%.0f", ctx.Server.BaseURL, cmd.ID) if _, ok := cmd.Agent.Tags.(map[string]interface{})["operator"]; ok { var t ComplianceTags t.Operator = cmd.Agent.Tags.(map[string]interface{})["operator"].(string) bitem.Tags = t } for i, result := range cmd.Results { buf, err := json.Marshal(result) if err != nil { return items, err } if i > (len(cmd.Action.Operations) - 1) { // skip this entry if the lookup fails continue } switch cmd.Action.Operations[i].Module { case "file": var el file.SearchResults var r modules.Result err = json.Unmarshal(buf, &r) if err != nil { return items, err } err = r.GetElements(&el) if err != nil { return items, err } for label, sr := range el { for _, mf := range sr { bitem.Check.Location = mf.File bitem.Check.Name = label bitem.Check.Test.Type = "file" bitem.Check.Test.Value = "" for _, v := range mf.Search.Names { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("name='%s'", v) } for _, v := range mf.Search.Sizes { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("size='%s'", v) } for _, v := range mf.Search.Modes { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("mode='%s'", v) } for _, v := range mf.Search.Mtimes { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("mtime='%s'", v) } for _, v := range mf.Search.Contents { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("content='%s'", v) } for _, v := range mf.Search.MD5 { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("md5='%s'", v) } for _, v := range mf.Search.SHA1 { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("sha1='%s'", v) } for _, v := range mf.Search.SHA256 { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("sha256='%s'", v) } for _, v := range mf.Search.SHA384 { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("sha384='%s'", v) } for _, v := range mf.Search.SHA512 { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("sha512='%s'", v) } for _, v := range mf.Search.SHA3_224 { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("sha3_224='%s'", v) } for _, v := range mf.Search.SHA3_256 { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("sha3_256='%s'", v) } for _, v := range mf.Search.SHA3_384 { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("sha3_384='%s'", v) } for _, v := range mf.Search.SHA3_512 { if len(bitem.Check.Test.Value) > 0 { bitem.Check.Test.Value += " and " } bitem.Check.Test.Value += fmt.Sprintf("sha3_512='%s'", v) } if mf.File == "" { for i, p := range mf.Search.Paths { if i > 0 { bitem.Check.Location += ", " } bitem.Check.Location += p } bitem.Compliance = false } else { bitem.Compliance = true } items = append(items, bitem) } } } } } return }