
BloodHound OpenGraph-Sammler für GitHub, der Organisationsstrukturen, Berechtigungen und cloudübergreifende Angriffspfade in einen navigierbaren Graphen für Sicherheitsaudits und Incident Response kartiert.

GitHound ist ein BloodHound OpenGraph-Collector für GitHub, der entwickelt wurde, um die Struktur und Berechtigungen Ihrer Organisation in einem navigierbaren Angriffspfad-Graphen abzubilden. Er:
Modelliert wichtige GitHub-Entitäten
Visualisieren und Analysieren in BloodHound
Mit GitHound erhalten Sie einen klaren, interaktiven Graphen Ihrer GitHub-Berechtigungslandschaft – perfekt für Sicherheitsüberprüfungen, Compliance-Audits und schnelle Incident-Untersuchungen.
Ausführliche Dokumentation finden Sie unter BloodHound Docs - GitHound.
# 1. Load the collector
. ./githound.ps1
# 2. Create a session with your Personal Access Token
$session = New-GitHubSession -OrganizationName "YourOrgName" -Token (Get-Clipboard)
# 3. Run the collection
Invoke-GitHound -Session $session
# 4. Upload the resulting githound_<orgId>.json file to BloodHound
Falls die Sammlung unterbrochen wird, setzen Sie an der Stelle fort, an der Sie aufgehört haben:
Invoke-GitHound -Session $session -Resume
GitHound unterstützt sowohl Personal-Access-Token-Sitzungen als auch GitHub-App-Installationssitzungen. Der bestehende, auf Organisationen bezogene GitHub-App-Workflow bleibt unverändert:
. ./githound.ps1
$session = New-GitHubJwtSession `
-OrganizationName "YourOrgName" `
-ClientId $clientId `
-PrivateKeyPath $privateKeyPath `
-InstallationId $installationId
Invoke-GitHound -Session $session -CollectAll
Dieselbe Funktion kann auch enterprise-fähige Sitzungen erstellen:
. ./githound.ps1
$session = New-GitHubJwtSession `
-EnterpriseName "YourEnterpriseSlug" `
-ClientId $clientId `
-PrivateKeyPath $privateKeyPath `
-InstallationId $installationId `
-PersonalAccessToken $pat
Enterprise-fähige Sitzungen behalten mehrere Authentifizierungskontexte auf der zurückgegebenen GitHound.Session bei:
Headers: die GitHub-App-Installationstoken-Header, die für die normale Sammlung verwendet werdenJwtHeaders: JWT-Header der GitHub-App, die für App-Ebene-Endpunkte wie die Installationsaufzählung verwendet werdenPatHeaders: optionale Personal-Access-Token-Header für Sammlungspfade, die eine Benutzer-Token-Authentifizierung erfordernUm die Installationen aufzulisten, die zur authentifizierten GitHub-App gehören:
Get-GitHubAppInstallation -Session $session |
Select-Object TargetType, InstallationId, Login, Name, SuspendedAt
Das Workflow-Parsing ist jetzt in Invoke-GitHound integriert, wenn Sie -CollectAll verwenden. Der Collector wird:
GH_Workflow-Knoten und Workflow-Inhalte sammelnGH_WorkflowJob und GH_WorkflowStep analysierenGH_CanPwnRequest und GH_CanDispatchTo berechnengithound_<orgId>.json-Ausgabe einfügenFür Wiederaufnahme-/Debugging-Zwecke wird der Zwischenprüfpunkt der Workflow-Analyse als githound_WorkflowAnalysis_<orgId>.json geschrieben.
GitHound enthält jetzt eine minimale Enterprise-Sammlungsgrundlage über Git-HoundEnterprise.
Dieser Collector erstellt derzeit:
GH_EnterpriseGH_Organization-Stub-Knoten für MitgliedsorganisationenGH_Contains-Kanten vom Enterprise zu seinen OrganisationenEnterprise-Benutzersammlung über Git-HoundEnterpriseUser fügt hinzu:
GH_UserGH_HasMember-Kanten vom Enterprise zu diesen BenutzernEnterprise-SAML-Sammlung über Git-HoundEnterpriseSamlProvider fügt hinzu:
GH_SamlIdentityProviderGH_ExternalIdentityGH_HasSamlIdentityProvider vom Enterprise zum AnbieterDieser Pfad erfordert eine PAT-gestützte Sitzung, da GitHub Enterprise-SAML über enterprise.ownerInfo bereitstellt.
Enterprise-Team-Sammlung über Git-HoundEnterpriseTeam fügt hinzu:
GH_EnterpriseTeamGH_AssignedTo-Kanten von Enterprise-Teams zu zugewiesenen OrganisationenGH_MemberOf-Kanten von Enterprise-Teams zu für die Organisation sichtbaren ent: GH_Team-Knoten mittels Eigenschaftsabgleichmembers-Rollen und GH_HasRole-Kanten von Benutzern zu diesen RollenEnterprise-Rollen-Sammlung über Git-HoundEnterpriseRole fügt hinzu:
GH_EnterpriseRoleGH_Contains-Kanten vom Enterprise zu diesen RollenGH_HasRole-Kanten von direkt zugewiesenen Benutzern und Enterprise-Teamsowners-Rolle, die aus enterprise.ownerInfo.admins befüllt wird, wenn PAT-gestützte Enterprise-Administratordaten verfügbar sindDerzeit werden rohe Enterprise-Berechtigungszeichenfolgen auf dem GH_EnterpriseRole-Knoten in seiner permissions-Eigenschaft beibehalten, anstatt in dedizierte Berechtigungskanten erweitert zu werden.
Enterprise-SCIM-Sammlung fügt derzeit hinzu:
SCIM_UserSCIM_GroupSCIM_Provisioned von SCIM_User zu GH_ExternalIdentitySCIM_Provisioned von SCIM_Group zu GH_EnterpriseTeam, wenn GitHub die Enterprise-Team-group_id bereitstelltSCIM_MemberOf von SCIM_User zu SCIM_GroupDies gibt GitHound eine anbieteragnostische Brücke vom gemeinsamen SCIM-Schema in das native Enterprise-Identitäts- und Team-Modell von GitHub.
Wenn ein gesammelter GH_SamlIdentityProvider den vorgelagerten IdP identifiziert, kann GitHound auch anbieterbewusste SCIM-Korrelationsecken innerhalb der SCIM-Sidecar-Ausgabe hinzufügen:
Okta_User -> SCIM_User
Okta_User.id = SCIM_User.externalIdOkta_Group -> SCIM_Group
Okta_Group.name = SCIM_Group.externalIdOkta_Group.oktaDomain = GH_SamlIdentityProvider.foreign_environmentidGitHound behält die SCIM-Ebene in einer eigenen Sidecar-Ausgabe, sodass diese Zuordnungen sichtbar bleiben, ohne SCIM-native Knoten in den Haupt-GitHub-nativen Enterprise-Graphen zu mischen:
githound_<entId>.json enthält native GitHub-Enterprise-Datengithound_scim_<entId>.json enthält SCIM-native Knoten und SCIM-Brückenkantengithound_saml_<entId>.json enthält SAML- und externe Identitätsdatengithound_hybrid_<entId>.json enthält modellübergreifende Kanten wie SAML_Implements, SAML_HasAccount und GH_SyncedTogithound_saml_<entId>.json enthält auch die normalisierte SAML-Topologie für den GitHub-Dienstanbieter, einschließlich SAML_TrustsIssuer und SAML_HasAssertionConsumerServiceDas native GitHub-Identitätsanbietermodell bleibt in den GitHub/SAML-nativen Ausgaben intakt:
GH_ExternalIdentityGH_HasExternalIdentityGH_MapsToUserDie normalisierte SAML-Ebene in githound_hybrid_<entId>.json platziert jetzt SAML_HasAccount direkt auf GH_User, während match_values aus den verknüpften GH_ExternalIdentity-SAML-Eigenschaften wie saml_identity_name_id und saml_identity_username abgeleitet werden.
Die von der Enterprise-Sammlung ausgegebenen GH_Organization-Stubs sind absichtlich als collected = false markiert. Sie stellen eine strukturelle Erkennung aus dem Enterprise-Kontext dar und sollen später durch die normale Organisationssammlung angereichert werden.
Für eine Enterprise-first-Orchestrierung sammelt Invoke-GitHoundEnterprise die unterstützten Enterprise-bezogenen Daten, zählt die zugehörigen Organisationsinstallationen auf und führt dann den vorhandenen Invoke-GitHound-Workflow für jede Organisation in einem eigenen Unterverzeichnis unter dem gewählten Prüfpunktpfad aus.
Beispiel:
$session = New-GitHubJwtSession `
-EnterpriseName "your-enterprise-slug" `
-ClientId $clientId `
-PrivateKeyPath $privateKeyPath `
-InstallationId $enterpriseInstallationId `
-PersonalAccessToken $pat
Invoke-GitHoundEnterprise -Session $session -CheckpointPath "./output/your-enterprise" -CollectAll
Für reine Enterprise-Tests ohne Aufzählung der zugehörigen Organisationen:
Invoke-GitHoundEnterprise -Session $session -CheckpointPath "./output/your-enterprise" -EnterpriseOnly

Ausführliche Dokumentation finden Sie unter BloodHound Docs - GitHound Schema.
Wichtige Kantenkategorien:
Primäres Angriffspfadmuster:
(:GH_User)-[:GH_HasRole|GH_MemberOf|GH_AddMember*1..]->(:GH_RepoRole)-[:GH_AdminTo|GH_CanPush]->(:GH_Repository)
Finden Sie die Objektkennung für Ihren Zielbenutzer:
MATCH (n:GH_User)
RETURN n
HINWEIS: Wählen Sie Tabellenlayout
https://github.com/user-attachments/assets/1ddfd075-2a15-4aa9-bad7-74c43e6c82d6
Ersetzen Sie den <object_id>-Wert in der folgenden Abfrage durch die Objektkennung des Benutzers:
MATCH p = (:GH_User {objectid:"<object_id>"})-[:GH_MemberOf|GH_AddMember|GH_HasRole|GH_HasBaseRole|GH_Owns*1..]->(:GH_RepoRole)-[:GH_WriteRepoContents]->(:GH_Repository)
RETURN p

Ermitteln Sie die Objektkennung für Ihr Zielrepository:
MATCH (n:GH_Repository)
RETURN n
Nehmen Sie die Objektkennung für Ihr Zielrepository und ersetzen Sie den <object_id>-Wert in der folgenden Abfrage damit:
MATCH p = (:GH_User)-[:GH_MemberOf|GH_HasRole|GH_HasBaseRole|GH_Owns|GH_AddMember*1..]->(:GH_RepoRole)-[:GH_WriteRepoContents]->(:GH_Repository {objectid:"<object_id>"})
RETURN p

MATCH p = (:GH_User)-[:GH_HasRole|GH_HasBaseRole]->(:GH_OrgRole {short_name: "owners"})
RETURN p

MATCH p = (:AZUser)-[:GH_SyncedTo]->(:GH_User)
RETURN p

Finden Sie GitHub-Entitäten, die Azure-Verbundidentitäten annehmen können (OIDC-Vertrauensbeziehungen):
// All GitHub → Azure OIDC attack paths
MATCH p = (:GH_Repository|GH_Branch|GH_Environment)-[:GH_CanAssumeIdentity]->(:AZFederatedIdentityCredential)
RETURN p
// Users with paths to Azure via GitHub Actions
MATCH p = (:GH_User)-[:GH_HasRole|GH_MemberOf|GH_AddMember*1..]->(:GH_RepoRole)-[:GH_CanPush]->(:GH_Repository)-[:GH_CanAssumeIdentity]->(:AZFederatedIdentityCredential)
RETURN p
MATCH p = (:GH_Repository)-[:GH_HasSecret]->(:GH_OrgSecret)
RETURN p
MATCH p = (:GH_Repository)-[:GH_Contains]->(:GH_SecretScanningAlert)
RETURN p
Wir begrüßen und schätzen Ihre Beiträge! Um den Prozess reibungslos und effizient zu gestalten, befolgen Sie bitte diese Schritte:
Ihre Idee besprechen
Forken und einen Branch erstellen
Forken Sie dieses Repository in Ihr eigenes Konto.
Erstellen Sie einen Topic-Branch für Ihre Arbeit:
git checkout -b feat/my-new-feature
Implementieren und testen
Folgen Sie dem vorhandenen Stil und den Mustern im Repo.
Fügen Sie Tests/Beispiele hinzu oder aktualisieren Sie sie, um Ihre Änderungen abzudecken.
Überprüfen Sie, ob Ihr Code wie erwartet funktioniert:
# e.g. dot-source the collector and run it, or load the model.json in BloodHound
Einen Pull Request einreichen
Pushen Sie Ihren Branch zu Ihrem Fork:
git push origin feat/my-new-feature
Öffnen Sie einen Pull Request gegen den main-Branch dieses Repositorys.
Fügen Sie in Ihrer PR-Beschreibung bitte Folgendes ein:
Überprüfen und zusammenführen
Vielen Dank, dass Sie helfen, diese Erweiterung zu verbessern! 🎉
Copyright 2025 Jared Atkinson
Licensed under the Apache License, Version 2.0
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Sofern nicht durch eine untergeordnete LICENSE-Datei oder einen Lizenzheader anders gekennzeichnet, werden alle Dateien in diesem Repository unter der Apache-2.0-Lizenz veröffentlicht. Eine vollständige Kopie der Lizenz finden Sie in der obersten LICENSE-Datei.
| Kategorie | Wichtige Kanten | Beschreibung |
|---|
| Enthaltenseinsbeziehung | GH_Contains, GH_Owns | Organisationshierarchie |
| Rollenvergabe | GH_HasRole, GH_MemberOf, GH_HasBaseRole | Wer hat welche Rollen |
| Repository-Berechtigungen | GH_AdminTo, GH_CanPush, GH_CanPull | Was Rollen tun können |
| Branch-Schutz | GH_BypassPullRequestAllowances, GH_RestrictionsCanPush | Zugriff auf Branch-Ebene |
| Geheimnisse | GH_HasSecret | Geheimniszugriffszuordnung |
| Cloud-übergreifend | GH_CanAssumeIdentity, GH_SyncedTo | Angriffspfade zu Azure/AWS |