【数据库-SQL 注入】SQL 注入漏洞详解 - Union 注入



1)漏洞简介

SQL 注入简介

SQL 注入 即是指 Web 应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在 Web 应用程序中事先定义好的查询语句的结尾上添加额外的 SQL 语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
在这里插入图片描述

SQL 注入概念

SQL 注入漏洞主要形成的原因是在数据交互中,站点针对前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到 SQL 语句中后,被当作 SQL 语句的一部分执行。 从而导致数据库受损(被脱裤、被删除、甚至整个服务器权限沦陷)。
主要是开发人员在构建代码时,没有对输入边界进行安全考虑,导致攻击着可以 通过合法的输入点提交一些精心构造的语句,从而欺骗后台数据库对其进行执行,导致数据库信息泄漏的一种漏洞。

SQL 注入攻击流程

  • 第一步:注入点探测
    自动方式:使用 Web 漏洞扫描工具,自动进行注入点发现
    手动方式:手工构造 sql inject 测试语句进行注入点发现

  • 第二步:信息获取
    通过注入点取期望得到的数据。
    环境信息:数据库类型,数据库版本,操作系统版本,用户信息等。
    数据库信息:数据库名,数据表名,表字段名,字段内容(加密内容破解)

  • 第三步:获取权限
    获取操作系统权限:通过数据库执行 Shell,上传木马

2)漏洞原理

可以通过网站存在的查询语句进行构造,为此开发者对其伤透了脑筋,漏洞不光是查询,可能还存在与 API、隐藏链接、http 头数据、写入数据等。需要对数据包的结构和传递函数比较了解,建议学习的时候把数据库的日志打开,就可以查看到传递到数据库的语句是什么样子的了。
需要记住的 information_schema 数据库的 SCHEMATA、TABLES、COLUMNS。 SCHEMATA 表中存放所有数据库的名,字段名为 SCHEMA_NAME。 关键函数 database() 当前数据库名、version() 当前 mysql 版本、user() 当前 mysql 用户。

3)漏洞危害

参数用户可控:前端传给后端的参数内容是用户可以控制的。( 输入框,URL,抓包 )
参数带入数据库查询:传入的参数拼接到 SQL 语句,且带入数据库查询。
information_schema:可用来访问数据库的元数据,相似于信息数据库。其中保存着 关于MySQL 服务器 所维护的所有其他数据库的信息(元数据)。如数据库名,数据库的表,表栏的数据类型与访问权限等。

4)SQL 注入分类

4.1)数字型

当输入的参数为整形时,如果存在注入漏洞,可以认为是数字型注入。

测试步骤:

  1. 加单引号, URL:www.text.com/text.php?id=3’
    对应的 sql: select * from table where id=3’ 这时 sql 语句出错, 程序无法正常从数据库中查询出数据, 就会抛出异常; 此时可以判断大概率存在注入, 因为只有服务器将这个单引号一起当作 SQL 语句执行时才会报错.
  2. 加 and 1=1, URL: www.text.com/text.php?id=3 and 1=1
    对应的 sql: select * from table where id=3 and 1=1 语句执行正常, 与原始页面无任何差异;
  3. 加 and 1=2, URL: www.text.com/text.php?id=3 and 1=2
    对应的 sql: select * from table where id=3 and 1=2 语句可以正常执行, 但是无法查询出结果, 所以返回数据与原始网页存在差异.
    加单引号测试
    SELECT first_name, last_name FROM users WHERE user_id = ‘1’';

加 and 1=1 测试

  • 有引号:网站把输入的 1 and 1=1 **当成字符串 **传递到后端,因隐式转换的存在,所以查询出结果。
  • 无引号:网站识别了输入的 and 1=1,做了逻辑判断。所以能查询出结果。存在 SQL 注入。
    SELECT first_name, last_name FROM users WHERE user_id = ‘1 and 1=1’;

加 and 1=2 测试

成功返回结果,说明输入的内容是被 当成了字符串执行(隐式转换)。并未做逻辑运算。
如果做了逻辑运算,则存在 SQL 注入漏洞。

SELECT first_name, last_name FROM users WHERE user_id = '1 and 1=2';

未做隐式转换的效果

SELECT first_name, last_name FROM users WHERE user_id = 1 and 1=1;
SELECT first_name, last_name FROM users WHERE user_id = 1 and 1=2;

4.2)字符型

当输入的参数为字符串时,称为字符型。
字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。
数字型语句:select * from table where id =3;
字符型如下:select * from table where name=‘admin’;
因此,在构造 Payload 时 通过闭合单引号 可以成功执行语句:
实现了绕过被单引号包含的结局
尝试输入: 1’ and 1=1 #
基于这种方法: 实现了绕过被单引号包含的结局
实现了在 SQL 语句层面, 输入的内容是两个正常的表达式.
SELECT first_name, last_name FROM users WHERE user_id = ‘1’ and 1=1 #';
可以判断为:字符型注入,对参数 id 没有做任何过滤,并且用单引号闭合。

因为条件 1=1 永远为真( 恒为真 )
所以 where 查询不再限制只返回特定 user_id 的记录,**而是返回整个表的内容。 **

理想效果

SELECT first_name,last_name FROM users WHERE user_id = 'suibianxie' or 1=1;
```C

闭合单引号

```C
SELECT first_name,last_name FROM users WHERE user_id = 'suibianxie' or 1=1 #';

4.3)Union 注入 ( 联合查询注入 )

联合查询是可合并多个相似的选择查询的结果集。等同于将一个表追加到另一个表,从而实现将两个表的查询组合到一起,使用 UNION 或 UNION ALL。
注意:UNION 操作符选取不重复的值。如果允许重复的值,请使用 UNION ALL

select user_id,first_name from users where user_id=1 union all select user_id,first_name from users where user_id=1;
select user_id,first_name from users where user_id=1 union select user_id,first_name from users where user_id=1;

前提条件:页面存在显示位
schemata:表里包含所有数据库的名字
tables:表里包含所有数据库的所有表名,默认字段为 table_name
columns:表里包含所有数据库的所有表的所有字段名

SCHEMA_NAME:数据库名
TABLE_NAME:表名
COLUMN_NAME:字段名
创作不易,关注公众号鼓励一下吧:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wxiaohe1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值