Skip to content

Commit

Permalink
Various type fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
lkarlslund committed Sep 28, 2022
1 parent b5e5231 commit 2a4ea61
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 68 deletions.
6 changes: 1 addition & 5 deletions modules/engine/objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,7 @@ func (os *Objects) Merge(attrtomerge []Attribute, o *Object) bool {
if attr.IsSingle() && mergetarget.HasAttr(attr) {
if !CompareAttributeValues(values.First(), mergetarget.Attr(attr).First()) {
// Conflicting attribute values, we can't merge these
ui.Debug().Msgf("Not merging %v into %v on %v with value '%v', as attribute %v is different (%v != %v)", o.Label(), mergetarget.Label(), mergeattr.String(), lookfor.String(), attr.String(), values.First().String(), mergetarget.Attr(attr).First().String())
// if attr == WhenCreated {
// ui.Debug().Msgf("Object details: %v", o.StringNoACL())
// ui.Debug().Msgf("Mergetarget details: %v", mergetarget.StringNoACL())
// }
ui.Trace().Msgf("Not merging %v into %v on %v with value '%v', as attribute %v is different (%v != %v)", o.Label(), mergetarget.Label(), mergeattr.String(), lookfor.String(), attr.String(), values.First().String(), mergetarget.Attr(attr).First().String())
failed = true
return false
}
Expand Down
2 changes: 1 addition & 1 deletion modules/integrations/activedirectory/analyze/adloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (ld *ADLoader) Close() ([]*engine.Objects, error) {
ld.shardobjects.Range(func(path string, ao *engine.Objects) bool {
_, netbiosname, _, _, err := FindDomain(ao)
if err != nil {
ui.Error().Msgf("Can't apply unique source for AD data from %v, this will give errors during object merging: %v", path, err)
ui.Fatal().Msgf("Can't apply unique source for AD data from %v, this will give errors during object merging: %v", path, err)
} else {
// Indicate from which domain we saw this if we have the data
nb := engine.AttributeValueString(netbiosname)
Expand Down
124 changes: 69 additions & 55 deletions modules/integrations/activedirectory/analyze/analyze-ad.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,16 @@ func init() {
}

for _, o := range ao.Slice() {

// Only for computers
if o.Type() != engine.ObjectTypeComputer {
continue
}

// ... that has LAPS installed
if !o.HasAttr(activedirectory.MSmcsAdmPwdExpirationTime) {
continue
}

// Analyze ACL
sd, err := o.SecurityDescriptor()
if err != nil {
Expand All @@ -127,8 +128,8 @@ func init() {
if machinesid.IsBlank() {
ui.Fatal().Msgf("Computer account %v has no objectSID", o.DN())
}
machine, ok := ao.Find(DomainJoinedSID, engine.AttributeValueSID(machinesid))
if !ok {
machine, found := ao.Find(DomainJoinedSID, engine.AttributeValueSID(machinesid))
if !found {
ui.Error().Msgf("Could not locate machine for domain SID %v", machinesid)
continue
}
Expand Down Expand Up @@ -728,13 +729,19 @@ func init() {
continue
}

machine := ao.AddNew(
sid := computeraccount.OneAttr(engine.ObjectSid)
if sid == nil {
ui.Error().Msgf("Computer account without SID: %v", computeraccount.DN())
continue
}
machine, _ := ao.FindOrAdd(
DomainJoinedSID, sid,
engine.IgnoreBlanks,
engine.Name, computeraccount.Attr(engine.Name),
activedirectory.ObjectCategorySimple, "Machine",
DomainJoinedSID, computeraccount.SID(),
DnsHostName, computeraccount.Attr(DnsHostName),
)
// ui.Debug().Msgf("Added machine for SID %v", sid.String())

machine.EdgeTo(computeraccount, EdgeAuthenticatesAs)
machine.EdgeTo(computeraccount, EdgeMachineAccount)
Expand Down Expand Up @@ -973,7 +980,7 @@ func init() {
}
},
"missing well-known SIDs",
engine.BeforeMerge,
engine.BeforeMergeLow,
)

Loader.AddProcessor(func(ao *engine.Objects) {
Expand Down Expand Up @@ -1003,54 +1010,6 @@ func init() {
}, TrustInfo{})

for _, object := range ao.Slice() {
// We'll put the ObjectClass UUIDs in a synthetic attribute, so we can look it up later quickly (and without access to Objects)
objectclasses := object.Attr(engine.ObjectClass)
if objectclasses.Len() > 0 {
guids := make([]engine.AttributeValue, 0, objectclasses.Len())
objectclasses.Iterate(func(class engine.AttributeValue) bool {
if oto, found := ao.Find(engine.LDAPDisplayName, class); found {
if guid, ok := oto.OneAttr(activedirectory.SchemaIDGUID).(engine.AttributeValueGUID); !ok {
ui.Debug().Msgf("%v", oto)
ui.Fatal().Msgf("Could not translate SchemaIDGUID for class %v - I need a Schema to work properly", class)
} else {
guids = append(guids, guid)
}
} else {
ui.Warn().Msgf("Could not resolve object class %v, perhaps you didn't get a dump of the schema?", class.String())
}
return true // continue
})
object.SetFlex(engine.ObjectClassGUIDs, guids)
}

// ObjectCategory handling
var objectcategoryguid engine.AttributeValue
var simple engine.AttributeValue

objectcategoryguid = engine.AttributeValueGUID(engine.UnknownGUID)
simple = engine.AttributeValueString("Unknown")

typedn := object.OneAttr(engine.ObjectCategory)

// Does it have one, and does it have a comma, then we're assuming it's not just something we invented
if typedn != nil {
if oto, found := ao.Find(engine.DistinguishedName, typedn); found {
if _, ok := oto.OneAttrRaw(activedirectory.SchemaIDGUID).(uuid.UUID); ok {
objectcategoryguid = oto.OneAttr(activedirectory.SchemaIDGUID)
simple = oto.OneAttr(activedirectory.Name)
} else {
ui.Error().Msgf("Could not translate SchemaIDGUID for %v", typedn)
}
} else {
ui.Error().Msgf("Could not resolve object category %v, perhaps you didn't get a dump of the schema?", typedn)
}
}

object.SetFlex(
engine.ObjectCategoryGUID, objectcategoryguid,
engine.ObjectCategorySimple, simple,
)

if rid, ok := object.AttrInt(activedirectory.PrimaryGroupID); ok {
sid := object.SID()
if len(sid) > 8 {
Expand Down Expand Up @@ -1194,7 +1153,62 @@ func init() {
}
},
"Active Directory objects and metadata",
engine.BeforeMergeLow)
engine.BeforeMerge)

Loader.AddProcessor(func(ao *engine.Objects) {
for _, object := range ao.Slice() {
// We'll put the ObjectClass UUIDs in a synthetic attribute, so we can look it up later quickly (and without access to Objects)
objectclasses := object.Attr(engine.ObjectClass)
if objectclasses.Len() > 0 {
guids := make([]engine.AttributeValue, 0, objectclasses.Len())
objectclasses.Iterate(func(class engine.AttributeValue) bool {
if oto, found := ao.Find(engine.LDAPDisplayName, class); found {
if guid, ok := oto.OneAttr(activedirectory.SchemaIDGUID).(engine.AttributeValueGUID); !ok {
ui.Debug().Msgf("%v", oto)
ui.Fatal().Msgf("Could not translate SchemaIDGUID for class %v - I need a Schema to work properly", class)
} else {
guids = append(guids, guid)
}
} else {
ui.Warn().Msgf("Could not resolve object class %v, perhaps you didn't get a dump of the schema?", class.String())
}
return true // continue
})
object.SetFlex(engine.ObjectClassGUIDs, guids)
}

// ObjectCategory handling
var objectcategoryguid engine.AttributeValue
var simple engine.AttributeValue

objectcategoryguid = engine.AttributeValueGUID(engine.UnknownGUID)
simple = engine.AttributeValueString("Unknown")

typedn := object.OneAttr(engine.ObjectCategory)

// Does it have one, and does it have a comma, then we're assuming it's not just something we invented
if typedn != nil {
if oto, found := ao.Find(engine.DistinguishedName, typedn); found {
if _, ok := oto.OneAttrRaw(activedirectory.SchemaIDGUID).(uuid.UUID); ok {
objectcategoryguid = oto.OneAttr(activedirectory.SchemaIDGUID)
simple = oto.OneAttr(activedirectory.Name)
} else {
ui.Error().Msgf("Could not translate SchemaIDGUID for %v", typedn)
}
} else {
ui.Error().Msgf("Could not resolve object category %v, perhaps you didn't get a dump of the schema?", typedn)
}
}

object.SetFlex(
engine.ObjectCategoryGUID, objectcategoryguid,
engine.ObjectCategorySimple, simple,
)
}
},
"Set ObjectCategorySimple (for Type call) to Active Directory objects",
engine.BeforeMergeLow,
)

Loader.AddProcessor(func(ao *engine.Objects) {
for _, object := range ao.Slice() {
Expand Down
8 changes: 4 additions & 4 deletions modules/integrations/activedirectory/analyze/gpoimport.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ func GPOparseGptTmplInf(rawini string) []SIDpair {
// Usernames does not
membername = membersid
membersid = ""
translatedsid, err := TranslateLocalizedGroupToSID(membername)
translatedsid, err := TranslateLocalizedNameToSID(membername)
if err != nil {
ui.Info().Msgf("GPO GptTmplInf Memberof non-SID member %v translation gave no results, assuming it's a custom name: %v", membername, err)
} else {
Expand All @@ -444,7 +444,7 @@ func GPOparseGptTmplInf(rawini string) []SIDpair {
// We have a couple we can try - please contribute with more
groupname = groupsid
groupsid = ""
translatedsid, err := TranslateLocalizedGroupToSID(groupname)
translatedsid, err := TranslateLocalizedNameToSID(groupname)
if err != nil {
ui.Info().Msgf("GPO GptTmplInf Memberof non-SID group %v translation gave no results (PLEASE CONTRIBUTE): %v", groupname, err)
} else {
Expand All @@ -470,7 +470,7 @@ func GPOparseGptTmplInf(rawini string) []SIDpair {
// We have a couple we can try - please contribute with more
groupname = groupsid
groupsid = ""
translatedsid, err := TranslateLocalizedGroupToSID(groupname)
translatedsid, err := TranslateLocalizedNameToSID(groupname)
if err != nil {
ui.Warn().Msgf("GPO GptTmplInf Memberof non-SID group %v translation failed (PLEASE CONTRIBUTE): %v", groupname, err)
} else {
Expand All @@ -486,7 +486,7 @@ func GPOparseGptTmplInf(rawini string) []SIDpair {
} else {
membername = membersid
membersid = ""
translatedsid, err := TranslateLocalizedGroupToSID(membername)
translatedsid, err := TranslateLocalizedNameToSID(membername)
if err != nil {
ui.Warn().Msgf("GPO GptTmplInf Memberof non-SID member %v translation failed (PLEASE CONTRIBUTE): %v", membername, err)
} else {
Expand Down
6 changes: 3 additions & 3 deletions modules/integrations/activedirectory/analyze/knownsids.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const (
)

var (
groupTranslationTable = map[string]windowssecurity.SID{
nameTranslationTable = map[string]windowssecurity.SID{
strings.ToLower("Administrators"): windowssecurity.AdministratorsSID, // EN
strings.ToLower("Administratorer"): windowssecurity.AdministratorsSID, // DK
strings.ToLower("Administratoren"): windowssecurity.AdministratorsSID, // DE
Expand All @@ -39,8 +39,8 @@ var (
}
)

func TranslateLocalizedGroupToSID(groupname string) (windowssecurity.SID, error) {
if sid, found := groupTranslationTable[strings.ToLower(groupname)]; found {
func TranslateLocalizedNameToSID(name string) (windowssecurity.SID, error) {
if sid, found := nameTranslationTable[strings.ToLower(name)]; found {
return sid, nil
}
return windowssecurity.SID(""), errors.New("Localized group name not found")
Expand Down

0 comments on commit 2a4ea61

Please sign in to comment.