SQL注入漏洞——联合查询注入与报错注入

本篇我们继续来深入SQL注入漏洞

有个困扰计算机多年的问题,就是“没法总是分清数据和指令”,这就是SQL注入的本质,这就是自然语言的弊端,即使是人类有时也分不清楚,密码是“12345678”还是“2444666668888888”。

再来回顾一下SQL注入是如何产生的:Web应用程序对用户输入的数据没有进行过滤,或者过滤不严,就把SQL语句带进数据库进行查询

判断sql注入:

SQL注入需要满足以下两个条件:

  • 参数可控:从前端传给后端的参数内容是由用户可以控制的;
  • 参数带入数据库查询:传入的参数拼接到SQL语句,且带入数据库查询。

当用户传入参数为 ‘1’ 时,在数据库执行如下所示:

select * from users where id='1' 

此SQL语句不符合语法规则就会报错:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1

当用户传入参数为 1 and 1=1 时:

select * from users where id=1 and 1=1

因为1=1为真,id=1也是真,and两边均为真,所以页面会返回id=1的结果

如果用户传入参数为 1 and 1=2 时,因为1=2 为假,所以页面会返回与id不一样的结果

由此我们可以初步判断存在SQL注入漏洞,攻击者可以进一步拼接SQL攻击语句进行攻击,致使信息泄露,甚至获取服务器权限。

本质上 就是看页面回显,无回显是指根据输入的语句,页面没有任何变化或者没有数据库中的内容显示到网页中。

id =1 and 1=1
id = 1 and 1=2
id = 1 or 1=1
id = '1' or '1'='1'
id=" 1 "or "1"="1"

例如:假设此时我们有一个用户表单,如果我们要查询所有用户的信息,我们可以用

select * from allusers

如果我们要查询某个用户的信息,那我们就可以在后面加上where,并且附上条件

where username = 'eggpain' and password = 'mima'

用户输入了用户名和密码后,服务器就会把输入的用户名和密码这两条数据加在where里面,这看起来是一个正常的操作,但如果,我们恶意的写错用户名,加上一个单引号,SQL查询语句就会变成这样。


当电脑执行查询语句的时候,会把一对引号中的视为字符数据而不是操作符,但由于这里的引号不成对,所以这里的SQL语句是会报错的

如果此时,服务器直接将错误信息返回给用户,黑客就知道是什么原因导致了报错,SQL注入攻击的门也就这样被打开了。

单单一个报错可能还没什么,但如果我们在单引号后面加上--,就会将后面的语句变为注释,注释是不会在SQL语句中执行的。如果黑客知道用户名,即使不知道密码,也能进行账号的登录了。

即使黑客不知道用户名,也没关系,在SQL语言中,当遇到where语句时,会判断条件是真还是假,如果我们想进行攻击,我们就用or将两个条件拼接起来,这时,只要有一条语句为真,整个判断就为真了。

这时,我们只需要增加一个为真的语句,例如1=1(SQL中不使用==判断,这点与C不同)这样,即使用户名信息错误,where这里的逻辑判断都是为真的,这样就完成了入侵。

联合注入:

联合注入顾名思义,就是使用联合查询进行注入的一种方式,是一种高效的注入方式,适用于有回显同时数据库软件版本是5.0以上的mysql数据库,以为5.0以上版本的数据库会有一个系统数据库information_schema,能很快的通过几条注入语句获取到想要的数据。

union有一个十分严苛的约束条件,因为是联合查询,必须保证字段数一致,即两个查询结果有相同的列数,因此我们要对字段数进行判断。

在SQL里,要合并两个表格的内容,常见的就是用union连接两个表格的查询语句。

对于union,union select的后面可以不需要指定表格的名字,直接在select后面用null来代替列名,null是一个特殊的值,表示空,这会直接在表格后面合并两个null值展示。

这个操作看似没什么意义,但是UNION的操作必须保证合并两边的列数是要一致的,一般黑客是不知道有多少列的,但是可以一直在后面加上null进行测试,看最后多少个null会返回成功的结果,就证明这个表格有多少列了。

当然还有其他方法可以获取表格的列数,当黑客用其他方法知道了另一个表格的信息后,就可以把表格的列名放在null的位置,并且指定选取的表格名。

这个方法不一定可行,因为UNION除了要保证列数一致以外,还要保证数据类型是一致的,例如数字和字符就不是相似类型了。如果id是数字,而username是字符,这样是无法进行合并的。

因此,实际上黑客在确定好列数之后,还会进行数据类型的判断,例如逐列进行数据类型判断。现在黑客就可以把所有东西放在一起。

首先,在可以可以注入的地方,使用单引号强行终止数据内容,并且加上注释关键词,使后面的语句失效,这样SQL语句就不会报错,黑客就可以在这里注入UNION语句了,如果要获取账号密码,账号密码信息就被合并了,并且展示到页面中。

布尔和时间延迟:

但是,并不是所有的网站都会显示信息,也不是所有的网站都会回显报错信息,但是黑客仍有办法去进行攻击。

例如,现在大部分网站都会使用cookie,这样服务器就能根据不同的cookie来识别不同的用户,从而展示不同的网页内容。也就是说,会在数据库里保存不同用户的cookie,用户登录网页的时候,就会在HTTP请求里加上cookie这个HTTP首部,相应的,也会生成服务器向数据库的查询语句。

此时黑客就可以使用前面说到的方法,在这里修改cookie的值,如果此时返回的还是原来的页面就证明是可以注入的,如果我们此时加上一个where故意使语句变错,如果此时页面内容改变了,黑客就知道查询到内容时是什么页面,查询不到内容又是什么页面了。


那现在只需要修改and后面的条件,就能猜测想要的内容了。例如使用SUBSTRING函数从字符串中提取子字符串,从而逐个猜测密码。


如果此时黑客知道管理员用户名,并且知道其信息保存在users表中,就可以将SUBSTRING里的第一个参数修改为一条查询语句,返回正确的页面就证明猜对了一个字符,以此类推,暴力破解。

字符串操作的函数:

在SQL中,`CONCAT`、`CONCAT_WS` 和 `GROUP_CONCAT` 是用于字符串操作的函数,它们可以合并多个字符串值。下面是它们各自的简要说明:

1. **CONCAT**:
   - `CONCAT` 函数用于将多个字符串值连接成一个字符串。
   - 语法:`CONCAT(str1, str2, ...)`。
   - 示例:`SELECT CONCAT('Hello', ' ', 'World');` 结果是 `'Hello World'`。

2. **CONCAT_WS**:
   - `CONCAT_WS` 函数允许你指定一个分隔符来连接多个字符串值。
   - 语法:`CONCAT_WS(separator, str1, str2, ...)`。
   - 第一个参数是分隔符,随后的参数是要连接的字符串。
   - 示例:`SELECT CONCAT_WS('-', '2024', '07', '02');` 结果是 `'2024-07-02'`。

3. **GROUP_CONCAT**:
   - `GROUP_CONCAT` 函数用于将分组的结果连接成一个字符串,通常与 `GROUP BY` 子句一起使用。
   - 语法:`GROUP_CONCAT([DISTINCT] str1 [ORDER BY ...] [SEPARATOR str2])`。
   - 可以指定一个分隔符,也可以使用 `ORDER BY` 对结果进行排序。
   - 示例:`SELECT author, GROUP_CONCAT(DISTINCT title SEPARATOR ', ') AS titles FROM books GROUP BY author;` 这将返回每个作者及其书籍标题的列表,每个作者的书籍标题由逗号和空格分隔。

报错注入:

1.报错注入原理:

报错注入是通过特殊函数错误使用并使其输出错误结果来获取信息的。PC发送有错误的查询语句给服务器,服务器收到错误消息并查询数据库,之后反馈错误提示database并包含数据库信息给PC。

在遇到有报错回显的时候,但是没有数据回显的情况下可以使用。

报错注入函数:

  1. floor():向下取整
  2. extractvalue():对XML文档进行查询的函数,当参数的格式不正确而产生的错误,会返回参数的信息。
  3. updatexml():更新XML文档的函数,原理跟extracvalue一样
  4. exp():以e为底的指数函数
  5. rand()+group()+count():
  6. ……(前三种较为常用)

2.extractvalue报错注入:

通过extractValue()报错注入

函数extractValue()包含两个参数

第一个参数XML文档对象名称,第二个参数为路径

eg.使用extractvalue查询xml里面的内容

> select extractvalue(doc,'/book/author/surname') from xml;

如果需要查询书名则可以用如下命令

>select extractvalue(doc,'/book/title') from xml;

报错注入实例:

假设一个Web应用程序的搜索功能存在SQL注入漏洞,其SQL查询如下:

SELECT * FROM products WHERE name = '用户输入的产品名称';

如果应用程序没有对用户输入进行适当的过滤或验证,攻击者可以输入以下内容:

'; DROP TABLE products; --

如果数据库执行这个查询,它将尝试删除products表,但由于这不是一个合法的操作(因为通常用户没有删除表的权限),数据库会返回一个错误信息,比如:

Error: DROP TABLE failed: 'products' does not exist.

攻击者通过这个错误信息得知数据库中存在一个名为products的表。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值