MSSQLHound
PowerShell collector for adding MSSQL attack paths to BloodHound with OpenGraph
Install / Use
/learn @SpecterOps/MSSQLHoundREADME
MSSQLHound
<img width="3147" height="711" alt="image" src="https://github.com/user-attachments/assets/476babac-c265-4d2b-bc03-f893fdb7bc1f" />A PowerShell collector for adding MSSQL attack paths to BloodHound with OpenGraph by Chris Thompson at SpecterOps
Introductory blog posts:
- https://specterops.io/blog/2025/08/04/adding-mssql-to-bloodhound-with-opengraph/
- https://specterops.io/blog/2026/01/20/updates-to-the-mssqlhound-opengraph-collector-for-bloodhound/
Please hit me up on the BloodHound Slack (@Mayyhem), Twitter (@_Mayyhem), or open an issue if you have any questions I can help with!
Table of Contents
- Overview
- Command Line Options
- Limitations
- Future Development
- MSSQL Graph Model
- MSSQL Nodes Reference
- MSSQL Edges Reference
- Edge Classes and Properties
CoerceAndRelayToMSSQLMSSQL_AddMemberMSSQL_AlterMSSQL_AlterAnyAppRoleMSSQL_AlterAnyDBRoleMSSQL_AlterAnyLoginMSSQL_AlterAnyServerRoleMSSQL_ChangeOwnerMSSQL_ChangePasswordMSSQL_ConnectMSSQL_ConnectAnyDatabaseMSSQL_ContainsMSSQL_ControlMSSQL_ControlDBMSSQL_ControlServerMSSQL_ExecuteAsMSSQL_ExecuteAsOwnerMSSQL_ExecuteOnHostMSSQL_GetAdminTGSMSSQL_GetTGSMSSQL_GrantAnyDBPermissionMSSQL_GrantAnyPermissionMSSQL_HasDBScopedCredMSSQL_HasLoginMSSQL_HasMappedCredMSSQL_HasProxyCredMSSQL_HostForMSSQL_ImpersonateMSSQL_ImpersonateAnyLoginMSSQL_IsMappedToMSSQL_IsTrustedByMSSQL_LinkedAsAdminMSSQL_LinkedToMSSQL_MemberOfMSSQL_OwnsMSSQL_ServiceAccountForMSSQL_TakeOwnership
- Edge Classes and Properties
Overview
Collects BloodHound OpenGraph compatible data from one or more MSSQL servers into individual temporary files, then zips them in the current directory
- Example:
mssql-bloodhound-20250724-115610.zip
System Requirements:
- PowerShell 4.0 or higher
- Target is running SQL Server 2005 or higher
- BloodHound v8.0.0+ with Postgres backend (to use prebuilt Cypher queries): https://bloodhound.specterops.io/get-started/custom-installation#postgresql
Minimum Permissions:
Windows Level:
- Active Directory domain context with line of sight to a domain controller
MSSQL Server Level:
CONNECT SQL(default for new logins)VIEW ANY DATABASE(default for new logins)
Recommended Permissions:
MSSQL Server Level:
VIEW ANY DEFINITIONpermission or##MS_DefinitionReader##role membership (available in versions 2022+)- Needed to read server principals and their permissions
- Without one of these permissions, there will be false negatives (invisible server principals)
VIEW SERVER PERFORMANCE STATEpermission or##MSS_ServerPerformanceStateReader##role membership (available in versions 2022+) or localAdministratorsgroup privileges on the target (fallback for WMI collection)- Only used for service account collection
MSSQL Database Level:
CONNECT ANY DATABASEserver permission (available in versions 2014+) or##MS_DatabaseConnector##role membership (available in versions 2022+) or login maps to a database user withCONNECTon individual databases- Needed to read database principals and their permissions
- Login maps to
msdbdatabase user withdb_datareaderrole or withSELECTpermission on:msdb.dbo.sysproxiesmsdb.dbo.sysproxyloginmsdb.dbo.sysproxysubsystemmsdb.dbo.syssubsystems- Only used for proxy account collection
Usage Info
Run MSSQLHound from a box where you aren’t highly concerned about resource consumption. While there are guardrails in place to stop the script if resource consumption is too high, it’s probably a good idea to be careful and run it on a workstation instead of directly on a critical database server, just in case.
If you don't already have a specific target or targets in mind, start by running the script with the -DomainEnumOnly flag set to see just how many servers you’re dealing with in Active Directory. Then, use the -ServerInstance option to run it again for a single server or add all of the servers that look interesting to a file and run it again with the -ServerListFile option.
If you don't do a dry run first and collect from all SQL servers with SPNs in the domain (the default action), expect the script to take a very long time to finish and eat up a ton of disk space if there ar a lot of servers in the environment. Based on limited testing in client environments, the file size for each server before they are all zipped ranges significantly from 2MB to 50MB+, depending on how many objects are on the server.
To populate the MSSQL node glyphs in BloodHound, execute MSSQLHound.ps1 -OutputFormat BloodHound-customnodes (or copy the following) and use the API Explorer page to submit the JSON to the custom-nodes endpoint.
{
"custom_types": {
"MSSQL_DatabaseUser": {
"icon": {
"name": "user",
"color": "#f5ef42",
"type": "font-awesome"
}
},
"MSSQL_Login": {
"icon": {
"name": "user-gear",
"color": "#dd42f5",
"type": "font-awesome"
}
},
"MSSQL_DatabaseRole": {
"icon": {
"name": "users",
"color": "#f5a142",
"type": "font-awesome"
}
},
"MSSQL_Database": {
"icon": {
"name": "database",
"color": "#f54242",
"type": "font-awesome"
}
},
"MSSQL_ApplicationRole": {
"icon": {
"name": "robot",
"color": "#6ff542",
"type": "font-awesome"
}
},
"MSSQL_Server": {
"icon": {
"name": "server",
"color": "#42b9f5",
"type": "font-awesome"
}
},
"MSSQL_ServerRole": {
"icon": {
"name": "users-gear",
"color": "#6942f5",
"type": "font-awesome"
}
}
}
}
There are several new edges that have to be non-traversable because they are not abusable 100% of the time, including when:
- the stored AD credentials might be stale/invalid, but maybe they are!
- MSSQL_HasMappedCred
- MSSQL_HasDBScopedCred
- MSSQL_HasProxyCred
- the server principal that owns the database does not have complete control of the server, but maybe it has other interesting permissions
- MSSQL_IsTrustedBy
- the server is linked to another server using a principal that does not have complete control of the remote server, but maybe it has other interesting permissions
- MSSQL_LinkedTo
- the service account can be used to impersonate domain users that have a login to the server, but we don’t have the necessary permissions to check that any domain users have logins
- MSSQL_ServiceAccountFor
- It would be unusual, but not impossible, for the MSSQL Server instance to run in the context of a domain service account and have no logins for domain users. If you can infer that certain domain users have access to a particular MSSQL Server instance or discover that information through other means (e.g., naming conventions, OSINT, organizational documentation, internal communications, etc.), you can request service tickets for those users to the MSSQL Server if you have control of the service account (e.g., by cracking weak passwords for Kerberoastable service principals).
Want to be a bit more aggressive with your pathfinding queries? You can make these edges traversable using the -MakeInterestingEdgesTraversable flag.
I also recommend conducting a collection with the -IncludeNontraversableEdges flag enabled at some point if you need to understand what permissions on which objects allow the traversable edges to be created. By default, non-traversable edges are skipped to make querying the data for valid attack paths easier. This is still a work in progress, bu
Related Skills
feishu-drive
339.3k|
things-mac
339.3kManage Things 3 via the `things` CLI on macOS (add/update projects+todos via URL scheme; read/search/list from the local Things database)
clawhub
339.3kUse the ClawHub CLI to search, install, update, and publish agent skills from clawhub.com
yu-ai-agent
2.0k编程导航 2025 年 AI 开发实战新项目,基于 Spring Boot 3 + Java 21 + Spring AI 构建 AI 恋爱大师应用和 ReAct 模式自主规划智能体YuManus,覆盖 AI 大模型接入、Spring AI 核心特性、Prompt 工程和优化、RAG 检索增强、向量数据库、Tool Calling 工具调用、MCP 模型上下文协议、AI Agent 开发(Manas Java 实现)、Cursor AI 工具等核心知识。用一套教程将程序员必知必会的 AI 技术一网打尽,帮你成为 AI 时代企业的香饽饽,给你的简历和求职大幅增加竞争力。
