Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
lkarlslund committed Sep 7, 2022
2 parents 5bf5dd9 + ecd31f4 commit cc7e2a4
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 124 deletions.
14 changes: 7 additions & 7 deletions modules/analyze/export-graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func GenerateCytoscapeJS(pg engine.Graph, alldetails bool) (CytoGraph, error) {
}

for _, connection := range pg.Connections {
edge := CytoFlatElement{
cytoedge := CytoFlatElement{
Group: "edges",
Data: MapStringInterface{
"id": fmt.Sprintf("e%v-%v", connection.Source.ID(), connection.Target.ID()),
Expand All @@ -137,20 +137,20 @@ func GenerateCytoscapeJS(pg engine.Graph, alldetails bool) (CytoGraph, error) {
}

for key, value := range connection.DynamicFields {
edge.Data[key] = value
cytoedge.Data[key] = value
}

var maxprob engine.Probability
for _, method := range connection.Methods() {
prob := method.Probability(connection.Source, connection.Target)
edge.Data["method_"+method.String()] = prob
for _, edge := range connection.Edges() {
prob := edge.Probability(connection.Source, connection.Target)
cytoedge.Data["method_"+edge.String()] = prob
if prob > maxprob {
maxprob = prob
}
}
edge.Data["_maxprob"] = maxprob
cytoedge.Data["_maxprob"] = maxprob

g.Elements[i] = edge
g.Elements[i] = cytoedge

i++
}
Expand Down
38 changes: 19 additions & 19 deletions modules/analyze/webservicefuncs.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ func analysisfuncs(ws *webservice) {
}

// var methods engine.EdgeBitmap
var methods_f, methods_m, methods_l engine.EdgeBitmap
var edges_f, egdes_m, edges_l engine.EdgeBitmap
var objecttypes_f, objecttypes_m, objecttypes_l []engine.ObjectType
for potentialfilter := range vars {
if len(potentialfilter) < 7 {
Expand All @@ -286,11 +286,11 @@ func analysisfuncs(ws *webservice) {
}
switch suffix {
case "_f":
methods_f = methods_f.Set(method)
edges_f = edges_f.Set(method)
case "_m":
methods_m = methods_m.Set(method)
egdes_m = egdes_m.Set(method)
case "_l":
methods_l = methods_l.Set(method)
edges_l = edges_l.Set(method)
}
} else if strings.HasPrefix(potentialfilter, "type_") {
prefix := potentialfilter[5 : len(potentialfilter)-2]
Expand All @@ -313,11 +313,11 @@ func analysisfuncs(ws *webservice) {
}

// Are we using the new format FML? The just choose the old format methods for FML
if methods_f.Count() == 0 && methods_m.Count() == 0 && methods_l.Count() == 0 {
if edges_f.Count() == 0 && egdes_m.Count() == 0 && edges_l.Count() == 0 {
// Spread the choices to FML
methods_f = engine.AllEdgeMethods
methods_m = engine.AllEdgeMethods
methods_l = engine.AllEdgeMethods
edges_f = engine.AllEdgesBitmap
egdes_m = engine.AllEdgesBitmap
edges_l = engine.AllEdgesBitmap
}

var pg engine.Graph
Expand All @@ -327,7 +327,7 @@ func analysisfuncs(ws *webservice) {
}

// We dont support this yet, so merge all of them
combinedmethods := methods_f.Merge(methods_m).Merge(methods_l)
combinedmethods := edges_f.Merge(egdes_m).Merge(edges_l)

for _, source := range includeobjects.Slice() {
for _, target := range excludeobjects.Slice() {
Expand All @@ -340,9 +340,9 @@ func analysisfuncs(ws *webservice) {
opts := engine.NewAnalyzeObjectsOptions()
opts.IncludeObjects = includeobjects
opts.ExcludeObjects = excludeobjects
opts.MethodsF = methods_f
opts.MethodsM = methods_m
opts.MethodsL = methods_l
opts.MethodsF = edges_f
opts.MethodsM = egdes_m
opts.MethodsL = edges_l
opts.ObjectTypesF = objecttypes_f
opts.ObjectTypesM = objecttypes_m
opts.ObjectTypesL = objecttypes_l
Expand Down Expand Up @@ -519,22 +519,22 @@ func analysisfuncs(ws *webservice) {
})
}

var selectedmethods []engine.Edge
for potentialmethod, values := range uq {
if method := engine.E(potentialmethod); method != engine.NonExistingEdgeType {
var selectededges []engine.Edge
for potentialedge, values := range uq {
if edge := engine.E(potentialedge); edge != engine.NonExistingEdgeType {
enabled, _ := util.ParseBool(values[0])
if len(values) == 1 && enabled {
selectedmethods = append(selectedmethods, method)
selectededges = append(selectededges, edge)
}
}
}
// If everything is deselected, select everything
if len(selectedmethods) == 0 {
selectedmethods = engine.AllEdgesSlice()
if len(selectededges) == 0 {
selectededges = engine.AllEdgesSlice()
}

var methods engine.EdgeBitmap
for _, m := range selectedmethods {
for _, m := range selectededges {
methods = methods.Set(m)
}

Expand Down
40 changes: 20 additions & 20 deletions modules/engine/analyzeobjects.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ func (pm Edge) Probability(source, target *Object) Probability {

func NewAnalyzeObjectsOptions() AnalyzeObjectsOptions {
return AnalyzeObjectsOptions{
MethodsF: AllEdgeMethods,
MethodsM: AllEdgeMethods,
MethodsL: AllEdgeMethods,
MethodsF: AllEdgesBitmap,
MethodsM: AllEdgesBitmap,
MethodsL: AllEdgesBitmap,
Reverse: false,
MaxDepth: 99,
MaxOutgoingConnections: -1,
Expand Down Expand Up @@ -102,7 +102,7 @@ func AnalyzeObjects(opts AnalyzeObjectsOptions) (pg Graph) {
}

// Methods and ObjectTypes allowed
detectmethods := opts.MethodsF
detectedges := opts.MethodsF

var detectobjecttypes map[ObjectType]struct{}
// If there are any, put them in a map - otherwise it's faster NOT to filter by checking if the filter map is nil
Expand All @@ -115,7 +115,7 @@ func AnalyzeObjects(opts AnalyzeObjectsOptions) (pg Graph) {

for opts.MaxDepth >= processinground {
if processinground == 2 {
detectmethods = opts.MethodsM
detectedges = opts.MethodsM
detectobjecttypes = nil
if len(opts.ObjectTypesM) > 0 {
detectobjecttypes = make(map[ObjectType]struct{})
Expand All @@ -135,39 +135,39 @@ func AnalyzeObjects(opts AnalyzeObjectsOptions) (pg Graph) {

newconnectionsmap := make(map[ObjectPair]EdgeBitmap) // Pwn Connection between objects

var pwnlist EdgeConnections
var ec EdgeConnections
if forward {
pwnlist = object.PwnableBy
ec = object.PwnableBy
} else {
pwnlist = object.CanPwn
ec = object.CanPwn
}

// Iterate over ever outgoing pwn
// This is not efficient, but we sort the pwnlist first
for _, pwntarget := range pwnlist.Objects() {
pwninfo := pwnlist[pwntarget]
for _, target := range ec.Objects() {
eb := ec[target]

// If this is not a chosen method, skip it
detectedmethods := pwninfo.Intersect(detectmethods)
detectededges := eb.Intersect(detectedges)

methodcount := detectedmethods.Count()
if methodcount == 0 {
edgecount := detectededges.Count()
if edgecount == 0 {
// Nothing useful or just a deny ACL, skip it
continue
}

if detectobjecttypes != nil {
if _, found := detectobjecttypes[pwntarget.Type()]; !found {
if _, found := detectobjecttypes[target.Type()]; !found {
// We're filtering on types, and it's not wanted
continue
}
}

var maxprobability Probability
if forward {
maxprobability = detectedmethods.MaxProbability(pwntarget, object)
maxprobability = detectededges.MaxProbability(target, object)
} else {
maxprobability = detectedmethods.MaxProbability(object, pwntarget)
maxprobability = detectededges.MaxProbability(object, target)
}
if maxprobability < Probability(opts.MinProbability) {
// Too unlikeliy, so we skip it
Expand All @@ -178,7 +178,7 @@ func AnalyzeObjects(opts AnalyzeObjectsOptions) (pg Graph) {
// Targets are allowed to pwn each other as a way to reach the goal of pwning all of them
// If pwner is already processed, we don't care what it can pwn someone more far away from targets
// If pwner is our attacker, we always want to know what it can do
tri, found := implicatedobjectsmap[pwntarget]
tri, found := implicatedobjectsmap[target]

// SKIP THIS IF
if
Expand All @@ -191,20 +191,20 @@ func AnalyzeObjects(opts AnalyzeObjectsOptions) (pg Graph) {
// It was found in an earlier round
tri.roundadded+opts.Fuzzlevel <= processinground &&
// If SIDs match between objects, it's a cross forest link and we want to see it
(object.SID().IsNull() || pwntarget.SID().IsNull() || object.SID().Component(2) != 21 || object.SID() != pwntarget.SID()) {
(object.SID().IsNull() || target.SID().IsNull() || object.SID().Component(2) != 21 || object.SID() != target.SID()) {
// skip it
continue
}

if opts.ExcludeObjects != nil {
if _, found := opts.ExcludeObjects.FindByID(pwntarget.ID()); found {
if _, found := opts.ExcludeObjects.FindByID(target.ID()); found {
// skip excluded objects
// ui.Debug().Msgf("Excluding target %v", pwntarget.DN())
continue
}
}

newconnectionsmap[ObjectPair{Source: object, Target: pwntarget}] = detectedmethods
newconnectionsmap[ObjectPair{Source: object, Target: target}] = detectededges
}

if opts.MaxOutgoingConnections == -1 || len(newconnectionsmap) < opts.MaxOutgoingConnections {
Expand Down
12 changes: 6 additions & 6 deletions modules/engine/analyzepaths.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func (q queue) Empty() bool {
return len(q.items) == 0
}

func AnalyzePaths(start, end *Object, obs *Objects, lookformethods EdgeBitmap, minprobability Probability, iterations int) Graph {
func AnalyzePaths(start, end *Object, obs *Objects, lookforedges EdgeBitmap, minprobability Probability, iterations int) Graph {
visited := make(map[*Object]struct{})
dist := make(map[*Object]uint32)
prev := make(map[*Object]*Object)
Expand All @@ -166,19 +166,19 @@ func AnalyzePaths(start, end *Object, obs *Objects, lookformethods EdgeBitmap, m

visited[source] = struct{}{}

for target, methods := range source.CanPwn {
for target, edges := range source.CanPwn {
if _, found := visited[target]; !found {

// If this is not a chosen method, skip it
detectedmethods := methods.Intersect(lookformethods)
detectededges := edges.Intersect(lookforedges)

methodcount := detectedmethods.Count()
if methodcount == 0 {
edgecount := detectededges.Count()
if edgecount == 0 {
// Nothing useful or just a deny ACL, skip it
continue
}

prob := detectedmethods.MaxProbability(v.Object, target)
prob := detectededges.MaxProbability(v.Object, target)
if prob < minprobability {
// Skip entirely if too
continue
Expand Down
50 changes: 25 additions & 25 deletions modules/engine/edge.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,43 +27,43 @@ const (

type EdgeInfo struct {
Target *Object
Method Edge
Edge Edge
Probability Probability
}

func (eb EdgeBitmap) Set(method Edge) EdgeBitmap {
EdgePopularity[method]++
return eb.set(method)
func (eb EdgeBitmap) Set(edge Edge) EdgeBitmap {
EdgePopularity[edge]++
return eb.set(edge)
}

func (eb EdgeBitmap) set(method Edge) EdgeBitmap {
func (eb EdgeBitmap) set(edge Edge) EdgeBitmap {
newpm := eb
bits := uint64(1) << (method % 64)
newpm[int(method)/64] = eb[int(method)/64] | bits
bits := uint64(1) << (edge % 64)
newpm[int(edge)/64] = eb[int(edge)/64] | bits
return newpm
}

func (eb EdgeBitmap) Clear(method Edge) EdgeBitmap {
func (eb EdgeBitmap) Clear(edge Edge) EdgeBitmap {
newpm := eb
bits := uint64(1) << (method % 64)
newpm[int(method)/64] = eb[int(method)/64] &^ bits
bits := uint64(1) << (edge % 64)
newpm[int(edge)/64] = eb[int(edge)/64] &^ bits
return newpm
}

func (eb EdgeBitmap) Intersect(methods EdgeBitmap) EdgeBitmap {
var newpm EdgeBitmap
func (eb EdgeBitmap) Intersect(edges EdgeBitmap) EdgeBitmap {
var new EdgeBitmap
for i := 0; i < PMBSIZE; i++ {
newpm[i] = eb[i] & methods[i]
new[i] = eb[i] & edges[i]
}
return newpm
return new
}

func (eb EdgeBitmap) Merge(methods EdgeBitmap) EdgeBitmap {
var newpm EdgeBitmap
func (eb EdgeBitmap) Merge(edges EdgeBitmap) EdgeBitmap {
var new EdgeBitmap
for i := 0; i < PMBSIZE; i++ {
newpm[i] = eb[i] | methods[i]
new[i] = eb[i] | edges[i]
}
return newpm
return new
}

func (eb EdgeBitmap) Count() int {
Expand All @@ -74,7 +74,7 @@ func (eb EdgeBitmap) Count() int {
return ones
}

func (eb EdgeBitmap) Methods() []Edge {
func (eb EdgeBitmap) Edges() []Edge {
result := make([]Edge, eb.Count())
var n int
for i := 0; i < len(edgeInfos); i++ {
Expand All @@ -97,9 +97,9 @@ func (ec EdgeConnections) Objects() ObjectSlice {
return result
}

func (ec EdgeConnections) Set(o *Object, method Edge) {
func (ec EdgeConnections) Set(o *Object, edge Edge) {
p := ec[o]
ec[o] = p.Set(method)
ec[o] = p.Set(edge)
}

type Edge int
Expand Down Expand Up @@ -139,7 +139,7 @@ func NewEdge(name string) Edge {

newindex := Edge(len(edgeInfos))
if newindex == MAXPWNMETHODPOSSIBLE {
panic("Too many PwnMethods")
panic("Too many Edge definitions")
}

edgeInfos = append(edgeInfos, &edgeInfo{
Expand All @@ -156,7 +156,7 @@ func NewEdge(name string) Edge {

func (p Edge) String() string {
if int(p) >= len(edgeInfos) {
return "INVALID PWN METHOD"
return "INVALID EDGE"
}
return edgeInfos[p].Name
}
Expand Down Expand Up @@ -221,13 +221,13 @@ var (
AnyEdgeType = Edge(9999)
)

var AllEdgeMethods EdgeBitmap
var AllEdgesBitmap EdgeBitmap

var EdgePopularity [MAXPWNMETHODPOSSIBLE]uint64

func init() {
for i := Edge(0); i < MAXPWNMETHODPOSSIBLE; i++ {
AllEdgeMethods = AllEdgeMethods.set(i)
AllEdgesBitmap = AllEdgesBitmap.set(i)
}
}

Expand Down
Loading

0 comments on commit cc7e2a4

Please sign in to comment.