在linux系统下利用SQL注入写shell时,总是失败是什么鬼?
0x00 故事背景
MySQL注入读写文件众所周知的三个条件:
- 绝对路径
File_priv
secure_file_priv
然后这里再补充两个:
apparmor
selinux
0x01 File_priv
代表用户所具有的文件操作权限
可以通过如下查询来查看指定用户的文件读写权限。
select file_priv from mysql.user where user=$USER host=$HOST;
0x02 secure_file_priv
代表MySQL服务器所具有的文件操作权限
默认是NULL,可以通过my.conf文件mysqld一栏里进行配置,配置完成后,重启便会生效。
secure_file_priv
可以设置如下这样进行设置:
- 设置为空,那么对所有路径均可进行导入导出。
- 设置为一个目录名字,那么只允许在该路径下导入导出。
- 设置为Null,那么禁止所有导入导出。
可以通过如下查询来查看MySQL服务器的文件读写权限
select @@global.secure_file_priv;
如果是secure_file_priv参数的限制,那么会爆出如下错误:
此时如果我们查看secure_file_priv变量,发现可能是NULL,那就是完全禁止的意思。
此时如果我们已经开启了这个变量,但是与允许的目录非同一目录时,可以发现爆出的错误是一样的:
因此,如果我们有幸看到这个报错信息时,说明两种情况:
- 数据库不允许导入导出
- 数据库在指定的目录不允许导入导出
需要注意的是:在windows下如果已经确定File_priv
和secure_file_priv
这两个条件都已经满足了以后,便可以继续后面的漏洞利用了;但是如果在linux下面则会出现意料之外的问题
0x03 过渡
如下情况基于在Linux操作系统进行阐述。
当我们已经可以通过注入读取/etc/passwd
文件了,但是却无法读取其他文件,或者写文件到指定目录。
读取/var/www目录下面的temp文件
写入到tmp目录下,与写入到其他目录下
查看刚刚写入到tmp目录下,文件的属性,可以看到所有者是mysql
或许是因为mysql启动用户是mysql,于是我们修改为root
同样先写入到tmp目录
并查看文件的属性,发现此时的归属者确实是root
于是再次尝试写文件到其他目录
可以看到仍旧无法写入
此时我们回顾一下我们所处的环境
secure_file_priv
=""Filr_pri
=y- mysql启动用户是root
- mysql登录用户是root
但是仍旧失败
0x04 apparmor
armor
英 ['ɑ:mə] 美 [ˈɑrmɚ]
n.
装甲;盔甲;装甲部队;保障
vt.
为…穿盔甲(或加置装甲);为…提供防御
AppArmor是一个高效和易于使用的Linux系统安全应用程序,可以有效的控制应用程序的各种权限,如文件/目录的操作权限、端口的开放关闭权限等。在ubuntu操作系统中一般是默认继承并且开启的。
此时我们关闭apparmor
service apparmor teardown
可以看到此时再次读写时,顺利执行。
0x05 selinux
安全增强型 Linux(Security-Enhanced Linux)简称 SELinux,它是一个 Linux 内核模块,也是 Linux 的一个安全子系统。
在centos下面,修改/etc/selinux/config。把SELINUX=enforcing,设置为SELINUX=disabled即可,然后重启系统,来关闭selinux。
关闭selinux之后,注入读写文件便会顺利了。
0x06 参考文章
官方文档
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_secure_file_priv
关于Mysql中select into outfile权限的探讨