diff --git a/modules/engine/loaders.go b/modules/engine/loaders.go index 75bda5d..16c39b4 100644 --- a/modules/engine/loaders.go +++ b/modules/engine/loaders.go @@ -10,8 +10,6 @@ import ( "github.com/rs/zerolog/log" ) -const PostProcessing LoaderID = -1 - type LoaderID int type Loader interface { diff --git a/modules/integrations/localmachine/analyze/analyzer.go b/modules/integrations/localmachine/analyze/analyzer.go index 1ffbcf0..bd26e0f 100644 --- a/modules/integrations/localmachine/analyze/analyzer.go +++ b/modules/integrations/localmachine/analyze/analyzer.go @@ -58,8 +58,10 @@ var ( PwnSIDCollision = engine.NewPwn("SIDCollision") - DNSHostname = engine.NewAttribute("dnsHostName") - PwnPatches = engine.NewPwn("Patches") + DNSHostname = engine.NewAttribute("dnsHostName") + PwnControlsUpdates = engine.NewPwn("ControlsUpdates") + WUServer = engine.NewAttribute("wuServer") + SCCMServer = engine.NewAttribute("sccmServer") ) func MapSID(original, new, input windowssecurity.SID) windowssecurity.SID { @@ -101,10 +103,19 @@ func (ld *LocalMachineLoader) ImportCollectorInfo(cinfo localmachine.Info) error if cinfo.Machine.WUServer != "" { if u, err := url.Parse(cinfo.Machine.WUServer); err == nil { - wsusserver, _ := ld.ao.FindOrAdd( - DNSHostname, engine.AttributeValueString(u.Host), + host, _, _ := strings.Cut(u.Host, ":") + computerobject.SetFlex( + WUServer, engine.AttributeValueString(host), + ) + } + } + + if cinfo.Machine.SCCMLastValidMP != "" { + if u, err := url.Parse(cinfo.Machine.SCCMLastValidMP); err == nil { + host, _, _ := strings.Cut(u.Host, ":") + computerobject.SetFlex( + SCCMServer, engine.AttributeValueString(host), ) - wsusserver.Pwns(computerobject, PwnPatches) } } diff --git a/modules/integrations/localmachine/analyze/analyzers.go b/modules/integrations/localmachine/analyze/analyzers.go new file mode 100644 index 0000000..5261dec --- /dev/null +++ b/modules/integrations/localmachine/analyze/analyzers.go @@ -0,0 +1,43 @@ +package analyze + +import ( + "github.com/lkarlslund/adalanche/modules/engine" + "github.com/rs/zerolog/log" +) + +func init() { + loader.AddProcessor( + func(ao *engine.Objects) { + for _, o := range ao.Slice() { + if o.HasAttr(WUServer) || o.HasAttr(SCCMServer) { + var hosts []string + if hostname := o.OneAttrString(WUServer); hostname != "" { + hosts = append(hosts, hostname) + } + + if hostname := o.OneAttrString(SCCMServer); hostname != "" { + hosts = append(hosts, hostname) + } + + for _, host := range hosts { + servers, found := ao.FindTwoMultiOrAdd( + DNSHostname, engine.AttributeValueString(host), + engine.ObjectClass, engine.AttributeValueString("computer"), + nil, + ) + if !found { + log.Warn().Msgf("Could not find controlling WSUS or SCCM server %v for %v", host, o.DN()) + continue + } + for _, server := range servers { + server.Pwns(o, PwnControlsUpdates) + } + } + } + } + }, + "Link SCCM and WSUS servers to controlled computers", + engine.AfterMerge, + ) + +} diff --git a/modules/integrations/localmachine/analyze/loader.go b/modules/integrations/localmachine/analyze/loader.go index a27617a..c05e38a 100644 --- a/modules/integrations/localmachine/analyze/loader.go +++ b/modules/integrations/localmachine/analyze/loader.go @@ -16,9 +16,9 @@ import ( const loadername = "LocalMachine JSON file" -func init() { - engine.AddLoader(func() engine.Loader { return &LocalMachineLoader{} }) -} +var ( + loader = engine.AddLoader(func() engine.Loader { return &LocalMachineLoader{} }) +) type LocalMachineLoader struct { ao *engine.Objects diff --git a/modules/integrations/localmachine/analyze/postprocessing.go b/modules/integrations/localmachine/analyze/postprocessing.go index 8f398a6..64a7cde 100644 --- a/modules/integrations/localmachine/analyze/postprocessing.go +++ b/modules/integrations/localmachine/analyze/postprocessing.go @@ -7,7 +7,7 @@ import ( ) func init() { - engine.PostProcessing.AddProcessor(func(ao *engine.Objects) { + loader.AddProcessor(func(ao *engine.Objects) { var warns int ln := engine.AttributeValueString(loadername) for _, o := range ao.Slice() {