Author / Maintainer: @defsecapp
SqlServerSecurityAudit is a Windows console tool that helps security engineers and developers discover risky SQL Server security and access surfaces by:
- scanning application configuration files for SQL Server connection strings and password-like attributes;
- actively connecting to SQL Server (optional) and checking security-relevant command execution surfaces such as
xp_cmdshell, OLE Automation, external scripts, SQL Agent CmdExec, and linked servers; - detecting password reuse between SQL logins and local administrator accounts;
- producing a text report summarizing findings in a human-readable format.
The tool is written in C# / .NET (target: .NET Framework 4.8) and is designed as a defensive security / AppSec utility.
- Recursively scans directory roots (or all suitable drives, if no root is specified) as the first step of the security audit.
- Looks for common .NET / web configuration files:
web.configapp.configconnectionStrings.configappsettings.jsonappsettings.*.json
- Extracts:
- SQL Server–like connection strings (using heuristics over
Data Source/Server,Initial Catalog/Database, and auth tokens). - Password-like attributes using a regex over names such as:
passw,pwd,psw,passwd,secret,token,apikey,auth,authorization,bearer, etc.
- SQL Server–like connection strings (using heuristics over
- Groups connection strings by (server, login) to reduce the number of SQL connections during the audit.
- For each distinct (server, login) pair (if active checks are enabled), the tool:
- connects to SQL Server using
SqlConnection; - records
SYSTEM_USERandORIGINAL_LOGIN()for effective identity; - collects server info:
- data source, resolved IP address,
- whether the server appears local or remote (based on host/IP comparison).
- connects to SQL Server using
For each successful connection, the tool checks a set of potential command execution surfaces as part of the SQL Server security audit:
- Configuration flags from
sys.configurations:xp_cmdshellshow advanced optionsOle Automation Proceduresexternal scripts enabled
xp_cmdshell:- optionally enables it via
sp_configure(when allowed in options); - runs
EXEC master..xp_cmdshell 'whoami'; - records success and captured output.
- optionally enables it via
- OLE Automation Procedures (
sp_OACreate/WScript.Shell):- optionally enables it via
sp_configure(when allowed in options); - runs
whoamithroughcmd /c whoamiusingWScript.Shell; - records output if successful.
- optionally enables it via
- External scripts (
sp_execute_external_script):- does not change the
external scripts enabledsetting; - if already enabled:
- attempts
whoamivia R; - falls back to Python if R fails;
- attempts
- records which language worked and the command output.
- does not change the
- SQL Agent CmdExec surface (if
msdbis available):- checks membership in
SQLAgentUserRole,SQLAgentReaderRole,SQLAgentOperatorRole; - counts job steps with
subsystem = 'CmdExec'; - flags the presence of a potentially dangerous CmdExec surface.
- checks membership in
- Linked servers:
- counts linked servers with
is_linked = 1andis_rpc_out_enabled = 1.
- counts linked servers with
All temporary changes to configuration (xp_cmdshell, Ole Automation Procedures, show advanced options) are reverted to original values when possible.
- Reads SQL Server service account from
sys.dm_server_services. - Classifies the service account as:
- built-in (
NT AUTHORITY\...,NT SERVICE\...,LocalSystem,Local Service,Network Service), or - domain/machine account (
DOMAIN\User).
- built-in (
- For domain accounts, attempts to check if the service account is a member of Domain Admins using
System.DirectoryServices.AccountManagement.
- After probes, groups successful connections into credential groups:
- key:
(server data source, login, password)(for SQL auth) or(server data source, IntegratedSecurity)for Windows auth.
- key:
- Each
CredentialGrouptracks:- server;
- login display (e.g.
sa,IntegratedSecurity); - raw password (for internal processing) and a separate display value (can be redacted in reports);
- list of
ConnectionCheckResultinstances; - list of file paths where these credentials were found.
This feature is disabled by default and must be explicitly enabled.
When enabled:
- Enumerates local administrator accounts on the machine using
System.DirectoryServices.AccountManagementon the localAdministratorsgroup (non-recursive). - Ensures
.\\Administratoris always present as a fallback target. - For each distinct password coming from:
- credential groups (SQL connection strings with SQL auth),
- password-like attributes in configuration files,
- The tool:
- calls
LogonUser(domain, user, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT)for each local admin account; - records if any admin account accepted the password;
- caches results per password to avoid repeated logon attempts.
- calls
The report highlights any cases where a password from configs is also valid for a local administrator account as CRITICAL.
- Generates a plain text report (UTF-8) in a single file (default:
sqlout.txtin the tool directory). - Contains:
- Summary header (timestamp, root scope, total credential groups).
- Detailed information for each credential group:
- server, login, password (optionally redacted);
- SQL identity (
SYSTEM_USER,ORIGINAL_LOGIN()); - example successful connection string;
- whether password matches any local admin (if enabled);
- file locations where the credentials were found;
- SQL Server IP and “local/remote” classification;
- SQL service account, domain / Domain Admin status;
- status and output for:
xp_cmdshell,- OLE Automation
whoami, - external scripts
whoami, - SQL Agent CmdExec surface,
- linked servers with RPC OUT;
- aggregated error details (if any).
- A section with extra password attributes:
- password-like attributes from configs that matched local admin accounts.
The tool is structured into several layers:
-
CLI layer (
Cli)Program– entry point.AppOptions– strongly typed options with safe defaults.AppOptionsParser– command-line parsing, profiles, and--help.
-
File scanning (
FileScanning)ConfigFileScanner– iterates over directories, filters config-like files.ConfigContentExtractor– reads each file once, extracting:- connection strings,
- password-like attributes (via regex).
-
SQL layer (
Sql)ConnectionGrouper– groups connection strings by(server, login)for efficient probing.SqlProbe– performs active SQL checks and collectsConnectionCheckResult.CredentialGrouper– groupsConnectionCheckResultintoCredentialGroupby(server, login, password).
-
Security layer (
Security)AdminPasswordTester– enumerates local admins (non-recursive) and checks password reuse usingLogonUser.
-
Reporting (
Reporting)TextReportWriter– convertsCredentialGroupandPasswordCandidatedata into a text report.ReportOptions,AuditReportInput– simple DTOs for decoupling reporting from the pipeline.
-
Pipeline (
Pipeline)AuditPipeline– orchestrates:- file scanning,
- content extraction,
- SQL probes,
- credential grouping,
- admin password reuse checks (optional),
- report generation.
This structure is intentionally modular to keep code testable and maintainable.
- OS: Windows (desktop/server).
- Runtime: .NET Framework 4.8 (or compatible).
- Permissions:
- read access to the directories being scanned;
- network access to the SQL Servers referenced in configs;
- SQL permissions sufficient to:
- connect to the target databases,
- query metadata like
sys.configurations,sys.dm_server_services,sys.servers,msdbtables; sp_configure/RECONFIGURE/xp_cmdshell/ OLE /sp_execute_external_scriptdepending on which features you enable.
- For admin password reuse checks:
- rights to call
LogonUserfor local administrator accounts.
- rights to call
The tool is intended to be used by administrators and security engineers who already have appropriate permissions in the environment.
Compile the project, then run:
SqlServerSecurityAudit.exe- scan all suitable drives;
- enable active SQL checks (connect and query);
- not change SQL Server configuration (
xp_cmdshell, OLE); - not test passwords against local administrators;
- redact passwords in the report;
- write
sqlout.txtto the tool directory.
You can control behaviour using profiles:
- No SQL connections (file-based analysis only).
- Active SQL checks enabled.
- No changes to SQL configuration.
- No admin password reuse checks.
(This is effectively the default profile.)
- Active SQL checks enabled.
- Allows toggling
xp_cmdshellandOle Automation Procedures. - Enables admin password reuse checks.
# Passive, file-only audit of a specific root
SqlServerSecurityAudit.exe --profile passive --root C:\Projects-
--root <path>
Add a root directory to scan (can be used multiple times). -
--scan-all/--no-scan-all
Enable or disable automatic scanning of all suitable drives when no root is specified. -
--output <file>or-o <file>
Set report file name (default:sqlout.txtin the tool directory).
-
--active-sql/--no-active-sql
Enable or disable active SQL checks (connections + probes). -
--xp-toggle/--no-xp-toggle
Allow or forbid changingxp_cmdshellconfiguration viasp_configure. -
--ole-toggle/--no-ole-toggle
Allow or forbid changingOle Automation Proceduresconfiguration.
-
--admin-reuse/--no-admin-reuse
Enable or disable testing passwords against local administrator accounts. -
--show-passwords/--no-show-passwords
Show raw passwords in the report or redact them (default: redacted).
SqlServerSecurityAudit.exe --help
SqlServerSecurityAudit.exe -?The report is a UTF-8 text file with several sections.
=== SQL Server security audit report ===
Timestamp: 2025-01-01 12:34:56
Root scope: C:\Projects
Total credential groups: 3
=== SQL Server command execution surface (grouped by server-login-password) ===
------------------------------------------------------------
Server data source: SQLSERVER01
Login: sa
Password: ******** (redacted)
Uses Windows auth: no
Actual SYSTEM_USER (inside SQL): dbo
Actual ORIGINAL_LOGIN() (inside SQL): sa
Example successful connection string:
Server=SQLSERVER01;Database=ProdDb;User Id=sa;Password=SuperSecret123;
Password matches at least one local Administrator account: YES (CRITICAL)
Matched admin account(s): SERVER01\Administrator
Found in 2 location(s):
- C:\Projects\App1\web.config
- C:\Projects\App2\appsettings.json
SQL Server IP: 10.0.0.10
SQL Server location: remote
SQL Server service account: DOMAIN\sql_svc
Service account is domain account: yes
Service account is Domain Admin: no
xp_cmdshell whoami: SUCCESS
xp_cmdshell whoami output: DOMAIN\sql_svc
OLE Automation whoami tried: yes
OLE Automation whoami: ERROR or not available
External scripts enabled: yes
External scripts whoami: SUCCESS via Python
External scripts whoami output: DOMAIN\sql_svc
SQL Agent CmdExec surface present: YES
SQL Agent CmdExec steps count: 5
SQL Agent roles: SQLAgentReaderRole,SQLAgentOperatorRole
Linked servers with RPC OUT: 2
Details: xp_cmdshell enable/disable messages, external script errors, etc.
=== Extra password attributes with 'passw' checked against local administrators ===
Total matching password attributes: 1
------------------------------------------------------------
File: C:\Projects\App1\appsettings.Development.json
Attribute name: DbAdminPassword
Password value: SuperSecret123
Source line snippet: "DbAdminPassword": "SuperSecret123",
Matches local admin account(s): SERVER01\Administrator
Admin password check details: No admin accounts accepted this password.The exact layout may evolve, but the main idea is:
- group by credentials to avoid noisy repetition;
- clearly flag dangerous combinations like:
xp_cmdshell+ high-privileged service account;- SQL login passwords reused as local admin passwords.
This tool is intended for defensive security and configuration auditing in environments where you are authorized to operate.
It can:
- change SQL Server configuration (when allowed by options) via
sp_configure; - execute commands through
xp_cmdshell, OLE Automation, and external scripts; - attempt logons for local administrator accounts.
Always:
- run it in accordance with your organization's policies;
- obtain proper approvals before running in production environments;
- test in non-production first.
Use at your own risk.
The author is not responsible for any damage, misconfiguration, or policy violations caused by misuse of this tool.
Potential future improvements:
- JSON / HTML report formats.
- More granular control over which SQL checks are executed.
- Better detection of configuration files (custom patterns).
- Optional recursive expansion of domain groups for admin enumeration (behind a dedicated flag).
- Unit tests for configuration parsing and grouping logic.