├── .editorconfig ├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── build.yml │ ├── cla.yml │ └── publish.yml ├── .gitignore ├── .prettierrc ├── Collectors ├── AzureHound.md ├── DebugBuilds │ ├── README.md │ ├── SharpHound.exe │ ├── SharpHound.pdb │ └── SharpHound.ps1 ├── SharpHound.exe └── SharpHound.ps1 ├── LICENSE-3RD-PARTY.md ├── LICENSE.md ├── README.md ├── docs ├── Makefile ├── README.md ├── _build │ ├── doctrees │ │ ├── environment.pickle │ │ └── index.doctree │ └── html │ │ ├── .buildinfo │ │ ├── _sources │ │ └── index.rst.txt │ │ ├── _static │ │ ├── alabaster.css │ │ ├── basic.css │ │ ├── custom.css │ │ ├── doctools.js │ │ ├── documentation_options.js │ │ ├── file.png │ │ ├── jquery-3.4.1.js │ │ ├── jquery.js │ │ ├── language_data.js │ │ ├── minus.png │ │ ├── plus.png │ │ ├── pygments.css │ │ ├── searchtools.js │ │ ├── underscore-1.3.1.js │ │ └── underscore.js │ │ ├── genindex.html │ │ ├── index.html │ │ ├── objects.inv │ │ ├── search.html │ │ └── searchindex.js ├── _static │ └── css │ │ └── custom.css ├── _templates │ └── layout.html ├── conf.py ├── data-analysis │ ├── bloodhound-gui.rst │ ├── edges.rst │ └── nodes.rst ├── data-collection │ ├── azurehound-all-flags.rst │ ├── azurehound.rst │ ├── bloodhound-py.rst │ ├── sharphound-all-flags.rst │ └── sharphound.rst ├── further-reading │ ├── further-reading.rst │ └── json.rst ├── html │ └── _static │ │ └── css │ │ └── custom.css ├── images │ ├── SharpHoundCheatSheet.png │ ├── bloodhound-initial-query.png │ ├── bloodhound-logo.png │ ├── bloodhound-logon.png │ ├── davidmcguire-edges.png │ ├── domain-users-to-domain-admins-filtered.png │ ├── domain-users-to-domain-admins.png │ ├── edge-filtering.gif │ ├── edge-filtering.png │ ├── import-data.gif │ ├── java_home_check.png │ ├── java_home_variable.png │ ├── log-out.png │ ├── neo4j-login.png │ ├── neo4j_error_1.png │ ├── neo4j_error_2.png │ ├── neo4j_paths.png │ ├── node-label-display-cycle.gif │ ├── node-search.gif │ ├── pathfinding.gif │ ├── pathfinding.png │ ├── raw-query.gif │ ├── right-click-edge-help.gif │ ├── right-click-group-node.png │ ├── run-raw-query.gif │ ├── search-for-domain-users.png │ ├── search-for-domains.png │ ├── search-for-user-with-admin-in-name.png │ ├── spotlight-click-node.gif │ └── spotlight.png ├── index.rst ├── installation │ ├── linux.rst │ ├── osx.rst │ └── windows.rst └── make.bat ├── index.html ├── main.js ├── package-lock.json ├── package.json ├── renderer.js ├── server.js ├── src ├── AppContainer.jsx ├── AppContext.jsx ├── components │ ├── Float │ │ ├── ExportContainer.jsx │ │ ├── ExportContainer.module.css │ │ ├── FileUploadDisplay.jsx │ │ ├── FileUploadDisplay.module.css │ │ ├── LoadingContainer.jsx │ │ ├── Login.jsx │ │ ├── NodeEditor.jsx │ │ ├── NodeEditor.module.css │ │ ├── NodeEditorRow.jsx │ │ ├── NodeEditorRow.module.css │ │ ├── PostProcessDisplay.jsx │ │ ├── QueryCustomCreate.jsx │ │ ├── QueryCustomCreate.module.css │ │ ├── QueryNodeSelect.jsx │ │ ├── QueryNodeSelectItem.jsx │ │ ├── Settings.jsx │ │ ├── Settings.module.css │ │ ├── UploadStatusContainer.jsx │ │ └── UploadStatusContainer.module.css │ ├── GlyphiconSpan.jsx │ ├── Graph.jsx │ ├── Icon.jsx │ ├── Menu │ │ ├── MenuButton.jsx │ │ └── MenuContainer.jsx │ ├── Modals │ │ ├── About.jsx │ │ ├── About.module.css │ │ ├── AddEdgeModal.jsx │ │ ├── AddEdgeModal.module.css │ │ ├── AddNodeModal.jsx │ │ ├── AddNodeModal.module.css │ │ ├── BaseModal.jsx │ │ ├── CancelUploadModal.jsx │ │ ├── ClearConfirmModal.jsx │ │ ├── ClearWarnModal.jsx │ │ ├── ClearingModal.jsx │ │ ├── ConfirmDrawModal.jsx │ │ ├── DeleteEdgeModal.jsx │ │ ├── DeleteNodeModal.jsx │ │ ├── GraphErrorModal.jsx │ │ ├── GraphErrorModal.module.css │ │ ├── HelpModal.jsx │ │ ├── HelpTexts │ │ │ ├── AZAKSContributor │ │ │ │ ├── AZAKSContributor.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZAddMembers │ │ │ │ ├── AZAddMembers.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZAddOwner │ │ │ │ ├── AZAddOwner.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZAddSecret │ │ │ │ ├── AZAddSecret.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZAppAdmin │ │ │ │ ├── AZAppAdmin.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZAutomationContributor │ │ │ │ ├── AZAutomationContributor.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZAvereContributor │ │ │ │ ├── AZAvereContributor.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZCloudAppAdmin │ │ │ │ ├── AZCloudAppAdmin.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZContains │ │ │ │ ├── AZContains.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZContributor │ │ │ │ ├── AZContributor.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZExecuteCommand │ │ │ │ ├── AZExecuteCommand.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZGetCertificates │ │ │ │ ├── AZGetCertificates.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZGetKeys │ │ │ │ ├── AZGetKeys.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZGetSecrets │ │ │ │ ├── AZGetSecrets.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZGlobalAdmin │ │ │ │ ├── AZGlobalAdmin.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZHasRole │ │ │ │ ├── AZHasRole.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZKeyVaultKVContributor │ │ │ │ ├── AZKeyVaultKVContributor.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZLogicAppContributor │ │ │ │ ├── AZLogicAppContributor.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGAddMember │ │ │ │ ├── AZMGAddMember.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGAddOwner │ │ │ │ ├── AZMGAddOwner.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGAddSecret │ │ │ │ ├── AZMGAddSecret.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGAppRoleAssignment_ReadWrite_All │ │ │ │ ├── AZMGAppRoleAssignment_ReadWrite_All.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGApplication_ReadWrite_All │ │ │ │ ├── AZMGApplication_ReadWrite_All.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGDirectory_ReadWrite_All │ │ │ │ ├── AZMGDirectory_ReadWrite_All.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGGrantAppRoles │ │ │ │ ├── AZMGGrantAppRoles.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGGrantRole │ │ │ │ ├── AZMGGrantRole.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGGroupMember_ReadWrite_All │ │ │ │ ├── AZMGGroupMember_ReadWrite_All.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGGroup_ReadWrite_All │ │ │ │ ├── AZMGGroup_ReadWrite_All.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGRoleManagement_ReadWrite_Directory │ │ │ │ ├── AZMGRoleManagement_ReadWrite_Directory.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMGServicePrincipalEndpoint_ReadWrite_All │ │ │ │ ├── AZMGServicePrincipalEndpoint_ReadWrite_All.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZManagedIdentity │ │ │ │ ├── AZManagedIdentity.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZMemberOf │ │ │ │ ├── AZMemberOf.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZNodeResourceGroup │ │ │ │ ├── AZNodeResourceGroup.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZOwns │ │ │ │ ├── AZOwns.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZPrivilegedAuthAdmin │ │ │ │ ├── AZPrivilegedAuthAdmin.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZPrivilegedRoleAdmin │ │ │ │ ├── AZPrivilegedRoleAdmin.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZResetPassword │ │ │ │ ├── AZResetPassword.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZRunsAs │ │ │ │ ├── AZRunsAs.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZUserAccessAdministrator │ │ │ │ ├── AZUserAccessAdministrator.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZVMAdminLogin │ │ │ │ ├── AZVMAdminLogin.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZVMContributor │ │ │ │ ├── AZVMContributor.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AZWebsiteContributor │ │ │ │ ├── AZWebsiteContributor.jsx │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AddAllowedToAct │ │ │ │ ├── AddAllowedToAct.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── AddKeyCredentialLink │ │ │ │ ├── AddKeyCredentialLink.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── AddMember │ │ │ │ ├── AddMember.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── AddSelf │ │ │ │ ├── AddSelf.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── AdminTo │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── AdminTo.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── AllExtendedRights │ │ │ │ ├── AllExtendedRights.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── AllowedToAct │ │ │ │ ├── AllowedToAct.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── AllowedToDelegate │ │ │ │ ├── AllowedToDelegate.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── CanPSRemote │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── CanPSRemote.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── CanRDP │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── CanRDP.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── Contains │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── Contains.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── DCSync │ │ │ │ ├── DCSync.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── Default │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── Default.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── DumpSMSAPassword │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── DumpSMSAPassword.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── ExecuteDCOM │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── ExecuteDCOM.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── ForceChangePassword │ │ │ │ ├── ForceChangePassword.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── Formatter.jsx │ │ │ ├── GenericAll │ │ │ │ ├── General.jsx │ │ │ │ ├── GenericAll.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── GenericWrite │ │ │ │ ├── General.jsx │ │ │ │ ├── GenericWrite.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── GetChanges │ │ │ │ ├── General.jsx │ │ │ │ ├── GetChanges.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── GetChangesAll │ │ │ │ ├── General.jsx │ │ │ │ ├── GetChangesAll.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── GpLink │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── GpLink.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── HasSIDHistory │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── HasSIDHistory.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── HasSession │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── HasSession.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── MemberOf │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── MemberOf.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ └── References.jsx │ │ │ ├── Owns │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── Owns.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── ReadGMSAPassword │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── ReadGMSAPassword.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── ReadLAPSPassword │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── ReadLAPSPassword.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── WindowsAbuse.jsx │ │ │ ├── SQLAdmin │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── SQLAdmin.jsx │ │ │ ├── SyncLAPSPassword │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── SyncLAPSPassword.jsx │ │ │ ├── TrustedBy │ │ │ │ ├── Abuse.jsx │ │ │ │ ├── General.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ └── TrustedBy.jsx │ │ │ ├── WriteAccountRestrictions │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ ├── WindowsAbuse.jsx │ │ │ │ └── WriteAccountRestrictions.jsx │ │ │ ├── WriteDacl │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ ├── WindowsAbuse.jsx │ │ │ │ └── WriteDacl.jsx │ │ │ ├── WriteOwner │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ ├── WindowsAbuse.jsx │ │ │ │ └── WriteOwner.jsx │ │ │ └── WriteSPN │ │ │ │ ├── General.jsx │ │ │ │ ├── LinuxAbuse.jsx │ │ │ │ ├── Opsec.jsx │ │ │ │ ├── References.jsx │ │ │ │ ├── WindowsAbuse.jsx │ │ │ │ └── WriteSPN.jsx │ │ ├── LogoutModal.jsx │ │ ├── SessionClearModal.jsx │ │ └── WarmupModal.jsx │ ├── PoseContainer.jsx │ ├── RawQuery.jsx │ ├── RawQuery.module.css │ ├── SearchContainer │ │ ├── EdgeFilter │ │ │ ├── EdgeFilter.jsx │ │ │ ├── EdgeFilter.module.css │ │ │ ├── EdgeFilterCheck.jsx │ │ │ └── EdgeFilterSection.jsx │ │ ├── SearchContainer.jsx │ │ ├── SearchContainer.module.css │ │ ├── SearchRow.jsx │ │ ├── SearchRow.module.css │ │ ├── TabContainer.jsx │ │ ├── TabContainer.module.css │ │ └── Tabs │ │ │ ├── AZApp.jsx │ │ │ ├── AZAutomationAccountNodeData.jsx │ │ │ ├── AZContainerRegistryNodeData.jsx │ │ │ ├── AZDeviceNodeData.jsx │ │ │ ├── AZFunctionAppNodeData.jsx │ │ │ ├── AZGroupNodeData.jsx │ │ │ ├── AZKeyVaultNodeData.jsx │ │ │ ├── AZLogicAppNodeData.jsx │ │ │ ├── AZManagedClusterNodeData.jsx │ │ │ ├── AZManagementGroupNodeData.jsx │ │ │ ├── AZResourceGroupNodeData.jsx │ │ │ ├── AZRoleNodeData.jsx │ │ │ ├── AZServicePrincipal.jsx │ │ │ ├── AZSubscriptionNodeData.jsx │ │ │ ├── AZTenantNodeData.jsx │ │ │ ├── AZUserNodeData.jsx │ │ │ ├── AZVMNodeData.jsx │ │ │ ├── AZVMScaleSetNodeData.jsx │ │ │ ├── AZWebAppNodeData.jsx │ │ │ ├── BaseNodeData.jsx │ │ │ ├── Components │ │ │ ├── CollapsibleSection.jsx │ │ │ ├── CollapsibleSection.module.css │ │ │ ├── CollapsibleSectionNew.jsx │ │ │ ├── DatabaseDataLabel.jsx │ │ │ ├── ExtraNodeProps.jsx │ │ │ ├── ExtraNodeProps.module.css │ │ │ ├── MappedNodeProps.jsx │ │ │ ├── MappedNodeProps.module.css │ │ │ ├── NodeALink.jsx │ │ │ ├── NodeCypherLabel.jsx │ │ │ ├── NodeCypherLink.jsx │ │ │ ├── NodeCypherLink.module.css │ │ │ ├── NodeCypherLinkComplex.jsx │ │ │ ├── NodeCypherNoNumberLink.jsx │ │ │ ├── NodeDisplayLink.jsx │ │ │ ├── NodeGallery.jsx │ │ │ ├── NodePlayCypherLink.jsx │ │ │ ├── NodePlayCypherLink.module.css │ │ │ ├── NoteGallery.module.css │ │ │ ├── Notes.jsx │ │ │ └── SelectedImage.jsx │ │ │ ├── ComputerNodeData.jsx │ │ │ ├── ContainerNodeData.jsx │ │ │ ├── DatabaseDataDisplay.jsx │ │ │ ├── DatabaseDataDisplay.module.css │ │ │ ├── DomainNodeData.jsx │ │ │ ├── GPONodeData.jsx │ │ │ ├── GroupNodeData.jsx │ │ │ ├── NoNodeData.jsx │ │ │ ├── NodeData.module.css │ │ │ ├── OUNodeData.jsx │ │ │ ├── PrebuiltQueries.json │ │ │ ├── PrebuiltQueries.module.css │ │ │ ├── PrebuiltQueriesDisplay.jsx │ │ │ ├── PrebuiltQueryNode.jsx │ │ │ └── UserNodeData.jsx │ ├── Spotlight │ │ ├── SpotlightContainer.jsx │ │ ├── SpotlightContainer.module.css │ │ └── SpotlightRow.jsx │ ├── Tooltips │ │ ├── EdgeTooltip.jsx │ │ ├── NodeTooltip.jsx │ │ ├── StageTooltip.jsx │ │ └── Tooltips.module.css │ └── Zoom │ │ └── ZoomContainer.jsx ├── css │ └── styles.css ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ ├── glyphicons-halflings-regular.woff2 │ ├── roboto-v15-latin-regular.eot │ ├── roboto-v15-latin-regular.svg │ ├── roboto-v15-latin-regular.ttf │ ├── roboto-v15-latin-regular.woff │ └── roboto-v15-latin-regular.woff2 ├── img │ ├── favicon.ico │ ├── icon.icns │ ├── icon.ico │ ├── icon.png │ ├── icon@2x.png │ ├── loading.gif │ ├── loading_new.gif │ ├── logo-white-on-transparent.png │ ├── logo-white-transparent-full.png │ └── logo-white-transparent.png ├── index.js └── js │ ├── ingestion_types.js │ ├── jquery-ui.min.js │ ├── newingestion.js │ ├── oldingestion.js │ ├── sigma.helpers.graph.min.js │ ├── utils.js │ └── worker.js ├── webpack.config.development.js └── webpack.config.production.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | insert_final_newline = true 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | indent_style = space 8 | indent_size = 4 9 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "node":true, 5 | "es2021": true 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:react/recommended", 10 | "prettier", 11 | "plugin:react-hooks/recommended" 12 | ], 13 | "parserOptions": { 14 | "ecmaFeatures": { 15 | "jsx": true 16 | }, 17 | "ecmaVersion": "latest", 18 | "sourceType": "module" 19 | }, 20 | "plugins": [ 21 | "react" 22 | ], 23 | "rules": { 24 | }, 25 | "globals": { 26 | "emitter": "writable", 27 | "appStore": "writable", 28 | "closeTooltip": "readonly", 29 | "$": "readonly", 30 | "sigma": "readonly", 31 | "driver": "readonly", 32 | "conf": "readonly", 33 | "jQuery": "readonly" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | If this is a SharpHound bug, please file the bug in the SharpHound repo [here](https://github.com/BloodHoundAD/SharpHound) 11 | 12 | **Describe the bug** 13 | A clear and concise description of what the bug is. 14 | 15 | **To Reproduce** 16 | Steps to reproduce the behavior: 17 | 1. Go to '...' 18 | 2. Click on '....' 19 | 3. Scroll down to '....' 20 | 4. See error 21 | 22 | **Expected behavior** 23 | A clear and concise description of what you expected to happen. 24 | 25 | **Screenshots** 26 | If applicable, add screenshots to help explain your problem. 27 | 28 | **Additional context** 29 | Add any other context about the problem here. If this bug is in the UI, open the console using Ctrl + Shift + I and see if there's any errors to attach here. 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/cla.yml: -------------------------------------------------------------------------------- 1 | name: "CLA Assistant" 2 | on: 3 | issue_comment: 4 | types: [created] 5 | pull_request_target: 6 | types: [opened,closed,synchronize] 7 | 8 | jobs: 9 | CLAssistant: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: "CLA Assistant" 13 | if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target' 14 | uses: contributor-assistant/github-action@v2.2.1 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | PERSONAL_ACCESS_TOKEN : ${{ secrets.REPO_SCOPE }} 18 | with: 19 | path-to-signatures: 'signatures.json' 20 | path-to-document: 'https://github.com/BloodHoundAD/CLA/blob/main/ICLA.md' 21 | branch: 'main' 22 | remote-organization-name: BloodHoundAD 23 | remote-repository-name: CLA 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | Bloodhound-* 3 | dist/ 4 | npm-debug.log 5 | *.bin 6 | *.csv 7 | graph.json 8 | .DS_Store 9 | .idea -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "trailingComma": "es5", 4 | "semi": true, 5 | "singleQuote": true, 6 | "jsxSingleQuote": true, 7 | "jsxBracketSameLine": true, 8 | "printWidth": 120 9 | } -------------------------------------------------------------------------------- /Collectors/AzureHound.md: -------------------------------------------------------------------------------- 1 | # [AzureHound Releases](https://github.com/BloodHoundAD/AzureHound/releases) 2 | 3 | To get AzureHound, download the appropriate release for your platform [here](https://github.com/BloodHoundAD/AzureHound/releases) or at the link above. -------------------------------------------------------------------------------- /Collectors/DebugBuilds/README.md: -------------------------------------------------------------------------------- 1 | # SharpHound Debug Builds 2 | To use this build, place the exe and the .pdb file in the same folder and then run the command that led to an exception/error 3 | 4 | ## Useful Flags 5 | * Set threads to 1 (-t 1) 6 | * Set verbosity to most verbose (-v 0) -------------------------------------------------------------------------------- /Collectors/DebugBuilds/SharpHound.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/Collectors/DebugBuilds/SharpHound.exe -------------------------------------------------------------------------------- /Collectors/DebugBuilds/SharpHound.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/Collectors/DebugBuilds/SharpHound.pdb -------------------------------------------------------------------------------- /Collectors/SharpHound.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/Collectors/SharpHound.exe -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # BHDocs 2 | -------------------------------------------------------------------------------- /docs/_build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/_build/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/_build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/_build/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/_build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: cbae78c425a9f14f87ffb59480c5c0d6 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. BloodHound documentation master file, created by 2 | sphinx-quickstart on Wed Apr 8 19:24:42 2020. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to BloodHound's documentation! 7 | ====================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | -------------------------------------------------------------------------------- /docs/_build/html/_static/custom.css: -------------------------------------------------------------------------------- 1 | /* This file intentionally left blank. */ 2 | -------------------------------------------------------------------------------- /docs/_build/html/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '3.0.3', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | BUILDER: 'html', 7 | FILE_SUFFIX: '.html', 8 | LINK_SUFFIX: '.html', 9 | HAS_SOURCE: true, 10 | SOURCELINK_SUFFIX: '.txt', 11 | NAVIGATION_WITH_KEYS: false 12 | }; -------------------------------------------------------------------------------- /docs/_build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/_build/html/_static/file.png -------------------------------------------------------------------------------- /docs/_build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/_build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/_build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/_build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/_build/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/_build/html/objects.inv -------------------------------------------------------------------------------- /docs/_build/html/searchindex.js: -------------------------------------------------------------------------------- 1 | Search.setIndex({docnames:["index"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":2,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,sphinx:56},filenames:["index.rst"],objects:{},objnames:{},objtypes:{},terms:{index:0,modul:0,page:0,search:0},titles:["Welcome to BloodHound\u2019s documentation!"],titleterms:{bloodhound:0,document:0,indic:0,tabl:0,welcom:0}}) -------------------------------------------------------------------------------- /docs/_static/css/custom.css: -------------------------------------------------------------------------------- 1 | /* Custom style for 'deprecated' admonitions */ 2 | div.admonition.deprecated { 3 | border-left: 4px solid #e03e2d; /* Strong red border */ 4 | background-color: #ffeaea; /* Light red background */ 5 | } 6 | 7 | /* Title bar styling */ 8 | div.admonition.deprecated .admonition-title { 9 | background-color: #e03e2d; 10 | color: white; 11 | } 12 | -------------------------------------------------------------------------------- /docs/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {% extends "!layout.html" %} 2 | 3 | {% block extrahead %} 4 | {{ super() }} 5 | {% if meta is defined and meta.canonical %} 6 | 7 | {% endif %} 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /docs/data-collection/bloodhound-py.rst: -------------------------------------------------------------------------------- 1 | .. admonition:: Deprecated Documentation 2 | :class: deprecated 3 | 4 | **This documentation refers to deprecated BloodHound Legacy (version 4.3, released in 2023).** 5 | 6 | Please use the `current BloodHound CE Documentation `_. 7 | 8 | .. meta:: 9 | :canonical: https://bloodhound.specterops.io/get-started/introduction 10 | 11 | 12 | BloodHound.py 13 | ============= 14 | 15 | BloodHound.py, written by `Dirk-jan Mollema`_, allows you to collect 16 | data for BloodHound from a Linux system, OSX system, or Windows 17 | system that has Python installed on it. 18 | 19 | .. _Dirk-jan Mollema: https://twitter.com/_dirkjan 20 | 21 | You can get BloodHound.py at https://github.com/dirkjanm/BloodHound.py 22 | 23 | .. note:: BloodHound.py is built and maintained by Dirk-Jan, it is not 24 | officially supported by the BloodHound development team 25 | -------------------------------------------------------------------------------- /docs/html/_static/css/custom.css: -------------------------------------------------------------------------------- 1 | /* Custom style for 'deprecated' admonitions */ 2 | div.admonition.deprecated { 3 | border-left: 4px solid #e03e2d; /* Strong red border */ 4 | background-color: #ffeaea; /* Light red background */ 5 | } 6 | 7 | /* Title bar styling */ 8 | div.admonition.deprecated .admonition-title { 9 | background-color: #e03e2d; 10 | color: white; 11 | } 12 | -------------------------------------------------------------------------------- /docs/images/SharpHoundCheatSheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/SharpHoundCheatSheet.png -------------------------------------------------------------------------------- /docs/images/bloodhound-initial-query.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/bloodhound-initial-query.png -------------------------------------------------------------------------------- /docs/images/bloodhound-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/bloodhound-logo.png -------------------------------------------------------------------------------- /docs/images/bloodhound-logon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/bloodhound-logon.png -------------------------------------------------------------------------------- /docs/images/davidmcguire-edges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/davidmcguire-edges.png -------------------------------------------------------------------------------- /docs/images/domain-users-to-domain-admins-filtered.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/domain-users-to-domain-admins-filtered.png -------------------------------------------------------------------------------- /docs/images/domain-users-to-domain-admins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/domain-users-to-domain-admins.png -------------------------------------------------------------------------------- /docs/images/edge-filtering.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/edge-filtering.gif -------------------------------------------------------------------------------- /docs/images/edge-filtering.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/edge-filtering.png -------------------------------------------------------------------------------- /docs/images/import-data.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/import-data.gif -------------------------------------------------------------------------------- /docs/images/java_home_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/java_home_check.png -------------------------------------------------------------------------------- /docs/images/java_home_variable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/java_home_variable.png -------------------------------------------------------------------------------- /docs/images/log-out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/log-out.png -------------------------------------------------------------------------------- /docs/images/neo4j-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/neo4j-login.png -------------------------------------------------------------------------------- /docs/images/neo4j_error_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/neo4j_error_1.png -------------------------------------------------------------------------------- /docs/images/neo4j_error_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/neo4j_error_2.png -------------------------------------------------------------------------------- /docs/images/neo4j_paths.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/neo4j_paths.png -------------------------------------------------------------------------------- /docs/images/node-label-display-cycle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/node-label-display-cycle.gif -------------------------------------------------------------------------------- /docs/images/node-search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/node-search.gif -------------------------------------------------------------------------------- /docs/images/pathfinding.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/pathfinding.gif -------------------------------------------------------------------------------- /docs/images/pathfinding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/pathfinding.png -------------------------------------------------------------------------------- /docs/images/raw-query.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/raw-query.gif -------------------------------------------------------------------------------- /docs/images/right-click-edge-help.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/right-click-edge-help.gif -------------------------------------------------------------------------------- /docs/images/right-click-group-node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/right-click-group-node.png -------------------------------------------------------------------------------- /docs/images/run-raw-query.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/run-raw-query.gif -------------------------------------------------------------------------------- /docs/images/search-for-domain-users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/search-for-domain-users.png -------------------------------------------------------------------------------- /docs/images/search-for-domains.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/search-for-domains.png -------------------------------------------------------------------------------- /docs/images/search-for-user-with-admin-in-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/search-for-user-with-admin-in-name.png -------------------------------------------------------------------------------- /docs/images/spotlight-click-node.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/spotlight-click-node.gif -------------------------------------------------------------------------------- /docs/images/spotlight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/docs/images/spotlight.png -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /renderer.js: -------------------------------------------------------------------------------- 1 | // This file is required by the index.html file and will 2 | // be executed in the renderer process for that window. 3 | // All of the Node.js APIs are available in this process. 4 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import webpack from 'webpack'; 3 | import webpackDevMiddleware from 'webpack-dev-middleware'; 4 | import webpackHotMiddleware from 'webpack-hot-middleware'; 5 | 6 | import config from './webpack.config.development'; 7 | 8 | const compiler = webpack(config); 9 | const app = express(); 10 | 11 | app.use(webpackDevMiddleware(compiler, { 12 | publicPath: config.output.publicPath, 13 | stats: { 14 | colors: true 15 | } 16 | })); 17 | 18 | app.use(webpackHotMiddleware(compiler)); 19 | 20 | app.listen(9000); -------------------------------------------------------------------------------- /src/AppContext.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export const AppContext = React.createContext({ 4 | darkMode: false, 5 | toggleDarkMode: () => {}, 6 | debugMode: false, 7 | toggleDebugMode: () => {}, 8 | lowDetailMode: false, 9 | toggleLowDetailMode: () => {}, 10 | edgeLabels: 0, 11 | setEdgeLabels: () => {}, 12 | nodeLabels: 0, 13 | setNodeLabels: () => {}, 14 | edgeIncluded: {}, 15 | setEdgeIncluded: () => {}, 16 | }); 17 | -------------------------------------------------------------------------------- /src/components/Float/FileUploadDisplay.module.css: -------------------------------------------------------------------------------- 1 | .panel { 2 | height: 100px; 3 | width: 100%; 4 | margin-top: 10px; 5 | margin-left: auto; 6 | margin-right: auto; 7 | } 8 | 9 | .panel > div:first-child { 10 | width: 100%; 11 | } 12 | 13 | .fileName { 14 | font-family: Helvetica; 15 | font-size: 18px; 16 | 17 | font-weight: bold; 18 | } 19 | 20 | .invisible { 21 | visibility: hidden; 22 | } 23 | 24 | .status { 25 | font-family: Helvetica; 26 | font-size: 15px; 27 | line-height: 32px; 28 | } 29 | 30 | .progressBar { 31 | color: #406f8e; 32 | height: 5px; 33 | } 34 | 35 | .light .fileName { 36 | color: #1d2735; 37 | } 38 | 39 | .dark .fileName { 40 | color: white; 41 | } 42 | 43 | .light .status { 44 | color: #406f8e; 45 | } 46 | 47 | .dark .status { 48 | color: #67a3cb; 49 | } 50 | -------------------------------------------------------------------------------- /src/components/Float/NodeEditor.module.css: -------------------------------------------------------------------------------- 1 | .error { 2 | border: 3px solid red; 3 | } 4 | 5 | .container :global { 6 | position: absolute; 7 | z-index: 20; 8 | top: 1em; 9 | right: 10em; 10 | overflow: auto; 11 | background-color: rgba(255, 255, 255, 0.9); 12 | box-shadow: 0 12px 15px 0 rgba(0, 0, 0, 0.2); 13 | } 14 | 15 | .container :global .panel { 16 | margin-bottom: 0; 17 | } 18 | 19 | .container :global .panel-heading { 20 | cursor: move; 21 | } 22 | 23 | .dark :global .panel-heading { 24 | background: black; 25 | color: white; 26 | } 27 | 28 | .dark :global .panel-body { 29 | background: black; 30 | color: white; 31 | } 32 | 33 | .dark :global button { 34 | background: black; 35 | color: white; 36 | } 37 | 38 | .dark :global textarea { 39 | color: black; 40 | } 41 | 42 | .dark :global button.close { 43 | opacity: 1; 44 | background-color: black; 45 | color: white; 46 | } 47 | -------------------------------------------------------------------------------- /src/components/Float/NodeEditorRow.module.css: -------------------------------------------------------------------------------- 1 | 2 | .nodeEditRow *[contenteditable='true'] { 3 | background-color: white; 4 | border: 1px solid lightgray; 5 | color:black 6 | } 7 | 8 | .nodeEditRow > td { 9 | padding: 5px !important; 10 | } 11 | 12 | .nodeEditString { 13 | resize: none; 14 | max-width: 400px; 15 | } 16 | 17 | .nodeEditNumber { 18 | resize: none; 19 | } 20 | 21 | .nodeEditArray { 22 | resize: none; 23 | max-height: 200px; 24 | width: 100%; 25 | height: 100%; 26 | max-width: 400px; 27 | overflow-y: scroll; 28 | white-space: pre-line; 29 | } 30 | -------------------------------------------------------------------------------- /src/components/Icon.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | export default class Icon extends Component { 5 | constructor(props) { 6 | super(props); 7 | } 8 | 9 | render() { 10 | return ( 11 | 20 | ); 21 | } 22 | } 23 | 24 | Icon.propTypes = { 25 | glyph: PropTypes.string.isRequired, 26 | extraClass: PropTypes.string, 27 | onClick: PropTypes.func, 28 | }; 29 | -------------------------------------------------------------------------------- /src/components/Modals/About.module.css: -------------------------------------------------------------------------------- 1 | .scroll { 2 | width: 100%; 3 | overflow: auto; 4 | height: 150px; 5 | white-space: pre-wrap; 6 | } 7 | 8 | .about { 9 | border-top-left-radius: 20px; 10 | border-top-right-radius: 20px; 11 | border-bottom: none; 12 | font-family: Helvetica, serif; 13 | } 14 | 15 | .btndone { 16 | border-radius: 25px; 17 | border: none; 18 | padding: 8px; 19 | font-family: Helvetica, serif; 20 | font-size: 15px; 21 | font-weight: 400; 22 | text-shadow: none; 23 | width: 150px; 24 | } 25 | 26 | .btndone :hover { 27 | color: white !important; 28 | } 29 | 30 | .footer { 31 | border-top: none; 32 | } 33 | 34 | .light { 35 | background-color: #e7e7e7; 36 | } 37 | 38 | .dark { 39 | background-color: #444b55; 40 | } 41 | 42 | .dark .btndone { 43 | background-color: #406f8e !important; 44 | border-color: #406f8e; 45 | color: white !important; 46 | } 47 | 48 | .light :global .modal-header { 49 | background-color: #e7e7e7; 50 | } 51 | -------------------------------------------------------------------------------- /src/components/Modals/AddEdgeModal.module.css: -------------------------------------------------------------------------------- 1 | .checkbox { 2 | position: relative; 3 | font-size: 24px; 4 | margin-right: 5px; 5 | top: 5px; 6 | display: inline; 7 | } 8 | 9 | .error { 10 | color: red; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/Modals/AddNodeModal.module.css: -------------------------------------------------------------------------------- 1 | .checkbox { 2 | position: relative; 3 | font-size: 24px; 4 | margin-right: 5px; 5 | top: 5px; 6 | display: inline; 7 | } 8 | 9 | .error { 10 | color: red; 11 | } 12 | -------------------------------------------------------------------------------- /src/components/Modals/BaseModal.jsx: -------------------------------------------------------------------------------- 1 | import React, {useContext} from 'react'; 2 | import {Modal} from 'react-bootstrap'; 3 | import clsx from 'clsx'; 4 | import {AppContext} from '../../AppContext'; 5 | 6 | const BaseModal = ({ show, onHide, label, className, children }) => { 7 | let context = useContext(AppContext); 8 | return ( 9 | 16 | {children} 17 | 18 | ); 19 | }; 20 | 21 | BaseModal.propTypes = {}; 22 | export default BaseModal; 23 | -------------------------------------------------------------------------------- /src/components/Modals/GraphErrorModal.module.css: -------------------------------------------------------------------------------- 1 | .error { 2 | white-space: pre; 3 | font-family: 'Roboto Mono', monospace; 4 | padding-left: 5px; 5 | } 6 | 7 | .width :global .modal-dialog { 8 | width: 75%; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAKSContributor/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The Azure Kubernetes Service Contributor role grants full control 7 | of the target Azure Kubernetes Service Managed Cluster. This includes 8 | the ability to remotely fetch administrator credentials for the cluster 9 | as well as the ability to execute arbitrary commands on compute 10 | nodes associated with the AKS Managed Cluster. 11 |

12 | ); 13 | }; 14 | 15 | export default General; 16 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAKSContributor/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This will depend on which particular abuse you perform, but in 7 | general Azure will create a log event for each abuse. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAKSContributor/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | Andy Robbins - BARK.ps1 8 | 9 |
10 | 11 | Karl Fosaaen - How To Extract Credentials from Azure Kubernetes Service (AKS) 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAddMembers/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

Via the Azure portal:

7 |
    8 |
  1. 9 | Find the group in your tenant (Azure Active Directory -> 10 | Groups -> Find Group in list) 11 |
  2. 12 |
  3. Click the group from the list
  4. 13 |
  5. In the left pane, click "Members"
  6. 14 |
  7. At the top, click "Add members"
  8. 15 |
  9. 16 | Find the principals you want to add to the group and click 17 | them, then click "select" at the bottom 18 |
  10. 19 |
  11. 20 | You should see a message in the top right saying "Member 21 | successfully added" 22 |
  12. 23 |
24 |

25 | Via PowerZure: Add-AzureADGroup -User [UPN] -Group [Group name] 26 |

27 | 28 | ); 29 | }; 30 | 31 | export default Abuse; 32 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAddMembers/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

The ability to add other principals to an Azure security group

6 | ); 7 | }; 8 | 9 | export default General; 10 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAddMembers/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | The Azure activity log for the tenant will log who added what 7 | principal to what group, including the date and time. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAddMembers/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://powerzure.readthedocs.io/en/latest/Functions/operational.html#add-azureadgroup 8 | 9 |
10 | 11 | https://docs.microsoft.com/en-us/powershell/module/azuread/add-azureadgroupmember?view=azureadps-2.0-preview 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAddOwner/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created during post-processing. It is created against 8 | all App Registrations and Service Principals within the same tenant 9 | when an Azure principal has one of the following Azure Active 10 | Directory roles: 11 |

12 | 13 |

14 |

20 |

21 | 22 |

23 | You will not see these privileges when auditing permissions against 24 | any of the mentioned objects when you use Microsoft tooling, including 25 | the Azure portal or any API. 26 |

27 | 28 | ); 29 | }; 30 | 31 | export default General; 32 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAddOwner/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | Any time you add an owner to any Azure object, the AzureAD audit 8 | logs will create an event logging who added an owner to what object, 9 | as well as what the new owner added to the object was. 10 |

11 | 12 | ); 13 | }; 14 | 15 | export default Opsec; 16 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAddOwner/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 |
15 | 16 | Andy Robbins - BARK.ps1 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default References; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAddSecret/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | Azure provides several systems and mechanisms for granting 8 | control of securable objects within Azure Active Directory, 9 | including tenant-scoped admin roles, object-scoped admin roles, 10 | explicit object ownership, and API permissions. 11 |

12 |

13 | When a principal has been granted "Cloud App Admin" or "App 14 | Admin" against the tenant, that principal gains the ability to 15 | add new secrets to all Service Principals and App Registrations. 16 | Additionally, a principal that has been granted "Cloud App 17 | Admin" or "App Admin" against, or explicit ownership of a 18 | Service Principal or App Registration gains the ability to add 19 | secrets to that particular object. 20 |

21 | 22 | ); 23 | }; 24 | 25 | export default General; 26 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAddSecret/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | When you create a new secret for an App or Service Principal, 8 | Azure creates an event called “Update application – Certificates 9 | and secrets management”. This event describes who added the secret 10 | to which application or service principal. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAddSecret/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 |
15 | 16 | Assign Azure AD roles at different scopes 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default References; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAppAdmin/AZAppAdmin.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Tabs, Tab } from 'react-bootstrap'; 4 | import General from './General'; 5 | import Abuse from './Abuse'; 6 | import Opsec from './Opsec'; 7 | import References from './References'; 8 | 9 | const AZAppAdmin = ({ sourceName, sourceType, targetName, targetType }) => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | AZAppAdmin.propTypes = { 29 | sourceName: PropTypes.string, 30 | sourceType: PropTypes.string, 31 | targetName: PropTypes.string, 32 | targetType: PropTypes.string, 33 | }; 34 | export default AZAppAdmin; 35 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAppAdmin/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 |

6 | Create a new credential for the app, then authenticate to the tenant 7 | as the app's service principal, then abuse whatever privilege it is 8 | that the service principal has. 9 |

10 | ); 11 | }; 12 | 13 | export default Abuse; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAppAdmin/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | rerturn( 5 |

6 | Principals with the Application Admin role can control 7 | tenant-resident apps. 8 |

9 | ); 10 | }; 11 | 12 | export default General; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAppAdmin/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | The Azure portal will create a log even whenever a new credential is 7 | created for a service principal. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAppAdmin/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | 6 | https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/ 7 | 8 | ); 9 | }; 10 | 11 | export default References; 12 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAutomationContributor/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The Azure Automation Contributor role grants full control 7 | of the target Azure Automation Account. This includes 8 | the ability to execute arbitrary commands on the Automation 9 | Account. 10 |

11 | ); 12 | }; 13 | 14 | export default General; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAutomationContributor/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This will depend on which particular abuse you perform, but in 7 | general Azure will create a log event for each abuse. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAutomationContributor/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | Andy Robbins - BARK.ps1 8 | 9 |
10 | 11 | Andy Robbins - Managed Identity Attack Paths, Part 1: Automation Accounts 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAvereContributor/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | The Avere Contributor role allows you to run SYSTEM 8 | commands on the VM 9 |

10 | 11 |

Via PowerZure:

12 | Invoke-AzureRunCommand 13 |
14 | Invoke-AzureRunMSBuild 15 |
16 | 17 | Invoke-AzureRunProgram 18 | 19 | 20 | ); 21 | }; 22 | 23 | export default Abuse; 24 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAvereContributor/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | Any principal granted the Avere Contributor role, scoped to the 7 | affected VM, can reset the built-in administrator password on the 8 | VM. 9 |

10 | ); 11 | }; 12 | 13 | export default General; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAvereContributor/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | Because you‘ll be running a command as the SYSTEM user on the 7 | Virtual Machine, the same opsec considerations for running malicious 8 | commands on any system should be taken into account: command line 9 | logging, PowerShell script block logging, EDR, etc. 10 |

11 | ); 12 | }; 13 | 14 | export default Opsec; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZAvereContributor/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T0008: Lateral Movement 8 | 9 |
10 | 11 | ATT&CK T1021: Remote Services 12 | 13 |
14 | 15 | Microsoft Docs - Avere Contributor 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default References; 22 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZCloudAppAdmin/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 |

6 | Create a new credential for the app, then authenticate to the tenant 7 | as the app's service principal, then abuse whatever privilege it is 8 | that the service principal has. 9 |

10 | ); 11 | }; 12 | 13 | export default Abuse; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZCloudAppAdmin/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | Principals with the Cloud App Admin role can control tenant-resident 7 | apps 8 |

9 | ); 10 | }; 11 | 12 | export default General; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZCloudAppAdmin/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | Auzre will create a log event whenever a new secret is created for a 7 | service principal. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZCloudAppAdmin/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 |

6 | 7 | https://dirkjanm.io/azure-ad-privilege-escalation-application-admin/ 8 | 9 |

10 | ); 11 | }; 12 | 13 | export default References; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZContains/AZContains.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Tabs, Tab } from 'react-bootstrap'; 4 | import General from './General'; 5 | import Abuse from './Abuse'; 6 | import Opsec from './Opsec'; 7 | import References from './References'; 8 | 9 | const AZContains = ({ sourceName, sourceType, targetName, targetType }) => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | {' '} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | AZContains.propTypes = { 29 | sourceName: PropTypes.string, 30 | sourceType: PropTypes.string, 31 | targetName: PropTypes.string, 32 | targetType: PropTypes.string, 33 | }; 34 | export default AZContains; 35 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZContains/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 |

6 | There is no abuse necessary, but any roles scoped on a parent object 7 | will descend down to all child objects. 8 |

9 | ); 10 | }; 11 | 12 | export default Abuse; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZContains/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | This indicates that the parent object contains the child object, 7 | such as a resource group containing a virtual machine, or a tenant 8 | "containing" a subscription. 9 |

10 | ); 11 | }; 12 | 13 | export default General; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZContains/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This depends on what you do, see other edges as far as opsec 7 | considerations for activating roles 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZContains/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return (<>) 5 | }; 6 | 7 | export default References; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZContributor/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The contributor role grants almost all abusable privileges in all 7 | circumstances, with some exceptions. Those exceptions are not 8 | collected by AzureHound. 9 |

10 | ); 11 | }; 12 | 13 | export default General; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZContributor/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This will depend on which particular abuse you perform, but in 7 | general Azure will create a log event for each abuse. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZContributor/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://blog.netspi.com/maintaining-azure-persistence-via-automation-accounts/{' '} 8 | 9 |
10 | 11 | https://blog.netspi.com/azure-automation-accounts-key-stores/ 12 | 13 |
14 | 15 | https://blog.netspi.com/get-azurepasswords/ 16 | 17 |
18 | 19 | https://blog.netspi.com/attacking-azure-cloud-shell/ 20 | 21 | 22 | ); 23 | }; 24 | 25 | export default References; 26 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZExecuteCommand/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | Principals with the Intune Administrators role are able to 7 | execute arbitrary PowerShell scripts on devices that are joined 8 | to the Azure Active Directory tenant. 9 |

10 | ); 11 | }; 12 | 13 | export default General; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZExecuteCommand/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | MITRE: Execution 8 | 9 |
10 | 11 | Death from Above: Lateral Movement from Azure to On-Prem AD 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetCertificates/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | Use PowerShell or PowerZure to fetch the certificate from the 8 | key vault 9 |

10 |

Via PowerZure

11 | 12 | Get-AzureKeyVaultContent 13 | 14 |
15 | 16 | Export-AzureKeyVaultcontent 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default Abuse; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetCertificates/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return

The ability to read certificates from key vaults

; 5 | }; 6 | 7 | export default General; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetCertificates/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | Azure will create a new log event for the key vault whenever a 7 | secret is accessed. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetCertificates/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://blog.netspi.com/azure-automation-accounts-key-stores/ 8 | 9 |
10 | 11 | https://powerzure.readthedocs.io/en/latest/Functions/operational.html#get-azurekeyvaultcontent 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetKeys/AZGetKeys.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Tabs, Tab } from 'react-bootstrap'; 4 | import General from './General'; 5 | import Abuse from './Abuse'; 6 | import Opsec from './Opsec'; 7 | import References from './References'; 8 | 9 | const AZGetKeys = ({ sourceName, sourceType, targetName, targetType }) => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | AZGetKeys.propTypes = { 29 | sourceName: PropTypes.string, 30 | sourceType: PropTypes.string, 31 | targetName: PropTypes.string, 32 | targetType: PropTypes.string, 33 | }; 34 | export default AZGetKeys; 35 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetKeys/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | Use PowerShell or PowerZure to fetch the key from the key vault 8 |

9 |

Via PowerZure

10 | 11 | Export-AzureKeyVaultContent 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default Abuse; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetKeys/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return

The ability to read keys from key vaults

; 5 | }; 6 | 7 | export default General; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetKeys/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | Azure will create a new log event for the key vault whenever a 7 | secret is accessed. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetKeys/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://blog.netspi.com/azure-automation-accounts-key-stores/ 8 | 9 |
10 | 11 | https://powerzure.readthedocs.io/en/latest/Functions/operational.html#export-azurekeyvaultcontent 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetSecrets/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | Use PowerShell or PowerZure to fetch the secret from the key 8 | vault 9 |

10 |

Via PowerZure

11 | 12 | Get-AzureKeyVaultContent 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default Abuse; 19 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetSecrets/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return

The ability to read secrets from key vaults

; 5 | }; 6 | 7 | export default General; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetSecrets/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | Azure will create a new log event for the key vault whenever a 7 | secret is accessed. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGetSecrets/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://blog.netspi.com/azure-automation-accounts-key-stores/ 8 | 9 |
10 | 11 | https://powerzure.readthedocs.io/en/latest/Functions/operational.html#get-azurekeyvaultcontent 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGlobalAdmin/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | This edge indicates the principal has the Global Admin role active 7 | against the target tenant. In other words, the principal is a Global 8 | Admin. Global Admins can do almost anything against almost every 9 | object type in the tenant, this is the highest privilege role in 10 | Azure. 11 |

12 | ); 13 | }; 14 | 15 | export default General; 16 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGlobalAdmin/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This depends on exactly what you do, but in general Azure will log 7 | each abuse action. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZGlobalAdmin/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | 6 | https://blog.netspi.com/attacking-azure-cloud-shell/ 7 | 8 | ); 9 | }; 10 | 11 | export default References; 12 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZHasRole/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | No abuse is necessary. This edge only indicates 8 | that the principal has been granted a particular 9 | AzureAD admin role. 10 |

11 | 12 | ); 13 | }; 14 | 15 | export default Abuse; 16 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZHasRole/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | This edge indicates that a principal has been granted a particular 7 | AzureAD admin role. 8 |

9 | ); 10 | }; 11 | 12 | export default General; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZHasRole/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | The opsec considerations for a particular action authorized by a 7 | principal“s active AzureAD role assignment will wholly depend 8 | on what the action taken is. This edge does not capture all abusable 9 | possibilities. 10 |

11 | ); 12 | }; 13 | 14 | export default Opsec; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZHasRole/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | Microsoft Graph Permission Reference 8 | 9 |
10 | 11 | Azure role-based access control 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZKeyVaultKVContributor/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | You can read secrets and alter access policies (grant yourself access to read secrets) 8 |

9 | 10 |

Via PowerZure:

11 | 12 | Get-AzureKeyVaultContent 13 | 14 |
15 | 16 | Export-AzureKeyVaultContent 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default Abuse; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZKeyVaultKVContributor/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The Key Vault Contributor role grants full control of the 7 | target Key Vault. This includes the ability to read all secrets 8 | stored on the Key Vault. 9 |

10 | ); 11 | }; 12 | 13 | export default General; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZKeyVaultKVContributor/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This will depend on which particular abuse you perform, but in 7 | general Azure will create a log event for each abuse. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZKeyVaultKVContributor/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://blog.netspi.com/maintaining-azure-persistence-via-automation-accounts/{' '} 8 | 9 |
10 | 11 | https://blog.netspi.com/azure-automation-accounts-key-stores/ 12 | 13 |
14 | 15 | https://blog.netspi.com/get-azurepasswords/ 16 | 17 |
18 | 19 | https://blog.netspi.com/attacking-azure-cloud-shell/ 20 | 21 | 22 | ); 23 | }; 24 | 25 | export default References; 26 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZLogicAppContributor/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | Currently you need access to the portal GUI to execute this abuse. 8 |

9 | 10 |

11 | The abuse involves adding or modifying an existing logic app to coerce 12 | the logic app into sending a JWT for its managed identity service principal 13 | to a web server you control. 14 |

15 | 16 |

17 | You can see a full walkthrough for executing that abuse in this blog post: 18 |

19 | 20 |

21 | 22 | Andy Robbins - Managed Identity Attack Paths, Part 2: Logic Apps 23 | 24 |

25 | 26 | 27 | ); 28 | }; 29 | 30 | export default Abuse; 31 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZLogicAppContributor/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The Logic Contributor role grants full control 7 | of the target Logic App. This includes the ability 8 | to execute arbitrary commands on the Logic App. 9 |

10 | ); 11 | }; 12 | 13 | export default General; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZLogicAppContributor/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This will depend on which particular abuse you perform, but in 7 | general Azure will create a log event for each abuse. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZLogicAppContributor/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | Andy Robbins - BARK.ps1 8 | 9 |
10 | 11 | Managed Identity Attack Paths, Part 2: Logic Apps 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGAddMember/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | The Azure activity log for the tenant will log who added what 8 | principal to what group, including the date and time. 9 |

10 | 11 | ); 12 | }; 13 | 14 | export default Opsec; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGAddMember/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 |
15 | 16 | Andy Robbins - BARK.ps1 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default References; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGAddOwner/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | Any time you add an owner to any Azure object, the AzureAD audit 8 | logs will create an event logging who added an owner to what object, 9 | as well as what the new owner added to the object was. 10 |

11 | 12 | ); 13 | }; 14 | 15 | export default Opsec; 16 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGAddOwner/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 |
15 | 16 | Andy Robbins - BARK.ps1 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default References; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGAddSecret/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | When you create a new secret for an App or Service Principal, 8 | Azure creates an event called “Update application – Certificates 9 | and secrets management”. This event describes who added the secret 10 | to which application or service principal. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGAddSecret/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 |
15 | 16 | Andy Robbins - BARK.ps1 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default References; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGAppRoleAssignment_ReadWrite_All/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the AppRoleAssignment.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Abuse; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGAppRoleAssignment_ReadWrite_All/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the AppRoleAssignment.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default General; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGAppRoleAssignment_ReadWrite_All/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the AppRoleAssignment.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGAppRoleAssignment_ReadWrite_All/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default References; 19 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGApplication_ReadWrite_All/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the Application.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Abuse; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGApplication_ReadWrite_All/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the Application.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default General; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGApplication_ReadWrite_All/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the Application.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGApplication_ReadWrite_All/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default References; 19 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGDirectory_ReadWrite_All/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the Directory.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Abuse; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGDirectory_ReadWrite_All/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the Directory.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default General; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGDirectory_ReadWrite_All/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the Directory.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGDirectory_ReadWrite_All/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default References; 19 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGrantAppRoles/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created during post-processing. It is created against 8 | AzureAD tenant objects when a Service Principal has one of the following 9 | MS Graph app role assignments: 10 |

11 | 12 |

13 |

17 |

18 | 19 | ); 20 | }; 21 | 22 | export default General; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGrantAppRoles/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | When you assign an app role to a Service Principal, the Azure 8 | Audit logs will create an event called "Add app role assignment 9 | to service principal". This event describes who made the change, 10 | what the target service principal was, and what app role assignment 11 | was granted. 12 |

13 | 14 | ); 15 | }; 16 | 17 | export default Opsec; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGrantAppRoles/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 |
15 | 16 | Andy Robbins - BARK.ps1 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default References; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGrantRole/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created during post-processing. It is created against 8 | all AzureAD admin roles when a Service Principal has the following 9 | MS Graph app role assignment: 10 |

11 | 12 |

13 |

16 |

17 | 18 |

19 | This privilege allows the Service Principal to promote itself or 20 | any other principal to any AzureAD admin role, including Global 21 | Administrator. 22 |

23 | 24 | ); 25 | }; 26 | 27 | export default General; 28 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGrantRole/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | When you assign an AzureAD admin role to a principal 8 | using this privilege, the Azure Audit log will create 9 | an event called "Add member to role outside of PIM 10 | (permanent)". 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGrantRole/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 |
15 | 16 | Andy Robbins - BARK.ps1 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default References; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGroupMember_ReadWrite_All/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the GroupMember.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Abuse; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGroupMember_ReadWrite_All/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the GroupMember.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default General; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGroupMember_ReadWrite_All/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the GroupMember.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGroupMember_ReadWrite_All/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default References; 19 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGroup_ReadWrite_All/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the Group.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Abuse; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGroup_ReadWrite_All/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the Group.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default General; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGroup_ReadWrite_All/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the Group.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGGroup_ReadWrite_All/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default References; 19 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGRoleManagement_ReadWrite_Directory/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the RoleManagement.ReadWrite.Directory edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Abuse; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGRoleManagement_ReadWrite_Directory/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the RoleManagement.ReadWrite.Directory edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default General; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGRoleManagement_ReadWrite_Directory/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the RoleManagement.ReadWrite.Directory edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGRoleManagement_ReadWrite_Directory/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 |
15 | 16 | Assign Azure AD roles at different scopes 17 | 18 | 19 | ); 20 | }; 21 | 22 | export default References; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGServicePrincipalEndpoint_ReadWrite_All/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the ServicePrincipalEndpoint.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Abuse; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGServicePrincipalEndpoint_ReadWrite_All/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the ServicePrincipalEndpoint.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default General; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGServicePrincipalEndpoint_ReadWrite_All/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | This edge is created when a Service Principal has been 8 | granted the ServicePrincipalEndpoint.ReadWrite.All edge. The edge is 9 | not abusable, but is used during post-processing to create 10 | abusable edges. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMGServicePrincipalEndpoint_ReadWrite_All/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T1098: Account Manipulation 8 | 9 |
10 | 11 | Andy Robbins - Azure Privilege Escalation via Service Principal 12 | Abuse 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default References; 19 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZManagedIdentity/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | Azure resources like Virtual Machines, Logic Apps, and Automation Accounts 7 | can be assigned to either System- or User-Assigned Managed Identities. 8 | This assignment allows the Azure resource to authenticate to Azure services 9 | as the Managed Identity without needing to know the credential for that 10 | Managed Identity. Managed Identities, whether System- or User-Assigned, are 11 | AzureAD Service Principals. 12 |

13 | ); 14 | }; 15 | 16 | export default General; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZManagedIdentity/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return

This will depend on which particular abuse you perform, but in general Azure will create a log event for each abuse.

; 5 | }; 6 | 7 | export default Opsec; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZManagedIdentity/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://attack.mitre.org/techniques/T1078/ 8 | 9 |
10 | 11 | https://posts.specterops.io/managed-identity-attack-paths-part-1-automation-accounts-82667d17187a 12 | 13 |
14 | 15 | https://m365internals.com/2021/11/30/lateral-movement-with-managed-identities-of-azure-virtual-machines 16 | 17 |
18 | 19 | https://github.com/BloodHoundAD/BARK 20 | 21 | 22 | ); 23 | }; 24 | 25 | export default References; 26 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMemberOf/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 |

6 | No abuse is necessary. This edge simply indicates that a principal 7 | belongs to a security group. 8 |

9 | ); 10 | }; 11 | 12 | export default Abuse; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMemberOf/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName }) => { 6 | return ( 7 | <> 8 |

9 | The {typeFormat(sourceType)} {sourceName} is a member of the 10 | group {targetName}. 11 |

12 |

13 | Groups in Azure Active Directory grant their direct members any privileges 14 | the group itself has. If a group has an AzureAD admin role, direct members 15 | of the group inherit those permissions. 16 |

17 | 18 | ); 19 | }; 20 | 21 | General.propTypes = { 22 | sourceName: PropTypes.string, 23 | sourceType: PropTypes.string, 24 | targetName: PropTypes.string, 25 | }; 26 | 27 | export default General; 28 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMemberOf/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return

No opsec considerations apply to this edge.

; 5 | }; 6 | 7 | export default Opsec; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZMemberOf/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | Create a role-assignable group in Azure Active Directory 8 | 9 | 10 | ); 11 | }; 12 | 13 | export default References; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZNodeResourceGroup/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | You will abuse this relationship by executing a command 8 | against the AKS Managed Cluster the edge is emiting from. 9 | You can target any managed identity assignment scoped to 10 | the Virtual Machine Scale Sets under the target Resource Group. 11 |

12 | 13 | ); 14 | }; 15 | 16 | export default Abuse; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZNodeResourceGroup/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 | 7 |

8 | This edge is created to link Azure Kubernetes Service 9 | Managed Clusters to the Virtual Machine Scale Sets they 10 | use to execute commands on. 11 |

12 | 13 |

14 | The system-assigned identity for the AKS Cluster will 15 | have the Contributor role against the target Resource Group 16 | and its child Virtual Machine Scale Sets. 17 |

18 | 19 | 20 | ); 21 | }; 22 | 23 | export default General; 24 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZNodeResourceGroup/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This will depend on which particular abuse you perform, but in 7 | general Azure will create a log event for each abuse. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZNodeResourceGroup/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | Andy Robbins - BARK.ps1 8 | 9 |
10 | 11 | Karl Fosaaen - How To Extract Credentials from Azure Kubernetes Service (AKS) 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZOwns/AZOwns.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Tabs, Tab } from 'react-bootstrap'; 4 | import General from './General'; 5 | import Abuse from './Abuse'; 6 | import Opsec from './Opsec'; 7 | import References from './References'; 8 | 9 | const AZOwns = ({ sourceName, sourceType, targetName, targetType }) => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | AZOwns.propTypes = { 29 | sourceName: PropTypes.string, 30 | sourceType: PropTypes.string, 31 | targetName: PropTypes.string, 32 | targetType: PropTypes.string, 33 | }; 34 | export default AZOwns; 35 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZOwns/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 |

6 | Everything a Contributor can do, with the addition of assigning 7 | rights to resources. 8 |

9 | ); 10 | }; 11 | 12 | export default Abuse; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZOwns/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | Object ownership means almost all abuses are possible against the 7 | target object. 8 |

9 | ); 10 | }; 11 | 12 | export default General; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZOwns/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This depends on which abuse you perform, but in general Azure will 7 | create a log for each abuse action. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZOwns/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | 6 | https://blog.netspi.com/attacking-azure-with-custom-script-extensions/ 7 | 8 | ); 9 | }; 10 | 11 | export default References; 12 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZPrivilegedAuthAdmin/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | This edge indicates the principal has the Privileged Authentication Administrator 7 | role active against the target tenant. Principals with this role can update 8 | sensitive properties for all users. Privileged Authentication Administrator can 9 | set or reset any authentication method (including passwords) for any user, 10 | including Global Administrators. 11 |

12 | ); 13 | }; 14 | 15 | export default General; 16 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZPrivilegedRoleAdmin/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 |

6 | Activate the Global Admin role for yourself or for another user 7 | using PowerZure or PowerShell. 8 |

9 | ); 10 | }; 11 | 12 | export default Abuse; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZPrivilegedRoleAdmin/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The Privileged Role Admin role can grant any other admin role to 7 | another principal at the tenant level. 8 |

9 | ); 10 | }; 11 | 12 | export default General; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZPrivilegedRoleAdmin/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | The Azure Activity Log will log who activated an admin role for what 7 | other principal, including the date and time. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZPrivilegedRoleAdmin/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | 6 | https://powerzure.readthedocs.io/en/latest/Functions/operational.html#add-azureadrole 7 | 8 | ); 9 | }; 10 | 11 | export default References; 12 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZResetPassword/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The ability to change another user's password without knowing their 7 | current password 8 |

9 | ); 10 | }; 11 | 12 | export default General; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZResetPassword/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | When resetting a user’s password and letting Azure 8 | set a new random password, Azure will log two events: 9 |

10 | 11 |

12 | “Reset user password” and “Reset password (by admin)”. 13 | These logs describe who performed the password reset, 14 | against which user, and at what time. 15 |

16 | 17 |

18 | When setting a specified new password for the user, 19 | Azure will log two events: 20 |

21 | 22 |

23 | “Reset user password” and “Update user”. The first log 24 | will describe who changed the target’s password and when. 25 |

26 | 27 | ); 28 | }; 29 | 30 | export default Opsec; 31 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZResetPassword/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 |

6 | 7 | https://powerzure.readthedocs.io/en/latest/Functions/operational.html#set-azureuserpassword 8 | 9 |

10 | ); 11 | }; 12 | 13 | export default References; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZRunsAs/AZRunsAs.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Tabs, Tab } from 'react-bootstrap'; 4 | import General from './General'; 5 | import Abuse from './Abuse'; 6 | import Opsec from './Opsec'; 7 | import References from './References'; 8 | 9 | const AZRunsAs = ({ sourceName, sourceType, targetName, targetType }) => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | AZRunsAs.propTypes = { 29 | sourceName: PropTypes.string, 30 | sourceType: PropTypes.string, 31 | targetName: PropTypes.string, 32 | targetType: PropTypes.string, 33 | }; 34 | export default AZRunsAs; 35 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZRunsAs/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 |

6 | This edge should be taken into consideration when abusing control of 7 | an app. Apps authenticate with service principals to the tenant, so 8 | if you have control of an app, what you are abusing is that control 9 | plus the fact that the app runs as a privileged service principal 10 |

11 | ); 12 | }; 13 | 14 | export default Abuse; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZRunsAs/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The Azure App runs as the Service Principal when it needs to 7 | authenticate to the tenant 8 |

9 | ); 10 | }; 11 | 12 | export default General; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZRunsAs/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return

No opsec considerations for this edge.

; 5 | }; 6 | 7 | export default Opsec; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZRunsAs/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return References go here; 5 | }; 6 | 7 | export default References; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZUserAccessAdministrator/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 |

6 | This role can be used to grant yourself or another principal any 7 | privilege you want against Automation Accounts, VMs, Key Vaults, and 8 | Resource Groups. Use the Azure portal to add a new, abusable role 9 | assignment against the target object for yourself. 10 |

11 | ); 12 | }; 13 | 14 | export default Abuse; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZUserAccessAdministrator/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The User Access Admin role can edit roles against many other objects 7 |

8 | ); 9 | }; 10 | 11 | export default General; 12 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZUserAccessAdministrator/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return

Azure will log any role activation event for any object type.

; 5 | }; 6 | 7 | export default Opsec; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZUserAccessAdministrator/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | 6 | https://blog.netspi.com/maintaining-azure-persistence-via-automation-accounts/ 7 | 8 | ); 9 | }; 10 | 11 | export default References; 12 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZVMAdminLogin/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | Connect to the VM via RDP and you will be granted local admin rights 8 | on the VM. 9 |

10 | 11 | ); 12 | }; 13 | 14 | export default Abuse; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZVMAdminLogin/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 | <> 6 |

7 | When a virtual machine is configured to allow logon with Azure 8 | AD credentials, the VM automatically has certain principals 9 | added to its local administrators group, including any principal 10 | granted the Virtual Machine Administrator Login (or "VMAL") 11 | admin role. 12 |

13 |

14 | Any principal granted this role, scoped to the affected VM, can 15 | connect to the VM via RDP and will be granted local admin rights 16 | on the VM. 17 |

18 | 19 | ); 20 | }; 21 | 22 | export default General; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZVMAdminLogin/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | If the target computer is a workstation and a user is currently 8 | logged on, one of two things will happen. If the user you are 9 | abusing is the same user as the one logged on, you will 10 | effectively take over their session and kick the logged on user 11 | off, resulting in a message to the user. If the users are 12 | different, you will be prompted to kick the currently logged on 13 | user off the system and log on. If the target computer is a 14 | server, you will be able to initiate the connection without 15 | issue provided the user you are abusing is not currently logged 16 | in. 17 |

18 |

19 | Remote desktop will create Logon and Logoff events with the 20 | access type RemoteInteractive. 21 |

22 | 23 | ); 24 | }; 25 | 26 | export default Opsec; 27 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZVMAdminLogin/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | ATT&CK T0008: Lateral Movement 8 | 9 | 10 | ATT&CK T1021: Remote Services 11 | 12 | 13 | Login to Windows virtual machine in Azure using Azure Active 14 | Directory authentication 15 | 16 | 17 | ); 18 | }; 19 | 20 | export default References; 21 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZVMContributor/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | The Virtual Machine Contributor role allows you to run SYSTEM 8 | commands on the VM 9 |

10 | 11 |

Via PowerZure:

12 | Invoke-AzureRunCommand 13 |
14 | Invoke-AzureRunMSBuild 15 |
16 | 17 | Invoke-AzureRunProgram 18 | 19 | 20 | ); 21 | }; 22 | 23 | export default Abuse; 24 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZVMContributor/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The Virtual Machine contributor role grants almost all abusable 7 | privileges against Virtual Machines. 8 |

9 | ); 10 | }; 11 | 12 | export default General; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZVMContributor/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | Because you'll be running a command as the SYSTEM user on the 7 | Virtual Machine, the same opsec considerations for running malicious 8 | commands on any system should be taken into account: command line 9 | logging, PowerShell script block logging, EDR, etc. 10 |

11 | ); 12 | }; 13 | 14 | export default Opsec; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZVMContributor/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | 6 | https://blog.netspi.com/running-powershell-scripts-on-azure-vms/ 7 | 8 | ); 9 | }; 10 | 11 | export default References; 12 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZWebsiteContributor/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | The Website Contributor role grants full control of the target 7 | Function App or Web App. Full control of either of those types 8 | of resources allows for arbitrary command execution against the 9 | target resoruce. 10 |

11 | ); 12 | }; 13 | 14 | export default General; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZWebsiteContributor/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This will depend on which particular abuse you perform, but in 7 | general Azure will create a log event for each abuse. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AZWebsiteContributor/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | Andy Robbins - BARK.ps1 8 | 9 |
10 | 11 | Karl Fosaaen - Lateral Movement in Azure App Services 12 | 13 |
14 | 15 | Andy Robbins - Abusing Azure App Service Managed Identity Assignments 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default References; 22 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AddAllowedToAct/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | To execute this attack, the Rubeus C# assembly needs to be executed 7 | on some system with the ability to send/receive traffic in the 8 | domain. Modification of the 9 | *msDS-AllowedToActOnBehalfOfOtherIdentity* property against the 10 | target also must occur, whether through PowerShell or another 11 | method. The property should be cleared (or reset to its original 12 | value) after attack execution in order to prevent easy detection. 13 |

14 | ); 15 | }; 16 | 17 | export default Opsec; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AddKeyCredentialLink/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat } from '../Formatter'; 4 | 5 | const General = ({sourceName, sourceType, targetName}) => { 6 | return ( 7 |

8 | {groupSpecialFormat(sourceType, sourceName)} the ability to write to 9 | the "msds-KeyCredentialLink" property on {targetName}. Writing to 10 | this property allows an attacker to create "Shadow Credentials" on 11 | the object and authenticate as the principal using kerberos PKINIT. 12 |

13 | ); 14 | }; 15 | 16 | General.propTypes = { 17 | sourceName: PropTypes.string, 18 | sourceType: PropTypes.string, 19 | targetName: PropTypes.string, 20 | }; 21 | 22 | export default General; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AddKeyCredentialLink/LinuxAbuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const LinuxAbuse = ({ sourceName, sourceType }) => { 5 | return ( 6 | <> 7 |

To abuse this privilege, use pyWhisker.

8 | 9 |
10 |                 {'pywhisker.py -d "domain.local" -u "controlledAccount" -p "somepassword" --target "targetAccount" --action "add"'}
11 |             
12 | 13 |

14 | For other optional parameters, view the pyWhisker documentation. 15 |

16 | 17 | ); 18 | }; 19 | 20 | LinuxAbuse.propTypes = { 21 | sourceName: PropTypes.string, 22 | sourceType: PropTypes.string, 23 | }; 24 | 25 | export default LinuxAbuse; 26 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AddKeyCredentialLink/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | Executing the attack will generate a 5136 (A directory object 8 | was modified) event at the domain controller if an appropriate 9 | SACL is in place on the target object. 10 |

11 | 12 |

13 | If PKINIT is not common in the environment, a 4768 (Kerberos 14 | authentication ticket (TGT) was requested) ticket can also 15 | expose the attacker. 16 |

17 | 18 | ); 19 | }; 20 | 21 | export default Opsec; 22 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AddKeyCredentialLink/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://github.com/eladshamir/Whisker 8 | 9 |
10 | 11 | https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AddKeyCredentialLink/WindowsAbuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const WindowsAbuse = ({ sourceName, sourceType }) => { 5 | return ( 6 | <> 7 |

To abuse this privilege, use Whisker.

8 | 9 |

10 | You may need to authenticate to the Domain Controller as{' '} 11 | {sourceType === 'User' || sourceType === 'Computer' 12 | ? `${sourceName} if you are not running a process as that user/computer` 13 | : `a member of ${sourceName} if you are not running a process as a member`} 14 |

15 | 16 |
17 |                 {'Whisker.exe add /target:'}
18 |             
19 | 20 |

21 | For other optional parameters, view the Whisker documentation. 22 |

23 | 24 | ); 25 | }; 26 | 27 | WindowsAbuse.propTypes = { 28 | sourceName: PropTypes.string, 29 | sourceType: PropTypes.string, 30 | }; 31 | 32 | export default WindowsAbuse; 33 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AddMember/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} the ability to add 10 | arbitrary principals, including{' '} 11 | {sourceType === 'Group' ? 'themselves' : 'itself'}, to the group{' '} 12 | {targetName}. Because of security group delegation, the members 13 | of a security group have the same privileges as that group. 14 |

15 | 16 |

17 | By adding itself to the group, {sourceName} will gain the same 18 | privileges that {targetName} already has. 19 |

20 | 21 | ); 22 | }; 23 | 24 | General.propTypes = { 25 | sourceName: PropTypes.string, 26 | sourceType: PropTypes.string, 27 | targetName: PropTypes.string, 28 | }; 29 | 30 | export default General; 31 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AddMember/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1 8 | 9 |
10 | 11 | https://www.youtube.com/watch?v=z8thoG7gPd0 12 | 13 |
14 | 15 | https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4728 16 | 17 |
18 | 19 | https://www.thehacker.recipes/ad/movement/dacl/addmember 20 | 21 | 22 | ); 23 | }; 24 | 25 | export default References; 26 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AddSelf/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} the ability to add{' '} 10 | {sourceType === 'Group' ? 'themselves' : 'itself'}, to the group{' '} 11 | {targetName}. Because of security group delegation, the members 12 | of a security group have the same privileges as that group. 13 |

14 | 15 |

16 | By adding itself to the group, {sourceName} will gain the same 17 | privileges that {targetName} already has. 18 |

19 | 20 | ); 21 | }; 22 | 23 | General.propTypes = { 24 | sourceName: PropTypes.string, 25 | sourceType: PropTypes.string, 26 | targetName: PropTypes.string, 27 | }; 28 | 29 | export default General; 30 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AdminTo/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | There are several forensic artifacts generated by the techniques 8 | described above. For instance, lateral movement via PsExec will 9 | generate 4697 events on the target system. If the target 10 | organization is collecting and analyzing those events, they may 11 | very easily detect lateral movement via PsExec. 12 |

13 | 14 |

15 | Additionally, an EDR product may detect your attempt to inject 16 | into lsass and alert a SOC analyst. There are many more opsec 17 | considerations to keep in mind when abusing administrator 18 | privileges. For more information, see the References tab. 19 |

20 | 21 | ); 22 | }; 23 | 24 | export default Opsec; 25 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AllExtendedRights/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat, typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName, targetType }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} the 10 | AllExtendedRights privilege to the {typeFormat(targetType)} 11 | {targetName}. 12 |

13 | 14 |

15 | Extended rights are special rights granted on objects which 16 | allow reading of privileged attributes, as well as performing 17 | special actions. 18 |

19 | 20 | ); 21 | }; 22 | 23 | General.propTypes = { 24 | sourceName: PropTypes.string, 25 | sourceType: PropTypes.string, 26 | targetName: PropTypes.string, 27 | targetType: PropTypes.string, 28 | }; 29 | 30 | export default General; 31 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AllExtendedRights/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | When using the PowerView functions, keep in mind that PowerShell v5 7 | introduced several security mechanisms that make it much easier for 8 | defenders to see what's going on with PowerShell in their network, 9 | such as script block logging and AMSI. You can bypass those security 10 | mechanisms by downgrading to PowerShell v2, which all PowerView 11 | functions support. 12 |

13 | ); 14 | }; 15 | 16 | export default Opsec; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AllowedToAct/LinuxAbuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const LinuxAbuse = ({ sourceName }) => { 5 | return ( 6 | <> 7 | We can then get a service ticket for the service name (sname) we 8 | want to "pretend" to be "admin" for. Impacket's getST.py example script 9 | can be used for that purpose. 10 |
11 |                 
12 |                     {
13 |                         "getST.py -spn 'cifs/targetcomputer.testlab.local' -impersonate 'admin' 'domain/attackersystem$:Summer2018!'"
14 |                     }
15 |                 
16 |             
17 | This ticket can then be used with Pass-the-Ticket, and could grant access 18 | to the file system of the TARGETCOMPUTER. 19 | 20 | ); 21 | }; 22 | 23 | LinuxAbuse.propTypes = { 24 | sourceName: PropTypes.string, 25 | }; 26 | 27 | export default LinuxAbuse; 28 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AllowedToAct/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | To execute this attack, the Rubeus C# assembly needs to be executed 7 | on some system with the ability to send/receive traffic in the 8 | domain. 9 |

10 | ); 11 | }; 12 | 13 | export default Opsec; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/AllowedToDelegate/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | As mentioned in the abuse info, in order to currently abuse this 7 | primitive the Rubeus C# assembly needs to be executed on some system 8 | with the ability to send/receive traffic in the domain. See the 9 | References for more information. 10 |

11 | ); 12 | }; 13 | 14 | export default Opsec; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/CanPSRemote/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat } from '../Formatter'; 4 | 5 | const General = ({sourceName, sourceType, targetName}) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} the capability to 10 | create a PSRemote Connection with the computer {targetName}. 11 |

12 | 13 |

14 | PS Session access allows you to enter an interactive session 15 | with the target computer. If authenticating as a low privilege 16 | user, a privilege escalation may allow you to gain high 17 | privileges on the system. 18 |

19 |

Note: This edge does not guarantee privileged execution.

20 | 21 | ); 22 | }; 23 | 24 | General.propTypes = { 25 | sourceName: PropTypes.string, 26 | sourceType: PropTypes.string, 27 | targetName: PropTypes.string, 28 | }; 29 | 30 | export default General; 31 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/CanPSRemote/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | When using the PowerShell functions, keep in mind that 8 | PowerShell v5 introduced several security mechanisms that make 9 | it much easier for defenders to see what's going on with 10 | PowerShell in their network, such as script block logging and 11 | AMSI. 12 |

13 |

14 | Entering a PSSession will generate a logon event on the target 15 | computer. 16 |

17 | 18 | ); 19 | }; 20 | 21 | export default Opsec; 22 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/CanPSRemote/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/new-pssession?view=powershell-7/ 8 | 9 |
10 | 11 | https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-7 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/CanRDP/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} the capability to 10 | create a Remote Desktop Connection with the computer{' '} 11 | {targetName}. 12 |

13 | 14 |

15 | Remote Desktop access allows you to enter an interactive session 16 | with the target computer. If authenticating as a low privilege 17 | user, a privilege escalation may allow you to gain high 18 | privileges on the system. 19 |

20 |

Note: This edge does not guarantee privileged execution.

21 | 22 | ); 23 | }; 24 | 25 | General.propTypes = { 26 | sourceName: PropTypes.string, 27 | sourceType: PropTypes.string, 28 | targetName: PropTypes.string, 29 | }; 30 | 31 | export default General; 32 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/CanRDP/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | If the target computer is a workstation and a user is currently 8 | logged on, one of two things will happen. If the user you are 9 | abusing is the same user as the one logged on, you will 10 | effectively take over their session and kick the logged on user 11 | off, resulting in a message to the user. If the users are 12 | different, you will be prompted to kick the currently logged on 13 | user off the system and log on. If the target computer is a 14 | server, you will be able to initiate the connection without 15 | issue provided the user you are abusing is not currently logged 16 | in. 17 |

18 |

19 | Remote desktop will create Logon and Logoff events with the 20 | access type RemoteInteractive. 21 |

22 | 23 | ); 24 | }; 25 | 26 | export default Opsec; 27 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/CanRDP/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://michael-eder.net/post/2018/native_rdp_pass_the_hash/ 8 | 9 |
10 | 11 | https://www.kali.org/penetration-testing/passing-hash-remote-desktop/ 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Contains/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return

There is no abuse info related to this edge.

; 5 | }; 6 | 7 | export default Abuse; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Contains/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName, targetType }) => { 6 | return ( 7 | <> 8 |

9 | {typeFormat(sourceType)} {sourceName} contains the{' '} 10 | {typeFormat(targetType)} {targetName}. 11 |

12 |

13 | GPOs linked to a container apply to all objects that are 14 | contained by the container. 15 |

16 | 17 | ); 18 | }; 19 | 20 | General.propTypes = { 21 | sourceName: PropTypes.string, 22 | sourceType: PropTypes.string, 23 | targetName: PropTypes.string, 24 | targetType: PropTypes.string, 25 | }; 26 | 27 | export default General; 28 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Contains/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return

There are no opsec considerations related to this edge.

; 5 | }; 6 | 7 | export default Opsec; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Contains/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | rerturn( 5 | <> 6 | https://wald0.com/?p=179 7 |
8 | 9 | https://blog.cptjesus.com/posts/bloodhound15 10 | 11 | 12 | ); 13 | }; 14 | 15 | export default References; 16 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/DCSync/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} the 10 | DS-Replication-Get-Changes and the 11 | DS-Replication-Get-Changes-All privilege on the domain{' '} 12 | {targetName}. 13 |

14 |

15 | These two privileges allow a principal to perform a DCSync 16 | attack. 17 |

18 | 19 | ); 20 | }; 21 | 22 | General.propTypes = { 23 | sourceName: PropTypes.string, 24 | sourceType: PropTypes.string, 25 | targetName: PropTypes.string, 26 | }; 27 | 28 | export default General; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/DCSync/LinuxAbuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const LinuxAbuse = () => { 4 | return ( 5 | <> 6 |

7 | You may perform a dcsync attack to get the password hash of an 8 | arbitrary principal using impacket's secretsdump.py example script: 9 |

10 | 11 |
12 |                 
13 |                     {
14 |                         "secretsdump.py 'testlab.local'/'Administrator':'Password'@'DOMAINCONTROLLER'"
15 |                     }
16 |                 
17 |             
18 | 19 |

20 | You can also perform the more complicated ExtraSids attack to 21 | hop domain trusts. For information on this see the blog post by 22 | harmj0y in the references tab. 23 |

24 | 25 | ); 26 | }; 27 | 28 | export default LinuxAbuse; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/DCSync/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | For detailed information on detection of dcsync as well as opsec 7 | considerations, see the adsecurity post in the references tab. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/DCSync/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://adsecurity.org/?p=1729 8 | 9 |
10 | 11 | https://blog.harmj0y.net/redteaming/mimikatz-and-dcsync-and-extrasids-oh-my/ 12 | 13 |
14 | 15 | https://www.thehacker.recipes/ad/movement/credentials/dumping/dcsync 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default References; 22 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/DCSync/WindowsAbuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const WindowsAbuse = () => { 4 | return ( 5 | <> 6 |

7 | You may perform a dcsync attack to get the password hash of an 8 | arbitrary principal using mimikatz: 9 |

10 |
11 |                 
12 |                     {
13 |                         'lsadump::dcsync /domain:testlab.local /user:Administrator'
14 |                     }
15 |                 
16 |             
17 |

18 | You can also perform the more complicated ExtraSids attack to 19 | hop domain trusts. For information on this see the blog post by 20 | harmj0y in the references tab. 21 |

22 | 23 | ); 24 | }; 25 | 26 | export default WindowsAbuse; 27 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Default/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return <>; 5 | }; 6 | export default Abuse; 7 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Default/Default.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Tabs, Tab } from 'react-bootstrap'; 4 | import General from './General'; 5 | import Abuse from './Abuse'; 6 | import Opsec from './Opsec'; 7 | import References from './References'; 8 | 9 | const Default = ({ sourceName, sourceType, targetName, targetType }) => { 10 | return ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ); 26 | }; 27 | 28 | Default.propTypes = { 29 | sourceName: PropTypes.string, 30 | sourceType: PropTypes.string, 31 | targetName: PropTypes.string, 32 | targetType: PropTypes.string, 33 | }; 34 | export default Default; 35 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Default/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const General = () => { 4 | return ( 5 |

6 | This is an error. Please report this to the BloodHound dev team 7 | along with instructions to replicate. 8 |

9 | ); 10 | }; 11 | 12 | export default General; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Default/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return <>; 5 | }; 6 | 7 | export default Opsec; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Default/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 |
8 | 9 |
10 | 11 | 12 | ); 13 | }; 14 | 15 | export default References; 16 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/DumpSMSAPassword/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import { groupSpecialFormat } from '../Formatter'; 5 | 6 | const General = ({sourceName, sourceType, targetName, targetType}) => { 7 | return ( 8 | <> 9 |

10 | {groupSpecialFormat(sourceType, sourceName)} the 11 | Standalone Managed Service Account (sMSA) {targetName} installed on it. 12 |

13 | 14 |

15 | With administrative privileges on {sourceName}, it is 16 | possible to dump {targetName}'s password stored in LSA 17 | secrets. 18 |

19 | 20 | ); 21 | }; 22 | 23 | General.propTypes = { 24 | sourceName: PropTypes.string, 25 | sourceType: PropTypes.string, 26 | targetName: PropTypes.string, 27 | }; 28 | 29 | export default General; 30 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/DumpSMSAPassword/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | 5 | return ( 6 | <> 7 |

8 | Access to registry hives can be monitored and alerted via event ID 4656 9 | (A handle to an object was requested). 10 |

11 | 12 | ) 13 | }; 14 | 15 | export default Opsec; 16 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/DumpSMSAPassword/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | 4 | const References = () => { 5 | return( 6 | <> 7 | https://simondotsh.com/infosec/2022/12/12/assessing-smsa.html 8 |
9 | https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dumping-lsa-secrets 10 |
11 | https://github.com/gentilkiwi/mimikatz 12 | 13 | ) 14 | }; 15 | 16 | export default References; 17 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/ExecuteDCOM/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} membership in the 10 | Distributed COM Users local group on the computer {targetName}. 11 |

12 |

13 | This can allow code execution under certain conditions by 14 | instantiating a COM object on a remote machine and invoking its 15 | methods. 16 |

17 | 18 | ); 19 | }; 20 | 21 | General.propTypes = { 22 | sourceName: PropTypes.string, 23 | sourceType: PropTypes.string, 24 | targetName: PropTypes.string, 25 | }; 26 | 27 | export default General; 28 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/ForceChangePassword/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat, typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName, targetType }) => { 6 | return ( 7 |

8 | {groupSpecialFormat(sourceType, sourceName)} the capability to 9 | change the {typeFormat(targetType)} {targetName}'s password without 10 | knowing that user's current password. 11 |

12 | ); 13 | }; 14 | 15 | General.propTypes = { 16 | sourceName: PropTypes.string, 17 | sourceType: PropTypes.string, 18 | targetName: PropTypes.string, 19 | targetType: PropTypes.string, 20 | }; 21 | 22 | export default General; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Formatter.jsx: -------------------------------------------------------------------------------- 1 | export const groupSpecialFormat = (sourceType, sourceName) => { 2 | if (sourceType === 'Group') { 3 | return `The members of the ${typeFormat( 4 | sourceType 5 | )} ${sourceName} have`; 6 | } else { 7 | return `The ${typeFormat(sourceType)} ${sourceName} has`; 8 | } 9 | }; 10 | 11 | export const typeFormat = type => { 12 | if (type === 'GPO' || type === 'OU') { 13 | return type; 14 | } else { 15 | return type.toLowerCase(); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GenericAll/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat, typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName, targetType }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} GenericAll 10 | privileges to the {typeFormat(targetType)} {targetName}. 11 |

12 | 13 |

14 | This is also known as full control. This privilege allows the 15 | trustee to manipulate the target object however they wish. 16 |

17 | 18 | ); 19 | }; 20 | 21 | General.propTypes = { 22 | sourceName: PropTypes.string, 23 | sourceType: PropTypes.string, 24 | targetName: PropTypes.string, 25 | targetType: PropTypes.string, 26 | }; 27 | export default General; 28 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GenericAll/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This depends on the target object and how to take advantage of this 7 | privilege. Opsec considerations for each abuse primitive are 8 | documented on the specific abuse edges and on the BloodHound wiki. 9 |

10 | ); 11 | }; 12 | 13 | export default Opsec; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GenericWrite/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat, typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName, targetType }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} generic write 10 | access to the {typeFormat(targetType)} {targetName}. 11 |

12 |

13 | Generic Write access grants you the ability to write to any 14 | non-protected attribute on the target object, including 15 | "members" for a group, and "serviceprincipalnames" for a user 16 |

17 | 18 | ); 19 | }; 20 | 21 | General.propTypes = { 22 | sourceName: PropTypes.string, 23 | sourceType: PropTypes.string, 24 | targetName: PropTypes.string, 25 | targetType: PropTypes.string, 26 | }; 27 | 28 | export default General; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GenericWrite/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | This depends on the target object and how to take advantage of this 7 | privilege. Opsec considerations for each abuse primitive are 8 | documented on the specific abuse edges and on the BloodHound wiki. 9 |

10 | ); 11 | }; 12 | 13 | export default Opsec; 14 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GetChanges/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} the 10 | DS-Replication-Get-Changes privilege on the domain {targetName}. 11 |

12 |

13 | Individually, this edge does not grant the ability to perform an 14 | attack. However, in conjunction with 15 | DS-Replication-Get-Changes-All, a principal may perform a DCSync 16 | attack. 17 |

18 | 19 | ); 20 | }; 21 | 22 | General.propTypes = { 23 | sourceName: PropTypes.string, 24 | sourceType: PropTypes.string, 25 | targetName: PropTypes.string, 26 | }; 27 | 28 | export default General; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GetChanges/LinuxAbuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const LinuxAbuse = () => { 4 | return ( 5 | <> 6 |

7 | You may perform a dcsync attack to get the password hash of an 8 | arbitrary principal using impacket's secretsdump.py example script: 9 |

10 | 11 |
12 |                 
13 |                     {
14 |                         "secretsdump.py 'testlab.local'/'Administrator':'Password'@'DOMAINCONTROLLER'"
15 |                     }
16 |                 
17 |             
18 | 19 |

20 | You can also perform the more complicated ExtraSids attack to 21 | hop domain trusts. For information on this see the blog post by 22 | harmj0y in the references tab. 23 |

24 | 25 | ); 26 | }; 27 | 28 | export default LinuxAbuse; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GetChanges/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | For detailed information on detection of dcsync as well as opsec 7 | considerations, see the adsecurity post in the references tab. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GetChanges/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://adsecurity.org/?p=1729 8 | 9 |
10 | 11 | https://blog.harmj0y.net/redteaming/mimikatz-and-dcsync-and-extrasids-oh-my/ 12 | 13 |
14 | 15 | https://www.thehacker.recipes/ad/movement/credentials/dumping/dcsync 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default References; 22 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GetChanges/WindowsAbuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const WindowsAbuse = () => { 4 | return ( 5 | <> 6 |

7 | With both GetChanges and GetChangesAll privileges in BloodHound, 8 | you may perform a dcsync attack to get the password hash of an 9 | arbitrary principal using mimikatz: 10 |

11 |
12 |                 
13 |                     {
14 |                         'lsadump::dcsync /domain:testlab.local /user:Administrator'
15 |                     }
16 |                 
17 |             
18 |

19 | You can also perform the more complicated ExtraSids attack to 20 | hop domain trusts. For information on this see the blog post by 21 | harmj0y in the references tab. 22 |

23 | 24 | ); 25 | }; 26 | 27 | export default WindowsAbuse; 28 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GetChangesAll/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} the 10 | DS-Replication-Get-Changes-All privilege on the domain{' '} 11 | {targetName}. 12 |

13 |

14 | Individually, this edge does not grant the ability to perform an 15 | attack. However, in conjunction with DS-Replication-Get-Changes, 16 | a principal may perform a DCSync attack. 17 |

18 | 19 | ); 20 | }; 21 | 22 | General.propTypes = { 23 | sourceName: PropTypes.string, 24 | sourceType: PropTypes.string, 25 | targetName: PropTypes.string, 26 | }; 27 | 28 | export default General; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GetChangesAll/LinuxAbuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const LinuxAbuse = () => { 4 | return ( 5 | <> 6 |

7 | You may perform a dcsync attack to get the password hash of an 8 | arbitrary principal using impacket's secretsdump.py example script: 9 |

10 | 11 |
12 |                 
13 |                     {
14 |                         "secretsdump.py 'testlab.local'/'Administrator':'Password'@'DOMAINCONTROLLER'"
15 |                     }
16 |                 
17 |             
18 | 19 |

20 | You can also perform the more complicated ExtraSids attack to 21 | hop domain trusts. For information on this see the blog post by 22 | harmj0y in the references tab. 23 |

24 | 25 | ); 26 | }; 27 | 28 | export default LinuxAbuse; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GetChangesAll/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | For detailed information on detection of dcsync as well as opsec 7 | considerations, see the adsecurity post in the references tab. 8 |

9 | ); 10 | }; 11 | 12 | export default Opsec; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GetChangesAll/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://adsecurity.org/?p=1729 8 | 9 |
10 | 11 | https://blog.harmj0y.net/redteaming/mimikatz-and-dcsync-and-extrasids-oh-my/ 12 | 13 |
14 | 15 | https://www.thehacker.recipes/ad/movement/credentials/dumping/dcsync 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default References; 22 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GetChangesAll/WindowsAbuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const WindowsAbuse = () => { 4 | return ( 5 | <> 6 |

7 | With both GetChanges and GetChangesAll privileges in BloodHound, 8 | you may perform a dcsync attack to get the password hash of an 9 | arbitrary principal using mimikatz: 10 |

11 |
12 |                 
13 |                     {
14 |                         'lsadump::dcsync /domain:testlab.local /user:Administrator'
15 |                     }
16 |                 
17 |             
18 |

19 | You can also perform the more complicated ExtraSids attack to 20 | hop domain trusts. For information on this see the blog post by 21 | harmj0y in the references tab. 22 |

23 | 24 | ); 25 | }; 26 | 27 | export default WindowsAbuse; 28 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GpLink/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return

There is no abuse info related to this edge.

; 5 | }; 6 | 7 | export default Abuse; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GpLink/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, targetName, targetType }) => { 6 | return ( 7 | <> 8 |

9 | The GPO {sourceName} is linked to the {typeFormat(targetType)}{' '} 10 | {targetName}. 11 |

12 |

13 | A linked GPO applies its settings to objects in the linked 14 | container. 15 |

16 | 17 | ); 18 | }; 19 | 20 | General.propTypes = { 21 | sourceName: PropTypes.string, 22 | targetName: PropTypes.string, 23 | targetType: PropTypes.string, 24 | }; 25 | 26 | export default General; 27 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GpLink/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return

There are no opsec considerations related to this edge.

; 5 | }; 6 | 7 | export default Opsec; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/GpLink/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | https://wald0.com/?p=179 7 |
8 | 9 | https://blog.cptjesus.com/posts/bloodhound15 10 | 11 | 12 | ); 13 | }; 14 | 15 | export default References; 16 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/HasSIDHistory/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 | <> 6 |

7 | No special actions are needed to abuse this, as the kerberos 8 | tickets created will have all SIDs in the object's SID history 9 | attribute added to them; however, if traversing a domain trust 10 | boundary, ensure that SID filtering is not enforced, as SID 11 | filtering will ignore any SIDs in the SID history portion of a 12 | kerberos ticket. 13 |

14 |

15 | By default, SID filtering is not enabled for all domain trust 16 | types. 17 |

18 | 19 | ); 20 | }; 21 | 22 | export default Abuse; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/HasSIDHistory/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName, targetType }) => { 6 | return ( 7 | <> 8 |

9 | The {typeFormat(sourceType)} {sourceName} has, in its SIDHistory 10 | attribute, the SID for the {typeFormat(targetType)} {targetName} 11 | . 12 |

13 |

14 | When a kerberos ticket is created for {sourceName}, it will 15 | include the SID for {targetName}, and therefore grant 16 | {sourceName} the same privileges and permissions as 17 | {targetName}. 18 |

19 | 20 | ); 21 | }; 22 | 23 | General.propTypes = { 24 | sourceName: PropTypes.string, 25 | sourceType: PropTypes.string, 26 | targetName: PropTypes.string, 27 | targetType: PropTypes.string, 28 | }; 29 | 30 | export default General; 31 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/HasSIDHistory/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return

No opsec considerations apply to this edge.

; 5 | }; 6 | 7 | export default Opsec; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/HasSession/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | An EDR product may detect your attempt to inject into lsass and 7 | alert a SOC analyst. There are many more opsec considerations to 8 | keep in mind when stealing credentials or tokens. For more 9 | information, see the References tab. 10 |

11 | ); 12 | }; 13 | 14 | export default Opsec; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/MemberOf/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return ( 5 |

6 | No abuse is necessary. This edge simply indicates that a principal 7 | belongs to a security group. 8 |

9 | ); 10 | }; 11 | 12 | export default Abuse; 13 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/MemberOf/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName }) => { 6 | return ( 7 | <> 8 |

9 | The {typeFormat(sourceType)} {sourceName} is a member of the 10 | group {targetName}. 11 |

12 |

13 | Groups in active directory grant their members any privileges 14 | the group itself has. If a group has rights to another 15 | principal, users/computers in the group, as well as other groups 16 | inside the group inherit those permissions. 17 |

18 | 19 | ); 20 | }; 21 | 22 | General.propTypes = { 23 | sourceName: PropTypes.string, 24 | sourceType: PropTypes.string, 25 | targetName: PropTypes.string, 26 | }; 27 | 28 | export default General; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/MemberOf/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return

No opsec considerations apply to this edge.

; 5 | }; 6 | 7 | export default Opsec; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/MemberOf/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://adsecurity.org/?tag=ad-delegation 8 | 9 |
10 | 11 | https://www.itprotoday.com/management-mobility/view-or-remove-active-directory-delegated-permissions{' '} 12 | 13 | 14 | ); 15 | }; 16 | 17 | export default References; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/Owns/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat, typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName, targetType }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} ownership of the{' '} 10 | {typeFormat(targetType)} {targetName}. 11 |

12 | 13 |

14 | Object owners retain the ability to modify object security 15 | descriptors, regardless of permissions on the object's DACL 16 |

17 | 18 | ); 19 | }; 20 | 21 | General.propTypes = { 22 | sourceName: PropTypes.string, 23 | sourceType: PropTypes.string, 24 | targetName: PropTypes.string, 25 | targetType: PropTypes.string, 26 | }; 27 | 28 | export default General; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/ReadGMSAPassword/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 | <> 6 |

7 | When abusing a GMSA that is already logged onto a system, you 8 | will have the same opsec considerations as when abusing a 9 | standard user logon. For more information about that, see the 10 | "HasSession" modal's opsec considerations tab. 11 |

12 |

13 | When retrieving the GMSA password from Active Directory, you may 14 | generate a 4662 event on the Domain Controller; however, that 15 | event will likely perfectly resemble a legitimate event if you 16 | request the password from the same context as a computer account 17 | that is already authorized to read the GMSA password. 18 |

19 | 20 | ); 21 | }; 22 | 23 | export default Opsec; 24 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/ReadLAPSPassword/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} the ability to read 10 | the password set by Local Administrator Password Solution (LAPS) 11 | on the computer {targetName}. 12 |

13 |

14 | The local administrator password for a computer managed by LAPS 15 | is stored in the confidential LDAP attribute, "ms-mcs-AdmPwd". 16 |

17 | 18 | ); 19 | }; 20 | 21 | General.propTypes = { 22 | sourceName: PropTypes.string, 23 | sourceType: PropTypes.string, 24 | targetName: PropTypes.string, 25 | }; 26 | 27 | export default General; 28 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/ReadLAPSPassword/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

Reading properties from LDAP is an extremely low risk operation.

6 | ); 7 | }; 8 | 9 | export default Opsec; 10 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/ReadLAPSPassword/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://www.specterops.io/assets/resources/an_ace_up_the_sleeve.pdf 8 | 9 |
10 | 11 | https://adsecurity.org/?p=3164 12 | 13 | 14 | https://www.thehacker.recipes/ad/movement/dacl/readlapspassword 15 | 16 | 17 | ); 18 | }; 19 | 20 | export default References; 21 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/SyncLAPSPassword/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {groupSpecialFormat} from "../Formatter"; 3 | 4 | const Abuse = ({sourceName, sourceType, targetName, targetType}) => { 5 | return ( 6 | <> 7 |

8 | To abuse this privilege with DirSync, first import DirSync into your agent session or into a PowerShell instance at the console. You must authenticate to the Domain Controller as {groupSpecialFormat(sourceType, sourceName)}. Then, execute the Sync-LAPS function: 9 |

10 | 11 |
12 |                 
13 |                     Sync-LAPS -LDAPFilter "(samaccountname={targetName})"
14 |                 
15 |             
16 | 17 |

18 | You can target a specific domain controller using the -Server parameter. 19 |

20 | 21 | ) 22 | }; 23 | 24 | export default Abuse; 25 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/SyncLAPSPassword/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import { groupSpecialFormat } from '../Formatter'; 5 | 6 | const General = ({sourceName, sourceType, targetName, targetType}) => { 7 | return ( 8 | <> 9 |

10 | {groupSpecialFormat(sourceType, sourceName)} the ability to 11 | synchronize the password set by Local Administrator Password 12 | Solution (LAPS) on the computer {targetName}. 13 |

14 | 15 |

16 | The local administrator password for a computer managed by LAPS 17 | is stored in the confidential and Read-Only Domain Controller 18 | (RODC) filtered LDAP attribute ms-mcs-AdmPwd. 19 |

20 | 21 | ); 22 | }; 23 | 24 | General.propTypes = { 25 | sourceName: PropTypes.string, 26 | sourceType: PropTypes.string, 27 | targetName: PropTypes.string, 28 | }; 29 | 30 | export default General; 31 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/SyncLAPSPassword/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | 5 | return ( 6 | <> 7 |

8 | Executing the attack will generate a 4662 (An operation was performed on an object) event at the domain controller if an appropriate SACL is in place on the target object. 9 |

10 | 11 | ) 12 | }; 13 | 14 | export default Opsec; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/SyncLAPSPassword/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | 4 | const References = () => { 5 | return( 6 | <> 7 | https://github.com/simondotsh/DirSync 8 |
9 | https://simondotsh.com/infosec/2022/07/11/dirsync.html 10 | 11 | ) 12 | }; 13 | 14 | export default References; 15 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/TrustedBy/Abuse.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Abuse = () => { 4 | return

There is no abuse associated with this edge.

; 5 | }; 6 | 7 | export default Abuse; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/TrustedBy/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const General = ({ sourceName, targetName }) => { 5 | return ( 6 | <> 7 |

8 | The domain {sourceName} is trusted by the domain {targetName}. 9 |

10 |

11 | This edge is informational and does not indicate any attacks, 12 | only that a trust exists. 13 |

14 | 15 | ); 16 | }; 17 | 18 | General.propTypes = { 19 | sourceName: PropTypes.string, 20 | targetName: PropTypes.string, 21 | }; 22 | 23 | export default General; 24 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/TrustedBy/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return

There is no opsec associated with this edge

; 5 | }; 6 | 7 | export default Opsec; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/TrustedBy/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return <>; 5 | }; 6 | 7 | export default References; 8 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/TrustedBy/TrustedBy.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Tabs, Tab } from 'react-bootstrap'; 3 | import General from './General'; 4 | import Abuse from './Abuse'; 5 | import Opsec from './Opsec'; 6 | import References from './References'; 7 | 8 | const TrustedBy = ({ sourceName, sourceType, targetName, targetType }) => { 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | ); 25 | }; 26 | 27 | TrustedBy.propTypes = {}; 28 | export default TrustedBy; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/WriteAccountRestrictions/Opsec.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Opsec = () => { 4 | return ( 5 |

6 | To execute this attack, the Rubeus C# assembly needs to be executed 7 | on some system with the ability to send/receive traffic in the 8 | domain. Modification of the 9 | *msDS-AllowedToActOnBehalfOfOtherIdentity* property against the 10 | target also must occur, whether through PowerShell or another 11 | method. The property should be cleared (or reset to its original 12 | value) after attack execution in order to prevent easy detection. 13 |

14 | ); 15 | }; 16 | 17 | export default Opsec; 18 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/WriteDacl/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat, typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName, targetType }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} permissions to 10 | modify the DACL (Discretionary Access Control List) on the{' '} 11 | {typeFormat(targetType)} {targetName} 12 |

13 |

14 | With write access to the target object's DACL, you can grant 15 | yourself any privilege you want on the object. 16 |

17 | 18 | ); 19 | }; 20 | 21 | General.propTypes = { 22 | sourceName: PropTypes.string, 23 | sourceType: PropTypes.string, 24 | targetName: PropTypes.string, 25 | targetType: PropTypes.string, 26 | }; 27 | 28 | export default General; 29 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/WriteOwner/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat, typeFormat } from '../Formatter'; 4 | 5 | const General = ({ sourceName, sourceType, targetName, targetType }) => { 6 | return ( 7 | <> 8 |

9 | {groupSpecialFormat(sourceType, sourceName)} the ability to 10 | modify the owner of the {typeFormat(targetType)} {targetName}. 11 |

12 |

13 | Object owners retain the ability to modify object security 14 | descriptors, regardless of permissions on the object's DACL. 15 |

16 | 17 | ); 18 | }; 19 | 20 | General.propTypes = { 21 | sourceName: PropTypes.string, 22 | sourceType: PropTypes.string, 23 | targetName: PropTypes.string, 24 | targetType: PropTypes.string, 25 | }; 26 | 27 | export default General; 28 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/WriteSPN/General.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { groupSpecialFormat, typeFormat } from '../Formatter'; 4 | 5 | const General = ({sourceName, sourceType, targetName, targetType}) => { 6 | return ( 7 |

8 | {groupSpecialFormat(sourceType, sourceName)} the ability to write to 9 | the "serviceprincipalname" attribute to the {typeFormat(targetType)}{' '} 10 | {targetName}. 11 |

12 | ); 13 | }; 14 | 15 | General.propTypes = { 16 | sourceName: PropTypes.string, 17 | sourceType: PropTypes.string, 18 | targetName: PropTypes.string, 19 | targetType: PropTypes.string, 20 | }; 21 | 22 | export default General; 23 | -------------------------------------------------------------------------------- /src/components/Modals/HelpTexts/WriteSPN/References.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const References = () => { 4 | return ( 5 | <> 6 | 7 | https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1 8 | 9 |
10 | 11 | https://www.harmj0y.net/redteaming/kerberoasting-revisited/ 12 | 13 |
14 | 15 | https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4728 16 | 17 | 18 | ); 19 | }; 20 | 21 | export default References; 22 | -------------------------------------------------------------------------------- /src/components/PoseContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { motion } from 'framer-motion'; 3 | 4 | const PoseContainer = ({ 5 | className, 6 | visible, 7 | dragHandle, 8 | draggable = true, 9 | children, 10 | }) => { 11 | return ( 12 | 33 | {children} 34 | 35 | ); 36 | }; 37 | 38 | PoseContainer.propTypes = {}; 39 | export default PoseContainer; 40 | -------------------------------------------------------------------------------- /src/components/RawQuery.module.css: -------------------------------------------------------------------------------- 1 | .button { 2 | position: relative; 3 | left: 50%; 4 | display: block; 5 | width: 200px; 6 | height: 2em; 7 | transform: translateX(-50%); 8 | border-radius: 20px 20px 0 0; 9 | border: none; 10 | background-color: white; 11 | pointer-events: auto; 12 | } 13 | 14 | .button:focus { 15 | outline: 0; 16 | } 17 | 18 | .container { 19 | position: absolute; 20 | z-index: 10; 21 | bottom: 0; 22 | overflow: hidden; 23 | width: 100%; 24 | pointer-events: none; 25 | } 26 | 27 | .input { 28 | position: relative; 29 | left: 50%; 30 | width: 70%; 31 | transform: translateX(-50%); 32 | pointer-events: auto; 33 | border: none; 34 | border-radius: 8px 8px 0 0; 35 | } 36 | 37 | .dark { 38 | } 39 | 40 | .dark .button { 41 | background-color: #151d29; 42 | color: white; 43 | } 44 | 45 | .dark .input { 46 | background-color: #444b55; 47 | color: white; 48 | } 49 | -------------------------------------------------------------------------------- /src/components/SearchContainer/EdgeFilter/EdgeFilterCheck.jsx: -------------------------------------------------------------------------------- 1 | import React, {useContext} from 'react'; 2 | import {AppContext} from '../../../AppContext'; 3 | import styles from './EdgeFilter.module.css'; 4 | 5 | const EdgeFilterCheck = ({ name }) => { 6 | const context = useContext(AppContext); 7 | 8 | const handleChange = (e) => { 9 | context.setEdgeIncluded(name, e.target.checked); 10 | }; 11 | 12 | return ( 13 |
14 | 22 |
23 | ); 24 | }; 25 | 26 | EdgeFilterCheck.propTypes = {}; 27 | export default EdgeFilterCheck; 28 | -------------------------------------------------------------------------------- /src/components/SearchContainer/SearchRow.module.css: -------------------------------------------------------------------------------- 1 | .spacing { 2 | margin-left: 10px; 3 | margin-right: 5px; 4 | } 5 | -------------------------------------------------------------------------------- /src/components/SearchContainer/TabContainer.module.css: -------------------------------------------------------------------------------- 1 | .tc :global li { 2 | float: none; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/SearchContainer/Tabs/Components/CollapsibleSection.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | cursor: pointer; 3 | font-family: helvetica, serif; 4 | font-size: 18px; 5 | padding-left: 10px; 6 | } 7 | 8 | .dark { 9 | color: #82b1c5; 10 | } 11 | 12 | .light { 13 | color: #406f8e; 14 | } 15 | 16 | .removeGutters { 17 | padding-left: 0; 18 | padding-right: 15px; 19 | } 20 | 21 | .itemlist { 22 | overflow-y: auto; 23 | overflow-x: hidden; 24 | margin: 5px 10px; 25 | } 26 | 27 | .itemlist :global table { 28 | margin-bottom: 0; 29 | margin-top: 0; 30 | } 31 | 32 | .itemlist :global table > thead { 33 | text-align: left; 34 | position: -webkit-sticky; 35 | position: sticky; 36 | } 37 | 38 | .itemlist :global table > tbody > tr { 39 | font-family: Helvetica, serif; 40 | font-size: 12px; 41 | border-style: none; 42 | } 43 | 44 | .dark > .dl > h5 { 45 | color: white !important; 46 | } 47 | 48 | .light > .dl > h5 { 49 | color: black; 50 | } 51 | 52 | .dark td { 53 | color: white !important; 54 | opacity: 1; 55 | } -------------------------------------------------------------------------------- /src/components/SearchContainer/Tabs/Components/NodeCypherLink.module.css: -------------------------------------------------------------------------------- 1 | dt { 2 | font-weight: 400 3 | } -------------------------------------------------------------------------------- /src/components/SearchContainer/Tabs/Components/NodeCypherNoNumberLink.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component} from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | export default class NodeCypherNoNumberLink extends Component { 5 | constructor(props) { 6 | super(props); 7 | } 8 | 9 | render() { 10 | let c = function () { 11 | emitter.emit( 12 | 'query', 13 | this.props.query, 14 | { objectid: this.props.target }, 15 | this.props.start, 16 | this.props.end 17 | ); 18 | }.bind(this); 19 | 20 | return ( 21 | 22 | {this.props.property} 23 | 24 | 25 | ); 26 | } 27 | } 28 | 29 | NodeCypherNoNumberLink.propTypes = { 30 | target: PropTypes.string.isRequired, 31 | property: PropTypes.string.isRequired, 32 | query: PropTypes.string.isRequired, 33 | start: PropTypes.string, 34 | end: PropTypes.string, 35 | }; 36 | -------------------------------------------------------------------------------- /src/components/SearchContainer/Tabs/Components/NodeDisplayLink.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const NodeDisplayLink = ({ title, value, graphQuery, queryProps }) => { 4 | return ( 5 | { 8 | emitter.emit('query', graphQuery, queryProps); 9 | }} 10 | > 11 | {title} 12 | {value} 13 | 14 | ); 15 | }; 16 | 17 | export default NodeDisplayLink; 18 | -------------------------------------------------------------------------------- /src/components/SearchContainer/Tabs/Components/NodePlayCypherLink.module.css: -------------------------------------------------------------------------------- 1 | .icon{ 2 | cursor: pointer; 3 | } -------------------------------------------------------------------------------- /src/components/SearchContainer/Tabs/Components/NoteGallery.module.css: -------------------------------------------------------------------------------- 1 | .inline { 2 | display: inline; 3 | } 4 | 5 | .check { 6 | position: relative; 7 | font-size: 18px; 8 | margin-left: 5px; 9 | } 10 | 11 | .green { 12 | color: green; 13 | } 14 | 15 | .textarea { 16 | resize: none; 17 | width: 98%; 18 | height: 100px; 19 | color: black; 20 | } 21 | 22 | .modal { 23 | background-color: rgba(0, 0, 0, 0.8); 24 | } 25 | 26 | .imageContainer { 27 | cursor: pointer; 28 | position: relative; 29 | } 30 | -------------------------------------------------------------------------------- /src/components/SearchContainer/Tabs/NoNodeData.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useContext } from 'react'; 3 | import { AppContext } from '../../../AppContext'; 4 | 5 | const NoNodeData = ({ visible }) => { 6 | const context = useContext(AppContext); 7 | return ( 8 |
12 |

Node Properties

13 |

Select a node for more information

14 |
15 | ); 16 | }; 17 | 18 | NoNodeData.propTypes = {}; 19 | export default NoNodeData; 20 | -------------------------------------------------------------------------------- /src/components/SearchContainer/Tabs/PrebuiltQueryNode.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import './PrebuiltQueries.module.css'; 3 | 4 | export default class PrebuiltQueryNode extends Component { 5 | render() { 6 | let c; 7 | 8 | c = function () { 9 | if (appStore.prebuiltQuery.length === 0) { 10 | appStore.prebuiltQuery = JSON.parse( 11 | JSON.stringify(this.props.info.queryList) 12 | ); 13 | emitter.emit('prebuiltQueryStart'); 14 | } 15 | }.bind(this); 16 | 17 | return ( 18 | 19 | {this.props.info.name} 20 | 21 | 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /src/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /src/fonts/roboto-v15-latin-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/fonts/roboto-v15-latin-regular.eot -------------------------------------------------------------------------------- /src/fonts/roboto-v15-latin-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/fonts/roboto-v15-latin-regular.ttf -------------------------------------------------------------------------------- /src/fonts/roboto-v15-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/fonts/roboto-v15-latin-regular.woff -------------------------------------------------------------------------------- /src/fonts/roboto-v15-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/fonts/roboto-v15-latin-regular.woff2 -------------------------------------------------------------------------------- /src/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/img/favicon.ico -------------------------------------------------------------------------------- /src/img/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/img/icon.icns -------------------------------------------------------------------------------- /src/img/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/img/icon.ico -------------------------------------------------------------------------------- /src/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/img/icon.png -------------------------------------------------------------------------------- /src/img/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/img/icon@2x.png -------------------------------------------------------------------------------- /src/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/img/loading.gif -------------------------------------------------------------------------------- /src/img/loading_new.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/img/loading_new.gif -------------------------------------------------------------------------------- /src/img/logo-white-on-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/img/logo-white-on-transparent.png -------------------------------------------------------------------------------- /src/img/logo-white-transparent-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/img/logo-white-transparent-full.png -------------------------------------------------------------------------------- /src/img/logo-white-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SpecterOps/BloodHound-Legacy/56ec4b90f7712bd18adda628e616cf13bccdf003/src/img/logo-white-transparent.png -------------------------------------------------------------------------------- /webpack.config.production.js: -------------------------------------------------------------------------------- 1 | var config = require('./webpack.config.development.js'); 2 | config.entry.shift(); 3 | config.plugins.shift(); 4 | config.output.publicPath = './dist/'; 5 | config.mode = 'production'; 6 | module.exports = config; 7 | --------------------------------------------------------------------------------