Skip to content

Commit

Permalink
Created DCsync node, switched from meta attributes to a single "tag" …
Browse files Browse the repository at this point in the history
…attribute, removed debug code, a few more privs to localmachine leading to nowhere,
  • Loading branch information
lkarlslund committed Jan 28, 2024
1 parent afdcf7e commit 706eb3b
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 133 deletions.
16 changes: 1 addition & 15 deletions modules/engine/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,7 @@ var (
NetbiosDomain = NewAttribute("netbiosDomain").Single() // Used to merge users with - if we only have a DOMAIN\USER type of info
DomainContext = NewAttribute("domainContext").Single()

MetaProtectedUser = NewAttribute("_protecteduser")
MetaUnconstrainedDelegation = NewAttribute("_unconstraineddelegation")
MetaConstrainedDelegation = NewAttribute("_constraineddelegation")
MetaHasSPN = NewAttribute("_hasspn")
MetaPasswordAge = NewAttribute("_passwordage")
MetaLastLoginAge = NewAttribute("_lastloginage")
MetaAccountActive = NewAttribute("accountActive")
MetaPasswordCantChange = NewAttribute("passwordCantChange")
MetaPasswordNotRequired = NewAttribute("passwordNotRequired").Type(AttributeTypeBool)
MetaPasswordNeverExpires = NewAttribute("passwordNeverExpires").Type(AttributeTypeBool)
MetaLinux = NewAttribute("_linux")
MetaWindows = NewAttribute("_windows")
MetaWorkstation = NewAttribute("_workstation")
MetaServer = NewAttribute("_server")
MetaLAPSInstalled = NewAttribute("_haslaps")
Tag = NewAttribute("tag")
)

func init() {
Expand Down
38 changes: 38 additions & 0 deletions modules/engine/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,44 @@ func (o *Object) Clear(a Attribute) {
o.values.Clear(a)
}

func (o *Object) Tag(v AttributeValueString) {
oldtags, found := o.Get(Tag)
if !found {
o.Set(Tag, AttributeValueSlice{v})
} else {
var exists bool
values := make(AttributeValueSlice, oldtags.Len()+1)
oldtags.Iterate(func(val AttributeValue) bool {
if val.String() == v.String() {
exists = true
return false
}
values = append(values, val)
return true
})
if !exists {
o.Set(Tag, append(values, v))
}
}
}

// FIXME performance optimization/redesign needed, but needs to work with Objects indexes
func (o *Object) HasTag(v AttributeValueString) bool {
tags, found := o.Get(Tag)
if !found {
return false
}
var exists bool
tags.Iterate(func(val AttributeValue) bool {
if val.String() == v.String() {
exists = true
return false
}
return true
})
return exists
}

func (o *Object) set(a Attribute, values AttributeValues) {
if a.IsSingle() && values.Len() > 1 {
ui.Warn().Msgf("Setting multiple values on non-multival attribute %v: %v", a.String(), strings.Join(values.StringSlice(), ", "))
Expand Down
6 changes: 1 addition & 5 deletions modules/engine/objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var idcounter uint32 // Unique ID +1 to assign to Object added to this collectio
type typestatistics [256]int

type Objects struct {
Datapath string
root *Object
DefaultValues []any
objects gsync.MapOf[ObjectID, *Object]
Expand Down Expand Up @@ -364,11 +365,6 @@ func (os *Objects) Merge(attrtomerge []Attribute, source *Object) bool {
return false // break
}

// Test that all mergeapprovers confirm this to be a valid merge
if source.SID().String() == "S-1-5-21-1912508229-386351500-4206070068-4522" {
ui.Trace().Msgf("Gotcha")
}

for _, mfi := range mergeapprovers {
res, err := mfi.mergefunc(source, target)
switch err {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,17 @@ var (
EdgeDSReplicationGetChanges = engine.NewEdge("DSReplGetChngs").SetDefault(false, false, false).Tag("Granted")
EdgeDSReplicationGetChangesAll = engine.NewEdge("DSReplGetChngsAll").SetDefault(false, false, false).Tag("Granted")
EdgeDSReplicationGetChangesInFilteredSet = engine.NewEdge("DSReplGetChngsInFiltSet").SetDefault(false, false, false).Tag("Granted")
EdgeDCsync = engine.NewEdge("DCsync").Tag("Granted")
EdgeCall = engine.NewEdge("Call").Describe("Call a service point")
EdgeControls = engine.NewEdge("Controls").Describe("Node controls a service point")
EdgeReadLAPSPassword = engine.NewEdge("ReadLAPSPassword").Tag("Pivot").Tag("Granted")
EdgeMemberOfGroup = engine.NewEdge("MemberOfGroup").Tag("Granted")
EdgeMemberOfGroupIndirect = engine.NewEdge("MemberOfGroupIndirect").SetDefault(false, false, false).Tag("Granted")
EdgeHasSPN = engine.NewEdge("HasSPN").Describe("Kerberoastable by requesting Kerberos service ticket against SPN and then bruteforcing the ticket").RegisterProbabilityCalculator(func(source, target *engine.Object) engine.Probability {
if uac, ok := target.AttrInt(UserAccountControl); ok && uac&0x0002 /*UAC_ACCOUNTDISABLE*/ != 0 {
// Account is disabled
return 0
if target.HasTag("active") {
return 50
}
return 50
// Account is disabled
return 0
}).Tag("Pivot")
EdgeDontReqPreauth = engine.NewEdge("DontReqPreauth").Describe("Kerberoastable by AS-REP by requesting a TGT and then bruteforcing the ticket").RegisterProbabilityCalculator(func(source, target *engine.Object) engine.Probability {
if uac, ok := target.AttrInt(UserAccountControl); ok && uac&0x0002 /*UAC_ACCOUNTDISABLE*/ != 0 {
Expand Down
Loading

0 comments on commit 706eb3b

Please sign in to comment.