一、 编码绕过 (Encoding Bypass)
编码绕过技术利用了编码方式对特殊字符的转化,绕过了过滤机制。常见的编码绕过包括 URL 编码、HTML 编码、十六进制编码和Unicode编码等。
- URL编码
URL编码用于将 URL 中的字符转换为其 ASCII 码的百分比表示形式。通常,它可以用来绕过一些简单的输入过滤机制,因为过滤器可能没有识别编码后的字符。
举例:
假设目标SQL查询如下:
SELECT * FROM users WHERE id=1;
可以将查询中的空格替换为 URL 编码 %20:
index.php?id=1%20AND%201=1
其中 %20 等同于空格。
- HTML编码
HTML编码是将字符转换为 HTML 实体字符编码的方式,绕过一些只对可见字符进行过滤的场景。例如,&amp; 被编码为 &amp;,< 被编码为 &lt;。
举例:
index.php?id=1&amp;AND&amp;1=1
这个方式能够绕过一些只对简单字符(如空格、&)进行过滤的防护机制。
- 十六进制编码
在SQL注入中,可以使用十六进制表示字符。这种方法可以绕过一些SQL过滤机制,因为某些过滤器可能无法识别十六进制表示。
举例:
假设 0x27 代表单引号 ',可以将单引号编码为十六进制形式:
index.php?id=1 AND ascii(CHAR(0x27))=39
- Unicode编码
Unicode编码将字符转换为 Unicode 标识符,可以在某些数据库管理系统中绕过过滤。特别是对于含有特殊字符的攻击,可以尝试用Unicode编码。
举例:
假设我们想绕过对 ' 单引号的过滤,可以使用 u0027 来代替:
index.php?id=1 AND ascii(u0027)=39
二、大小写绕过 (Case Sensitivity Bypass)
SQL关键字在多数数据库中是不区分大小写的。攻击者可以通过变换关键字的大小写,绕过一些对SQL关键字的过滤。
举例:
在一个过滤器只允许大写字母的情况下,可以使用以下大小写混合的方式绕过:
index.php?id=1 AnD 1=1
在这种情况下,AND 关键字的大小写被改变为 AnD,并且数据库在解析时依然会正确执行。
三、 注释绕过 (Comment Bypass)
SQL注释是SQL语句中用于忽略部分内容的标记。通过插入注释,攻击者可以注入恶意SQL代码并阻止被过滤的部分语句执行。
- 单行注释
SQL注释语法 -- 或 # 可以用于注释掉后面的SQL语句。
举例:
index.php?id=1--%20AND%201=1
该注入将 AND 1=1 部分注释掉,因此SQL查询中不会执行被过滤的部分。
- 多行注释
/**/ 用于表示多行注释,可以绕过一些过滤机制,尤其是用于注入较长的SQL片段。
举例:
index.php?id=1/**/AND/**/1=1
- MySQL特有注释
(/*! … */)
MySQL支持特有的注释形式 /*! ... */,该形式的注释只有MySQL服务器识别和执行,其他数据库系统(如PostgreSQL)会忽略它。
举例:
index.php?id=-1/*!UNION*//*!SELECT*/1,2,3
这种注释方式在MySQL环境下非常有效,允许攻击者只在MySQL中执行特定的SQL语句,绕过某些过滤机制。
四、 函数替换 (Function Substitution)
某些SQL注入防护机制会通过过滤常见的SQL关键字来阻止注入。攻击者可以通过替代这些过滤的关键字或函数来绕过防护。
- 使用子串函数 (Substring / Mid)
SQL注入常用的 SELECT 语句可以通过一些数据库内建的函数来替代。例如,在某些情况下可以使用 SUBSTRING()(或 MID())函数替代原始的 SELECT 查询。
举例:
index.php?id=-1 AND substring('SELECT 1,2,3', 1, 6)
- ASCII / HEX / BIN 函数
ASCII()、HEX() 和 BIN() 等函数可以转换字符为数字、十六进制或二进制,帮助绕过简单的字符过滤。
举例:
index.php?id=-1 AND ascii('A') = 65
- 使用 Benchmark / Sleep 函数
SLEEP() 和 BENCHMARK() 可以引起延迟,通常在盲注(blind injection)中用于确认漏洞的存在。
举例:
index.php?id=1AND SLEEP(5)
在SQL注入攻击中,延时操作(例如 SLEEP(5))可以帮助确认是否成功执行了注入。如果页面加载明显变慢,则表示SQL语句已经成功执行。
五、 变量替换 (Variable Substitution)
数据库支持使用系统变量来获取某些信息。攻击者可以使用这些系统变量来进一步操控查询或获取敏感信息。
举例:
获取当前数据库用户:user()
获取当前数据库的连接用户:@@user
index.php?id=-1ANDuser() ='root'
六、符号与关键字替换 (Symbol and Keyword Replacement)
某些SQL注入防护会过滤常见的SQL关键字,如 AND、OR、UNION 等。攻击者可以用其他符号或函数替代这些关键字来绕过过滤。
- 替代 AND / OR
可以使用 & 替代 AND,| 替代 OR。
举例:
index.php?id=1&1=1
在某些情况下,数据库会理解 & 和 AND 作为同义词,从而绕过 AND 关键字的过滤。
七、 HTTP参数污染 (HTTP Parameter Pollution)
HTTP参数污染是通过发送多个相同的查询参数来混淆服务器。不同的Web服务器或框架对这些重复参数的处理方式不同,攻击者可以利用这个差异进行注入。
举例:
假设存在多个参数 id:
http://example.com/page?id=1&id=2&id=3
在某些Web应用中,服务器会处理所有 id 参数并返回多个值。不同的后端框架或解析器可能会以不同的方式处理这些参数,从而可能允许攻击者注入不同的SQL语句。
八、 缓冲区溢出 (Buffer Overflow)
缓冲区溢出攻击并不直接与SQL注入相关,但在某些情况下,尤其是Web应用程序的底层是用C语言或C++编写时,SQL注入的恶意负载可能通过发送过长的数据包触发缓冲区溢出,从而绕过过滤器。
- 利用过长数据包
攻击者可能通过发送特别长的SQL注入数据包,超出缓冲区的限制,来触发溢出并绕过防护。
九、 二次注入 (Second-Order Injection)
二次注入是指攻击者将恶意负载分成多个查询进行注入,绕过单次注入长度限制。这种攻击常见于字段输入有长度限制的场景。
- 分批注入
当目标数据库字段存在长度限制时,攻击者可以通过分多个阶段发送SQL命令,绕过每次注入时对字段长度的限制。
举例:
假设每次注入的SQL查询有长度限制,攻击者可以将payload分成多个查询阶段,逐步注入到数据库中。
十、 时间盲注(Time-Based Blind Injection)
时间盲注是一种利用数据库执行时间差来确认注入是否成功的方法。攻击者可以使用 SLEEP() 或类似的延时函数来引起数据库延时,如果服务器响应时间增加,就意味着注入成功。
举例:
如果目标应用存在盲注漏洞,攻击者可以构造以下请求:
index.php?id=1 AND SLEEP(5)
如果页面响应延迟5秒,则表明SQL查询执行成功。利用这种方式,攻击者可以逐步推测出数据库结构、表名、列名等信息。
- 盲注语句(Boolean Blind Injection)
如果没有显式错误信息返回,攻击者可以通过测试返回的真假结果来判断查询是否成功执行。
例如:
index.php?id=1 AND 1=1 -- (返回真)
index.php?id=1 AND 1=2 -- (返回假)
通过这种方式,攻击者可以猜测出数据库的具体内容。
十一、盲注的二次注入(Second-Order Blind Injection)
二次盲注与二次注入类似,但在盲注的情境下,攻击者必须通过多个请求来注入和验证数据。这意味着注入的payload首先会被存储或处理,并且直到后续请求时才能触发SQL查询的执行。
举例:
假设攻击者能够通过用户注册、登录等功能插入SQL片段,这些片段在后续请求(如身份验证、数据查看等)时被触发。比如,首先将SQL注入字符串存入某字段:
index.php?username=admin' --
然后,系统将admin' --保存,直到进行身份验证时,通过后续请求触发SQL查询。
十二、 基于错误的注入(Error-Based Injection)
在基于错误的SQL注入中,攻击者通过触发数据库错误来泄漏信息。这类攻击依赖于数据库在发生错误时返回详细的错误消息,攻击者可以通过分析错误信息来进一步推断数据库的结构和内容。
举例:
index.php?id=1' OR 1=1 --
如果数据库返回详细错误信息,例如“SQL syntax error”或“Unknown column”,攻击者就可以通过错误信息推测出数据库的表结构、列名或数据类型。
十三、 联合查询注入(Union-Based Injection)
联合查询注入是通过在原有SQL查询中加入 UNION 查询语句来返回额外的结果。攻击者可以利用 UNION 操作符来从数据库中获取其他表的信息,通常用来泄漏敏感数据。
举例:
假设查询本应返回用户信息:
SELECT id, name FROM users WHERE id=1;
攻击者可能通过注入 UNION 查询来检索数据库中的其他表或列:
index.php?id=1UNIONSELECT username, password FROM users;
这样,攻击者就可以将 users 表的 username 和 password 字段的值返回到前端,甚至进一步通过联合查询暴露数据库中的敏感信息。
十四、 注入中的字符限制(Character Encoding Limitations)
当输入字段的长度受到限制时,攻击者可以通过多个请求或特殊编码的方式将SQL注入分成多个片段。这样,即使单个字段长度受限,攻击者也能绕过限制,逐步完成注入。
举例:
假设SQL查询的输入字段长度限制为某个固定长度,攻击者可以通过拆分SQL注入payload来分多次注入。通过不断发送请求,逐步构造完整的注入语句。
十五、多阶段注入(Multi-Stage Injection)
多阶段注入与二次注入相似,不同的是它需要更多的操作来最终触发完整的攻击。在某些场景下,攻击者可以通过在不同的请求阶段分开注入有效载荷来绕过检测和过滤。
举例:
假设攻击者在第一个请求阶段插入SQL片段到数据库中,之后通过另一个请求触发SQL查询并执行。例如:
1.第一个请求注入SQL代码:
index.php?id=1' --
2.第二个请求中,通过后续查询触发并执行SQL查询。
通过分阶段的注入,攻击者可以绕过单次请求的字符限制或过滤机制。
十六、基于文件的注入(File Inclusion)
某些Web应用程序允许用户输入文件路径或文件名,攻击者可以利用文件包含漏洞,通过注入恶意的文件路径,导致系统执行恶意脚本或SQL查询。虽然这种攻击主要与文件包含漏洞相关,但它与SQL注入结合使用时,也能绕过防护机制。
举例:
index.php?page=evilfile.php?cmd=1;DROPTABLE users;
在这种情况下,攻击者通过注入一个包含恶意SQL命令的文件路径,可能会导致SQL查询的执行。
十七、 混淆(Obfuscation)
SQL注入混淆是指攻击者通过改变注入payload的形态,使其对自动化防护工具难以识别,但依然能被数据库解析执行。常见的混淆方法包括:
1.插入无效的空格
2.插入注释·
3.使用不同的SQL符号替代原始符号(如 OR 改为 |,AND 改为 &)
举例:
index.php?id=1/**/AND/**/1=1
这种注入通过插入 /**/ 来混淆SQL语句,绕过一些基于模式的检测。
十八、 环境特定的绕过(Environment-Specific Bypass)
不同的数据库管理系统(DBMS)可能会有不同的SQL语法和行为,攻击者可以利用这些特定的差异进行绕过。例如,MySQL和PostgreSQL的SQL语法和函数不同,攻击者可以针对具体数据库来调整注入payload。
举例:
在MySQL中,LIMIT 用来限制返回的结果数量,而在PostgreSQL中,LIMIT 可能会被替换为 FETCHFIRST 等。
攻击者可以利用这些差异调整SQL语句来规避过滤和防护。
原文始发于微信公众号(信安一把索):web漏洞挖掘方法 - sql注入绕过篇
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论