[网络安全]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测试平台相关注入知识、攻击姿势。


我是秋说,我们下次见。


目录
相关文章
|
2天前
|
机器学习/深度学习 数据采集 人工智能
GeneralDyG:南洋理工推出通用动态图异常检测方法,支持社交网络、电商和网络安全
GeneralDyG 是南洋理工大学推出的通用动态图异常检测方法,通过时间 ego-graph 采样、图神经网络和时间感知 Transformer 模块,有效应对数据多样性、动态特征捕捉和计算成本高等挑战。
31 18
GeneralDyG:南洋理工推出通用动态图异常检测方法,支持社交网络、电商和网络安全
|
5天前
|
机器学习/深度学习 算法 PyTorch
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
软演员-评论家算法(Soft Actor-Critic, SAC)是深度强化学习领域的重要进展,基于最大熵框架优化策略,在探索与利用之间实现动态平衡。SAC通过双Q网络设计和自适应温度参数,提升了训练稳定性和样本效率。本文详细解析了SAC的数学原理、网络架构及PyTorch实现,涵盖演员网络的动作采样与对数概率计算、评论家网络的Q值估计及其损失函数,并介绍了完整的SAC智能体实现流程。SAC在连续动作空间中表现出色,具有高样本效率和稳定的训练过程,适合实际应用场景。
33 7
深度强化学习中SAC算法:数学原理、网络架构及其PyTorch实现
|
29天前
|
机器学习/深度学习 数据采集 人工智能
基于Huffman树的层次化Softmax:面向大规模神经网络的高效概率计算方法
层次化Softmax算法通过引入Huffman树结构,将传统Softmax的计算复杂度从线性降至对数级别,显著提升了大规模词汇表的训练效率。该算法不仅优化了计算效率,还在处理大规模离散分布问题上提供了新的思路。文章详细介绍了Huffman树的构建、节点编码、概率计算及基于Gensim的实现方法,并讨论了工程实现中的优化策略与应用实践。
68 15
基于Huffman树的层次化Softmax:面向大规模神经网络的高效概率计算方法
|
14天前
|
前端开发 网络协议 安全
【网络原理】——HTTP协议、fiddler抓包
HTTP超文本传输,HTML,fiddler抓包,URL,urlencode,HTTP首行方法,GET方法,POST方法
|
14天前
|
域名解析 网络协议 关系型数据库
【网络原理】——带你认识IP~(长文~实在不知道取啥标题了)
IP协议详解,IP协议管理地址(NAT机制),IP地址分类、组成、特殊IP地址,MAC地址,数据帧格式,DNS域名解析系统
|
14天前
|
存储 JSON 缓存
【网络原理】——HTTP请求头中的属性
HTTP请求头,HOST、Content-Agent、Content-Type、User-Agent、Referer、Cookie。
|
14天前
|
安全 算法 网络协议
【网络原理】——图解HTTPS如何加密(通俗简单易懂)
HTTPS加密过程,明文,密文,密钥,对称加密,非对称加密,公钥和私钥,证书加密
|
14天前
|
XML JSON 网络协议
【网络原理】——拥塞控制,延时/捎带应答,面向字节流,异常情况
拥塞控制,延时应答,捎带应答,面向字节流(粘包问题),异常情况(心跳包)
|
16天前
|
网络协议 安全 网络安全
探索网络模型与协议:从OSI到HTTPs的原理解析
OSI七层网络模型和TCP/IP四层模型是理解和设计计算机网络的框架。OSI模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,而TCP/IP模型则简化为链路层、网络层、传输层和 HTTPS协议基于HTTP并通过TLS/SSL加密数据,确保安全传输。其连接过程涉及TCP三次握手、SSL证书验证、对称密钥交换等步骤,以保障通信的安全性和完整性。数字信封技术使用非对称加密和数字证书确保数据的机密性和身份认证。 浏览器通过Https访问网站的过程包括输入网址、DNS解析、建立TCP连接、发送HTTPS请求、接收响应、验证证书和解析网页内容等步骤,确保用户与服务器之间的安全通信。
71 1
|
21天前
|
域名解析 缓存 网络协议
优化Lua-cURL:减少网络请求延迟的实用方法
优化Lua-cURL:减少网络请求延迟的实用方法

热门文章

最新文章