[网络安全]SQL注入原理及常见攻击方法简析

简介: 一般而言,登录验证逻辑语句为:select * from 表名 where name(用户名)='$输入' and pass(密码)='$输入'当数据表中同时存在输入的name和pass字段时,页面将回显登录成功。

登陆验证后端逻辑

一般而言,登录验证逻辑语句为:

select * from 表名 where name(用户名)='$输入' and pass(密码)='$输入'

当数据表中同时存在输入的name和pass字段时,页面将回显登录成功。


未知用户名注入攻击原理

若后端逻辑为:select * from users where name='xx' and password='xx'


手工注入

在用户名中输入qiu' or '1=1 ,密码中同样输入qiu' or '1=1

xx被输入的内容替换,查询语句变为:

select * from users where name='qiu' or '1=1' and password='qiu' or '1=1'

等同于


SELECT * FROM users WHERE (name='qiu' or '1'='1') AND (password='qiu' OR '1'='1')

1

括号内的 OR 表达式由于包含了一个恒成立的表达式 ‘1’=‘1’,所以不论用户名与密码是否正确,它始终返回真。

查询条件变为真and真,因此,sql语句注入成功。


基于#注释符的sql注入

在 SQL 语句中,# 号被用作单行注释符号。如果在一条 SQL 语句中以 # 开头,则后面的所有文字都将被解释器忽略掉,不会被执行。


当password不能为空时,用户名输入qiu' or 1=1 #,密码满足不为空即可

注入语句等同于:


select * from users where name='qiu' or 1=1 # and password='xxx'

1

即select * from users where name='qiu' or 1=1

故sql语句注入成功


当password为可为空时,用户名输入qiu' or 1=1 #

注入语句等同于:


select * from user where name='qiu' or 1=1 #' and pass=''

1

即:

select * from user where name='qiu' or 1=1

故sql语句注入成功


基于错误消息的sql注入

当应用程序遇到异常或错误时,会返回相关的错误消息给客户端,这些消息可能包含有关SQL查询语句、数据库表结构和内容等敏感信息。

攻击者可以通过构造sql攻击语句,让应用程序触发错误或异常,并从中获取有利消息。举例如下:


SELECT * FROM users WHERE id=1 AND 1=(SELECT COUNT(*) FROM users GROUP BY CONCAT_WS(':', username, password));

1

该语句使用GROUP BY子句将用户名和密码进行连接,并通过CONCAT_WS函数指定分隔符。由于一个用户只能有一个密码,所以每个组别只有一条记录。COUNT() 函数用于返回匹配指定条件的行数,所以当我们使用COUNT函数统计结果时就可以将结果与数字1进行比较。


如果我们输入任意的用户名及密码,在数据库中查询不到该字段。导致数字1与查询结果不匹配,即1=0,该查询语句会触发一个错误消息,而错误消息可能包含有关SQL语句、数据库和表结构等敏感信息。


报错注入

报错注入是一种常见的 SQL 注入攻击方式,通过向输入参数中插入恶意 SQL 代码,从而导致数据库执行异常 SQL 语句并返回错误信息。攻击者可以通过分析错误信息来获取敏感信息或执行恶意操作。


简要分析利用字符集转换错误

攻击者在输入参数中插入特定的字符集转换函数,例如 CONVERT() 或 CAST(),从而导致数据库执行异常 SQL 语句。当数据库返回错误信息时,这些信息通常会包含一些关键信息,比如数据库名称、表名、字段名等。攻击者可以利用这些信息,进一步构造有效的注入攻击。


假设应用程序中有一个搜索功能,可以根据用户名查询用户信息。当用户输入用户名并提交查询请求时,应用程序会构造以下 SQL 查询语句:


SELECT * FROM users WHERE name='输入的用户名';

1

如果攻击者在输入框中输入以下查询条件:


' CONVERT(int, (SELECT TOP 1 password_hash FROM users)) --

1

则应用程序构造的 SQL 查询语句将变为:


SELECT * FROM users WHERE name='' CONVERT(int, (SELECT TOP 1 password_hash FROM users)) -- ';

1

这条 SQL 语句会触发数据库的异常错误,因为将一个字符串类型的参数转换为整数类型是不合法的。数据库返回的错误消息可能会包含一些关键信息,比如密码哈希值等。


报错注入与基于错误消息的sql注入区别

基于错误信息的 SQL 注入和报错注入其实是同一种攻击方式。它们都是利用了数据库执行异常 SQL 语句时返回错误信息的特性,从而获取敏感信息或执行恶意操作。

区别在于:

基于错误消息的 SQL 注入更侧重于利用错误消息中包含的关键信息,进一步构造有效的注入攻击。而报错注入则更侧重于向数据库中插入一些恶意代码或数据,从而触发数据库的异常错误。


已知用户名注入攻击原理

若已知用户名为qiu


基于- -注释符的sql注入

SQL 使用双短横线注释符号来注释掉整行的内容,并从双短横线开始一直到行末都不会被解释为有效的 SQL 语句。因此,攻击者可以在用户名或密码中添加 --,来注释掉后面的字符串,从而绕过过滤器的检测。例如用户名输入qiu'--,密码输入xx

注入语句等同于:


SELECT * FROM users WHERE username = 'qiu'--'  AND password = 'xx'

1

即SELECT * FROM users WHERE username = 'qiu'


这条 SQL 语句将只查询 users 表中用户名为qiu的记录。

基于/* */注释符的sql注入

SQL 使用斜线星号注释符号来注释掉多行的内容,从/* 开始,到*/结束的区域都会被注释掉。攻击者可以在用户名或密码中添加 /*,来注释掉后面的字符串。例如用户名输入qiu’/* ,密码输入xx

注入语句等同于:


SELECT * FROM users WHERE username = 'qiu'/* AND password = 'xx'

1

即SELECT * FROM users WHERE username = 'qiu'

这条 SQL 语句将只查询 users 表中用户名为qiu的记录。


注意:如果/*注释符号没有被正确地闭合掉,那么在执行 SQL 语句时就会出现语法错误,导致查询失败。为了避免这种情况的发生,一些 SQL 解析器会自动将后续的所有内容视为注释,直到遇到 */ 注释符号为止。


已知用户名与未知用户名攻击区别

对于未知用户名的注入攻击,注入成功后登录的是大概率是普通用户,而一般来说,获取管理员权限是黑客的主要目的。所以在知道管理员用户名时,可使用已知用户名攻击方式获取管理员权限,从而进行访问和窃取敏感数据、破坏和修改系统设置等恶意活动。同时,如果仅仅想登录系统获取相关信息,以上两种攻击方式均可选择。

sql注入绕过

一般来说,登录后端对用户名及密码有验证限制,例如:用户名、密码不能出现特殊字符等。此时常规的 SQL 注入攻击方式可能会被限制或无法成功实施。但这并不意味着 SQL 注入完全无法发生,攻击者仍然有可能利用其它漏洞点进行注入。


利用数字型注入

在数字型注入攻击中,攻击者通常会使用数字类型的变量或参数来注入恶意代码。攻击者将注入的恶意代码嵌入到数字型变量或参数中,并检查应用程序的响应结果以确定是否成功执行该注入。攻击者还可以利用数字运算符、格式字符串和其他SQL语法结构来进行数字型注入攻击。


基于布尔型运算的盲注攻击

盲注攻击是指攻击者无法直接获取查询结果,而只能通过不断猜测和推测来获得信息的一种注入攻击方式。

对于位置参数的SQL语句,攻击者可以通过修改参数值,并在其中嵌入布尔型运算符,从而利用盲注技术进行攻击。通常情况下,布尔型运算符的返回值只有真或假两种情况。

若后端语句如下:


SELECT * FROM users WHERE id = ?


其中id为位置参数,攻击者可以通过修改该参数值来构造恶意的查询语句,例如:


SELECT * FROM users WHERE id = 1 AND (SELECT COUNT(*) FROM users) > 0

1

在这个查询语句中,我们使用布尔型运算符 > 来判断user表中是否存在记录。如果该表中存在数据,那么COUNT函数返回的结果就大于0,故sql语句注入成功。通过不断尝试和推测,攻击者就可以逐步了解目标数据库的内容和结构等敏感信息。


基于联合查询的注入攻击

举例如下:


SELECT * FROM users WHERE id=1; DROP TABLE users;


这个可变参数值可以使SQL语句执行两个操作:首先查询 id 为 1 的用户信息,然后删除 users 表。因此,攻击者可以利用该漏洞非法地访问和操作数据库。

需要注意的是,由于大多数数字类型的数据都不允许附加特定的字符或语法结构。因此,攻击者需要结合使用其它方法,如二进制编码、脚本编码等,来成功地进行数字型注入攻击。


基于数字型操作符的注入攻击

攻击者还可以利用其他数字型操作符来构造注入,例如 AND、UNION、IN 等等。以 IN 操作符为例:

在 SQL 中,IN 操作符用于指定一个值集合,从而在查询时选择与该集合中任意一个值匹配的行。

例如,以下查询语句将检索 id 字段的值等于 1、2 或 3 的用户信息:


SELECT * FROM users WHERE id IN (1, 2, 3);


在数字型注入攻击中,攻击者可以利用这个操作符来向查询语句中注入恶意代码。例如:


SELECT * FROM users WHERE id IN (1, 2, 3) AND 1=1

由于布尔表达式 AND 1=1 恒成立,查询语句中前面的选择条件被忽略,而只保留了恒成立的后面的条件,从而使查询没有了限制条件。这就导致所有的用户记录都被返回。


利用模糊匹配注入

如果应用程序使用模糊匹配或通配符查询,攻击者可以在查询字符串中注入模糊匹配或通配符来扩展查询范围,检索到应用程序不打算公开的数据。

假设某个应用程序提供了一个搜索功能,可以根据关键字查询用户信息。该应用程序使用以下 SQL 查询语句来实现搜索功能:


SELECT * FROM users WHERE username LIKE '输入';


该功能使用了 LIKE 操作符。该操作符允许使用 % 和 _ 这两个通配符来代替查询字符串中的字符。

比如,abc%表示以 abc 开头的字符串,%abc表示以 abc 结尾的字符串。

例如,攻击者可输入如下语句:


xx OR 1=1--


语句变为:


SELECT * FROM users WHERE username LIKE ' xx OR 1=1-- ';

其中--可注释掉后面的语句,由于1=1恒成立,OR前的xx被省略,数据库会返回所有用户信息。


sql注入攻击思路

判断是否存在 Sql 注入漏洞

单引号判断法是一种简单的判断 SQL 注入漏洞的方法。该方法的基本原理是,在输入框中输入一个带有单引号的字符串,如果应用程序对输入参数没有进行正确的过滤和转义,则会发生语法错误,进而证明存在 SQL 注入漏洞。


具体步骤如下:


1.在输入框中输入一个带有单引号的字符串,例如 qiu'


2.观察是否发生了语法错误或异常提示


3.如果出现了语法错误或异常提示,那么说明该应用程序可能存在 SQL 注入漏洞


需要注意的是,单引号判断法只是一种初步的检测方法,不能保证能够检测所有的 SQL 注入漏洞。有些应用程序可能会对输入参数进行合理的过滤和转义,从而避免了单引号判断法的检测。


判断sql注入的类型

数字型注入的判断

假定后端逻辑为select * from <表名> where id = x


当输入x and 1=1时,sql语句变为:


select * from <表名> where id = x and 1=1


语法正确且逻辑判断为真,所以返回正常。


当输入x and 1=2时,sql语句变为:


select * from <表名> where id = x and 1=2


语法正确但是逻辑判断为假,所以返回错误。


若存在以上回显,即可判断该漏洞类型为数字型注入漏洞


字符型注入与数字型注入的区分

假定后端逻辑为select * from <表名> where id ='x'


当输入x and 1=1时,sql语句变为:


select * from <表名> where id ='x and 1=1'


当输入x' and '1'='2时,sql语句变为:


select * from <表名> where id = 'x and 1=2'


查询语句将 and 语句全部转换为了字符串,并没有进行 and 的逻辑判断,所以不会出现数字型注入中返回正常或返回错误的结果。

通过以上,即可判断:如果存在回显,则该漏洞类型不是字符型注入漏洞


字符型注入的判断:

假定后端逻辑为:select * from <表名> where id = 'x'


当输入x' and '1'='1时,sql 语句变为:


select * from <表名> where id = 'x' and '1'='1'


语法正确,逻辑判断正确,所以返回正确

当输入x' and '1'='2时,sql语句变为:


select * from <表名> where id = 'x' and '1'='2'


语法正确,但逻辑判断错误,所以返回错误

若存在以上回显,即可判断该漏洞类型为字符型注入漏洞

布尔型注入

基于布尔盲注的SQL注入攻击是一种利用目标Web应用程序对SQL查询条件正确/错误响应的不同表现来推测查询语句的正确性,从而获取数据库中敏感信息的攻击方式。

1)例如,攻击者可以构造如下SQL语句,用于判断某个字段是否存在:


SELECT CASE WHEN (username = 'admin') THEN 1 ELSE 0 END FROM users

1

这个查询语句选取了users表中的一个字段username,并通过CASE WHEN语句来判断该字段的值是否等于’admin’。如果字段的值等于’admin’,则返回1,说明该字段存在;否则,返回0,说明该字段不存在。


CASE WHEN语句是一个条件表达式,其基本形式如下:

CASE WHEN condition THEN expr1 [ELSE expr2] END

其中,condition是一个逻辑表达式,如果为真,则返回expr1;否则,返回expr2。


该类注入,是需要攻击者知道表名、列名及字段的。这里介绍一种使用ASCII码二分法逐一猜解表名、列名、字段的方法。


先确定要猜解的表名admin,再构造 SQL 查询语句,比如:


SELECT COUNT(*) FROM admin WHERE ascii(mid(table_name,N,1)) > X;

1

其中,N 表示正在猜解的字符在表名中从左到右的位置,X 表示当前猜测的 ASCII 码值。COUNT(*) 函数用于满足条件 ascii(mid(table_name,N,1)) > X 的行数。

若查询结果大于 0,则说明 实际ASCII码值大于当前猜测值,应将x取大;

反之,如果查询结果为 0,则说明实际ASCII 码值小于或等于当前猜测值,应将x取小。重复该步骤,直到找到当前字符的正确 ASCII 码值。


例如,表名第一个字符为a,a的ascii码是97。攻击者在不知道表名的情况下给x赋值,x取64,a>64,回显大于0;x取大,取96,回显大于0,再猜>100,回显小于0;x取小,取98,再猜>98,回显小于0,这样就知道ascii码是97了,即为a。


2)再者,攻击者可以通过修改查询语句中的条件表达式,来判断不同的字段是否存在或符合条件。如下语句可判断某个字段是否为数字类型:


SELECT CASE WHEN ISNUMERIC(column_name) = 1 THEN 1 ELSE 0 END FROM table_name


在这个语句中,ISNUMERIC函数用于判断column_name字段的值是否为数字。如果是数字类型,则返回1;否则,返回0。


时间盲注

基于时间盲注的SQL注入是一种利用Web应用程序对SQL语句的响应时间来推测查询语句正确性的攻击方式。攻击者不停地尝试不同的SQL语句,观察程序的响应时间,从而判断SQL语句是否正确,进而获取数据库中的敏感信息。

例如,攻击者可以构造如下查询语句:


SELECT * FROM users WHERE username = 'admin' AND password = 'password' AND sleep(5) #'


#起作用后,语句变为:


SELECT * FROM users WHERE username = 'admin' AND password = 'password' AND sleep(5)

1

其中,sleep函数用于让数据库暂停执行5秒钟的时间,以便观察Web应用程序的响应时间。如果程序响应时间增长,则说明该漏洞存在时间盲注。


联合注入

基于联合查询的SQL注入是一种数据库查询语句中包含联合查询的攻击方式。攻击者将原始查询结果与构造的SQL查询语句的结果联合到一起,从而获取敏感信息或执行恶意操作。

举例如下:


SELECT * FROM users WHERE username='admin' UNION SELECT NULL,NULL,NULL FROM information_schema.tables --

1

首先,查询 users 表中 username 值为 ‘admin’ 的记录,这是一个正常的 SQL 查询语句。

然后,使用UNION将查询结果与另一个 SELECT 语句的结果合并。第二个SELECT语句中插入了三个NULL 值,来匹配前面查询的 users 表中的字段数目。

最后,利用 – 来注释掉原本的 SQL 查询语句,从而执行恶意代码。攻击者可查询到 information_schema.tables 中的所有表名信息。


实例如下:


SELECT * FROM users WHERE username='admin' UNION SELECT credit_card_number, expiration_date FROM credit_cards

攻击者将从 credit_cards 表中获取到信用卡号和过期日期等敏感信息

若回显成功,则说明该漏洞存在联合注入。


总结

以上为SQL注入常见原理及攻击方法简析。由于SQL语言的复杂性、灵活性及作者水平有限,本文仅供参考;具体姿势及其它注入原理、方法读者可自行探索。

后续会分享DVWA应用程序及SQLLABS测试平台相关注入知识、攻击姿势。


我是秋说,我们下次见。


目录
相关文章
|
24天前
|
网络协议 安全 5G
网络与通信原理
【10月更文挑战第14天】网络与通信原理涉及众多方面的知识,从信号处理到网络协议,从有线通信到无线通信,从差错控制到通信安全等。深入理解这些原理对于设计、构建和维护各种通信系统至关重要。随着技术的不断发展,网络与通信原理也在不断演进和完善,为我们的生活和工作带来了更多的便利和创新。
61 3
|
28天前
|
安全 数据安全/隐私保护
谨防二维码陷阱:揭秘网络钓鱼攻击与保护措施
当我们深入了解二维码的世界时,了解它们的特性和潜在风险变得至关重要,揭示了伴随其广泛普及的更为阴暗的一面
|
8天前
|
存储 安全 网络安全
如何识别和防范网络钓鱼攻击?
通过以上方法的综合运用,可以有效识别和防范网络钓鱼攻击,降低遭受网络安全威胁的风险,保护个人信息和财产安全。
31 12
|
9天前
|
安全 网络安全 数据安全/隐私保护
社会工程学攻击:了解并预防心理操控的网络欺诈
社会工程学攻击:了解并预防心理操控的网络欺诈
22 7
|
6天前
|
运维 物联网 网络虚拟化
网络功能虚拟化(NFV):定义、原理及应用前景
网络功能虚拟化(NFV):定义、原理及应用前景
21 3
|
20天前
|
存储 安全 网络安全
互联网上如何有效应对网络勒索攻击?
有效应对网络勒索攻击需要采取多方面的措施,从预防、监测到应急响应和数据恢复等多个环节进行综合防护。
42 4
|
17天前
|
网络协议 安全 算法
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
实战:WireShark 抓包及快速定位数据包技巧、使用 WireShark 对常用协议抓包并分析原理 、WireShark 抓包解决服务器被黑上不了网等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
|
17天前
|
网络协议 安全 算法
网络空间安全之一个WH的超前沿全栈技术深入学习之路(9-2):WireShark 简介和抓包原理及实战过程一条龙全线分析——就怕你学成黑客啦!
实战:WireShark 抓包及快速定位数据包技巧、使用 WireShark 对常用协议抓包并分析原理 、WireShark 抓包解决服务器被黑上不了网等具体操作详解步骤;精典图示举例说明、注意点及常见报错问题所对应的解决方法IKUN和I原们你这要是学不会我直接退出江湖;好吧!!!
|
3天前
|
存储 SQL 安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【10月更文挑战第39天】在数字化时代,网络安全和信息安全成为了我们生活中不可或缺的一部分。本文将介绍网络安全漏洞、加密技术和安全意识等方面的内容,帮助读者更好地了解网络安全的重要性,并提供一些实用的技巧和方法来保护自己的信息安全。
14 2
|
4天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【10月更文挑战第38天】本文将探讨网络安全与信息安全的重要性,包括网络安全漏洞、加密技术和安全意识等方面。我们将通过代码示例和实际操作来展示如何保护网络和信息安全。无论你是个人用户还是企业,都需要了解这些知识以保护自己的网络安全和信息安全。