Skip to content

Commit

Permalink
added some more bh(e) query compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
olafhartong committed Sep 20, 2024
1 parent ba44895 commit 78c7729
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 5 deletions.
19 changes: 19 additions & 0 deletions actions/09_Bloodhound/bh_kerberoastable_users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Name: Kerberoastable users
ID: BH_SPN_Users
Description: This action lists all users with an SPN
Author: FalconForce
Version: '1.0'
Info: |
This is intended to be used as an enrichment list to quantify the impact of an alert on a user that owns a resource.
Active: false # Enable to run this action
Debug: false # Enable to see query results in the console
SourcePlatform: BloodHound
Query: |
MATCH (a:User {hasspn:true}) RETURN a
Targets:
- Name: CSV
Enabled: true
Path: output/kerberoastable_users.csv
- Name: Sentinel
Enabled: false
# TODO: Add filtering for output - WIP for now
22 changes: 22 additions & 0 deletions actions/09_Bloodhound/bh_tier0_users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Name: Kerberoastable users
ID: BH_Tier0_Users
Description: This action lists all users with an SPN
Author: FalconForce
Version: '1.0'
Info: |
This is intended to be used as an enrichment list to quantify the impact of an alert on a user that owns a resource.
Active: false # Enable to run this action
Debug: false # Enable to see query results in the console
SourcePlatform: BloodHound
Query: |
MATCH (x:Group)
WHERE (coalesce(x.system_tags,'') CONTAINS 'admin_tier_0')
WITH x.objectid as ObjectID, x.name as Name
MATCH (y:Group {objectid:ObjectID})
MATCH (u:User)
MATCH (u)-[MemberOf]->(y)
RETURN u
Targets:
- Name: CSV
Enabled: true
Path: output/tier0_users.csv
27 changes: 23 additions & 4 deletions input_processor/bloodhound.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"falconhound/internal"
"fmt"
"io"
Expand Down Expand Up @@ -40,7 +41,7 @@ func BHRequest(query string, creds internal.Credentials) (internal.QueryResults,

method := "POST"
uri := "/api/v2/graphs/cypher"
queryBody := fmt.Sprintf("{\"query\":\"%s\"}", query)
queryBody := fmt.Sprintf("{\"query\":\"%s\", \"include_properties\": true}", query)
log.Println("Query body:", queryBody)
body := []byte(queryBody)

Expand Down Expand Up @@ -91,7 +92,25 @@ func BHRequest(query string, creds internal.Credentials) (internal.QueryResults,
fmt.Println("Error reading response body:", err)
}

fmt.Println("Response:", string(respbody))
// TODO parse response body into QueryResults
return nil, nil
//fmt.Println("Response:", string(respbody))

var bhresults internal.BHQueryResults
err = json.Unmarshal(respbody, &bhresults)
if err != nil {
return internal.QueryResults{}, fmt.Errorf("error unmarshalling response body: %w", err)
}

// append each node in bhresults to the results
results := make(internal.QueryResults, 0)
for _, node := range bhresults.Data.Nodes {
result := make(map[string]interface{})
result["label"] = node.Label
result["kind"] = node.Kind
result["objectId"] = node.ObjectID
result["isTierZero"] = node.IsTierZero
result["lastSeen"] = node.LastSeen
result["properties"] = node.Properties
results = append(results, result)
}
return results, nil
}
45 changes: 45 additions & 0 deletions internal/bh_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,48 @@ type OU struct {
ChildObjects []TypedPrincipal
Links []GPLink
}

type Node struct {
Label string `json:"label"`
Kind string `json:"kind"`
ObjectID string `json:"objectId"`
IsTierZero bool `json:"isTierZero"`
LastSeen string `json:"lastSeen"`
Properties NodeProperties `json:"properties"`
}

type NodeProperties struct {
AdminCount bool `json:"admincount"`
Description string `json:"description"`
DistinguishedName string `json:"distinguishedname"`
Domain string `json:"domain"`
DomainSID string `json:"domainsid"`
DontReqPreAuth bool `json:"dontreqpreauth"`
Enabled bool `json:"enabled"`
HasSPN bool `json:"hasspn"`
IsACLProtected bool `json:"isaclprotected"`
LastLogon int64 `json:"lastlogon"`
LastLogonTimestamp int64 `json:"lastlogontimestamp"`
LastSeen string `json:"lastseen"`
Name string `json:"name"`
ObjectID string `json:"objectid"`
PasswordNotRequired bool `json:"passwordnotreqd"`
PwdLastSet int64 `json:"pwdlastset"`
PwdNeverExpires bool `json:"pwdneverexpires"`
SAMAccountName string `json:"samaccountname"`
Sensitive bool `json:"sensitive"`
ServicePrincipalNames []string `json:"serviceprincipalnames"`
SIDHistory []string `json:"sidhistory"`
TrustedToAuth bool `json:"trustedtoauth"`
UnconstrainedDelegation bool `json:"unconstraineddelegation"`
WhenCreated int64 `json:"whencreated"`
}

type Data struct {
Nodes map[string]Node `json:"nodes"`
Edges []interface{} `json:"edges"` // Assuming edges are not used in this example
}

type BHQueryResults struct {
Data Data `json:"data"`
}
2 changes: 1 addition & 1 deletion internal/version.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package internal

const Version = "FalconHound v1.4.0"
const Version = "FalconHound v1.4.1"

0 comments on commit 78c7729

Please sign in to comment.