@@ -48,13 +48,12 @@ func setThreadsafe(enable bool) {
48
48
var UnknownGUID = uuid.UUID {0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff }
49
49
50
50
type Object struct {
51
- values AttributeValueMap
52
- PwnableBy EdgeConnections
53
- CanPwn EdgeConnections
54
- parent * Object
55
- sdcache * SecurityDescriptor
56
- sid windowssecurity.SID
57
- children []* Object
51
+ values AttributeValueMap
52
+ edges [2 ]EdgeConnections
53
+ parent * Object
54
+ sdcache * SecurityDescriptor
55
+ sid windowssecurity.SID
56
+ children []* Object
58
57
59
58
members map [* Object ]struct {}
60
59
membersrecursive map [* Object ]struct {}
@@ -190,20 +189,20 @@ func (o *Object) AbsorbEx(source *Object, fast bool) {
190
189
}
191
190
}
192
191
193
- for pwntarget , methods := range source .CanPwn {
194
- target .CanPwn [ pwntarget ] = target .CanPwn [pwntarget ].Merge (methods )
195
- delete (source .CanPwn , pwntarget )
192
+ for pwntarget , methods := range source .edges [ Out ] {
193
+ target.edges [ Out ][ pwntarget ] = target.edges [ Out ] [pwntarget ].Merge (methods )
194
+ delete (source .edges [ Out ] , pwntarget )
196
195
197
- pwntarget .PwnableBy [ target ] = pwntarget .PwnableBy [target ].Merge (methods )
198
- delete (pwntarget .PwnableBy , source )
196
+ pwntarget.edges [ In ][ target ] = pwntarget.edges [ In ] [target ].Merge (methods )
197
+ delete (pwntarget .edges [ In ] , source )
199
198
}
200
199
201
- for pwner , methods := range source .PwnableBy {
202
- target .PwnableBy [ pwner ] = target .PwnableBy [pwner ].Merge (methods )
203
- delete (source .PwnableBy , pwner )
200
+ for pwner , methods := range source .edges [ In ] {
201
+ target.edges [ In ][ pwner ] = target.edges [ In ] [pwner ].Merge (methods )
202
+ delete (source .edges [ In ] , pwner )
204
203
205
- pwner .CanPwn [ target ] = pwner .CanPwn [target ].Merge (methods )
206
- delete (pwner .CanPwn , source )
204
+ pwner.edges [ Out ][ target ] = pwner.edges [ Out ] [target ].Merge (methods )
205
+ delete (pwner .edges [ Out ] , source )
207
206
}
208
207
209
208
// For everyone that is a member of source, relink them to the target
@@ -981,9 +980,9 @@ func (o *Object) init() {
981
980
if o .values == nil {
982
981
o .values = NewAttributeValueMap ()
983
982
}
984
- if o .CanPwn == nil || o .PwnableBy == nil {
985
- o .CanPwn = make (EdgeConnections )
986
- o .PwnableBy = make (EdgeConnections )
983
+ if o .edges [ Out ] == nil || o .edges [ In ] == nil {
984
+ o .edges [ Out ] = make (EdgeConnections )
985
+ o .edges [ In ] = make (EdgeConnections )
987
986
}
988
987
}
989
988
@@ -1107,13 +1106,21 @@ func (o *Object) GUID() uuid.UUID {
1107
1106
return guid
1108
1107
}
1109
1108
1109
+ // Look up edge
1110
+ func (o * Object ) Edge (direction EdgeDirection , target * Object ) EdgeBitmap {
1111
+ o .lock ()
1112
+ bm := o.edges [direction ][target ]
1113
+ o .unlock ()
1114
+ return bm
1115
+ }
1116
+
1110
1117
// Register that this object can pwn another object using the given method
1111
1118
func (o * Object ) EdgeTo (target * Object , method Edge ) {
1112
- o .PwnsEx (target , method , false )
1119
+ o .EdgeToEx (target , method , false )
1113
1120
}
1114
1121
1115
1122
// Enhanched Pwns function that allows us to force the pwn (normally self-pwns are filtered out)
1116
- func (o * Object ) PwnsEx (target * Object , method Edge , force bool ) {
1123
+ func (o * Object ) EdgeToEx (target * Object , method Edge , force bool ) {
1117
1124
if ! force {
1118
1125
if o == target { // SID check solves (some) dual-AD analysis problems
1119
1126
// We don't care about self owns
@@ -1134,14 +1141,49 @@ func (o *Object) PwnsEx(target *Object, method Edge, force bool) {
1134
1141
}
1135
1142
1136
1143
o .lock ()
1137
- o .CanPwn .Set (target , method ) // Add the connection
1144
+ o .edges [Out ].Set (target , method ) // Add the connection
1145
+ o .unlock ()
1146
+
1147
+ target .lock ()
1148
+ target .edges [In ].Set (o , method ) // Add the reverse connection too
1149
+ target .unlock ()
1150
+ }
1151
+
1152
+ func (o * Object ) EdgeClear (target * Object , method Edge ) {
1153
+ o .lock ()
1154
+ currentedge := o.edges [Out ][target ]
1155
+ if currentedge .IsSet (method ) {
1156
+ o.edges [Out ][target ] = currentedge .Clear (method )
1157
+ }
1138
1158
o .unlock ()
1139
1159
1140
1160
target .lock ()
1141
- target .PwnableBy .Set (o , method ) // Add the reverse connection too
1161
+ currentedge = target.edges [In ][o ]
1162
+ if currentedge .IsSet (method ) {
1163
+ target.edges [In ][o ] = currentedge .Clear (method )
1164
+ }
1142
1165
target .unlock ()
1143
1166
}
1144
1167
1168
+ func (o * Object ) EdgeCount (direction EdgeDirection ) int {
1169
+ o .lock ()
1170
+ result := len (o .edges [direction ])
1171
+ o .unlock ()
1172
+ return result
1173
+ }
1174
+
1175
+ func (o * Object ) EdgeIterator (direction EdgeDirection , ei func (target * Object , edge EdgeBitmap ) bool ) {
1176
+ o .lock ()
1177
+ for target , edge := range o .edges [direction ] {
1178
+ o .unlock ()
1179
+ if ! ei (target , edge ) {
1180
+ return
1181
+ }
1182
+ o .lock ()
1183
+ }
1184
+ o .unlock ()
1185
+ }
1186
+
1145
1187
func (o * Object ) ChildOf (parent * Object ) {
1146
1188
o .lock ()
1147
1189
if o .parent != nil {
0 commit comments